diff options
-rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 129 | ||||
-rw-r--r-- | services/surfaceflinger/BufferStateLayer.h | 30 | ||||
-rw-r--r-- | services/surfaceflinger/EffectLayer.cpp | 117 | ||||
-rw-r--r-- | services/surfaceflinger/EffectLayer.h | 39 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 76 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 117 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/mock/MockLayer.h | 6 |
9 files changed, 195 insertions, 337 deletions
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 0cedfc8138..b939752be5 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -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; @@ -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; @@ -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++; @@ -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; @@ -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(); @@ -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; @@ -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 { @@ -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( @@ -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. @@ -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 && @@ -1249,7 +1273,12 @@ bool BufferStateLayer::isHdrY410() const { } sp<compositionengine::LayerFE> BufferStateLayer::getCompositionEngineLayerFE() const { - return asLayerFE(); + // 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() { @@ -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) { @@ -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, @@ -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; } @@ -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; @@ -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; @@ -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) { @@ -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 diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index a0a52bfcd3..6ef2b1932e 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -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; @@ -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; @@ -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, @@ -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(); @@ -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; @@ -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; @@ -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; diff --git a/services/surfaceflinger/EffectLayer.cpp b/services/surfaceflinger/EffectLayer.cpp index d161c510fd..7180fa6a58 100644 --- a/services/surfaceflinger/EffectLayer.cpp +++ b/services/surfaceflinger/EffectLayer.cpp @@ -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" diff --git a/services/surfaceflinger/EffectLayer.h b/services/surfaceflinger/EffectLayer.h index 747b0bfe9a..311d4935fc 100644 --- a/services/surfaceflinger/EffectLayer.h +++ b/services/surfaceflinger/EffectLayer.h @@ -19,7 +19,7 @@ #include <cstdint> -#include "Layer.h" +#include "BufferStateLayer.h" namespace android { @@ -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 diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 8a401eb597..930ae72286 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -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; @@ -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; @@ -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; @@ -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) { @@ -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++; @@ -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. @@ -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; @@ -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) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index b05a4a04e5..946b7d0238 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -172,6 +172,7 @@ public: // dataspace is only used by BufferStateLayer and EffectLayer ui::Dataspace dataspace; + bool dataspaceRequested; // The fields below this point are only used by BufferStateLayer uint64_t frameNumber; @@ -317,7 +318,7 @@ public: // Set a 2x2 transformation matrix on the layer. This transform // will be applied after parent transforms, but before any final // producer specified transform. - virtual bool setMatrix(const layer_state_t::matrix22_t& matrix); + virtual bool setMatrix(const layer_state_t::matrix22_t& matrix) = 0; // This second set of geometry attributes are controlled by // setGeometryAppliesWithResize, and their default mode is to be @@ -327,9 +328,9 @@ public: // setPosition operates in parent buffer space (pre parent-transform) or display // space for top-level layers. - virtual bool setPosition(float x, float y); + virtual bool setPosition(float x, float y) = 0; // Buffer space - virtual bool setCrop(const Rect& crop); + bool setCrop(const Rect& crop); // TODO(b/38182121): Could we eliminate the various latching modes by // using the layer hierarchy? @@ -338,7 +339,7 @@ public: virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ); virtual bool setAlpha(float alpha); - virtual bool setColor(const half3& /*color*/) { return false; }; + virtual bool setColor(const half3& /*color*/) = 0; // Set rounded corner radius for this layer and its children. // @@ -365,29 +366,27 @@ public: virtual bool isDimmingEnabled() const { return getDrawingState().dimmingEnabled; }; // Used only to set BufferStateLayer state - virtual bool setTransform(uint32_t /*transform*/) { return false; }; - virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; + virtual bool setTransform(uint32_t /*transform*/) = 0; + virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) = 0; virtual bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */, const BufferData& /* bufferData */, nsecs_t /* postTime */, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, std::optional<nsecs_t> /* dequeueTime */, - const FrameTimelineInfo& /*info*/) { - return false; - }; - virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; }; - virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; }; - virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; }; - virtual bool setApi(int32_t /*api*/) { return false; }; - virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; }; + const FrameTimelineInfo& /*info*/) = 0; + virtual bool setDataspace(ui::Dataspace /*dataspace*/) = 0; + virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) = 0; + virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) = 0; + virtual bool setApi(int32_t /*api*/) = 0; + virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) = 0; virtual bool setTransactionCompletedListeners( - const std::vector<sp<CallbackHandle>>& /*handles*/); + const std::vector<sp<CallbackHandle>>& /*handles*/) = 0; virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace); virtual bool setColorSpaceAgnostic(const bool agnostic); virtual bool setDimmingEnabled(const bool dimmingEnabled); virtual bool setDefaultFrameRateCompatibility(FrameRateCompatibility compatibility); virtual bool setFrameRateSelectionPriority(int32_t priority); virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint); - virtual void setAutoRefresh(bool /* autoRefresh */) {} + virtual void setAutoRefresh(bool /* autoRefresh */) = 0; bool setDropInputMode(gui::DropInputMode); // If the variable is not set on the layer, it traverses up the tree to inherit the frame @@ -396,10 +395,10 @@ public: // virtual FrameRateCompatibility getDefaultFrameRateCompatibility() const; // - virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; } + virtual ui::Dataspace getDataSpace() const = 0; - virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const; - virtual compositionengine::LayerFECompositionState* editCompositionState(); + virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const = 0; + virtual compositionengine::LayerFECompositionState* editCompositionState() = 0; // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with @@ -415,18 +414,18 @@ public: * pixel format includes an alpha channel) and the "opaque" flag set * on the layer. It does not examine the current plane alpha value. */ - virtual bool isOpaque(const Layer::State&) const { return false; } + virtual bool isOpaque(const Layer::State&) const = 0; /* * Returns whether this layer can receive input. */ - virtual bool canReceiveInput() const; + virtual bool canReceiveInput() const = 0; /* * isProtected - true if the layer may contain protected contents in the * GRALLOC_USAGE_PROTECTED sense. */ - virtual bool isProtected() const { return false; } + virtual bool isProtected() const = 0; /* * isFixedSize - true if content has a fixed size @@ -436,7 +435,7 @@ public: /* * usesSourceCrop - true if content should use a source crop */ - virtual bool usesSourceCrop() const { return false; } + virtual bool usesSourceCrop() const = 0; // Most layers aren't created from the main thread, and therefore need to // grab the SF state lock to access HWC, but ContainerLayer does, so we need @@ -444,11 +443,9 @@ public: virtual bool isCreatedFromMainThread() const { return false; } ui::Transform getActiveTransform(const Layer::State& s) const { return s.transform; } - Region getActiveTransparentRegion(const Layer::State& s) const { - return s.transparentRegionHint; - } - virtual Rect getCrop(const Layer::State& s) const { return s.crop; } - virtual bool needsFiltering(const DisplayDevice*) const { return false; } + virtual Region getActiveTransparentRegion(const Layer::State& s) const = 0; + Rect getCrop(const Layer::State& s) const { return s.crop; } + virtual bool needsFiltering(const DisplayDevice*) const = 0; // True if this layer requires filtering // This method is distinct from needsFiltering() in how the filter @@ -459,13 +456,11 @@ public: // different. // If the parent transform needs to be undone when capturing the layer, then // the inverse parent transform is also required. - virtual bool needsFilteringForScreenshots(const DisplayDevice*, const ui::Transform&) const { - return false; - } + virtual bool needsFilteringForScreenshots(const DisplayDevice*, const ui::Transform&) const = 0; virtual void updateCloneBufferInfo(){}; - virtual bool isHdrY410() const { return false; } + virtual bool isHdrY410() const = 0; /* * called after composition. @@ -474,10 +469,10 @@ public: virtual void onPostComposition(const DisplayDevice*, const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, - const CompositorTiming&) {} + const CompositorTiming&) = 0; // If a buffer was replaced this frame, release the former buffer - virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { } + virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) = 0; /* * latchBuffer - called each time the screen is redrawn and returns whether @@ -485,34 +480,30 @@ public: * operation, so this should be set only if needed). Typically this is used * to figure out if the content or size of a surface has changed. */ - virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) { - return false; - } + virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) = 0; - virtual void latchAndReleaseBuffer() {} + virtual void latchAndReleaseBuffer() = 0; /* * returns the rectangle that crops the content of the layer and scales it * to the layer's size. */ - virtual Rect getBufferCrop() const { return Rect(); } + virtual Rect getBufferCrop() const = 0; /* * Returns the transform applied to the buffer. */ - virtual uint32_t getBufferTransform() const { return 0; } + virtual uint32_t getBufferTransform() const = 0; - virtual sp<GraphicBuffer> getBuffer() const { return nullptr; } - virtual const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const { - return mDrawingState.buffer; - }; + virtual sp<GraphicBuffer> getBuffer() const = 0; + virtual const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const = 0; - virtual ui::Transform::RotationFlags getTransformHint() const { return ui::Transform::ROT_0; } + virtual ui::Transform::RotationFlags getTransformHint() const = 0; /* * Returns if a frame is ready */ - virtual bool hasReadyFrame() const { return false; } + virtual bool hasReadyFrame() const = 0; virtual int32_t getQueuedFrameCount() const { return 0; } @@ -520,19 +511,17 @@ public: * Returns active buffer size in the correct orientation. Buffer size is determined by undoing * any buffer transformations. If the layer has no buffer then return INVALID_RECT. */ - virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; } + virtual Rect getBufferSize(const Layer::State&) const = 0; /** * Returns the source bounds. If the bounds are not defined, it is inferred from the * buffer size. Failing that, the bounds are determined from the passed in parent bounds. * For the root layer, this is the display viewport size. */ - virtual FloatRect computeSourceBounds(const FloatRect& parentBounds) const { - return parentBounds; - } + virtual FloatRect computeSourceBounds(const FloatRect& parentBounds) const = 0; virtual FrameRate getFrameRateForLayerTree() const; - virtual bool getTransformToDisplayInverse() const { return false; } + virtual bool getTransformToDisplayInverse() const = 0; // Returns how rounded corners should be drawn for this layer. // A layer can override its parent's rounded corner settings if the parent's rounded @@ -548,19 +537,19 @@ public: * overrides this so we can generate input-info for Buffered layers that don't * have them (for input occlusion detection checks). */ - virtual bool needsInputInfo() const { return hasInputInfo(); } + virtual bool needsInputInfo() const = 0; // Implements RefBase. void onFirstRef() override; // implements compositionengine::LayerFE - const compositionengine::LayerFECompositionState* getCompositionState() const override; - bool onPreComposition(nsecs_t) override; + virtual const compositionengine::LayerFECompositionState* getCompositionState() const = 0; + virtual bool onPreComposition(nsecs_t) = 0; void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override; std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings&) const override; - void onLayerDisplayed(ftl::SharedFuture<FenceResult>) override; + virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>) = 0; void setWasClientComposed(const sp<Fence>& fence) override { mLastClientCompositionFence = fence; @@ -838,13 +827,13 @@ public: float getBorderWidth(); const half4& getBorderColor(); - virtual bool setBufferCrop(const Rect& /* bufferCrop */) { return false; } - virtual bool setDestinationFrame(const Rect& /* destinationFrame */) { return false; } - virtual std::atomic<int32_t>* getPendingBufferCounter() { return nullptr; } - virtual std::string getPendingBufferCounterName() { return ""; } - virtual bool updateGeometry() { return false; } + virtual bool setBufferCrop(const Rect& /* bufferCrop */) = 0; + virtual bool setDestinationFrame(const Rect& /* destinationFrame */) = 0; + virtual std::atomic<int32_t>* getPendingBufferCounter() = 0; + virtual std::string getPendingBufferCounterName() = 0; + virtual bool updateGeometry() = 0; - virtual bool simpleBufferUpdate(const layer_state_t&) const { return false; } + virtual bool simpleBufferUpdate(const layer_state_t&) const = 0; protected: friend class impl::SurfaceInterceptor; @@ -899,7 +888,7 @@ protected: compositionengine::OutputLayer* findOutputLayerForDisplay(const DisplayDevice*) const; bool usingRelativeZ(LayerVector::StateSet) const; - virtual ui::Transform getInputTransform() const; + virtual ui::Transform getInputTransform() const = 0; /** * Get the bounds in layer space within which this layer can receive input. * @@ -913,7 +902,7 @@ protected: * "replaceTouchableRegionWithCrop" is specified. In this case, the layer will receive input * in this layer's space, regardless of the specified crop layer. */ - virtual Rect getInputBounds() const; + virtual Rect getInputBounds() const = 0; // constant sp<SurfaceFlinger> mFlinger; @@ -984,7 +973,7 @@ protected: sp<Fence> mLastClientCompositionFence; bool mClearClientCompositionFenceOnLayerDisplayed = false; private: - virtual void setTransformHint(ui::Transform::RotationFlags) {} + virtual void setTransformHint(ui::Transform::RotationFlags) = 0; // Returns true if the layer can draw shadows on its border. virtual bool canDrawShadows() const { return true; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3acf203b0a..57ca859a24 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4575,7 +4575,11 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHa switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceBufferQueue: - case ISurfaceComposerClient::eFXSurfaceBufferState: { + case ISurfaceComposerClient::eFXSurfaceContainer: + case ISurfaceComposerClient::eFXSurfaceBufferState: + args.flags |= ISurfaceComposerClient::eNoColorFill; + FMT_FALLTHROUGH; + case ISurfaceComposerClient::eFXSurfaceEffect: { result = createBufferStateLayer(args, outHandle, &layer); std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter(); if (pendingBufferCounter) { @@ -4584,12 +4588,6 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHa pendingBufferCounter); } } break; - case ISurfaceComposerClient::eFXSurfaceContainer: - args.flags |= ISurfaceComposerClient::eNoColorFill; - FMT_FALLTHROUGH; - case ISurfaceComposerClient::eFXSurfaceEffect: - result = createEffectLayer(args, outHandle, &layer); - break; default: result = BAD_VALUE; break; diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h index 1a49ead275..2c62b286ef 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h +++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h @@ -24,8 +24,8 @@ #include <scheduler/TimeKeeper.h> +#include "BufferStateLayer.h" #include "Clock.h" -#include "Layer.h" #include "Scheduler/EventThread.h" #include "Scheduler/RefreshRateConfigs.h" #include "Scheduler/Scheduler.h" @@ -66,10 +66,10 @@ private: std::chrono::steady_clock::time_point mNow; }; -class FuzzImplLayer : public Layer { +class FuzzImplLayer : public BufferStateLayer { public: FuzzImplLayer(SurfaceFlinger* flinger, std::string name) - : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {} + : BufferStateLayer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {} explicit FuzzImplLayer(SurfaceFlinger* flinger) : FuzzImplLayer(flinger, "FuzzLayer") {} const char* getType() const override { return ""; } diff --git a/services/surfaceflinger/tests/unittests/mock/MockLayer.h b/services/surfaceflinger/tests/unittests/mock/MockLayer.h index d086d79834..48d05cbcba 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockLayer.h +++ b/services/surfaceflinger/tests/unittests/mock/MockLayer.h @@ -18,14 +18,14 @@ #include <gmock/gmock.h> -#include "Layer.h" +#include "BufferStateLayer.h" namespace android::mock { -class MockLayer : public Layer { +class MockLayer : public BufferStateLayer { public: MockLayer(SurfaceFlinger* flinger, std::string name) - : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) { + : BufferStateLayer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) { EXPECT_CALL(*this, getDefaultFrameRateCompatibility()) .WillOnce(testing::Return(scheduler::LayerInfo::FrameRateCompatibility::Default)); } |