Loading services/surfaceflinger/BufferLayer.cpp +76 −80 Original line number Diff line number Diff line Loading @@ -180,9 +180,13 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli } bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) || (isSecure() && !targetSettings.isSecure); const State& s(getDrawingState()); compositionengine::LayerFE::LayerSettings& layer = *result; if (!blackOutLayer) { if (blackOutLayer) { prepareClearClientComposition(layer, true /* blackout */); return layer; } const State& s(getDrawingState()); layer.source.buffer.buffer = mBufferInfo.mBuffer; layer.source.buffer.isOpaque = isOpaque(s); layer.source.buffer.fence = mBufferInfo.mFence; Loading Loading @@ -260,14 +264,6 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli layer.source.buffer.useTextureFiltering = useFiltering; layer.source.buffer.textureTransform = mat4(static_cast<const float*>(textureMatrix)) * tr; } else { // If layer is blacked out, force alpha to 1 so that we draw a black color // layer. layer.source.buffer.buffer = nullptr; layer.alpha = 1.0; layer.frameNumber = 0; layer.bufferId = 0; } return layer; } Loading services/surfaceflinger/BufferLayer.h +3 −2 Original line number Diff line number Diff line Loading @@ -173,14 +173,15 @@ protected: BufferInfo mBufferInfo; virtual void gatherBufferInfo() = 0; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) override; /* * compositionengine::LayerFE overrides */ const compositionengine::LayerFECompositionState* getCompositionState() const override; bool onPreComposition(nsecs_t) override; void preparePerFrameCompositionState() override; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) override; // Loads the corresponding system property once per process static bool latchUnsignaledBuffers(); Loading services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +29 −11 Original line number Diff line number Diff line Loading @@ -97,6 +97,21 @@ public: // Modified by each call to prepareClientComposition to indicate the // region of the target buffer that should be cleared. Region& clearRegion; // Viewport of the target being rendered to. This is used to determine // the shadow light position. const Rect& viewport; // Dataspace of the output so we can optimize how to render the shadow // by avoiding unnecessary color space conversions. const ui::Dataspace dataspace; // True if the region excluding the shadow is visible. const bool realContentIsVisible; // If set to true, change the layer settings to render a clear output. // This may be requested by the HWC const bool clearContent; }; // A superset of LayerSettings required by RenderEngine to compose a layer Loading @@ -109,18 +124,12 @@ public: uint64_t frameNumber = 0; }; // Returns the LayerSettings to pass to RenderEngine::drawLayers, or // nullopt_t if the layer does not render virtual std::optional<LayerSettings> prepareClientComposition( // Returns the z-ordered list of LayerSettings to pass to RenderEngine::drawLayers. The list // may contain shadows casted by the layer or the content of the layer itself. If the layer // does not render then an empty list will be returned. virtual std::vector<LayerSettings> prepareClientCompositionList( ClientCompositionTargetSettings&) = 0; // Returns the LayerSettings used to draw shadows around a layer. It is passed // to RenderEngine::drawLayers. Returns nullopt_t if the layer does not render // shadows. virtual std::optional<LayerSettings> prepareShadowClientComposition( const LayerSettings& layerSettings, const Rect& displayViewport, ui::Dataspace outputDataspace) = 0; // Called after the layer is displayed to update the presentation fence virtual void onLayerDisplayed(const sp<Fence>&) = 0; Loading @@ -142,7 +151,10 @@ static inline bool operator==(const LayerFE::ClientCompositionTargetSettings& lh lhs.useIdentityTransform == rhs.useIdentityTransform && lhs.needsFiltering == rhs.needsFiltering && lhs.isSecure == rhs.isSecure && lhs.supportsProtectedContent == rhs.supportsProtectedContent && lhs.clearRegion.hasSameRects(rhs.clearRegion); lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.viewport == rhs.viewport && lhs.dataspace == rhs.dataspace && lhs.realContentIsVisible == rhs.realContentIsVisible && lhs.clearContent == rhs.clearContent; } static inline bool operator==(const LayerFE::LayerSettings& lhs, Loading @@ -164,6 +176,12 @@ static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& setti *os << "\n .supportsProtectedContent = " << settings.supportsProtectedContent; *os << "\n .clearRegion = "; PrintTo(settings.clearRegion, os); *os << "\n .viewport = "; PrintTo(settings.viewport, os); *os << "\n .dataspace = "; PrintTo(settings.dataspace, os); *os << "\n .realContentIsVisible = " << settings.realContentIsVisible; *os << "\n .clearContent = " << settings.clearContent; *os << "\n}"; } Loading services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +2 −4 Original line number Diff line number Diff line Loading @@ -35,11 +35,9 @@ public: MOCK_METHOD1(onPreComposition, bool(nsecs_t)); MOCK_METHOD1(prepareCompositionState, void(compositionengine::LayerFE::StateSubset)); MOCK_METHOD1(prepareClientComposition, std::optional<LayerSettings>( MOCK_METHOD1(prepareClientCompositionList, std::vector<compositionengine::LayerFE::LayerSettings>( compositionengine::LayerFE::ClientCompositionTargetSettings&)); MOCK_METHOD3(prepareShadowClientComposition, std::optional<LayerSettings>(const LayerSettings&, const Rect&, ui::Dataspace)); MOCK_METHOD1(onLayerDisplayed, void(const sp<Fence>&)); Loading services/surfaceflinger/CompositionEngine/src/Output.cpp +19 −28 Original line number Diff line number Diff line Loading @@ -963,11 +963,16 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( // rectangle, as by definition the layer must blend with whatever is // underneath. We also skip the first layer as the buffer target is // guaranteed to start out cleared. bool clearClientComposition = const bool clearClientComposition = layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer; ALOGV(" Composition type: client %d clear %d", clientComposition, clearClientComposition); // If the layer casts a shadow but the content casting the shadow is occluded, skip // composing the non-shadow content and only draw the shadows. const bool realContentIsVisible = clientComposition && !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty(); if (clientComposition || clearClientComposition) { compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{ clip, Loading @@ -976,35 +981,21 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( outputState.isSecure, supportsProtectedContent, clientComposition ? clearRegion : dummyRegion, outputState.viewport, outputDataspace, realContentIsVisible, !clientComposition, /* clearContent */ }; if (std::optional<LayerFE::LayerSettings> result = layerFE.prepareClientComposition(targetSettings)) { if (!clientComposition) { LayerFE::LayerSettings& layerSettings = *result; layerSettings.source.buffer.buffer = nullptr; layerSettings.source.solidColor = half3(0.0, 0.0, 0.0); layerSettings.alpha = half(0.0); layerSettings.disableBlending = true; layerSettings.frameNumber = 0; } else { std::optional<LayerFE::LayerSettings> shadowLayer = layerFE.prepareShadowClientComposition(*result, outputState.viewport, outputDataspace); if (shadowLayer) { clientCompositionLayers.push_back(*shadowLayer); } } // If the layer casts a shadow but the content casting the shadow is occluded, skip // composing the non-shadow content and only draw the shadows. const bool skipNonShadowContentComposition = clientComposition && layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty(); if (!skipNonShadowContentComposition) { std::vector<LayerFE::LayerSettings> results = layerFE.prepareClientCompositionList(targetSettings); if (realContentIsVisible && !results.empty()) { layer->editState().clientCompositionTimestamp = systemTime(); clientCompositionLayers.push_back(*result); } } clientCompositionLayers.insert(clientCompositionLayers.end(), std::make_move_iterator(results.begin()), std::make_move_iterator(results.end())); results.clear(); } firstLayer = false; Loading Loading
services/surfaceflinger/BufferLayer.cpp +76 −80 Original line number Diff line number Diff line Loading @@ -180,9 +180,13 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli } bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) || (isSecure() && !targetSettings.isSecure); const State& s(getDrawingState()); compositionengine::LayerFE::LayerSettings& layer = *result; if (!blackOutLayer) { if (blackOutLayer) { prepareClearClientComposition(layer, true /* blackout */); return layer; } const State& s(getDrawingState()); layer.source.buffer.buffer = mBufferInfo.mBuffer; layer.source.buffer.isOpaque = isOpaque(s); layer.source.buffer.fence = mBufferInfo.mFence; Loading Loading @@ -260,14 +264,6 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli layer.source.buffer.useTextureFiltering = useFiltering; layer.source.buffer.textureTransform = mat4(static_cast<const float*>(textureMatrix)) * tr; } else { // If layer is blacked out, force alpha to 1 so that we draw a black color // layer. layer.source.buffer.buffer = nullptr; layer.alpha = 1.0; layer.frameNumber = 0; layer.bufferId = 0; } return layer; } Loading
services/surfaceflinger/BufferLayer.h +3 −2 Original line number Diff line number Diff line Loading @@ -173,14 +173,15 @@ protected: BufferInfo mBufferInfo; virtual void gatherBufferInfo() = 0; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) override; /* * compositionengine::LayerFE overrides */ const compositionengine::LayerFECompositionState* getCompositionState() const override; bool onPreComposition(nsecs_t) override; void preparePerFrameCompositionState() override; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) override; // Loads the corresponding system property once per process static bool latchUnsignaledBuffers(); Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +29 −11 Original line number Diff line number Diff line Loading @@ -97,6 +97,21 @@ public: // Modified by each call to prepareClientComposition to indicate the // region of the target buffer that should be cleared. Region& clearRegion; // Viewport of the target being rendered to. This is used to determine // the shadow light position. const Rect& viewport; // Dataspace of the output so we can optimize how to render the shadow // by avoiding unnecessary color space conversions. const ui::Dataspace dataspace; // True if the region excluding the shadow is visible. const bool realContentIsVisible; // If set to true, change the layer settings to render a clear output. // This may be requested by the HWC const bool clearContent; }; // A superset of LayerSettings required by RenderEngine to compose a layer Loading @@ -109,18 +124,12 @@ public: uint64_t frameNumber = 0; }; // Returns the LayerSettings to pass to RenderEngine::drawLayers, or // nullopt_t if the layer does not render virtual std::optional<LayerSettings> prepareClientComposition( // Returns the z-ordered list of LayerSettings to pass to RenderEngine::drawLayers. The list // may contain shadows casted by the layer or the content of the layer itself. If the layer // does not render then an empty list will be returned. virtual std::vector<LayerSettings> prepareClientCompositionList( ClientCompositionTargetSettings&) = 0; // Returns the LayerSettings used to draw shadows around a layer. It is passed // to RenderEngine::drawLayers. Returns nullopt_t if the layer does not render // shadows. virtual std::optional<LayerSettings> prepareShadowClientComposition( const LayerSettings& layerSettings, const Rect& displayViewport, ui::Dataspace outputDataspace) = 0; // Called after the layer is displayed to update the presentation fence virtual void onLayerDisplayed(const sp<Fence>&) = 0; Loading @@ -142,7 +151,10 @@ static inline bool operator==(const LayerFE::ClientCompositionTargetSettings& lh lhs.useIdentityTransform == rhs.useIdentityTransform && lhs.needsFiltering == rhs.needsFiltering && lhs.isSecure == rhs.isSecure && lhs.supportsProtectedContent == rhs.supportsProtectedContent && lhs.clearRegion.hasSameRects(rhs.clearRegion); lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.viewport == rhs.viewport && lhs.dataspace == rhs.dataspace && lhs.realContentIsVisible == rhs.realContentIsVisible && lhs.clearContent == rhs.clearContent; } static inline bool operator==(const LayerFE::LayerSettings& lhs, Loading @@ -164,6 +176,12 @@ static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& setti *os << "\n .supportsProtectedContent = " << settings.supportsProtectedContent; *os << "\n .clearRegion = "; PrintTo(settings.clearRegion, os); *os << "\n .viewport = "; PrintTo(settings.viewport, os); *os << "\n .dataspace = "; PrintTo(settings.dataspace, os); *os << "\n .realContentIsVisible = " << settings.realContentIsVisible; *os << "\n .clearContent = " << settings.clearContent; *os << "\n}"; } Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +2 −4 Original line number Diff line number Diff line Loading @@ -35,11 +35,9 @@ public: MOCK_METHOD1(onPreComposition, bool(nsecs_t)); MOCK_METHOD1(prepareCompositionState, void(compositionengine::LayerFE::StateSubset)); MOCK_METHOD1(prepareClientComposition, std::optional<LayerSettings>( MOCK_METHOD1(prepareClientCompositionList, std::vector<compositionengine::LayerFE::LayerSettings>( compositionengine::LayerFE::ClientCompositionTargetSettings&)); MOCK_METHOD3(prepareShadowClientComposition, std::optional<LayerSettings>(const LayerSettings&, const Rect&, ui::Dataspace)); MOCK_METHOD1(onLayerDisplayed, void(const sp<Fence>&)); Loading
services/surfaceflinger/CompositionEngine/src/Output.cpp +19 −28 Original line number Diff line number Diff line Loading @@ -963,11 +963,16 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( // rectangle, as by definition the layer must blend with whatever is // underneath. We also skip the first layer as the buffer target is // guaranteed to start out cleared. bool clearClientComposition = const bool clearClientComposition = layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer; ALOGV(" Composition type: client %d clear %d", clientComposition, clearClientComposition); // If the layer casts a shadow but the content casting the shadow is occluded, skip // composing the non-shadow content and only draw the shadows. const bool realContentIsVisible = clientComposition && !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty(); if (clientComposition || clearClientComposition) { compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{ clip, Loading @@ -976,35 +981,21 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( outputState.isSecure, supportsProtectedContent, clientComposition ? clearRegion : dummyRegion, outputState.viewport, outputDataspace, realContentIsVisible, !clientComposition, /* clearContent */ }; if (std::optional<LayerFE::LayerSettings> result = layerFE.prepareClientComposition(targetSettings)) { if (!clientComposition) { LayerFE::LayerSettings& layerSettings = *result; layerSettings.source.buffer.buffer = nullptr; layerSettings.source.solidColor = half3(0.0, 0.0, 0.0); layerSettings.alpha = half(0.0); layerSettings.disableBlending = true; layerSettings.frameNumber = 0; } else { std::optional<LayerFE::LayerSettings> shadowLayer = layerFE.prepareShadowClientComposition(*result, outputState.viewport, outputDataspace); if (shadowLayer) { clientCompositionLayers.push_back(*shadowLayer); } } // If the layer casts a shadow but the content casting the shadow is occluded, skip // composing the non-shadow content and only draw the shadows. const bool skipNonShadowContentComposition = clientComposition && layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty(); if (!skipNonShadowContentComposition) { std::vector<LayerFE::LayerSettings> results = layerFE.prepareClientCompositionList(targetSettings); if (realContentIsVisible && !results.empty()) { layer->editState().clientCompositionTimestamp = systemTime(); clientCompositionLayers.push_back(*result); } } clientCompositionLayers.insert(clientCompositionLayers.end(), std::make_move_iterator(results.begin()), std::make_move_iterator(results.end())); results.clear(); } firstLayer = false; Loading