Loading services/surfaceflinger/BufferStateLayer.cpp +103 −26 Original line number Diff line number Diff line Loading @@ -300,10 +300,6 @@ bool BufferStateLayer::willPresentCurrentTransaction() const { (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr))); } Rect BufferStateLayer::getCrop(const Layer::State& s) const { return s.crop; } bool BufferStateLayer::setTransform(uint32_t transform) { if (mDrawingState.bufferTransform == transform) return false; mDrawingState.bufferTransform = transform; Loading @@ -321,16 +317,6 @@ bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInver return true; } bool BufferStateLayer::setCrop(const Rect& crop) { if (mDrawingState.crop == crop) return false; mDrawingState.sequence++; mDrawingState.crop = crop; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) { if (mDrawingState.bufferCrop == bufferCrop) return false; Loading Loading @@ -408,9 +394,6 @@ bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix) { return false; } ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.sequence++; Loading Loading @@ -536,6 +519,7 @@ bool BufferStateLayer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& } bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { mDrawingState.dataspaceRequested = true; if (mDrawingState.dataspace == dataspace) return false; mDrawingState.dataspace = dataspace; mDrawingState.modified = true; Loading Loading @@ -858,6 +842,9 @@ void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) { * how to go from screen space back to window space. */ ui::Transform BufferStateLayer::getInputTransform() const { if (!hasBufferOrSidebandStream()) { return getTransform(); } sp<Layer> parent = mDrawingParent.promote(); if (parent == nullptr) { return ui::Transform(); Loading @@ -872,6 +859,10 @@ ui::Transform BufferStateLayer::getInputTransform() const { * that's already included. */ Rect BufferStateLayer::getInputBounds() const { if (!hasBufferOrSidebandStream()) { return getCroppedBufferSize(getDrawingState()); } Rect bufferBounds = getCroppedBufferSize(getDrawingState()); if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) { return bufferBounds; Loading Loading @@ -1080,13 +1071,22 @@ void BufferStateLayer::useEmptyDamage() { bool BufferStateLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. if ((mSidebandStream == nullptr) && (mBufferInfo.mBuffer == nullptr)) { if (!hasSomethingToDraw()) { return false; } // if the layer has the opaque flag, then we're always opaque, // otherwise we use the current buffer's format. return ((s.flags & layer_state_t::eLayerOpaque) != 0) || getOpacityForFormat(getPixelFormat()); // if the layer has the opaque flag, then we're always opaque if ((s.flags & layer_state_t::eLayerOpaque) == layer_state_t::eLayerOpaque) { return true; } // If the buffer has no alpha channel, then we are opaque if (hasBufferOrSidebandStream() && isOpaqueFormat(getPixelFormat())) { return true; } // Lastly consider the layer opaque if drawing a color with alpha == 1.0 return fillsColor() && getAlpha() == 1.0_hf; } bool BufferStateLayer::canReceiveInput() const { Loading @@ -1094,8 +1094,15 @@ bool BufferStateLayer::canReceiveInput() const { } bool BufferStateLayer::isVisible() const { return !isHiddenByPolicy() && getAlpha() > 0.0f && (mBufferInfo.mBuffer != nullptr || mSidebandStream != nullptr); if (!hasSomethingToDraw()) { return false; } if (isHiddenByPolicy()) { return false; } return getAlpha() > 0.0f || hasBlur(); } std::optional<compositionengine::LayerFE::LayerSettings> BufferStateLayer::prepareClientComposition( Loading Loading @@ -1130,6 +1137,11 @@ BufferStateLayer::prepareClientCompositionInternal( return result; } if (hasEffect()) { prepareEffectsClientComposition(*result, targetSettings); return result; } if (CC_UNLIKELY(mBufferInfo.mBuffer == 0) && mSidebandStream != nullptr) { // For surfaceview of tv sideband, there is no activeBuffer // in bufferqueue, we need return LayerSettings. Loading Loading @@ -1241,6 +1253,18 @@ BufferStateLayer::prepareClientCompositionInternal( return layer; } void BufferStateLayer::prepareEffectsClientComposition( compositionengine::LayerFE::LayerSettings& layerSettings, compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings.source.solidColor = getColor().rgb; } else if (hasBlur() || drawShadows()) { layerSettings.skipContentDraw = true; } } bool BufferStateLayer::isHdrY410() const { // pixel format is HDR Y410 masquerading as RGBA_1010102 return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ && Loading @@ -1249,7 +1273,12 @@ bool BufferStateLayer::isHdrY410() const { } sp<compositionengine::LayerFE> BufferStateLayer::getCompositionEngineLayerFE() const { // There's no need to get a CE Layer if the layer isn't going to draw anything. if (hasSomethingToDraw()) { return asLayerFE(); } else { return nullptr; } } compositionengine::LayerFECompositionState* BufferStateLayer::editCompositionState() { Loading @@ -1262,7 +1291,14 @@ const compositionengine::LayerFECompositionState* BufferStateLayer::getCompositi void BufferStateLayer::preparePerFrameCompositionState() { Layer::preparePerFrameCompositionState(); if (hasBufferOrSidebandStream()) { preparePerFrameBufferCompositionState(); } else { preparePerFrameEffectsCompositionState(); } } void BufferStateLayer::preparePerFrameBufferCompositionState() { // Sideband layers auto* compositionState = editCompositionState(); if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) { Loading @@ -1289,6 +1325,13 @@ void BufferStateLayer::preparePerFrameCompositionState() { compositionState->sidebandStreamHasFrame = false; } void BufferStateLayer::preparePerFrameEffectsCompositionState() { auto* compositionState = editCompositionState(); compositionState->color = getColor(); compositionState->compositionType = aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; } void BufferStateLayer::onPostComposition(const DisplayDevice* display, const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, Loading Loading @@ -1441,7 +1484,7 @@ bool BufferStateLayer::isProtected() const { // hardware.h, instead of using hard-coded values here. #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) bool BufferStateLayer::getOpacityForFormat(PixelFormat format) { bool BufferStateLayer::isOpaqueFormat(PixelFormat format) { if (HARDWARE_IS_DEVICE_FORMAT(format)) { return true; } Loading @@ -1458,6 +1501,9 @@ bool BufferStateLayer::getOpacityForFormat(PixelFormat format) { } bool BufferStateLayer::needsFiltering(const DisplayDevice* display) const { if (!hasBufferOrSidebandStream()) { return false; } const auto outputLayer = findOutputLayerForDisplay(display); if (outputLayer == nullptr) { return false; Loading @@ -1474,6 +1520,9 @@ bool BufferStateLayer::needsFiltering(const DisplayDevice* display) const { bool BufferStateLayer::needsFilteringForScreenshots( const DisplayDevice* display, const ui::Transform& inverseParentTransform) const { if (!hasBufferOrSidebandStream()) { return false; } const auto outputLayer = findOutputLayerForDisplay(display); if (outputLayer == nullptr) { return false; Loading Loading @@ -1535,7 +1584,11 @@ uint32_t BufferStateLayer::getBufferTransform() const { } ui::Dataspace BufferStateLayer::getDataSpace() const { return mBufferInfo.mDataspace; return mDrawingState.dataspaceRequested ? getRequestedDataSpace() : ui::Dataspace::UNKNOWN; } ui::Dataspace BufferStateLayer::getRequestedDataSpace() const { return hasBufferOrSidebandStream() ? mBufferInfo.mDataspace : mDrawingState.dataspace; } ui::Dataspace BufferStateLayer::translateDataspace(ui::Dataspace dataspace) { Loading Loading @@ -1636,4 +1689,28 @@ const std::shared_ptr<renderengine::ExternalTexture>& BufferStateLayer::getExter return mBufferInfo.mBuffer; } bool BufferStateLayer::setColor(const half3& color) { if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g && mDrawingState.color.b == color.b) { return false; } mDrawingState.sequence++; mDrawingState.color.r = color.r; mDrawingState.color.g = color.g; mDrawingState.color.b = color.b; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::fillsColor() const { return !hasBufferOrSidebandStream() && mDrawingState.color.r >= 0.0_hf && mDrawingState.color.g >= 0.0_hf && mDrawingState.color.b >= 0.0_hf; } bool BufferStateLayer::hasBlur() const { return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0; } } // namespace android services/surfaceflinger/BufferStateLayer.h +24 −6 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ public: // GRALLOC_USAGE_PROTECTED sense. bool isProtected() const override; bool usesSourceCrop() const override { return true; } bool usesSourceCrop() const override { return hasBufferOrSidebandStream(); } bool isHdrY410() const override; Loading Loading @@ -103,7 +103,7 @@ public: uint32_t getBufferTransform() const override; ui::Dataspace getDataSpace() const override; ui::Dataspace getRequestedDataSpace() const; sp<GraphicBuffer> getBuffer() const override; const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const override; Loading @@ -116,11 +116,12 @@ public: void releasePendingBuffer(nsecs_t dequeueReadyTime) override; Rect getCrop(const Layer::State& s) const; Region getActiveTransparentRegion(const Layer::State& s) const override { return s.transparentRegionHint; } bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */, const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, std::optional<nsecs_t> dequeueTime, Loading Loading @@ -154,6 +155,7 @@ public: std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) const override; bool setColor(const half3& color) override; protected: void gatherBufferInfo(); Loading Loading @@ -189,8 +191,10 @@ protected: */ const compositionengine::LayerFECompositionState* getCompositionState() const override; void preparePerFrameCompositionState() override; void preparePerFrameBufferCompositionState(); void preparePerFrameEffectsCompositionState(); static bool getOpacityForFormat(PixelFormat format); static bool isOpaqueFormat(PixelFormat format); // from graphics API const uint32_t mTextureName; Loading Loading @@ -218,7 +222,9 @@ private: // We generate InputWindowHandles for all non-cursor buffered layers regardless of whether they // have an InputChannel. This is to enable the InputDispatcher to do PID based occlusion // detection. bool needsInputInfo() const override { return !mPotentialCursor; } bool needsInputInfo() const override { return (hasInputInfo() || hasBufferOrSidebandStream()) && !mPotentialCursor; } // Returns true if this layer requires filtering bool needsFiltering(const DisplayDevice*) const override; Loading Loading @@ -265,6 +271,18 @@ private: std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal( compositionengine::LayerFE::ClientCompositionTargetSettings&) const; // Returns true if there is a valid color to fill. bool fillsColor() const; // Returns true if this layer has a blur value. bool hasBlur() const; bool hasEffect() const { return fillsColor() || drawShadows() || hasBlur(); } bool hasBufferOrSidebandStream() const { return ((mSidebandStream != nullptr) || (mBufferInfo.mBuffer != nullptr)); } bool hasSomethingToDraw() const { return hasEffect() || hasBufferOrSidebandStream(); } void prepareEffectsClientComposition( compositionengine::LayerFE::LayerSettings&, compositionengine::LayerFE::ClientCompositionTargetSettings&) const; ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID; uint64_t mPreviousReleasedFrameNumber = 0; Loading services/surfaceflinger/EffectLayer.cpp +1 −116 Original line number Diff line number Diff line Loading @@ -41,122 +41,7 @@ namespace android { // --------------------------------------------------------------------------- EffectLayer::EffectLayer(const LayerCreationArgs& args) : Layer(args), mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {} EffectLayer::EffectLayer(const LayerCreationArgs& args) : BufferStateLayer(args) {} EffectLayer::~EffectLayer() = default; std::optional<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { std::optional<compositionengine::LayerFE::LayerSettings> layerSettings = Layer::prepareClientComposition(targetSettings); // Nothing to render. if (!layerSettings) { return {}; } // set the shadow for the layer if needed prepareShadowClientComposition(*layerSettings, targetSettings.viewport); // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings->source.solidColor = getColor().rgb; return layerSettings; } else if (hasBlur() || drawShadows()) { layerSettings->skipContentDraw = true; return layerSettings; } return {}; } bool EffectLayer::isVisible() const { return hasSomethingToDraw() && !isHiddenByPolicy() && (getAlpha() > 0.0_hf || hasBlur()); } bool EffectLayer::setColor(const half3& color) { if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g && mDrawingState.color.b == color.b) { return false; } mDrawingState.sequence++; mDrawingState.color.r = color.r; mDrawingState.color.g = color.g; mDrawingState.color.b = color.b; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool EffectLayer::setDataspace(ui::Dataspace dataspace) { if (mDrawingState.dataspace == dataspace) { return false; } mDrawingState.sequence++; mDrawingState.dataspace = dataspace; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } void EffectLayer::preparePerFrameCompositionState() { Layer::preparePerFrameCompositionState(); auto* compositionState = editCompositionState(); compositionState->color = getColor(); compositionState->compositionType = aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; } sp<compositionengine::LayerFE> EffectLayer::getCompositionEngineLayerFE() const { // There's no need to get a CE Layer if the EffectLayer isn't going to draw anything. In that // case, it acts more like a ContainerLayer so returning a null CE Layer makes more sense if (hasSomethingToDraw()) { return asLayerFE(); } else { return nullptr; } } compositionengine::LayerFECompositionState* EffectLayer::editCompositionState() { return mCompositionState.get(); } const compositionengine::LayerFECompositionState* EffectLayer::getCompositionState() const { return mCompositionState.get(); } bool EffectLayer::isOpaque(const Layer::State& s) const { // Consider the layer to be opaque if its opaque flag is set or its effective // alpha (considering the alpha of its parents as well) is 1.0; return (s.flags & layer_state_t::eLayerOpaque) != 0 || (fillsColor() && getAlpha() == 1.0_hf); } ui::Dataspace EffectLayer::getDataSpace() const { return mDrawingState.dataspace; } sp<Layer> EffectLayer::createClone() { sp<EffectLayer> layer = mFlinger->getFactory().createEffectLayer( LayerCreationArgs(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata())); layer->setInitialValuesForClone(sp<Layer>::fromExisting(this)); return layer; } bool EffectLayer::fillsColor() const { return mDrawingState.color.r >= 0.0_hf && mDrawingState.color.g >= 0.0_hf && mDrawingState.color.b >= 0.0_hf; } bool EffectLayer::hasBlur() const { return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0; } } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion" services/surfaceflinger/EffectLayer.h +2 −37 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ #include <cstdint> #include "Layer.h" #include "BufferStateLayer.h" namespace android { Loading @@ -27,45 +27,10 @@ namespace android { // * fill the bounds of the layer with a color // * render a shadow cast by the bounds of the layer // If no effects are enabled, the layer is considered to be invisible. class EffectLayer : public Layer { class EffectLayer : public BufferStateLayer { public: explicit EffectLayer(const LayerCreationArgs&); ~EffectLayer() override; sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override; compositionengine::LayerFECompositionState* editCompositionState() override; const char* getType() const override { return "EffectLayer"; } bool isVisible() const override; bool setColor(const half3& color) override; bool setDataspace(ui::Dataspace dataspace) override; ui::Dataspace getDataSpace() const override; bool isOpaque(const Layer::State& s) const override; protected: /* * compositionengine::LayerFE overrides */ const compositionengine::LayerFECompositionState* getCompositionState() const override; void preparePerFrameCompositionState() override; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const override; std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState; sp<Layer> createClone() override; private: // Returns true if there is a valid color to fill. bool fillsColor() const; // Returns true if this layer has a blur value. bool hasBlur() const; bool hasSomethingToDraw() const { return fillsColor() || drawShadows() || hasBlur(); } }; } // namespace android services/surfaceflinger/Layer.cpp +1 −75 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ Layer::Layer(const LayerCreationArgs& args) mDrawingState.acquireFence = sp<Fence>::make(-1); mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence); mDrawingState.dataspace = ui::Dataspace::UNKNOWN; mDrawingState.dataspaceRequested = false; mDrawingState.hdrMetadata.validTypes = 0; mDrawingState.surfaceDamageRegion = Region::INVALID_REGION; mDrawingState.cornerRadius = 0.0f; Loading Loading @@ -204,13 +205,6 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, // callbacks // --------------------------------------------------------------------------- /* * onLayerDisplayed is only meaningful for BufferLayer, but, is called through * Layer. So, the implementation is done in BufferLayer. When called on a * EffectLayer object, it's essentially a NOP. */ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult>) {} void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) { if (mDrawingState.zOrderRelativeOf == nullptr) { return; Loading Loading @@ -521,22 +515,6 @@ sp<compositionengine::LayerFE> Layer::asLayerFE() const { return sp<compositionengine::LayerFE>::fromExisting(layerFE); } sp<compositionengine::LayerFE> Layer::getCompositionEngineLayerFE() const { return nullptr; } compositionengine::LayerFECompositionState* Layer::editCompositionState() { return nullptr; } const compositionengine::LayerFECompositionState* Layer::getCompositionState() const { return nullptr; } bool Layer::onPreComposition(nsecs_t) { return false; } void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) { using StateSubset = compositionengine::LayerFE::StateSubset; Loading Loading @@ -736,16 +714,6 @@ void Layer::setTransactionFlags(uint32_t mask) { mTransactionFlags |= mask; } bool Layer::setPosition(float x, float y) { if (mDrawingState.transform.tx() == x && mDrawingState.transform.ty() == y) return false; mDrawingState.sequence++; mDrawingState.transform.set(x, y); mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) { ssize_t idx = mCurrentChildren.indexOf(childLayer); if (idx < 0) { Loading Loading @@ -939,24 +907,6 @@ bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) { setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { if (matrix.dsdx == mDrawingState.transform.dsdx() && matrix.dtdy == mDrawingState.transform.dtdy() && matrix.dtdx == mDrawingState.transform.dtdx() && matrix.dsdy == mDrawingState.transform.dsdy()) { return false; } ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.sequence++; mDrawingState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setTransparentRegionHint(const Region& transparent) { mDrawingState.sequence++; Loading Loading @@ -2188,14 +2138,6 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromDrawingState; } ui::Transform Layer::getInputTransform() const { return getTransform(); } Rect Layer::getInputBounds() const { return getCroppedBufferSize(getDrawingState()); } // Applies the given transform to the region, while protecting against overflows caused by any // offsets. If applying the offset in the transform to any of the Rects in the region would result // in an overflow, they are not added to the output Region. Loading Loading @@ -2459,10 +2401,6 @@ bool Layer::hasInputInfo() const { mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL); } bool Layer::canReceiveInput() const { return !isHiddenByPolicy(); } compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( const DisplayDevice* display) const { if (!display) return nullptr; Loading Loading @@ -2684,18 +2622,6 @@ void Layer::cloneDrawingState(const Layer* from) { mDrawingState.callbackHandles = {}; } bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) { if (handles.empty()) { return false; } for (const auto& handle : handles) { mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle); } return true; } // --------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) { Loading Loading
services/surfaceflinger/BufferStateLayer.cpp +103 −26 Original line number Diff line number Diff line Loading @@ -300,10 +300,6 @@ bool BufferStateLayer::willPresentCurrentTransaction() const { (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr))); } Rect BufferStateLayer::getCrop(const Layer::State& s) const { return s.crop; } bool BufferStateLayer::setTransform(uint32_t transform) { if (mDrawingState.bufferTransform == transform) return false; mDrawingState.bufferTransform = transform; Loading @@ -321,16 +317,6 @@ bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInver return true; } bool BufferStateLayer::setCrop(const Rect& crop) { if (mDrawingState.crop == crop) return false; mDrawingState.sequence++; mDrawingState.crop = crop; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) { if (mDrawingState.bufferCrop == bufferCrop) return false; Loading Loading @@ -408,9 +394,6 @@ bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix) { return false; } ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.sequence++; Loading Loading @@ -536,6 +519,7 @@ bool BufferStateLayer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& } bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { mDrawingState.dataspaceRequested = true; if (mDrawingState.dataspace == dataspace) return false; mDrawingState.dataspace = dataspace; mDrawingState.modified = true; Loading Loading @@ -858,6 +842,9 @@ void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) { * how to go from screen space back to window space. */ ui::Transform BufferStateLayer::getInputTransform() const { if (!hasBufferOrSidebandStream()) { return getTransform(); } sp<Layer> parent = mDrawingParent.promote(); if (parent == nullptr) { return ui::Transform(); Loading @@ -872,6 +859,10 @@ ui::Transform BufferStateLayer::getInputTransform() const { * that's already included. */ Rect BufferStateLayer::getInputBounds() const { if (!hasBufferOrSidebandStream()) { return getCroppedBufferSize(getDrawingState()); } Rect bufferBounds = getCroppedBufferSize(getDrawingState()); if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) { return bufferBounds; Loading Loading @@ -1080,13 +1071,22 @@ void BufferStateLayer::useEmptyDamage() { bool BufferStateLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. if ((mSidebandStream == nullptr) && (mBufferInfo.mBuffer == nullptr)) { if (!hasSomethingToDraw()) { return false; } // if the layer has the opaque flag, then we're always opaque, // otherwise we use the current buffer's format. return ((s.flags & layer_state_t::eLayerOpaque) != 0) || getOpacityForFormat(getPixelFormat()); // if the layer has the opaque flag, then we're always opaque if ((s.flags & layer_state_t::eLayerOpaque) == layer_state_t::eLayerOpaque) { return true; } // If the buffer has no alpha channel, then we are opaque if (hasBufferOrSidebandStream() && isOpaqueFormat(getPixelFormat())) { return true; } // Lastly consider the layer opaque if drawing a color with alpha == 1.0 return fillsColor() && getAlpha() == 1.0_hf; } bool BufferStateLayer::canReceiveInput() const { Loading @@ -1094,8 +1094,15 @@ bool BufferStateLayer::canReceiveInput() const { } bool BufferStateLayer::isVisible() const { return !isHiddenByPolicy() && getAlpha() > 0.0f && (mBufferInfo.mBuffer != nullptr || mSidebandStream != nullptr); if (!hasSomethingToDraw()) { return false; } if (isHiddenByPolicy()) { return false; } return getAlpha() > 0.0f || hasBlur(); } std::optional<compositionengine::LayerFE::LayerSettings> BufferStateLayer::prepareClientComposition( Loading Loading @@ -1130,6 +1137,11 @@ BufferStateLayer::prepareClientCompositionInternal( return result; } if (hasEffect()) { prepareEffectsClientComposition(*result, targetSettings); return result; } if (CC_UNLIKELY(mBufferInfo.mBuffer == 0) && mSidebandStream != nullptr) { // For surfaceview of tv sideband, there is no activeBuffer // in bufferqueue, we need return LayerSettings. Loading Loading @@ -1241,6 +1253,18 @@ BufferStateLayer::prepareClientCompositionInternal( return layer; } void BufferStateLayer::prepareEffectsClientComposition( compositionengine::LayerFE::LayerSettings& layerSettings, compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings.source.solidColor = getColor().rgb; } else if (hasBlur() || drawShadows()) { layerSettings.skipContentDraw = true; } } bool BufferStateLayer::isHdrY410() const { // pixel format is HDR Y410 masquerading as RGBA_1010102 return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ && Loading @@ -1249,7 +1273,12 @@ bool BufferStateLayer::isHdrY410() const { } sp<compositionengine::LayerFE> BufferStateLayer::getCompositionEngineLayerFE() const { // There's no need to get a CE Layer if the layer isn't going to draw anything. if (hasSomethingToDraw()) { return asLayerFE(); } else { return nullptr; } } compositionengine::LayerFECompositionState* BufferStateLayer::editCompositionState() { Loading @@ -1262,7 +1291,14 @@ const compositionengine::LayerFECompositionState* BufferStateLayer::getCompositi void BufferStateLayer::preparePerFrameCompositionState() { Layer::preparePerFrameCompositionState(); if (hasBufferOrSidebandStream()) { preparePerFrameBufferCompositionState(); } else { preparePerFrameEffectsCompositionState(); } } void BufferStateLayer::preparePerFrameBufferCompositionState() { // Sideband layers auto* compositionState = editCompositionState(); if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) { Loading @@ -1289,6 +1325,13 @@ void BufferStateLayer::preparePerFrameCompositionState() { compositionState->sidebandStreamHasFrame = false; } void BufferStateLayer::preparePerFrameEffectsCompositionState() { auto* compositionState = editCompositionState(); compositionState->color = getColor(); compositionState->compositionType = aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; } void BufferStateLayer::onPostComposition(const DisplayDevice* display, const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, Loading Loading @@ -1441,7 +1484,7 @@ bool BufferStateLayer::isProtected() const { // hardware.h, instead of using hard-coded values here. #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) bool BufferStateLayer::getOpacityForFormat(PixelFormat format) { bool BufferStateLayer::isOpaqueFormat(PixelFormat format) { if (HARDWARE_IS_DEVICE_FORMAT(format)) { return true; } Loading @@ -1458,6 +1501,9 @@ bool BufferStateLayer::getOpacityForFormat(PixelFormat format) { } bool BufferStateLayer::needsFiltering(const DisplayDevice* display) const { if (!hasBufferOrSidebandStream()) { return false; } const auto outputLayer = findOutputLayerForDisplay(display); if (outputLayer == nullptr) { return false; Loading @@ -1474,6 +1520,9 @@ bool BufferStateLayer::needsFiltering(const DisplayDevice* display) const { bool BufferStateLayer::needsFilteringForScreenshots( const DisplayDevice* display, const ui::Transform& inverseParentTransform) const { if (!hasBufferOrSidebandStream()) { return false; } const auto outputLayer = findOutputLayerForDisplay(display); if (outputLayer == nullptr) { return false; Loading Loading @@ -1535,7 +1584,11 @@ uint32_t BufferStateLayer::getBufferTransform() const { } ui::Dataspace BufferStateLayer::getDataSpace() const { return mBufferInfo.mDataspace; return mDrawingState.dataspaceRequested ? getRequestedDataSpace() : ui::Dataspace::UNKNOWN; } ui::Dataspace BufferStateLayer::getRequestedDataSpace() const { return hasBufferOrSidebandStream() ? mBufferInfo.mDataspace : mDrawingState.dataspace; } ui::Dataspace BufferStateLayer::translateDataspace(ui::Dataspace dataspace) { Loading Loading @@ -1636,4 +1689,28 @@ const std::shared_ptr<renderengine::ExternalTexture>& BufferStateLayer::getExter return mBufferInfo.mBuffer; } bool BufferStateLayer::setColor(const half3& color) { if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g && mDrawingState.color.b == color.b) { return false; } mDrawingState.sequence++; mDrawingState.color.r = color.r; mDrawingState.color.g = color.g; mDrawingState.color.b = color.b; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::fillsColor() const { return !hasBufferOrSidebandStream() && mDrawingState.color.r >= 0.0_hf && mDrawingState.color.g >= 0.0_hf && mDrawingState.color.b >= 0.0_hf; } bool BufferStateLayer::hasBlur() const { return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0; } } // namespace android
services/surfaceflinger/BufferStateLayer.h +24 −6 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ public: // GRALLOC_USAGE_PROTECTED sense. bool isProtected() const override; bool usesSourceCrop() const override { return true; } bool usesSourceCrop() const override { return hasBufferOrSidebandStream(); } bool isHdrY410() const override; Loading Loading @@ -103,7 +103,7 @@ public: uint32_t getBufferTransform() const override; ui::Dataspace getDataSpace() const override; ui::Dataspace getRequestedDataSpace() const; sp<GraphicBuffer> getBuffer() const override; const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const override; Loading @@ -116,11 +116,12 @@ public: void releasePendingBuffer(nsecs_t dequeueReadyTime) override; Rect getCrop(const Layer::State& s) const; Region getActiveTransparentRegion(const Layer::State& s) const override { return s.transparentRegionHint; } bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */, const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, std::optional<nsecs_t> dequeueTime, Loading Loading @@ -154,6 +155,7 @@ public: std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) const override; bool setColor(const half3& color) override; protected: void gatherBufferInfo(); Loading Loading @@ -189,8 +191,10 @@ protected: */ const compositionengine::LayerFECompositionState* getCompositionState() const override; void preparePerFrameCompositionState() override; void preparePerFrameBufferCompositionState(); void preparePerFrameEffectsCompositionState(); static bool getOpacityForFormat(PixelFormat format); static bool isOpaqueFormat(PixelFormat format); // from graphics API const uint32_t mTextureName; Loading Loading @@ -218,7 +222,9 @@ private: // We generate InputWindowHandles for all non-cursor buffered layers regardless of whether they // have an InputChannel. This is to enable the InputDispatcher to do PID based occlusion // detection. bool needsInputInfo() const override { return !mPotentialCursor; } bool needsInputInfo() const override { return (hasInputInfo() || hasBufferOrSidebandStream()) && !mPotentialCursor; } // Returns true if this layer requires filtering bool needsFiltering(const DisplayDevice*) const override; Loading Loading @@ -265,6 +271,18 @@ private: std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal( compositionengine::LayerFE::ClientCompositionTargetSettings&) const; // Returns true if there is a valid color to fill. bool fillsColor() const; // Returns true if this layer has a blur value. bool hasBlur() const; bool hasEffect() const { return fillsColor() || drawShadows() || hasBlur(); } bool hasBufferOrSidebandStream() const { return ((mSidebandStream != nullptr) || (mBufferInfo.mBuffer != nullptr)); } bool hasSomethingToDraw() const { return hasEffect() || hasBufferOrSidebandStream(); } void prepareEffectsClientComposition( compositionengine::LayerFE::LayerSettings&, compositionengine::LayerFE::ClientCompositionTargetSettings&) const; ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID; uint64_t mPreviousReleasedFrameNumber = 0; Loading
services/surfaceflinger/EffectLayer.cpp +1 −116 Original line number Diff line number Diff line Loading @@ -41,122 +41,7 @@ namespace android { // --------------------------------------------------------------------------- EffectLayer::EffectLayer(const LayerCreationArgs& args) : Layer(args), mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {} EffectLayer::EffectLayer(const LayerCreationArgs& args) : BufferStateLayer(args) {} EffectLayer::~EffectLayer() = default; std::optional<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { std::optional<compositionengine::LayerFE::LayerSettings> layerSettings = Layer::prepareClientComposition(targetSettings); // Nothing to render. if (!layerSettings) { return {}; } // set the shadow for the layer if needed prepareShadowClientComposition(*layerSettings, targetSettings.viewport); // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings->source.solidColor = getColor().rgb; return layerSettings; } else if (hasBlur() || drawShadows()) { layerSettings->skipContentDraw = true; return layerSettings; } return {}; } bool EffectLayer::isVisible() const { return hasSomethingToDraw() && !isHiddenByPolicy() && (getAlpha() > 0.0_hf || hasBlur()); } bool EffectLayer::setColor(const half3& color) { if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g && mDrawingState.color.b == color.b) { return false; } mDrawingState.sequence++; mDrawingState.color.r = color.r; mDrawingState.color.g = color.g; mDrawingState.color.b = color.b; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool EffectLayer::setDataspace(ui::Dataspace dataspace) { if (mDrawingState.dataspace == dataspace) { return false; } mDrawingState.sequence++; mDrawingState.dataspace = dataspace; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } void EffectLayer::preparePerFrameCompositionState() { Layer::preparePerFrameCompositionState(); auto* compositionState = editCompositionState(); compositionState->color = getColor(); compositionState->compositionType = aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; } sp<compositionengine::LayerFE> EffectLayer::getCompositionEngineLayerFE() const { // There's no need to get a CE Layer if the EffectLayer isn't going to draw anything. In that // case, it acts more like a ContainerLayer so returning a null CE Layer makes more sense if (hasSomethingToDraw()) { return asLayerFE(); } else { return nullptr; } } compositionengine::LayerFECompositionState* EffectLayer::editCompositionState() { return mCompositionState.get(); } const compositionengine::LayerFECompositionState* EffectLayer::getCompositionState() const { return mCompositionState.get(); } bool EffectLayer::isOpaque(const Layer::State& s) const { // Consider the layer to be opaque if its opaque flag is set or its effective // alpha (considering the alpha of its parents as well) is 1.0; return (s.flags & layer_state_t::eLayerOpaque) != 0 || (fillsColor() && getAlpha() == 1.0_hf); } ui::Dataspace EffectLayer::getDataSpace() const { return mDrawingState.dataspace; } sp<Layer> EffectLayer::createClone() { sp<EffectLayer> layer = mFlinger->getFactory().createEffectLayer( LayerCreationArgs(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata())); layer->setInitialValuesForClone(sp<Layer>::fromExisting(this)); return layer; } bool EffectLayer::fillsColor() const { return mDrawingState.color.r >= 0.0_hf && mDrawingState.color.g >= 0.0_hf && mDrawingState.color.b >= 0.0_hf; } bool EffectLayer::hasBlur() const { return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0; } } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion"
services/surfaceflinger/EffectLayer.h +2 −37 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ #include <cstdint> #include "Layer.h" #include "BufferStateLayer.h" namespace android { Loading @@ -27,45 +27,10 @@ namespace android { // * fill the bounds of the layer with a color // * render a shadow cast by the bounds of the layer // If no effects are enabled, the layer is considered to be invisible. class EffectLayer : public Layer { class EffectLayer : public BufferStateLayer { public: explicit EffectLayer(const LayerCreationArgs&); ~EffectLayer() override; sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override; compositionengine::LayerFECompositionState* editCompositionState() override; const char* getType() const override { return "EffectLayer"; } bool isVisible() const override; bool setColor(const half3& color) override; bool setDataspace(ui::Dataspace dataspace) override; ui::Dataspace getDataSpace() const override; bool isOpaque(const Layer::State& s) const override; protected: /* * compositionengine::LayerFE overrides */ const compositionengine::LayerFECompositionState* getCompositionState() const override; void preparePerFrameCompositionState() override; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const override; std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState; sp<Layer> createClone() override; private: // Returns true if there is a valid color to fill. bool fillsColor() const; // Returns true if this layer has a blur value. bool hasBlur() const; bool hasSomethingToDraw() const { return fillsColor() || drawShadows() || hasBlur(); } }; } // namespace android
services/surfaceflinger/Layer.cpp +1 −75 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ Layer::Layer(const LayerCreationArgs& args) mDrawingState.acquireFence = sp<Fence>::make(-1); mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence); mDrawingState.dataspace = ui::Dataspace::UNKNOWN; mDrawingState.dataspaceRequested = false; mDrawingState.hdrMetadata.validTypes = 0; mDrawingState.surfaceDamageRegion = Region::INVALID_REGION; mDrawingState.cornerRadius = 0.0f; Loading Loading @@ -204,13 +205,6 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, // callbacks // --------------------------------------------------------------------------- /* * onLayerDisplayed is only meaningful for BufferLayer, but, is called through * Layer. So, the implementation is done in BufferLayer. When called on a * EffectLayer object, it's essentially a NOP. */ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult>) {} void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) { if (mDrawingState.zOrderRelativeOf == nullptr) { return; Loading Loading @@ -521,22 +515,6 @@ sp<compositionengine::LayerFE> Layer::asLayerFE() const { return sp<compositionengine::LayerFE>::fromExisting(layerFE); } sp<compositionengine::LayerFE> Layer::getCompositionEngineLayerFE() const { return nullptr; } compositionengine::LayerFECompositionState* Layer::editCompositionState() { return nullptr; } const compositionengine::LayerFECompositionState* Layer::getCompositionState() const { return nullptr; } bool Layer::onPreComposition(nsecs_t) { return false; } void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) { using StateSubset = compositionengine::LayerFE::StateSubset; Loading Loading @@ -736,16 +714,6 @@ void Layer::setTransactionFlags(uint32_t mask) { mTransactionFlags |= mask; } bool Layer::setPosition(float x, float y) { if (mDrawingState.transform.tx() == x && mDrawingState.transform.ty() == y) return false; mDrawingState.sequence++; mDrawingState.transform.set(x, y); mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) { ssize_t idx = mCurrentChildren.indexOf(childLayer); if (idx < 0) { Loading Loading @@ -939,24 +907,6 @@ bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) { setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { if (matrix.dsdx == mDrawingState.transform.dsdx() && matrix.dtdy == mDrawingState.transform.dtdy() && matrix.dtdx == mDrawingState.transform.dtdx() && matrix.dsdy == mDrawingState.transform.dsdy()) { return false; } ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.sequence++; mDrawingState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setTransparentRegionHint(const Region& transparent) { mDrawingState.sequence++; Loading Loading @@ -2188,14 +2138,6 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromDrawingState; } ui::Transform Layer::getInputTransform() const { return getTransform(); } Rect Layer::getInputBounds() const { return getCroppedBufferSize(getDrawingState()); } // Applies the given transform to the region, while protecting against overflows caused by any // offsets. If applying the offset in the transform to any of the Rects in the region would result // in an overflow, they are not added to the output Region. Loading Loading @@ -2459,10 +2401,6 @@ bool Layer::hasInputInfo() const { mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL); } bool Layer::canReceiveInput() const { return !isHiddenByPolicy(); } compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( const DisplayDevice* display) const { if (!display) return nullptr; Loading Loading @@ -2684,18 +2622,6 @@ void Layer::cloneDrawingState(const Layer* from) { mDrawingState.callbackHandles = {}; } bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) { if (handles.empty()) { return false; } for (const auto& handle : handles) { mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle); } return true; } // --------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) { Loading