From 99e27f0bc236e38d88ff4f9912ede514a729b8eb Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 16 Jun 2016 15:18:02 -0700 Subject: Change setPositionAppliesWithResize to apply to all geometry. To support seamless rotation, change setPositionAppliesWithResize to also include the crop. As the transformation matrix is already frozen during resize, this enables the window manager to set the total geometry state before and after resize in a race free fashion. Bug: 28823590 Change-Id: I3f8f0e162b7ef4e9403c1220c7e4191b3ef30526 --- libs/gui/SurfaceComposerClient.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 92ae41eec8..1620eb2b79 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -165,7 +165,7 @@ public: uint64_t frameNumber); status_t setOverrideScalingMode(const sp& client, const sp& id, int32_t overrideScalingMode); - status_t setPositionAppliesWithResize(const sp& client, + status_t setGeometryAppliesWithResize(const sp& client, const sp& id); void setDisplaySurface(const sp& token, @@ -445,7 +445,7 @@ status_t Composer::setOverrideScalingMode( return NO_ERROR; } -status_t Composer::setPositionAppliesWithResize( +status_t Composer::setGeometryAppliesWithResize( const sp& client, const sp& id) { Mutex::Autolock lock(mLock); @@ -453,7 +453,7 @@ status_t Composer::setPositionAppliesWithResize( if (!s) { return BAD_INDEX; } - s->what |= layer_state_t::ePositionAppliesWithResize; + s->what |= layer_state_t::eGeometryAppliesWithResize; return NO_ERROR; } @@ -699,9 +699,9 @@ status_t SurfaceComposerClient::setOverrideScalingMode( this, id, overrideScalingMode); } -status_t SurfaceComposerClient::setPositionAppliesWithResize( +status_t SurfaceComposerClient::setGeometryAppliesWithResize( const sp& id) { - return getComposer().setPositionAppliesWithResize(this, id); + return getComposer().setGeometryAppliesWithResize(this, id); } // ---------------------------------------------------------------------------- -- cgit v1.2.3-59-g8ed1b From 367c5684f4d417e5176bec12d67f4e2e42738fe0 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 20 Jun 2016 11:55:28 -0700 Subject: SurfaceControl: Add getTransformToDisplayInverse For seamless rotation, the window manager needs access to this flag, as it will apply the inverse display transform itself to all other windows. Bug: 28823590 Change-Id: Ifeee1078a9cb4cd01c8052570c137c6228b2f13d --- include/gui/ISurfaceComposerClient.h | 3 ++ include/gui/SurfaceComposerClient.h | 3 ++ include/gui/SurfaceControl.h | 2 + libs/gui/ISurfaceComposerClient.cpp | 51 +++++++++++++++++++++- libs/gui/SurfaceComposerClient.cpp | 8 ++++ libs/gui/SurfaceControl.cpp | 7 +++ services/surfaceflinger/Client.cpp | 10 +++++ services/surfaceflinger/Client.h | 2 + services/surfaceflinger/Layer.cpp | 4 ++ services/surfaceflinger/Layer.h | 2 + services/surfaceflinger/SurfaceFlingerConsumer.cpp | 1 + services/surfaceflinger/SurfaceFlingerConsumer.h | 3 +- 12 files changed, 94 insertions(+), 2 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index bb79bd02b8..c27a741632 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -77,6 +77,9 @@ public: * Requires ACCESS_SURFACE_FLINGER permission */ virtual status_t getLayerFrameStats(const sp& handle, FrameStats* outStats) const = 0; + + virtual status_t getTransformToDisplayInverse(const sp& handle, + bool* outTransformToDisplayInverse) const = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 3d6051e8b6..95e8b70c61 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -147,6 +147,9 @@ public: status_t clearLayerFrameStats(const sp& token) const; status_t getLayerFrameStats(const sp& token, FrameStats* outStats) const; + status_t getTransformToDisplayInverse(const sp& token, + bool* outTransformToDisplayInverse) const; + static status_t clearAnimationFrameStats(); static status_t getAnimationFrameStats(FrameStats* outStats); diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index 043eb53646..5e731c3964 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -97,6 +97,8 @@ public: status_t clearLayerFrameStats() const; status_t getLayerFrameStats(FrameStats* outStats) const; + status_t getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const; + private: // can't be copied SurfaceControl& operator = (SurfaceControl& rhs); diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 2ecb9083ff..dd5b169dba 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -41,7 +41,8 @@ enum { CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION, DESTROY_SURFACE, CLEAR_LAYER_FRAME_STATS, - GET_LAYER_FRAME_STATS + GET_LAYER_FRAME_STATS, + GET_TRANSFORM_TO_DISPLAY_INVERSE }; class BpSurfaceComposerClient : public BpInterface @@ -94,6 +95,35 @@ public: reply.read(*outStats); return reply.readInt32(); } + + virtual status_t getTransformToDisplayInverse(const sp& handle, + bool* outTransformToDisplayInverse) const { + Parcel data, reply; + status_t result = + data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); + if (result != NO_ERROR) { + return result; + } + result = data.writeStrongBinder(handle); + if (result != NO_ERROR) { + return result; + } + result = remote()->transact(GET_TRANSFORM_TO_DISPLAY_INVERSE, data, &reply); + if (result != NO_ERROR) { + return result; + } + int transformInverse; + result = reply.readInt32(&transformInverse); + if (result != NO_ERROR) { + return result; + } + *outTransformToDisplayInverse = transformInverse != 0 ? true : false; + status_t result2 = reply.readInt32(&result); + if (result2 != NO_ERROR) { + return result2; + } + return result; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -145,6 +175,25 @@ status_t BnSurfaceComposerClient::onTransact( reply->writeInt32(result); return NO_ERROR; } + case GET_TRANSFORM_TO_DISPLAY_INVERSE: { + CHECK_INTERFACE(ISurfaceComposerClient, data, reply); + sp handle; + status_t result = data.readStrongBinder(&handle); + if (result != NO_ERROR) { + return result; + } + bool transformInverse = false; + result = getTransformToDisplayInverse(handle, &transformInverse); + if (result != NO_ERROR) { + return result; + } + result = reply->writeInt32(transformInverse ? 1 : 0); + if (result != NO_ERROR) { + return result; + } + result = reply->writeInt32(NO_ERROR); + return result; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 1620eb2b79..26b2209e6a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -612,6 +612,14 @@ status_t SurfaceComposerClient::getLayerFrameStats(const sp& token, return mClient->getLayerFrameStats(token, outStats); } +status_t SurfaceComposerClient::getTransformToDisplayInverse(const sp& token, + bool* outTransformToDisplayInverse) const { + if (mStatus != NO_ERROR) { + return mStatus; + } + return mClient->getTransformToDisplayInverse(token, outTransformToDisplayInverse); +} + inline Composer& SurfaceComposerClient::getComposer() { return mComposer; } diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 223e1f4ba2..33c1d906e6 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -190,6 +190,13 @@ status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const { return client->getLayerFrameStats(mHandle, outStats); } +status_t SurfaceControl::getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const { + status_t err = validate(); + if (err < 0) return err; + const sp& client(mClient); + return client->getTransformToDisplayInverse(mHandle, outTransformToDisplayInverse); +} + status_t SurfaceControl::validate() const { if (mHandle==0 || mClient==0) { diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 2a025b8a93..415bdcae2e 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -173,5 +173,15 @@ status_t Client::getLayerFrameStats(const sp& handle, FrameStats* outSt return NO_ERROR; } +status_t Client::getTransformToDisplayInverse(const sp& handle, + bool* outTransformToDisplayInverse) const { + sp layer = getLayerUser(handle); + if (layer == NULL) { + return NAME_NOT_FOUND; + } + *outTransformToDisplayInverse = layer->getTransformToDisplayInverse(); + return NO_ERROR; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index b6d738125a..12db50568f 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -63,6 +63,8 @@ private: virtual status_t clearLayerFrameStats(const sp& handle) const; virtual status_t getLayerFrameStats(const sp& handle, FrameStats* outStats) const; + virtual status_t getTransformToDisplayInverse( + const sp& handle, bool* outTransformToDisplayInverse) const; virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3f70144904..f67e66ecfb 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2207,6 +2207,10 @@ std::vector Layer::getOccupancyHistory( return history; } +bool Layer::getTransformToDisplayInverse() const { + return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); +} + // --------------------------------------------------------------------------- Layer::LayerCleaner::LayerCleaner(const sp& flinger, diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 3ea38f0179..a51c804b11 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -418,6 +418,8 @@ public: return mFlinger->getFrameTimestamps(*this, frameNumber, outTimestamps); } + bool getTransformToDisplayInverse() const; + protected: // constant sp mFlinger; diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index ba0a527ebc..e0e4c61e69 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -129,6 +129,7 @@ status_t SurfaceFlingerConsumer::acquireBufferLocked(BufferItem* item, } bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const { + Mutex::Autolock lock(mMutex); return mTransformToDisplayInverse; } diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 37626591a7..4271039d25 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -66,8 +66,9 @@ public: // See GLConsumer::bindTextureImageLocked(). status_t bindTextureImage(); - // must be called from SF main thread bool getTransformToDisplayInverse() const; + + // must be called from SF main thread const Region& getSurfaceDamage() const; // Sets the contents changed listener. This should be used instead of -- cgit v1.2.3-59-g8ed1b From 28f24d0ab481bd9c6fd5618414fee694e837c5c6 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 12 Jul 2016 13:30:53 -0700 Subject: 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 --- include/gui/ISurfaceComposer.h | 9 ++ include/gui/SurfaceComposerClient.h | 10 ++ include/ui/DisplayInfo.h | 1 - libs/gui/ISurfaceComposer.cpp | 128 +++++++++++++++++++++ libs/gui/SurfaceComposerClient.cpp | 16 +++ services/surfaceflinger/DisplayDevice.cpp | 11 ++ services/surfaceflinger/DisplayDevice.h | 9 ++ services/surfaceflinger/DisplayHardware/HWC2.cpp | 9 +- services/surfaceflinger/DisplayHardware/HWC2.h | 4 +- .../DisplayHardware/HWC2On1Adapter.cpp | 78 +++++++------ .../DisplayHardware/HWC2On1Adapter.h | 21 ++-- .../surfaceflinger/DisplayHardware/HWComposer.cpp | 25 +++- .../surfaceflinger/DisplayHardware/HWComposer.h | 4 +- .../DisplayHardware/HWComposer_hwc1.cpp | 13 ++- .../DisplayHardware/HWComposer_hwc1.h | 13 ++- services/surfaceflinger/SurfaceFlinger.cpp | 109 ++++++++++++++++-- services/surfaceflinger/SurfaceFlinger.h | 19 +++ services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 68 ++++++++--- 18 files changed, 465 insertions(+), 82 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') 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& display, int id) = 0; + virtual status_t getDisplayColorModes(const sp& display, + Vector* outColorModes) = 0; + virtual android_color_mode_t getActiveColorMode(const sp& display) = 0; + virtual status_t setActiveColorMode(const sp& 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& display, int id); + // Gets the list of supported color modes for the given display + static status_t getDisplayColorModes(const sp& display, + Vector* outColorModes); + + // Gets the active color mode for the given display + static android_color_mode_t getActiveColorMode(const sp& display); + + // Sets the active color mode for the given display + static status_t setActiveColorMode(const sp& 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& 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 +#include + #include #include #include @@ -269,6 +271,82 @@ public: return reply.readInt32(); } + virtual status_t getDisplayColorModes(const sp& display, + Vector* 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(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(reply.readInt32()), i); + } + } + return result; + } + + virtual android_color_mode_t getActiveColorMode(const sp& 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(result); + } + result = data.writeStrongBinder(display); + if (result != NO_ERROR) { + ALOGE("getActiveColorMode failed to writeStrongBinder: %d", result); + return static_cast(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(result); + } + return static_cast(reply.readInt32()); + } + + virtual status_t setActiveColorMode(const sp& 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(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 colorModes; + sp 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(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 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(colorMode)); + return result; + } + case SET_ACTIVE_COLOR_MODE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp 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(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 #include +#include + #include #include @@ -771,6 +773,20 @@ status_t SurfaceComposerClient::setActiveConfig(const sp& display, int return ComposerService::getComposerService()->setActiveConfig(display, id); } +status_t SurfaceComposerClient::getDisplayColorModes(const sp& display, + Vector* outColorModes) { + return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes); +} + +android_color_mode_t SurfaceComposerClient::getActiveColorMode(const sp& display) { + return ComposerService::getComposerService()->getActiveColorMode(display); +} + +status_t SurfaceComposerClient::setActiveColorMode(const sp& display, + android_color_mode_t colorMode) { + return ComposerService::getComposerService()->setActiveColorMode(display, colorMode); +} + void SurfaceComposerClient::setDisplayPowerMode(const sp& 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 @@ -414,6 +414,17 @@ int DisplayDevice::getActiveConfig() const { 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) { 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* outModes) const +Error Display::getColorModes(std::vector* outModes) const { uint32_t numModes = 0; int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, @@ -599,7 +599,10 @@ Error Display::getColorModes(std::vector* outModes) const return error; } - std::swap(*outModes, modes); + outModes->resize(numModes); + for (size_t i = 0; i < numModes; i++) { + (*outModes)[i] = static_cast(modes[i]); + } return Error::None; } @@ -805,7 +808,7 @@ Error Display::setClientTarget(buffer_handle_t target, return static_cast(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(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, Composition>* outTypes); [[clang::warn_unused_result]] Error getColorModes( - std::vector* outModes) const; + std::vector* outModes) const; // Doesn't call into the HWC2 device, so no errors are possible std::vector> getConfigs() const; @@ -307,7 +307,7 @@ public: buffer_handle_t target, const android::sp& 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(6); +static constexpr Attribute ColorMode = static_cast(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( - displayHook); + return asFP(setColorModeHook); case FunctionDescriptor::SetColorTransform: return asFP(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 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(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(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 HWC2On1Adapter::Display::Config::getColorTransforms() const +std::set HWC2On1Adapter::Display::Config::getColorModes() const { - std::set colorTransforms; + std::set 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 void HWC2On1Adapter::Display::populateColorModes() { - mColorModes = mConfigs[0]->getColorTransforms(); + mColorModes = mConfigs[0]->getColorModes(); for (const auto& config : mConfigs) { - std::set intersection; - auto configModes = config->getColorTransforms(); + std::set 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 getColorTransforms() const; + std::set getColorModes() const; // splitLine divides the output into two lines suitable for // dumpsys SurfaceFlinger @@ -281,7 +282,7 @@ private: std::unordered_map mAttributes; // Maps from color transform to HWC1 config ID - std::unordered_map mHwc1Ids; + std::unordered_map mHwc1Ids; }; class Changes { @@ -378,8 +379,8 @@ private: std::vector> mConfigs; std::shared_ptr mActiveConfig; - std::set mColorModes; - int32_t mActiveColorMode; + std::set 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(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(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 return config; } -std::vector HWComposer::getColorModes(int32_t displayId) const { - std::vector modes; +std::vector HWComposer::getColorModes(int32_t displayId) const { + std::vector modes; if (!isValidDisplay(displayId)) { ALOGE("getColorModes: Attempted to access invalid display %d", @@ -379,12 +379,31 @@ std::vector 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(error)); - return std::vector(); + return std::vector(); } 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(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 getActiveConfig(int32_t displayId) const; - std::vector getColorModes(int32_t displayId) const; + std::vector 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 #include +#include + #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(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::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 +#include + #include #include @@ -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& 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& 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 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& display, int mode) { if (mMode < 0 || mMode >= static_cast(configs.size())) { ALOGE("Attempt to set active config = %d for display with %zu configs", mMode, configs.size()); + return true; } sp hw(mFlinger.getDisplayDevice(mDisplay)); if (hw == NULL) { @@ -722,6 +712,101 @@ status_t SurfaceFlinger::setActiveConfig(const sp& display, int mode) { postMessageSync(msg); return NO_ERROR; } +status_t SurfaceFlinger::getDisplayColorModes(const sp& display, + Vector* 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 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& display) { + sp device(getDisplayDevice(display)); + if (device != nullptr) { + return device->getActiveColorMode(); + } + return static_cast(BAD_VALUE); +} + +void SurfaceFlinger::setActiveColorModeInternal(const sp& 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& display, + android_color_mode_t colorMode) { + class MessageSetActiveColorMode: public MessageBase { + SurfaceFlinger& mFlinger; + sp mDisplay; + android_color_mode_t mMode; + public: + MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp& disp, + android_color_mode_t mode) : + mFlinger(flinger), mDisplay(disp) { mMode = mode; } + virtual bool handler() { + Vector 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 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 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 +#include + #include #include "Barrier.h" @@ -222,6 +224,10 @@ private: virtual status_t getDisplayConfigs(const sp& display, Vector* configs); virtual int getActiveConfig(const sp& display); + virtual status_t getDisplayColorModes(const sp& display, + Vector* configs); + virtual android_color_mode_t getActiveColorMode(const sp& display); + virtual status_t setActiveColorMode(const sp& display, android_color_mode_t colorMode); virtual void setPowerMode(const sp& display, int mode); virtual status_t setActiveConfig(const sp& 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& hw, int mode); + // Called on the main thread in response to setActiveColorMode() + void setActiveColorModeInternal(const sp& 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& 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 #include +#include + #include "Client.h" #include "clz.h" #include "Colorizer.h" @@ -574,20 +576,8 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& display, return BAD_VALUE; } - if (!display.get()) - return NAME_NOT_FOUND; - - int32_t type = NAME_NOT_FOUND; - for (int i=0 ; i& 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& display, int mode) { return NO_ERROR; } +status_t SurfaceFlinger::getDisplayColorModes(const sp& display, + Vector* outColorModes) { + if (outColorModes == nullptr || display.get() == nullptr) { + return BAD_VALUE; + } + + int32_t type = getDisplayType(display); + if (type < 0) return type; + + std::set 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& display) { + if (display.get() == nullptr) return static_cast(BAD_VALUE); + + int32_t type = getDisplayType(display); + if (type < 0) return static_cast(type); + + return getHwComposer().getColorMode(type); +} + +status_t SurfaceFlinger::setActiveColorMode(const sp& 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& 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(); -- cgit v1.2.3-59-g8ed1b From 1aad24c0c47598b0cce5ea2cadd5c2a5f3c5196d Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 4 Aug 2016 10:24:22 -0700 Subject: Fail setDisplaySurface if can't enable async Bug 30106031 Change-Id: I1c2d048b59e9805e72542c387fbcdb002496a13f --- include/gui/SurfaceComposerClient.h | 4 ++-- libs/gui/SurfaceComposerClient.cpp | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index b8ee331736..c4f88b60cc 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -166,8 +166,8 @@ public: static status_t getHdrCapabilities(const sp& display, HdrCapabilities* outCapabilities); - static void setDisplaySurface(const sp& token, - const sp& bufferProducer); + static status_t setDisplaySurface(const sp& token, + sp bufferProducer); static void setDisplayLayerStack(const sp& token, uint32_t layerStack); static void setDisplaySize(const sp& token, uint32_t width, uint32_t height); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 3df5f74fc9..7ed12b7bb4 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -170,8 +170,8 @@ public: status_t setGeometryAppliesWithResize(const sp& client, const sp& id); - void setDisplaySurface(const sp& token, - const sp& bufferProducer); + status_t setDisplaySurface(const sp& token, + sp bufferProducer); void setDisplayLayerStack(const sp& token, uint32_t layerStack); void setDisplayProjection(const sp& token, uint32_t orientation, @@ -473,12 +473,22 @@ DisplayState& Composer::getDisplayStateLocked(const sp& token) { return mDisplayStates.editItemAt(static_cast(index)); } -void Composer::setDisplaySurface(const sp& token, - const sp& bufferProducer) { +status_t Composer::setDisplaySurface(const sp& token, + sp bufferProducer) { + // Make sure that composition can never be stalled by a virtual display + // consumer that isn't processing buffers fast enough. + status_t err = bufferProducer->setAsyncMode(true); + if (err != NO_ERROR) { + ALOGE("Composer::setDisplaySurface Failed to enable async mode on the " + "BufferQueue. This BufferQueue cannot be used for virtual " + "display. (%d)", err); + return err; + } Mutex::Autolock _l(mLock); DisplayState& s(getDisplayStateLocked(token)); s.surface = bufferProducer; s.what |= DisplayState::eSurfaceChanged; + return NO_ERROR; } void Composer::setDisplayLayerStack(const sp& token, @@ -716,9 +726,9 @@ status_t SurfaceComposerClient::setGeometryAppliesWithResize( // ---------------------------------------------------------------------------- -void SurfaceComposerClient::setDisplaySurface(const sp& token, - const sp& bufferProducer) { - Composer::getInstance().setDisplaySurface(token, bufferProducer); +status_t SurfaceComposerClient::setDisplaySurface(const sp& token, + sp bufferProducer) { + return Composer::getInstance().setDisplaySurface(token, bufferProducer); } void SurfaceComposerClient::setDisplayLayerStack(const sp& token, -- cgit v1.2.3-59-g8ed1b From eddbef88cf78deb9b08a6cad2c9cb67e4ddcea0d Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 1 Sep 2016 11:21:21 -0700 Subject: libgui: Add null pointer check in setDisplaySurface Bug 31236602 Change-Id: I78d4e28e40db93f7e7e304355b370af0fa790b9d --- libs/gui/SurfaceComposerClient.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 7ed12b7bb4..b78de2ea59 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -475,14 +475,16 @@ DisplayState& Composer::getDisplayStateLocked(const sp& token) { status_t Composer::setDisplaySurface(const sp& token, sp bufferProducer) { - // Make sure that composition can never be stalled by a virtual display - // consumer that isn't processing buffers fast enough. - status_t err = bufferProducer->setAsyncMode(true); - if (err != NO_ERROR) { - ALOGE("Composer::setDisplaySurface Failed to enable async mode on the " - "BufferQueue. This BufferQueue cannot be used for virtual " - "display. (%d)", err); - return err; + if (bufferProducer.get() != nullptr) { + // Make sure that composition can never be stalled by a virtual display + // consumer that isn't processing buffers fast enough. + status_t err = bufferProducer->setAsyncMode(true); + if (err != NO_ERROR) { + ALOGE("Composer::setDisplaySurface Failed to enable async mode on the " + "BufferQueue. This BufferQueue cannot be used for virtual " + "display. (%d)", err); + return err; + } } Mutex::Autolock _l(mLock); DisplayState& s(getDisplayStateLocked(token)); -- cgit v1.2.3-59-g8ed1b