SF: Merge EffectLayer into BufferStateLayer
This makes all the Layer instances a BufferStateLayer. The layer can
draw effects or hold a buffer. If the caller tries to do both, drawing
a buffer takes precedence.
Test: go/wm-smoke
Test: presubmit
Bug: 238781169
Change-Id: Ied68cd1ed7399f6408bd24d9e0220707d6a3a2ab
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0cedfc8..b939752 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -300,10 +300,6 @@
(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 @@
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 @@
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::setDataspace(ui::Dataspace dataspace) {
+ mDrawingState.dataspaceRequested = true;
if (mDrawingState.dataspace == dataspace) return false;
mDrawingState.dataspace = dataspace;
mDrawingState.modified = true;
@@ -858,6 +842,9 @@
* 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 @@
* 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 @@
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::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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
// 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::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::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 @@
}
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 @@
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 a0a52bf..6ef2b19 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -75,7 +75,7 @@
// 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 @@
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 @@
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 @@
std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
compositionengine::LayerFE::ClientCompositionTargetSettings&) const override;
+ bool setColor(const half3& color) override;
protected:
void gatherBufferInfo();
@@ -189,8 +191,10 @@
*/
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 @@
// 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 @@
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 d161c51..7180fa6 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 747b0bf..311d493 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 @@
// * 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 8a401eb..930ae72 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -124,6 +124,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 b05a4a0..946b7d0 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -172,6 +172,7 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
//
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 @@
* 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 @@
/*
* 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 @@
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 @@
// 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 @@
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 @@
* 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 @@
* 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 @@
* 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 @@
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 @@
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 @@
* "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 @@
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 3acf203..57ca859 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4575,7 +4575,11 @@
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 @@
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 1a49ead..2c62b28 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 @@
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 d086d79..48d05cb 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));
}