* 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.
*/
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,
// 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);
bool secure;
nsecs_t appVsyncOffset;
nsecs_t presentationDeadline;
- int colorTransform;
};
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
#include <private/gui/LayerState.h>
+#include <system/graphics.h>
+
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
#include <ui/HdrCapabilities.h>
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());
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();
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
+#include <system/graphics.h>
+
#include <ui/DisplayInfo.h>
#include <gui/CpuConsumer.h>
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);
return mActiveConfig;
}
+// ----------------------------------------------------------------------------
+#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) {
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.
*/
int mPowerMode;
// Current active config
int mActiveConfig;
+#ifdef USE_HWC2
+ // current active color mode
+ android_color_mode_t mActiveColorMode;
+#endif
};
}; // namespace android
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,
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;
}
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);
[[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;
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(
using namespace HWC2;
-static constexpr Attribute ColorTransform = static_cast<Attribute>(6);
+static constexpr Attribute ColorMode = static_cast<Attribute>(6);
namespace android {
&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:
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);
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) {
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
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) {
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
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);
}
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()));
if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
ALOGV("getActiveConfig is null, choosing config 0");
mActiveConfig = mConfigs[0];
- mActiveColorMode = -1;
+ mActiveColorMode = HAL_COLOR_MODE_NATIVE;
return;
}
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;
}
}
ALOGV("Unable to find active HWC1 config %u, defaulting to "
"config 0", activeConfig);
mActiveConfig = mConfigs[0];
- mActiveColorMode = -1;
+ mActiveColorMode = HAL_COLOR_MODE_NATIVE;
}
}
}
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);
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; }
// 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
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 {
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;
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);
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",
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);
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;
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <system/graphics.h>
+
#include "HWComposer.h"
#include "../Layer.h" // needed only for debugging
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",
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;
}
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) {
#include <hardware/hwcomposer_defs.h>
+#include <system/graphics.h>
+
#include <ui/Fence.h>
#include <utils/BitSet.h>
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.
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;
// 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;
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) {
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);
#include <hardware/hwcomposer_defs.h>
+#include <system/graphics.h>
+
#include <private/gui/LayerState.h>
#include "Barrier.h"
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();
// 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();
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);
#include <private/android_filesystem_config.h>
#include <private/gui/SyncFeatures.h>
+#include <set>
+
#include "Client.h"
#include "clz.h"
#include "Colorizer.h"
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 {
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
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();