diff options
-rw-r--r-- | libs/gui/LayerState.cpp | 2 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 14 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 8 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 1 | ||||
-rw-r--r-- | libs/gui/tests/RegionSampling_test.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayer.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/ColorLayer.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/ColorLayer.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/ContainerLayer.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/ContainerLayer.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 22 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerProperties.cpp | 14 |
15 files changed, 83 insertions, 30 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 962d2630bc..84ba64494f 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -100,6 +100,7 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(bgColorAlpha); output.writeUint32(static_cast<uint32_t>(bgColorDataspace)); + output.writeBool(colorSpaceAgnostic); return NO_ERROR; } @@ -177,6 +178,7 @@ status_t layer_state_t::read(const Parcel& input) bgColorAlpha = input.readFloat(); bgColorDataspace = static_cast<ui::Dataspace>(input.readUint32()); + colorSpaceAgnostic = input.readBool(); return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 050ba8736b..0a4ad462d9 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -989,6 +989,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesir return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorSpaceAgnostic( + const sp<SurfaceControl>& sc, const bool agnostic) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eColorSpaceAgnosticChanged; + s->colorSpaceAgnostic = agnostic; + + registerSurfaceControlForCallback(sc); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 32d7391141..35e795c30b 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -88,6 +88,7 @@ struct layer_state_t { eCachedBufferChanged = 0x2'00000000, eBackgroundColorChanged = 0x4'00000000, eMetadataChanged = 0x8'00000000, + eColorSpaceAgnosticChanged = 0x10'00000000, }; layer_state_t() @@ -115,7 +116,8 @@ struct layer_state_t { api(-1), colorTransform(mat4()), bgColorAlpha(0), - bgColorDataspace(ui::Dataspace::UNKNOWN) { + bgColorDataspace(ui::Dataspace::UNKNOWN), + colorSpaceAgnostic(false) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -192,6 +194,10 @@ struct layer_state_t { // the background color layer float bgColorAlpha; ui::Dataspace bgColorDataspace; + + // A color space agnostic layer means the color of this layer can be + // interpreted in any color space. + bool colorSpaceAgnostic; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index e0623399ba..2c483eefbf 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -360,6 +360,7 @@ public: Transaction& setSidebandStream(const sp<SurfaceControl>& sc, const sp<NativeHandle>& sidebandStream); Transaction& setDesiredPresentTime(nsecs_t desiredPresentTime); + Transaction& setColorSpaceAgnostic(const sp<SurfaceControl>& sc, const bool agnostic); Transaction& addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext); diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp index 5652c0ca53..d33ecfbdb9 100644 --- a/libs/gui/tests/RegionSampling_test.cpp +++ b/libs/gui/tests/RegionSampling_test.cpp @@ -240,7 +240,7 @@ protected: float const luma_gray = 0.50; }; -TEST_F(RegionSamplingTest, CollectsLuma) { +TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) { fill_render(rgba_green); sp<ISurfaceComposer> composer = ComposerService::getComposerService(); @@ -254,7 +254,7 @@ TEST_F(RegionSamplingTest, CollectsLuma) { composer->removeRegionSamplingListener(listener); } -TEST_F(RegionSamplingTest, CollectsChangingLuma) { +TEST_F(RegionSamplingTest, DISABLED_CollectsChangingLuma) { fill_render(rgba_green); sp<ISurfaceComposer> composer = ComposerService::getComposerService(); @@ -275,7 +275,7 @@ TEST_F(RegionSamplingTest, CollectsChangingLuma) { composer->removeRegionSamplingListener(listener); } -TEST_F(RegionSamplingTest, CollectsLumaFromTwoRegions) { +TEST_F(RegionSamplingTest, DISABLED_CollectsLumaFromTwoRegions) { fill_render(rgba_green); sp<ISurfaceComposer> composer = ComposerService::getComposerService(); sp<Listener> greenListener = new Listener(); diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 756ca4273c..7884362570 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -239,7 +239,8 @@ bool BufferLayer::isHdrY410() const { void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) { + int32_t supportedPerFrameMetadata, + const ui::Dataspace targetDataspace) { RETURN_IF_NO_HWC_LAYER(displayDevice); // Apply this display's projection's viewport to the visible region @@ -291,10 +292,10 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice, setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::DEVICE); } - ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace); - error = hwcLayer->setDataspace(mCurrentDataSpace); + ui::Dataspace dataspace = isColorSpaceAgnostic() ? targetDataspace : mCurrentDataSpace; + error = hwcLayer->setDataspace(dataspace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), dataspace, to_string(error).c_str(), static_cast<int32_t>(error)); } diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index e9dbdeaf26..8149cba0cc 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -81,7 +81,8 @@ public: bool isHdrY410() const override; void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) override; + const Rect& viewport, int32_t supportedPerFrameMetadata, + const ui::Dataspace targetDataspace) override; bool onPreComposition(nsecs_t refreshStartTime) override; bool onPostComposition(const std::optional<DisplayId>& displayId, diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 2aeece7756..a2692bc592 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -81,7 +81,8 @@ bool ColorLayer::setColor(const half3& color) { void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, const Rect& viewport, - int32_t /* supportedPerFrameMetadata */) { + int32_t /* supportedPerFrameMetadata */, + const ui::Dataspace targetDataspace) { RETURN_IF_NO_HWC_LAYER(display); Region visible = transform.transform(visibleRegion.intersect(viewport)); @@ -101,9 +102,10 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display, setCompositionType(display, Hwc2::IComposerClient::Composition::SOLID_COLOR); - error = hwcLayer->setDataspace(mCurrentDataSpace); + const ui::Dataspace dataspace = isColorSpaceAgnostic() ? targetDataspace : mCurrentDataSpace; + error = hwcLayer->setDataspace(dataspace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), dataspace, to_string(error).c_str(), static_cast<int32_t>(error)); } diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 9786419796..9a72b4026f 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -36,7 +36,8 @@ public: bool setColor(const half3& color) override; void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) override; + const Rect& viewport, int32_t supportedPerFrameMetadata, + const ui::Dataspace targetDataspace) override; bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; } diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index 738f4b63c9..7927fa95b6 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -40,6 +40,6 @@ bool ContainerLayer::canReceiveInput() const { } void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&, const ui::Transform&, - const Rect&, int32_t) {} + const Rect&, int32_t, const ui::Dataspace) {} } // namespace android diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index c7cfdcd1ef..7222a3e15a 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -34,7 +34,8 @@ public: bool canReceiveInput() const override; void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) override; + const Rect& viewport, int32_t supportedPerFrameMetadata, + const ui::Dataspace targetDataspace) override; bool isCreatedFromMainThread() const override { return true; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5ab4523e8e..5c3fb05744 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -103,6 +103,7 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.cornerRadius = 0.0f; mCurrentState.api = -1; mCurrentState.hasColorTransform = false; + mCurrentState.colorSpaceAgnostic = false; // drawing state & current state are identical mDrawingState = mCurrentState; @@ -1355,6 +1356,17 @@ bool Layer::setLayerStack(uint32_t layerStack) { return true; } +bool Layer::setColorSpaceAgnostic(const bool agnostic) { + if (mCurrentState.colorSpaceAgnostic == agnostic) { + return false; + } + mCurrentState.sequence++; + mCurrentState.colorSpaceAgnostic = agnostic; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + uint32_t Layer::getLayerStack() const { auto p = mDrawingParent.promote(); if (p == nullptr) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 143ac948da..1afb9173f3 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -210,6 +210,7 @@ public: // The deque of callback handles for this frame. The back of the deque contains the most // recent callback handle. std::deque<sp<CallbackHandle>> callbackHandles; + bool colorSpaceAgnostic; }; explicit Layer(const LayerCreationArgs& args); @@ -297,6 +298,7 @@ public: virtual bool setColorTransform(const mat4& matrix); virtual mat4 getColorTransform() const; virtual bool hasColorTransform() const; + virtual bool isColorSpaceAgnostic() const { return mDrawingState.colorSpaceAgnostic; } // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; @@ -315,6 +317,7 @@ public: return false; }; virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace); + virtual bool setColorSpaceAgnostic(const bool agnostic); ui::Dataspace getDataSpace() const { return mCurrentDataSpace; } @@ -450,7 +453,8 @@ public: bool getForceClientComposition(const sp<DisplayDevice>& display); virtual void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) = 0; + int32_t supportedPerFrameMetadata, + const ui::Dataspace targetDataspace) = 0; // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 96f7d1e684..e445eb6bbf 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1754,6 +1754,13 @@ void SurfaceFlinger::calculateWorkingSet() { if (mDrawingState.colorMatrixChanged) { display->setColorTransform(mDrawingState.colorMatrix); } + Dataspace targetDataspace = Dataspace::UNKNOWN; + if (useColorManagement) { + ColorMode colorMode; + RenderIntent renderIntent; + pickColorMode(displayDevice, &colorMode, &targetDataspace, &renderIntent); + display->setColorMode(colorMode, targetDataspace, renderIntent); + } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { if (layer->isHdrY410()) { layer->forceClientComposition(displayDevice); @@ -1785,15 +1792,7 @@ void SurfaceFlinger::calculateWorkingSet() { const auto& displayState = display->getState(); layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport, - displayDevice->getSupportedPerFrameMetadata()); - } - - if (useColorManagement) { - ColorMode colorMode; - Dataspace dataSpace; - RenderIntent renderIntent; - pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent); - display->setColorMode(colorMode, dataSpace, renderIntent); + displayDevice->getSupportedPerFrameMetadata(), targetDataspace); } } @@ -3884,6 +3883,11 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState if (what & layer_state_t::eMetadataChanged) { if (layer->setMetadata(s.metadata)) flags |= eTraversalNeeded; } + if (what & layer_state_t::eColorSpaceAgnosticChanged) { + if (layer->setColorSpaceAgnostic(s.colorSpaceAgnostic)) { + flags |= eTraversalNeeded; + } + } std::vector<sp<CallbackHandle>> callbackHandles; if ((what & layer_state_t::eListenerCallbacksChanged) && (!s.listenerCallbacks.empty())) { mTransactionCompletedThread.run(); diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp index f2881f5542..cb9a6c0daa 100644 --- a/services/surfaceflinger/SurfaceFlingerProperties.cpp +++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp @@ -166,11 +166,15 @@ bool use_color_management(bool defaultValue) { auto tmpuseColorManagement = SurfaceFlingerProperties::use_color_management(); auto tmpHasHDRDisplay = SurfaceFlingerProperties::has_HDR_display(); auto tmpHasWideColorDisplay = SurfaceFlingerProperties::has_wide_color_display(); - if (tmpuseColorManagement.has_value() && tmpHasHDRDisplay.has_value() && - tmpHasWideColorDisplay.has_value()) { - return *tmpuseColorManagement || *tmpHasHDRDisplay || *tmpHasWideColorDisplay; - } - return defaultValue; + + auto tmpuseColorManagementVal = tmpuseColorManagement.has_value() ? *tmpuseColorManagement : + defaultValue; + auto tmpHasHDRDisplayVal = tmpHasHDRDisplay.has_value() ? *tmpHasHDRDisplay : + defaultValue; + auto tmpHasWideColorDisplayVal = tmpHasWideColorDisplay.has_value() ? *tmpHasWideColorDisplay : + defaultValue; + + return tmpuseColorManagementVal || tmpHasHDRDisplayVal || tmpHasWideColorDisplayVal; } int64_t default_composition_dataspace(Dataspace defaultValue) { |