summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michael Wright <michaelwr@google.com> 2016-07-12 13:30:53 -0700
committer Michael Wright <michaelwr@google.com> 2016-07-15 14:20:36 -0700
commit28f24d0ab481bd9c6fd5618414fee694e837c5c6 (patch)
treeadccc010077cbfb5ca7240df513bae5de7943e68
parent57243a2a26cf7280c0a819d7f95821e6c2efa440 (diff)
Color transforms are now color modes.
Rename color transforms to color modes for all interfaces exposed to surfaceflinger clients. Also split it out to be a separate configuration value from display modes. Bug: 29044347 Change-Id: I87e937f7c954a50c946e8e2c606797caa416c5d8
-rw-r--r--include/gui/ISurfaceComposer.h9
-rw-r--r--include/gui/SurfaceComposerClient.h10
-rw-r--r--include/ui/DisplayInfo.h1
-rw-r--r--libs/gui/ISurfaceComposer.cpp128
-rw-r--r--libs/gui/SurfaceComposerClient.cpp16
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp11
-rw-r--r--services/surfaceflinger/DisplayDevice.h9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.cpp9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp78
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h21
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp25
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp13
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h13
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp109
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h19
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp68
18 files changed, 465 insertions, 82 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index af26721b35..74a4123bb6 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -137,6 +137,12 @@ public:
* should be used */
virtual status_t setActiveConfig(const sp<IBinder>& display, int id) = 0;
+ virtual status_t getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes) = 0;
+ virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) = 0;
+ virtual status_t setActiveColorMode(const sp<IBinder>& display,
+ android_color_mode_t colorMode) = 0;
+
/* Capture the specified screen. requires READ_FRAME_BUFFER permission
* This function will fail if there is a secure window on screen.
*/
@@ -193,6 +199,9 @@ public:
SET_POWER_MODE,
GET_DISPLAY_STATS,
GET_HDR_CAPABILITIES,
+ GET_DISPLAY_COLOR_MODES,
+ GET_ACTIVE_COLOR_MODE,
+ SET_ACTIVE_COLOR_MODE,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 95e8b70c61..b8ee331736 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -83,6 +83,16 @@ public:
// returned by getDisplayInfo
static status_t setActiveConfig(const sp<IBinder>& display, int id);
+ // Gets the list of supported color modes for the given display
+ static status_t getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes);
+
+ // Gets the active color mode for the given display
+ static android_color_mode_t getActiveColorMode(const sp<IBinder>& display);
+
+ // Sets the active color mode for the given display
+ static status_t setActiveColorMode(const sp<IBinder>& display, android_color_mode_t colorMode);
+
/* Triggers screen on/off or low power mode and waits for it to complete */
static void setDisplayPowerMode(const sp<IBinder>& display, int mode);
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index ad73ee72f9..799944f3ee 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -36,7 +36,6 @@ struct DisplayInfo {
bool secure;
nsecs_t appVsyncOffset;
nsecs_t presentationDeadline;
- int colorTransform;
};
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a8b4fa8226..f0b0ada270 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -32,6 +32,8 @@
#include <private/gui/LayerState.h>
+#include <system/graphics.h>
+
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
#include <ui/HdrCapabilities.h>
@@ -269,6 +271,82 @@ public:
return reply.readInt32();
}
+ virtual status_t getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes) {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayColorModes failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayColorModes failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_COLOR_MODES, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayColorModes failed to transact: %d", result);
+ return result;
+ }
+ result = static_cast<status_t>(reply.readInt32());
+ if (result == NO_ERROR) {
+ size_t numModes = reply.readUint32();
+ outColorModes->clear();
+ outColorModes->resize(numModes);
+ for (size_t i = 0; i < numModes; ++i) {
+ outColorModes->replaceAt(static_cast<android_color_mode_t>(reply.readInt32()), i);
+ }
+ }
+ return result;
+ }
+
+ virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getActiveColorMode failed to writeInterfaceToken: %d", result);
+ return static_cast<android_color_mode_t>(result);
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("getActiveColorMode failed to writeStrongBinder: %d", result);
+ return static_cast<android_color_mode_t>(result);
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_ACTIVE_COLOR_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getActiveColorMode failed to transact: %d", result);
+ return static_cast<android_color_mode_t>(result);
+ }
+ return static_cast<android_color_mode_t>(reply.readInt32());
+ }
+
+ virtual status_t setActiveColorMode(const sp<IBinder>& display,
+ android_color_mode_t colorMode) {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("setActiveColorMode failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("setActiveColorMode failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = data.writeInt32(colorMode);
+ if (result != NO_ERROR) {
+ ALOGE("setActiveColorMode failed to writeInt32: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::SET_ACTIVE_COLOR_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("setActiveColorMode failed to transact: %d", result);
+ return result;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
virtual status_t clearAnimationFrameStats() {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -469,6 +547,56 @@ status_t BnSurfaceComposer::onTransact(
reply->writeInt32(result);
return NO_ERROR;
}
+ case GET_DISPLAY_COLOR_MODES: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ Vector<android_color_mode_t> colorModes;
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayColorModes failed to readStrongBinder: %d", result);
+ return result;
+ }
+ result = getDisplayColorModes(display, &colorModes);
+ reply->writeInt32(result);
+ if (result == NO_ERROR) {
+ reply->writeUint32(static_cast<uint32_t>(colorModes.size()));
+ for (size_t i = 0; i < colorModes.size(); ++i) {
+ reply->writeInt32(colorModes[i]);
+ }
+ }
+ return NO_ERROR;
+ }
+ case GET_ACTIVE_COLOR_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
+ return result;
+ }
+ android_color_mode_t colorMode = getActiveColorMode(display);
+ result = reply->writeInt32(static_cast<int32_t>(colorMode));
+ return result;
+ }
+ case SET_ACTIVE_COLOR_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
+ return result;
+ }
+ int32_t colorModeInt = 0;
+ result = data.readInt32(&colorModeInt);
+ if (result != NO_ERROR) {
+ ALOGE("setActiveColorMode failed to readInt32: %d", result);
+ return result;
+ }
+ result = setActiveColorMode(display,
+ static_cast<android_color_mode_t>(colorModeInt));
+ result = reply->writeInt32(result);
+ return result;
+ }
case CLEAR_ANIMATION_FRAME_STATS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
status_t result = clearAnimationFrameStats();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 26b2209e6a..3df5f74fc9 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -29,6 +29,8 @@
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
+#include <system/graphics.h>
+
#include <ui/DisplayInfo.h>
#include <gui/CpuConsumer.h>
@@ -771,6 +773,20 @@ status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int
return ComposerService::getComposerService()->setActiveConfig(display, id);
}
+status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes) {
+ return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes);
+}
+
+android_color_mode_t SurfaceComposerClient::getActiveColorMode(const sp<IBinder>& display) {
+ return ComposerService::getComposerService()->getActiveColorMode(display);
+}
+
+status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display,
+ android_color_mode_t colorMode) {
+ return ComposerService::getComposerService()->setActiveColorMode(display, colorMode);
+}
+
void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token,
int mode) {
ComposerService::getComposerService()->setPowerMode(token, mode);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index a67b3ffa22..5c2c0adf3a 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -415,6 +415,17 @@ int DisplayDevice::getActiveConfig() const {
}
// ----------------------------------------------------------------------------
+#ifdef USE_HWC2
+void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
+ mActiveColorMode = mode;
+}
+
+android_color_mode_t DisplayDevice::getActiveColorMode() const {
+ return mActiveColorMode;
+}
+#endif
+
+// ----------------------------------------------------------------------------
void DisplayDevice::setLayerStack(uint32_t stack) {
mLayerStack = stack;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index dd9b104f4e..105e980ab4 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -182,6 +182,11 @@ public:
void setPowerMode(int mode);
bool isDisplayOn() const;
+#ifdef USE_HWC2
+ android_color_mode_t getActiveColorMode() const;
+ void setActiveColorMode(android_color_mode_t mode);
+#endif
+
/* ------------------------------------------------------------------------
* Display active config management.
*/
@@ -252,6 +257,10 @@ private:
int mPowerMode;
// Current active config
int mActiveConfig;
+#ifdef USE_HWC2
+ // current active color mode
+ android_color_mode_t mActiveColorMode;
+#endif
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 87a0e9a13a..4fe3cfd03e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -581,7 +581,7 @@ Error Display::getChangedCompositionTypes(
return Error::None;
}
-Error Display::getColorModes(std::vector<int32_t>* outModes) const
+Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
{
uint32_t numModes = 0;
int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
@@ -599,7 +599,10 @@ Error Display::getColorModes(std::vector<int32_t>* outModes) const
return error;
}
- std::swap(*outModes, modes);
+ outModes->resize(numModes);
+ for (size_t i = 0; i < numModes; i++) {
+ (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
+ }
return Error::None;
}
@@ -805,7 +808,7 @@ Error Display::setClientTarget(buffer_handle_t target,
return static_cast<Error>(intError);
}
-Error Display::setColorMode(int32_t mode)
+Error Display::setColorMode(android_color_mode_t mode)
{
int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
return static_cast<Error>(intError);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index beb7bc6689..fb04af877e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -282,7 +282,7 @@ public:
[[clang::warn_unused_result]] Error getChangedCompositionTypes(
std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes);
[[clang::warn_unused_result]] Error getColorModes(
- std::vector<int32_t>* outModes) const;
+ std::vector<android_color_mode_t>* outModes) const;
// Doesn't call into the HWC2 device, so no errors are possible
std::vector<std::shared_ptr<const Config>> getConfigs() const;
@@ -307,7 +307,7 @@ public:
buffer_handle_t target,
const android::sp<android::Fence>& acquireFence,
android_dataspace_t dataspace);
- [[clang::warn_unused_result]] Error setColorMode(int32_t mode);
+ [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
[[clang::warn_unused_result]] Error setColorTransform(
const android::mat4& matrix, android_color_transform_t hint);
[[clang::warn_unused_result]] Error setOutputBuffer(
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index e739ef45f5..8bcee39b9d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -75,7 +75,7 @@ static hwc2_function_pointer_t asFP(T function)
using namespace HWC2;
-static constexpr Attribute ColorTransform = static_cast<Attribute>(6);
+static constexpr Attribute ColorMode = static_cast<Attribute>(6);
namespace android {
@@ -268,9 +268,7 @@ hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
&Display::setClientTarget, buffer_handle_t, int32_t,
int32_t, hwc_region_t>);
case FunctionDescriptor::SetColorMode:
- return asFP<HWC2_PFN_SET_COLOR_MODE>(
- displayHook<decltype(&Display::setColorMode),
- &Display::setColorMode, int32_t>);
+ return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
case FunctionDescriptor::SetColorTransform:
return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
case FunctionDescriptor::SetOutputBuffer:
@@ -894,7 +892,7 @@ Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
return Error::None;
}
-Error HWC2On1Adapter::Display::setColorMode(int32_t mode)
+Error HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode)
{
std::unique_lock<std::recursive_mutex> lock (mStateMutex);
@@ -1198,11 +1196,14 @@ void HWC2On1Adapter::Display::populateConfigs()
newConfig->setAttribute(Attribute::DpiY,
values[attributeMap[HWC_DISPLAY_DPI_Y]]);
if (hasColor) {
- newConfig->setAttribute(ColorTransform,
+ // In HWC1, color modes are referred to as color transforms. To avoid confusion with
+ // the HWC2 concept of color transforms, we internally refer to them as color modes for
+ // both HWC1 and 2.
+ newConfig->setAttribute(ColorMode,
values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
}
- // We can only do this after attempting to read the color transform
+ // We can only do this after attempting to read the color mode
newConfig->setHwc1Id(hwc1ConfigId);
for (auto& existingConfig : mConfigs) {
@@ -1678,8 +1679,8 @@ int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const
void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id)
{
- int32_t colorTransform = getAttribute(ColorTransform);
- mHwc1Ids.emplace(colorTransform, id);
+ android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
+ mHwc1Ids.emplace(colorMode, id);
}
bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const
@@ -1692,18 +1693,20 @@ bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const
return false;
}
-int32_t HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
- uint32_t id) const
+Error HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
+ uint32_t id, android_color_mode_t* outMode) const
{
for (const auto& idPair : mHwc1Ids) {
if (id == idPair.second) {
- return idPair.first;
+ *outMode = idPair.first;
+ return Error::None;
}
}
- return -1;
+ ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
+ return Error::BadParameter;
}
-Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(int32_t mode,
+Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
uint32_t* outId) const
{
for (const auto& idPair : mHwc1Ids) {
@@ -1726,25 +1729,26 @@ bool HWC2On1Adapter::Display::Config::merge(const Config& other)
return false;
}
}
- int32_t otherColorTransform = other.getAttribute(ColorTransform);
- if (mHwc1Ids.count(otherColorTransform) != 0) {
+ android_color_mode_t otherColorMode =
+ static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
+ if (mHwc1Ids.count(otherColorMode) != 0) {
ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
- "identical", mHwc1Ids.at(otherColorTransform),
- other.mHwc1Ids.at(otherColorTransform));
+ "identical", mHwc1Ids.at(otherColorMode),
+ other.mHwc1Ids.at(otherColorMode));
return false;
}
- mHwc1Ids.emplace(otherColorTransform,
- other.mHwc1Ids.at(otherColorTransform));
+ mHwc1Ids.emplace(otherColorMode,
+ other.mHwc1Ids.at(otherColorMode));
return true;
}
-std::set<int32_t> HWC2On1Adapter::Display::Config::getColorTransforms() const
+std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const
{
- std::set<int32_t> colorTransforms;
+ std::set<android_color_mode_t> colorModes;
for (const auto& idPair : mHwc1Ids) {
- colorTransforms.emplace(idPair.first);
+ colorModes.emplace(idPair.first);
}
- return colorTransforms;
+ return colorModes;
}
std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const
@@ -1787,15 +1791,15 @@ std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const
for (const auto& id : mHwc1Ids) {
- int32_t colorTransform = id.first;
+ android_color_mode_t colorMode = id.first;
uint32_t hwc1Id = id.second;
std::memset(buffer, 0, BUFFER_SIZE);
- if (colorTransform == mDisplay.mActiveColorMode) {
+ if (colorMode == mDisplay.mActiveColorMode) {
writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
- colorTransform);
+ colorMode);
} else {
writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
- colorTransform);
+ colorMode);
}
output.append(buffer, writtenBytes);
}
@@ -1814,10 +1818,10 @@ std::shared_ptr<const HWC2On1Adapter::Display::Config>
void HWC2On1Adapter::Display::populateColorModes()
{
- mColorModes = mConfigs[0]->getColorTransforms();
+ mColorModes = mConfigs[0]->getColorModes();
for (const auto& config : mConfigs) {
- std::set<int32_t> intersection;
- auto configModes = config->getColorTransforms();
+ std::set<android_color_mode_t> intersection;
+ auto configModes = config->getColorModes();
std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
configModes.cbegin(), configModes.cend(),
std::inserter(intersection, intersection.begin()));
@@ -1830,7 +1834,7 @@ void HWC2On1Adapter::Display::initializeActiveConfig()
if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
ALOGV("getActiveConfig is null, choosing config 0");
mActiveConfig = mConfigs[0];
- mActiveColorMode = -1;
+ mActiveColorMode = HAL_COLOR_MODE_NATIVE;
return;
}
@@ -1842,7 +1846,13 @@ void HWC2On1Adapter::Display::initializeActiveConfig()
ALOGV("Setting active config to %d for HWC1 config %u",
config->getId(), activeConfig);
mActiveConfig = config;
- mActiveColorMode = config->getColorModeForHwc1Id(activeConfig);
+ if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
+ // This should never happen since we checked for the config's presence before
+ // setting it as active.
+ ALOGE("Unable to find color mode for active HWC1 config %d",
+ config->getId());
+ mActiveColorMode = HAL_COLOR_MODE_NATIVE;
+ }
break;
}
}
@@ -1850,7 +1860,7 @@ void HWC2On1Adapter::Display::initializeActiveConfig()
ALOGV("Unable to find active HWC1 config %u, defaulting to "
"config 0", activeConfig);
mActiveConfig = mConfigs[0];
- mActiveColorMode = -1;
+ mActiveColorMode = HAL_COLOR_MODE_NATIVE;
}
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
index dc7c355617..bdacc737c6 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
@@ -213,7 +213,7 @@ private:
HWC2::Error setClientTarget(buffer_handle_t target,
int32_t acquireFence, int32_t dataspace,
hwc_region_t damage);
- HWC2::Error setColorMode(int32_t mode);
+ HWC2::Error setColorMode(android_color_mode_t mode);
HWC2::Error setColorTransform(android_color_transform_t hint);
HWC2::Error setOutputBuffer(buffer_handle_t buffer,
int32_t releaseFence);
@@ -258,8 +258,9 @@ private:
void setHwc1Id(uint32_t id);
bool hasHwc1Id(uint32_t id) const;
- int32_t getColorModeForHwc1Id(uint32_t id) const;
- HWC2::Error getHwc1IdForColorMode(int32_t mode,
+ HWC2::Error getColorModeForHwc1Id(uint32_t id,
+ android_color_mode_t *outMode) const;
+ HWC2::Error getHwc1IdForColorMode(android_color_mode_t mode,
uint32_t* outId) const;
void setId(hwc2_config_t id) { mId = id; }
@@ -269,7 +270,7 @@ private:
// mode. Returns whether the merge was successful
bool merge(const Config& other);
- std::set<int32_t> getColorTransforms() const;
+ std::set<android_color_mode_t> getColorModes() const;
// splitLine divides the output into two lines suitable for
// dumpsys SurfaceFlinger
@@ -281,7 +282,7 @@ private:
std::unordered_map<HWC2::Attribute, int32_t> mAttributes;
// Maps from color transform to HWC1 config ID
- std::unordered_map<int32_t, uint32_t> mHwc1Ids;
+ std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
};
class Changes {
@@ -378,8 +379,8 @@ private:
std::vector<std::shared_ptr<Config>> mConfigs;
std::shared_ptr<const Config> mActiveConfig;
- std::set<int32_t> mColorModes;
- int32_t mActiveColorMode;
+ std::set<android_color_mode_t> mColorModes;
+ android_color_mode_t mActiveColorMode;
std::string mName;
HWC2::DisplayType mType;
HWC2::PowerMode mPowerMode;
@@ -432,6 +433,12 @@ private:
hint);
}
+ static int32_t setColorModeHook(hwc2_device_t* device,
+ hwc2_display_t display, int32_t /*android_color_mode_t*/ intMode) {
+ auto mode = static_cast<android_color_mode_t>(intMode);
+ return callDisplayFunction(device, display, &Display::setColorMode, mode);
+ }
+
static int32_t setPowerModeHook(hwc2_device_t* device,
hwc2_display_t display, int32_t intMode) {
auto mode = static_cast<HWC2::PowerMode>(intMode);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 199848f767..4ac58c5984 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -364,8 +364,8 @@ std::shared_ptr<const HWC2::Display::Config>
return config;
}
-std::vector<int32_t> HWComposer::getColorModes(int32_t displayId) const {
- std::vector<int32_t> modes;
+std::vector<android_color_mode_t> HWComposer::getColorModes(int32_t displayId) const {
+ std::vector<android_color_mode_t> modes;
if (!isValidDisplay(displayId)) {
ALOGE("getColorModes: Attempted to access invalid display %d",
@@ -379,12 +379,31 @@ std::vector<int32_t> HWComposer::getColorModes(int32_t displayId) const {
if (error != HWC2::Error::None) {
ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
to_string(error).c_str(), static_cast<int32_t>(error));
- return std::vector<int32_t>();
+ return std::vector<android_color_mode_t>();
}
return modes;
}
+status_t HWComposer::setActiveColorMode(int32_t displayId, android_color_mode_t mode) {
+ if (!isValidDisplay(displayId)) {
+ ALOGE("setActiveColorMode: Display %d is not valid", displayId);
+ return BAD_INDEX;
+ }
+
+ auto& displayData = mDisplayData[displayId];
+ auto error = displayData.hwcDisplay->setColorMode(mode);
+ if (error != HWC2::Error::None) {
+ ALOGE("setActiveConfig: Failed to set color mode %d on display %d: "
+ "%s (%d)", mode, displayId, to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ return UNKNOWN_ERROR;
+ }
+
+ return NO_ERROR;
+}
+
+
void HWComposer::setVsyncEnabled(int32_t disp, HWC2::Vsync enabled) {
if (disp < 0 || disp >= HWC_DISPLAY_VIRTUAL) {
ALOGD("setVsyncEnabled: Ignoring for virtual display %d", disp);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 17676ae5f0..41671f62fd 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -154,7 +154,9 @@ public:
std::shared_ptr<const HWC2::Display::Config>
getActiveConfig(int32_t displayId) const;
- std::vector<int32_t> getColorModes(int32_t displayId) const;
+ std::vector<android_color_mode_t> getColorModes(int32_t displayId) const;
+
+ status_t setActiveColorMode(int32_t displayId, android_color_mode_t mode);
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index 4afd8a2dce..ef416581a2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -42,6 +42,8 @@
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <system/graphics.h>
+
#include "HWComposer.h"
#include "../Layer.h" // needed only for debugging
@@ -403,7 +405,7 @@ status_t HWComposer::queryDisplayProperties(int disp) {
config.ydpi = values[i] / 1000.0f;
break;
case HWC_DISPLAY_COLOR_TRANSFORM:
- config.colorTransform = values[i];
+ config.colorMode = static_cast<android_color_mode_t>(values[i]);
break;
default:
ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
@@ -519,6 +521,11 @@ nsecs_t HWComposer::getRefreshPeriod(int disp) const {
return mDisplayData[disp].configs[currentConfig].refresh;
}
+android_color_mode_t HWComposer::getColorMode(int disp) const {
+ size_t currentConfig = mDisplayData[disp].currentConfig;
+ return mDisplayData[disp].configs[currentConfig].colorMode;
+}
+
const Vector<HWComposer::DisplayConfig>& HWComposer::getConfigs(int disp) const {
return mDisplayData[disp].configs;
}
@@ -1182,10 +1189,10 @@ void HWComposer::dump(String8& result) const {
for (size_t c = 0; c < disp.configs.size(); ++c) {
const DisplayConfig& config(disp.configs[c]);
result.appendFormat(" %s%zd: %ux%u, xdpi=%f, ydpi=%f"
- ", refresh=%" PRId64 ", colorTransform=%d\n",
+ ", refresh=%" PRId64 ", colorMode=%d\n",
c == disp.currentConfig ? "* " : "", c,
config.width, config.height, config.xdpi, config.ydpi,
- config.refresh, config.colorTransform);
+ config.refresh, config.colorMode);
}
if (disp.list) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index c86181781b..170e382330 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -22,6 +22,8 @@
#include <hardware/hwcomposer_defs.h>
+#include <system/graphics.h>
+
#include <ui/Fence.h>
#include <utils/BitSet.h>
@@ -257,7 +259,15 @@ public:
float xdpi;
float ydpi;
nsecs_t refresh;
- int colorTransform;
+ android_color_mode_t colorMode;
+ bool operator==(const DisplayConfig& rhs) const {
+ return width == rhs.width &&
+ height == rhs.height &&
+ xdpi == rhs.xdpi &&
+ ydpi == rhs.ydpi &&
+ refresh == rhs.refresh &&
+ colorMode == rhs.colorMode;
+ }
};
// Query display parameters. Pass in a display index (e.g.
@@ -274,6 +284,7 @@ public:
float getDpiX(int disp) const;
float getDpiY(int disp) const;
nsecs_t getRefreshPeriod(int disp) const;
+ android_color_mode_t getColorMode(int disp) const;
const Vector<DisplayConfig>& getConfigs(int disp) const;
size_t getCurrentConfig(int disp) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f298399ac5..3050d1cd7a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -631,18 +631,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
// All non-virtual displays are currently considered secure.
info.secure = true;
- // DisplayManager expects each color mode to be its own display
- // info record.
- std::vector<int32_t> modes = getHwComposer().getColorModes(type);
-
- if (modes.size() == 0) {
- info.colorTransform = 0;
- configs->push_back(info);
- }
- for (int32_t mode : modes) {
- info.colorTransform = mode;
- configs->push_back(info);
- }
+ configs->push_back(info);
}
return NO_ERROR;
@@ -704,6 +693,7 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
ALOGE("Attempt to set active config = %d for display with %zu configs",
mMode, configs.size());
+ return true;
}
sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
if (hw == NULL) {
@@ -722,6 +712,101 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
postMessageSync(msg);
return NO_ERROR;
}
+status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes) {
+ if ((outColorModes == nullptr) || (display.get() == nullptr)) {
+ return BAD_VALUE;
+ }
+
+ if (!display.get()) {
+ return NAME_NOT_FOUND;
+ }
+
+ int32_t type = NAME_NOT_FOUND;
+ for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
+ if (display == mBuiltinDisplays[i]) {
+ type = i;
+ break;
+ }
+ }
+
+ if (type < 0) {
+ return type;
+ }
+
+ std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
+ outColorModes->clear();
+ std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
+
+ return NO_ERROR;
+}
+
+android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
+ sp<DisplayDevice> device(getDisplayDevice(display));
+ if (device != nullptr) {
+ return device->getActiveColorMode();
+ }
+ return static_cast<android_color_mode_t>(BAD_VALUE);
+}
+
+void SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
+ android_color_mode_t mode) {
+ ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
+ this);
+ int32_t type = hw->getDisplayType();
+ android_color_mode_t currentMode = hw->getActiveColorMode();
+
+ if (mode == currentMode) {
+ ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
+ return;
+ }
+
+ if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ ALOGW("Trying to set config for virtual display");
+ return;
+ }
+
+ hw->setActiveColorMode(mode);
+ getHwComposer().setActiveColorMode(type, mode);
+}
+
+
+status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
+ android_color_mode_t colorMode) {
+ class MessageSetActiveColorMode: public MessageBase {
+ SurfaceFlinger& mFlinger;
+ sp<IBinder> mDisplay;
+ android_color_mode_t mMode;
+ public:
+ MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
+ android_color_mode_t mode) :
+ mFlinger(flinger), mDisplay(disp) { mMode = mode; }
+ virtual bool handler() {
+ Vector<android_color_mode_t> modes;
+ mFlinger.getDisplayColorModes(mDisplay, &modes);
+ bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
+ if (mMode < 0 || !exists) {
+ ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
+ mDisplay.get());
+ return true;
+ }
+ sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
+ if (hw == nullptr) {
+ ALOGE("Attempt to set active color mode = %d for null display %p",
+ mMode, mDisplay.get());
+ } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
+ ALOGW("Attempt to set active color mode= %d for virtual display",
+ mMode);
+ } else {
+ mFlinger.setActiveColorModeInternal(hw, mMode);
+ }
+ return true;
+ }
+ };
+ sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
+ postMessageSync(msg);
+ return NO_ERROR;
+}
status_t SurfaceFlinger::clearAnimationFrameStats() {
Mutex::Autolock _l(mStateLock);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f063aaf2c6..5cb99027b4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -46,6 +46,8 @@
#include <hardware/hwcomposer_defs.h>
+#include <system/graphics.h>
+
#include <private/gui/LayerState.h>
#include "Barrier.h"
@@ -222,6 +224,10 @@ private:
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& display);
+ virtual status_t getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* configs);
+ virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display);
+ virtual status_t setActiveColorMode(const sp<IBinder>& display, android_color_mode_t colorMode);
virtual void setPowerMode(const sp<IBinder>& display, int mode);
virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
virtual status_t clearAnimationFrameStats();
@@ -260,6 +266,9 @@ private:
// called on the main thread in response to setPowerMode()
void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
+ // Called on the main thread in response to setActiveColorMode()
+ void setActiveColorModeInternal(const sp<DisplayDevice>& hw, android_color_mode_t colorMode);
+
// Returns whether the transaction actually modified any state
bool handleMessageTransaction();
@@ -368,6 +377,16 @@ private:
return mDisplays.valueFor(dpy);
}
+ int32_t getDisplayType(const sp<IBinder>& display) {
+ if (!display.get()) return NAME_NOT_FOUND;
+ for (int i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; ++i) {
+ if (display == mBuiltinDisplays[i]) {
+ return i;
+ }
+ }
+ return NAME_NOT_FOUND;
+ }
+
// mark a region of a layer stack dirty. this updates the dirty
// region of all screens presenting this layer stack.
void invalidateLayerStack(uint32_t layerStack, const Region& dirty);
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 7062ea2511..6fe2358634 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -59,6 +59,8 @@
#include <private/android_filesystem_config.h>
#include <private/gui/SyncFeatures.h>
+#include <set>
+
#include "Client.h"
#include "clz.h"
#include "Colorizer.h"
@@ -574,20 +576,8 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
return BAD_VALUE;
}
- if (!display.get())
- return NAME_NOT_FOUND;
-
- int32_t type = NAME_NOT_FOUND;
- for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
- if (display == mBuiltinDisplays[i]) {
- type = i;
- break;
- }
- }
-
- if (type < 0) {
- return type;
- }
+ int32_t type = getDisplayType(display);
+ if (type < 0) return type;
// TODO: Not sure if display density should handled by SF any longer
class Density {
@@ -649,7 +639,6 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
info.ydpi = ydpi;
info.fps = float(1e9 / hwConfig.refresh);
info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
- info.colorTransform = hwConfig.colorTransform;
// This is how far in advance a buffer must be queued for
// presentation at a given time. If you want a buffer to appear
@@ -750,6 +739,55 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
return NO_ERROR;
}
+status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
+ Vector<android_color_mode_t>* outColorModes) {
+ if (outColorModes == nullptr || display.get() == nullptr) {
+ return BAD_VALUE;
+ }
+
+ int32_t type = getDisplayType(display);
+ if (type < 0) return type;
+
+ std::set<android_color_mode_t> colorModes;
+ for (const HWComposer::DisplayConfig& hwConfig : getHwComposer().getConfigs(type)) {
+ colorModes.insert(hwConfig.colorMode);
+ }
+
+ outColorModes->clear();
+ std::copy(colorModes.cbegin(), colorModes.cend(), std::back_inserter(*outColorModes));
+
+ return NO_ERROR;
+}
+
+android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
+ if (display.get() == nullptr) return static_cast<android_color_mode_t>(BAD_VALUE);
+
+ int32_t type = getDisplayType(display);
+ if (type < 0) return static_cast<android_color_mode_t>(type);
+
+ return getHwComposer().getColorMode(type);
+}
+
+status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
+ android_color_mode_t colorMode) {
+ if (display.get() == nullptr || colorMode < 0) {
+ return BAD_VALUE;
+ }
+
+ int32_t type = getDisplayType(display);
+ if (type < 0) return type;
+ const Vector<HWComposer::DisplayConfig>& hwConfigs = getHwComposer().getConfigs(type);
+ HWComposer::DisplayConfig desiredConfig = hwConfigs[getHwComposer().getCurrentConfig(type)];
+ desiredConfig.colorMode = colorMode;
+ for (size_t c = 0; c < hwConfigs.size(); ++c) {
+ const HWComposer::DisplayConfig config = hwConfigs[c];
+ if (config == desiredConfig) {
+ return setActiveConfig(display, c);
+ }
+ }
+ return BAD_VALUE;
+}
+
status_t SurfaceFlinger::clearAnimationFrameStats() {
Mutex::Autolock _l(mStateLock);
mAnimFrameTracker.clearStats();