SF: Introduce OutputLayerCompositionState
This moves the display-dependent state from LayerBE.h to a new
OutputLayerCompositionState.h header, adds some simple accessors to
get the new state, and minimally adjusts the existing SurfaceFlinger
code to use the new structure.
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I00370f05dc6b2a3db34094862c46084e7575dbda
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 89eee6b..e4db6df 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -24,8 +24,11 @@
#include <mutex>
#include <compositionengine/CompositionEngine.h>
+#include <compositionengine/Display.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerCreationArgs.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <cutils/compiler.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
@@ -66,11 +69,10 @@
BufferLayer::~BufferLayer() {
mFlinger->deleteTextureAsync(mTextureName);
- if (!getBE().mHwcLayers.empty()) {
+ if (destroyAllHwcLayersPlusChildren()) {
ALOGE("Found stale hardware composer layers when destroying "
"surface flinger layer %s",
mName.string());
- destroyAllHwcLayersPlusChildren();
}
mFlinger->mTimeStats->onDestroy(getSequence());
@@ -171,7 +173,8 @@
layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
layer.source.buffer.isY410BT2020 = isHdrY410();
// TODO: we could be more subtle with isFixedSize()
- const bool useFiltering = needsFiltering() || renderArea.needsFiltering() || isFixedSize();
+ const bool useFiltering = needsFiltering(renderArea.getDisplayDevice()) ||
+ renderArea.needsFiltering() || isFixedSize();
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
@@ -240,23 +243,26 @@
getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
}
-void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
- const Rect& viewport, int32_t supportedPerFrameMetadata) {
- RETURN_IF_NO_HWC_LAYER(displayId);
+void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice,
+ const ui::Transform& transform, const Rect& viewport,
+ int32_t supportedPerFrameMetadata) {
+ RETURN_IF_NO_HWC_LAYER(displayDevice);
// Apply this display's projection's viewport to the visible region
// before giving it to the HWC HAL.
Region visible = transform.transform(visibleRegion.intersect(viewport));
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
+ const auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);
+
+ auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
auto error = hwcLayer->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
- getBE().compositionInfo.hwc.visibleRegion = visible;
+ outputLayer->editState().visibleRegion = visible;
error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
if (error != HWC2::Error::None) {
@@ -268,7 +274,7 @@
// Sideband layers
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
- setCompositionType(displayId, HWC2::Composition::Sideband);
+ setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::SIDEBAND);
ALOGV("[%s] Requesting Sideband composition", mName.string());
error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
if (error != HWC2::Error::None) {
@@ -283,10 +289,10 @@
// Device or Cursor layers
if (mPotentialCursor) {
ALOGV("[%s] Requesting Cursor composition", mName.string());
- setCompositionType(displayId, HWC2::Composition::Cursor);
+ setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::CURSOR);
} else {
ALOGV("[%s] Requesting Device composition", mName.string());
- setCompositionType(displayId, HWC2::Composition::Device);
+ setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::DEVICE);
}
ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace);
@@ -313,7 +319,7 @@
getBE().compositionInfo.hwc.supportedPerFrameMetadata = supportedPerFrameMetadata;
getBE().compositionInfo.hwc.colorTransform = getColorTransform();
- setHwcLayerBuffer(displayId);
+ setHwcLayerBuffer(displayDevice);
}
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -605,9 +611,21 @@
return true;
}
-bool BufferLayer::needsFiltering() const {
- const auto displayFrame = getBE().compositionInfo.hwc.displayFrame;
- const auto sourceCrop = getBE().compositionInfo.hwc.sourceCrop;
+bool BufferLayer::needsFiltering(const sp<const DisplayDevice>& displayDevice) const {
+ // If we are not capturing based on the state of a known display device, we
+ // only return mNeedsFiltering
+ if (displayDevice == nullptr) {
+ return mNeedsFiltering;
+ }
+
+ const auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ if (outputLayer == nullptr) {
+ return mNeedsFiltering;
+ }
+
+ const auto& compositionState = outputLayer->getState();
+ const auto displayFrame = compositionState.displayFrame;
+ const auto sourceCrop = compositionState.sourceCrop;
return mNeedsFiltering || sourceCrop.getHeight() != displayFrame.getHeight() ||
sourceCrop.getWidth() != displayFrame.getWidth();
}
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 0f8a350..d358bae 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -80,8 +80,8 @@
bool isHdrY410() const override;
- void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
- int32_t supportedPerFrameMetadata) override;
+ void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
+ const Rect& viewport, int32_t supportedPerFrameMetadata) override;
bool onPreComposition(nsecs_t refreshStartTime) override;
bool onPostComposition(const std::optional<DisplayId>& displayId,
@@ -148,7 +148,7 @@
virtual status_t updateActiveBuffer() = 0;
virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
- virtual void setHwcLayerBuffer(DisplayId displayId) = 0;
+ virtual void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) = 0;
protected:
// Loads the corresponding system property once per process
@@ -177,7 +177,7 @@
private:
// Returns true if this layer requires filtering
- bool needsFiltering() const;
+ bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const;
uint64_t getHeadFrameNumber() const;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 0313c32..b66a46a 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -14,13 +14,16 @@
* limitations under the License.
*/
+#include <compositionengine/Display.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <system/window.h>
+
#include "BufferQueueLayer.h"
#include "LayerRejecter.h"
#include "TimeStats/TimeStats.h"
-#include <system/window.h>
-
namespace android {
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
@@ -350,13 +353,16 @@
return NO_ERROR;
}
-void BufferQueueLayer::setHwcLayerBuffer(DisplayId displayId) {
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
+void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ LOG_FATAL_IF(!outputLayer->getState.hwc);
+ auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
+ (*outputLayer->editState().hwc)
+ .hwcBufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
auto acquireFence = mConsumer->getCurrentFence();
auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index d392a69..30107e2 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -97,7 +97,7 @@
status_t updateActiveBuffer() override;
status_t updateFrameNumber(nsecs_t latchTime) override;
- void setHwcLayerBuffer(DisplayId displayId) override;
+ void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) override;
// -----------------------------------------------------------------------
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 2d6da76..369e71f 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -19,15 +19,17 @@
#define LOG_TAG "BufferStateLayer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include "BufferStateLayer.h"
-#include "ColorLayer.h"
+#include <limits>
-#include "TimeStats/TimeStats.h"
-
+#include <compositionengine/Display.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <private/gui/SyncFeatures.h>
#include <renderengine/Image.h>
-#include <limits>
+#include "BufferStateLayer.h"
+#include "ColorLayer.h"
+#include "TimeStats/TimeStats.h"
namespace android {
@@ -611,9 +613,10 @@
return NO_ERROR;
}
-void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
+void BufferStateLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);
+ auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
const State& s(getDrawingState());
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3320c5b..a97f0a4 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -131,7 +131,7 @@
status_t updateActiveBuffer() override;
status_t updateFrameNumber(nsecs_t latchTime) override;
- void setHwcLayerBuffer(DisplayId displayId) override;
+ void setHwcLayerBuffer(const sp<const DisplayDevice>& display) override;
private:
void onFirstRef() override;
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index d82ff0e..c901673 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -23,8 +23,11 @@
#include <sys/types.h>
#include <compositionengine/CompositionEngine.h>
+#include <compositionengine/Display.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerCreationArgs.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
#include <utils/Errors.h>
@@ -73,23 +76,27 @@
return true;
}
-void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
- const Rect& viewport, int32_t /* supportedPerFrameMetadata */) {
- RETURN_IF_NO_HWC_LAYER(displayId);
+void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display,
+ const ui::Transform& transform, const Rect& viewport,
+ int32_t /* supportedPerFrameMetadata */) {
+ RETURN_IF_NO_HWC_LAYER(display);
Region visible = transform.transform(visibleRegion.intersect(viewport));
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);
+
+ auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
+
auto error = hwcLayer->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
- getBE().compositionInfo.hwc.visibleRegion = visible;
+ outputLayer->editState().visibleRegion = visible;
- setCompositionType(displayId, HWC2::Composition::SolidColor);
+ setCompositionType(display, Hwc2::IComposerClient::Composition::SOLID_COLOR);
error = hwcLayer->setDataspace(mCurrentDataSpace);
if (error != HWC2::Error::None) {
@@ -116,7 +123,7 @@
ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
- getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
+ outputLayer->editState().bufferTransform = static_cast<Hwc2::Transform>(0);
error = hwcLayer->setColorTransform(getColorTransform());
if (error != HWC2::Error::None) {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index ed4c2d8..df0adac 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -35,8 +35,8 @@
bool setColor(const half3& color) override;
- void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
- int32_t supportedPerFrameMetadata) override;
+ void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
+ const Rect& viewport, int32_t supportedPerFrameMetadata) override;
bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index ce6b06c..e934f8b 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -5,6 +5,7 @@
"-DLOG_TAG=\"CompositionEngine\"",
],
shared_libs: [
+ "android.frameworks.vr.composer@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
@@ -28,6 +29,9 @@
"libtrace_proto",
],
header_libs: [
+ "android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
+ "android.hardware.graphics.composer@2.3-command-buffer",
"libsurfaceflinger_headers",
],
}
@@ -46,6 +50,7 @@
"src/Output.cpp",
"src/OutputCompositionState.cpp",
"src/OutputLayer.cpp",
+ "src/OutputLayerCompositionState.cpp",
"src/RenderSurface.cpp",
],
local_include_dirs: ["include"],
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index 4b8ef38..48cb581 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -16,14 +16,22 @@
#pragma once
+#include <string>
+
#include <utils/StrongPointer.h>
-namespace android::compositionengine {
+namespace android {
+
+namespace compositionengine {
class Output;
class Layer;
class LayerFE;
+namespace impl {
+struct OutputLayerCompositionState;
+} // namespace impl
+
/**
* An output layer contains the output-dependent composition state for a layer
*/
@@ -39,6 +47,22 @@
// Gets the front-end layer interface this output layer represents
virtual LayerFE& getLayerFE() const = 0;
+
+ using CompositionState = compositionengine::impl::OutputLayerCompositionState;
+
+ // Gets the raw composition state data for the layer
+ // TODO(lpique): Make this protected once it is only internally called.
+ virtual const CompositionState& getState() const = 0;
+
+ // Allows mutable access to the raw composition state data for the layer.
+ // This is meant to be used by the various functions that are part of the
+ // composition process.
+ // TODO(lpique): Make this protected once it is only internally called.
+ virtual CompositionState& editState() = 0;
+
+ // Debugging
+ virtual void dump(std::string& result) const = 0;
};
-} // namespace android::compositionengine
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index ddeb730..2009380 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -29,8 +29,6 @@
class GraphicBuffer;
-struct CompositionInfo;
-
namespace compositionengine {
/**
@@ -70,7 +68,7 @@
virtual status_t beginFrame(bool mustRecompose) = 0;
// Prepares the frame for rendering
- virtual status_t prepareFrame(std::vector<CompositionInfo>& compositionData) = 0;
+ virtual status_t prepareFrame() = 0;
// Allocates a buffer as scratch space for GPU composition
virtual sp<GraphicBuffer> dequeueBuffer() = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index f3d0258..5798540 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -17,8 +17,10 @@
#pragma once
#include <memory>
+#include <string>
#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
namespace android::compositionengine::impl {
@@ -32,10 +34,17 @@
compositionengine::Layer& getLayer() const override;
compositionengine::LayerFE& getLayerFE() const override;
+ const OutputLayerCompositionState& getState() const override;
+ OutputLayerCompositionState& editState() override;
+
+ void dump(std::string& result) const override;
+
private:
const compositionengine::Output& mOutput;
std::shared_ptr<compositionengine::Layer> mLayer;
sp<compositionengine::LayerFE> mLayerFE;
+
+ OutputLayerCompositionState mState;
};
std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
new file mode 100644
index 0000000..b78e9e0
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <optional>
+#include <string>
+
+#include <compositionengine/impl/HwcBufferCache.h>
+#include <renderengine/Mesh.h>
+#include <ui/FloatRect.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include "DisplayHardware/ComposerHal.h"
+
+namespace HWC2 {
+class Layer;
+} // namespace HWC2
+
+namespace android {
+
+class HWComposer;
+
+namespace compositionengine::impl {
+
+struct OutputLayerCompositionState {
+ // The region of this layer which is visible on this output
+ Region visibleRegion;
+
+ // If true, client composition will be used on this output
+ bool forceClientComposition{false};
+
+ // If true, when doing client composition, the target may need to be cleared
+ bool clearClientTarget{false};
+
+ // The display frame for this layer on this output
+ Rect displayFrame;
+
+ // The source crop for this layer on this output
+ FloatRect sourceCrop;
+
+ // The buffer transform to use for this layer o on this output.
+ Hwc2::Transform bufferTransform{static_cast<Hwc2::Transform>(0)};
+
+ // The Z order index of this layer on this output
+ uint32_t z;
+
+ /*
+ * HWC state
+ */
+
+ struct Hwc {
+ explicit Hwc(std::shared_ptr<HWC2::Layer> hwcLayer) : hwcLayer(hwcLayer) {}
+
+ // The HWC Layer backing this layer
+ std::shared_ptr<HWC2::Layer> hwcLayer;
+
+ // The HWC composition type for this layer
+ Hwc2::IComposerClient::Composition hwcCompositionType{
+ Hwc2::IComposerClient::Composition::INVALID};
+
+ // The buffer cache for this layer. This is used to lower the
+ // cost of sending reused buffers to the HWC.
+ HwcBufferCache hwcBufferCache;
+ };
+
+ // The HWC state is optional, and is only set up if there is any potential
+ // HWC acceleration possible.
+ std::optional<Hwc> hwc;
+
+ // Debugging
+ void dump(std::string& result) const;
+};
+
+} // namespace compositionengine::impl
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 2f0fceb..58b13ed 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -51,7 +51,7 @@
void setDisplaySize(const ui::Size&) override;
void setProtected(bool useProtected) override;
status_t beginFrame(bool mustRecompose) override;
- status_t prepareFrame(std::vector<CompositionInfo>& compositionData) override;
+ status_t prepareFrame() override;
sp<GraphicBuffer> dequeueBuffer() override;
void queueBuffer(base::unique_fd&& readyFence) override;
void onPresentDisplayCompleted() override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
index f5e5026..6bd61ee 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -20,6 +20,7 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/Output.h>
#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <gmock/gmock.h>
namespace android::compositionengine::mock {
@@ -32,6 +33,11 @@
MOCK_CONST_METHOD0(getOutput, const compositionengine::Output&());
MOCK_CONST_METHOD0(getLayer, compositionengine::Layer&());
MOCK_CONST_METHOD0(getLayerFE, compositionengine::LayerFE&());
+
+ MOCK_CONST_METHOD0(getState, const impl::OutputLayerCompositionState&());
+ MOCK_METHOD0(editState, impl::OutputLayerCompositionState&());
+
+ MOCK_CONST_METHOD1(dump, void(std::string&));
};
} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index e9ff330..8442bef 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -20,7 +20,6 @@
#include <gmock/gmock.h>
#include <ui/GraphicBuffer.h>
-#include "LayerBE.h"
namespace android::compositionengine::mock {
@@ -37,7 +36,7 @@
MOCK_METHOD1(setProtected, void(bool));
MOCK_METHOD1(setBufferDataspace, void(ui::Dataspace));
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
- MOCK_METHOD1(prepareFrame, status_t(std::vector<CompositionInfo>& compositionData));
+ MOCK_METHOD0(prepareFrame, status_t());
MOCK_METHOD0(dequeueBuffer, sp<GraphicBuffer>());
MOCK_METHOD1(queueBuffer, void(base::unique_fd&&));
MOCK_METHOD0(onPresentDisplayCompleted, void());
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e103ebe..f97add4 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -146,6 +146,14 @@
} else {
out.append(" No render surface!\n");
}
+
+ out.append("\n %d Layers", mOutputLayersOrderedByZ.size());
+ for (const auto& outputLayer : mOutputLayersOrderedByZ) {
+ if (!outputLayer) {
+ continue;
+ }
+ outputLayer->dump(out);
+ }
}
compositionengine::DisplayColorProfile* Output::getDisplayColorProfile() const {
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index e95f3a6..78c1403 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerFE.h>
#include <compositionengine/Output.h>
@@ -48,5 +49,20 @@
return *mLayerFE;
}
+const OutputLayerCompositionState& OutputLayer::getState() const {
+ return mState;
+}
+
+OutputLayerCompositionState& OutputLayer::editState() {
+ return mState;
+}
+
+void OutputLayer::dump(std::string& out) const {
+ using android::base::StringAppendF;
+
+ StringAppendF(&out, " Output Layer %p\n", this);
+ mState.dump(out);
+}
+
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
new file mode 100644
index 0000000..10f27b8
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <compositionengine/impl/DumpHelpers.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
+
+#include "DisplayHardware/HWC2.h"
+
+namespace android::compositionengine::impl {
+
+namespace {
+
+void dumpHwc(const OutputLayerCompositionState::Hwc& hwc, std::string& out) {
+ out.append("\n hwc: ");
+
+ if (hwc.hwcLayer == nullptr) {
+ out.append("No layer ");
+ } else {
+ dumpHex(out, "layer", hwc.hwcLayer->getId());
+ }
+
+ dumpVal(out, "composition", toString(hwc.hwcCompositionType), hwc.hwcCompositionType);
+}
+
+} // namespace
+
+void OutputLayerCompositionState::dump(std::string& out) const {
+ out.append(" ");
+ dumpVal(out, "visibleRegion", visibleRegion);
+
+ out.append(" ");
+ dumpVal(out, "forceClientComposition", forceClientComposition);
+ dumpVal(out, "clearClientTarget", clearClientTarget);
+ dumpVal(out, "displayFrame", displayFrame);
+ dumpVal(out, "sourceCrop", sourceCrop);
+ dumpVal(out, "bufferTransform%", toString(bufferTransform), bufferTransform);
+ dumpVal(out, "z-index", z);
+
+ if (hwc) {
+ dumpHwc(*hwc, out);
+ }
+
+ out.append("\n");
+}
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 3f841d2..ebb1bc2 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -99,11 +99,11 @@
return mDisplaySurface->beginFrame(mustRecompose);
}
-status_t RenderSurface::prepareFrame(std::vector<CompositionInfo>& compositionData) {
+status_t RenderSurface::prepareFrame() {
auto& hwc = mCompositionEngine.getHwComposer();
const auto id = mDisplay.getId();
if (id) {
- status_t error = hwc.prepare(*id, compositionData);
+ status_t error = hwc.prepare(*id, mDisplay);
if (error != NO_ERROR) {
return error;
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index ece412f..885cdd4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -16,10 +16,9 @@
#pragma once
+#include <compositionengine/Output.h>
#include <gmock/gmock.h>
-#include "LayerBE.h"
-
#include "DisplayHardware/HWComposer.h"
namespace android {
@@ -41,7 +40,7 @@
std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
- MOCK_METHOD2(prepare, status_t(DisplayId, std::vector<CompositionInfo>&));
+ MOCK_METHOD2(prepare, status_t(DisplayId, const compositionengine::Output&));
MOCK_METHOD5(setClientTarget,
status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
ui::Dataspace));
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index c56d92a..0a7c462 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -22,6 +22,7 @@
#include <compositionengine/mock/CompositionEngine.h>
#include <compositionengine/mock/Display.h>
#include <compositionengine/mock/DisplaySurface.h>
+#include <compositionengine/mock/OutputLayer.h>
#include <gtest/gtest.h>
#include <renderengine/mock/RenderEngine.h>
#include <system/window.h>
@@ -284,64 +285,66 @@
* RenderSurface::prepareFrame()
*/
-TEST_F(RenderSurfaceTest, prepareFrameTakesEarlyOutOnHwcError) {
- std::vector<CompositionInfo> data;
-
- EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data)))
+TEST_F(RenderSurfaceTest, prepareFramePassesOutputLayersToHwc) {
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
.WillOnce(Return(INVALID_OPERATION));
- EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data));
+ EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame());
+}
+
+TEST_F(RenderSurfaceTest, prepareFrameTakesEarlyOutOnHwcError) {
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
+ .WillOnce(Return(INVALID_OPERATION));
+
+ EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame());
}
TEST_F(RenderSurfaceTest, prepareFrameHandlesMixedComposition) {
- std::vector<CompositionInfo> data;
- EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
+ .WillOnce(Return(NO_ERROR));
EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_MIXED))
.WillOnce(Return(INVALID_OPERATION));
- EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data));
+ EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame());
}
TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyGlesComposition) {
- std::vector<CompositionInfo> data;
-
- EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
+ .WillOnce(Return(NO_ERROR));
EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_GLES))
.WillOnce(Return(NO_ERROR));
- EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
+ EXPECT_EQ(NO_ERROR, mSurface.prepareFrame());
}
TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyHwcComposition) {
- std::vector<CompositionInfo> data;
-
- EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
+ .WillOnce(Return(NO_ERROR));
EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC))
.WillOnce(Return(NO_ERROR));
- EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
+ EXPECT_EQ(NO_ERROR, mSurface.prepareFrame());
}
TEST_F(RenderSurfaceTest, prepareFrameHandlesNoComposition) {
- std::vector<CompositionInfo> data;
-
- EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay)))
+ .WillOnce(Return(NO_ERROR));
EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC))
.WillOnce(Return(NO_ERROR));
- EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
+ EXPECT_EQ(NO_ERROR, mSurface.prepareFrame());
}
/* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index 941b4ad..22c40d7 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -39,6 +39,7 @@
return !isHiddenByPolicy();
}
-void ContainerLayer::setPerFrameData(DisplayId, const ui::Transform&, const Rect&, int32_t) {}
+void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&, const ui::Transform&,
+ const Rect&, int32_t) {}
} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index fec82d7..c69997d 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -33,8 +33,8 @@
bool canReceiveInput() const override;
- void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
- int32_t supportedPerFrameMetadata) override;
+ void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
+ const Rect& viewport, int32_t supportedPerFrameMetadata) override;
bool isCreatedFromMainThread() const override { return true; }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 9674f0d..a827c47 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -266,6 +266,7 @@
int getHeight() const override { return mDevice->getHeight(); }
int getWidth() const override { return mDevice->getWidth(); }
bool isSecure() const override { return mDevice->isSecure(); }
+ const sp<const DisplayDevice> getDisplayDevice() const override { return mDevice; }
bool needsFiltering() const override {
// check if the projection from the logical display to the physical
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 5b4d347..3b9e0e6 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -20,13 +20,14 @@
#define LOG_TAG "HWComposer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Errors.h>
-#include <utils/Trace.h>
-
+#include <compositionengine/Output.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <log/log.h>
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
-
-#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/Trace.h>
#include "HWComposer.h"
#include "HWC2.h"
@@ -398,7 +399,7 @@
return NO_ERROR;
}
-status_t HWComposer::prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) {
+status_t HWComposer::prepare(DisplayId displayId, const compositionengine::Output& output) {
ATRACE_CALL();
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -462,47 +463,42 @@
displayData.hasClientComposition = false;
displayData.hasDeviceComposition = false;
- for (auto& compositionInfo : compositionData) {
- auto hwcLayer = compositionInfo.hwc.hwcLayer;
+ for (auto& outputLayer : output.getOutputLayersOrderedByZ()) {
+ auto& state = outputLayer->editState();
+ LOG_FATAL_IF(!state.hwc.);
+ auto hwcLayer = (*state.hwc).hwcLayer;
- if (changedTypes.count(&*hwcLayer) != 0) {
- // We pass false so we only update our state and don't call back
- // into the HWC device
- validateChange(compositionInfo.compositionType,
- changedTypes[&*hwcLayer]);
- compositionInfo.compositionType = changedTypes[&*hwcLayer];
- compositionInfo.layer->mLayer->setCompositionType(displayId,
- compositionInfo.compositionType,
- false);
+ if (auto it = changedTypes.find(hwcLayer.get()); it != changedTypes.end()) {
+ auto newCompositionType = it->second;
+ validateChange(static_cast<HWC2::Composition>((*state.hwc).hwcCompositionType),
+ newCompositionType);
+ (*state.hwc).hwcCompositionType =
+ static_cast<Hwc2::IComposerClient::Composition>(newCompositionType);
}
- switch (compositionInfo.compositionType) {
- case HWC2::Composition::Client:
+ switch ((*state.hwc).hwcCompositionType) {
+ case Hwc2::IComposerClient::Composition::CLIENT:
displayData.hasClientComposition = true;
break;
- case HWC2::Composition::Device:
- case HWC2::Composition::SolidColor:
- case HWC2::Composition::Cursor:
- case HWC2::Composition::Sideband:
+ case Hwc2::IComposerClient::Composition::DEVICE:
+ case Hwc2::IComposerClient::Composition::SOLID_COLOR:
+ case Hwc2::IComposerClient::Composition::CURSOR:
+ case Hwc2::IComposerClient::Composition::SIDEBAND:
displayData.hasDeviceComposition = true;
break;
default:
break;
}
- if (layerRequests.count(&*hwcLayer) != 0 &&
- layerRequests[&*hwcLayer] ==
- HWC2::LayerRequest::ClearClientTarget) {
- compositionInfo.hwc.clearClientTarget = true;
- compositionInfo.layer->mLayer->setClearClientTarget(displayId, true);
- } else {
- if (layerRequests.count(&*hwcLayer) != 0) {
+ state.clearClientTarget = false;
+ if (auto it = layerRequests.find(hwcLayer.get()); it != layerRequests.end()) {
+ auto request = it->second;
+ if (request == HWC2::LayerRequest::ClearClientTarget) {
+ state.clearClientTarget = true;
+ } else {
LOG_DISPLAY_ERROR(displayId,
- ("Unknown layer request " + to_string(layerRequests[&*hwcLayer]))
- .c_str());
+ ("Unknown layer request " + to_string(request)).c_str());
}
- compositionInfo.hwc.clearClientTarget = false;
- compositionInfo.layer->mLayer->setClearClientTarget(displayId, false);
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f42f860..ca59a26 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -45,6 +45,10 @@
class Composer;
} // namespace Hwc2
+namespace compositionengine {
+class Output;
+} // namespace compositionengine
+
class HWComposer {
public:
virtual ~HWComposer();
@@ -68,8 +72,7 @@
virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
// Asks the HAL what it can do
- virtual status_t prepare(DisplayId displayId,
- std::vector<CompositionInfo>& compositionData) = 0;
+ virtual status_t prepare(DisplayId displayId, const compositionengine::Output&) = 0;
virtual status_t setClientTarget(DisplayId displayId, uint32_t slot,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
@@ -205,7 +208,7 @@
void destroyLayer(DisplayId displayId, HWC2::Layer* layer) override;
// Asks the HAL what it can do
- status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) override;
+ status_t prepare(DisplayId displayId, const compositionengine::Output&) override;
status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace dataspace) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 51e1f00..69ec638 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -24,44 +24,40 @@
#include <stdlib.h>
#include <sys/types.h>
#include <algorithm>
+#include <mutex>
#include <android-base/stringprintf.h>
-
+#include <compositionengine/Display.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <cutils/compiler.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
-
+#include <gui/BufferItem.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/Surface.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/DebugUtils.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/NativeHandle.h>
#include <utils/StopWatch.h>
#include <utils/Trace.h>
-#include <ui/DebugUtils.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <gui/BufferItem.h>
-#include <gui/LayerDebugInfo.h>
-#include <gui/Surface.h>
-
#include "BufferLayer.h"
#include "ColorLayer.h"
#include "Colorizer.h"
#include "DisplayDevice.h"
+#include "DisplayHardware/HWComposer.h"
#include "Layer.h"
+#include "LayerProtoHelper.h"
#include "LayerRejecter.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
-
-#include "DisplayHardware/HWComposer.h"
#include "TimeStats/TimeStats.h"
-#include <renderengine/RenderEngine.h>
-
-#include <mutex>
-#include "LayerProtoHelper.h"
-
#define DEBUG_RESIZE 0
namespace android {
@@ -211,9 +207,16 @@
// h/w composer set-up
// ---------------------------------------------------------------------------
-bool Layer::createHwcLayer(HWComposer* hwc, DisplayId displayId) {
- LOG_ALWAYS_FATAL_IF(hasHwcLayer(displayId), "Already have a layer for display %s",
- to_string(displayId).c_str());
+bool Layer::createHwcLayer(HWComposer* hwc, const sp<DisplayDevice>& displayDevice) {
+ LOG_ALWAYS_FATAL_IF(!displayDevice->getId());
+ auto displayId = *displayDevice->getId();
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ LOG_ALWAYS_FATAL_IF(!outputLayer);
+
+ LOG_ALWAYS_FATAL_IF(outputLayer->getState().hwc.has_value(),
+ "Already have a layer for display %s",
+ displayDevice->getDisplayName().c_str());
+
auto layer = std::shared_ptr<HWC2::Layer>(
hwc->createLayer(displayId),
[hwc, displayId](HWC2::Layer* layer) {
@@ -221,42 +224,56 @@
if (!layer) {
return false;
}
- LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[displayId];
- hwcInfo.hwc = hwc;
- hwcInfo.layer = layer;
- layer->setLayerDestroyedListener(
- [this, displayId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(displayId); });
+ auto& state = outputLayer->editState();
+ state.hwc.emplace(layer);
return true;
}
-bool Layer::destroyHwcLayer(DisplayId displayId) {
- if (!hasHwcLayer(displayId)) {
+bool Layer::destroyHwcLayer(const sp<DisplayDevice>& displayDevice) {
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ if (outputLayer == nullptr) {
return false;
}
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
- LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
- hwcInfo.layer = nullptr;
-
- return true;
+ auto& state = outputLayer->editState();
+ bool result = state.hwc.has_value();
+ state.hwc.reset();
+ return result;
}
-void Layer::destroyHwcLayersForAllDisplays() {
- size_t numLayers = getBE().mHwcLayers.size();
- for (size_t i = 0; i < numLayers; ++i) {
- LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.empty(), "destroyAllHwcLayers failed");
- destroyHwcLayer(getBE().mHwcLayers.begin()->first);
+bool Layer::destroyHwcLayersForAllDisplays() {
+ bool destroyedAnyLayers = false;
+
+ for (const auto& [token, displayDevice] : mFlinger->mDisplays) {
+ if (destroyHwcLayer(displayDevice)) {
+ destroyedAnyLayers = true;
+ }
}
+
+ return destroyedAnyLayers;
}
-void Layer::destroyAllHwcLayersPlusChildren() {
- destroyHwcLayersForAllDisplays();
- LOG_ALWAYS_FATAL_IF(!getBE().mHwcLayers.empty(),
- "All hardware composer layers should have been destroyed");
+bool Layer::destroyAllHwcLayersPlusChildren() {
+ bool result = destroyHwcLayersForAllDisplays();
for (const sp<Layer>& child : mDrawingChildren) {
- child->destroyAllHwcLayersPlusChildren();
+ result |= child->destroyAllHwcLayersPlusChildren();
}
+
+ return result;
+}
+
+bool Layer::hasHwcLayer(const sp<const DisplayDevice>& displayDevice) {
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ LOG_FATAL_IF(!outputLayer);
+ return outputLayer->getState().hwc && (*outputLayer->getState().hwc).hwcLayer != nullptr;
+}
+
+HWC2::Layer* Layer::getHwcLayer(const sp<const DisplayDevice>& displayDevice) {
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ if (!outputLayer || !outputLayer->getState().hwc) {
+ return nullptr;
+ }
+ return (*outputLayer->getState().hwc).hwcLayer.get();
}
Rect Layer::getContentCrop() const {
@@ -494,19 +511,25 @@
}
void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
- RETURN_IF_NO_HWC_LAYER(*displayId);
- auto& hwcInfo = getBE().mHwcLayers[*displayId];
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ LOG_FATAL_IF(!outputLayer->getState().hwc);
+ auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
- // enable this layer
- hwcInfo.forceClientComposition = false;
-
- if (isSecure() && !display->isSecure()) {
- hwcInfo.forceClientComposition = true;
+ if (!hasHwcLayer(display)) {
+ ALOGE("[%s] failed to setGeometry: no HWC layer found (%s)", mName.string(),
+ display->getDebugName().c_str());
+ return;
}
- auto& hwcLayer = hwcInfo.layer;
+ auto& compositionState = outputLayer->editState();
+
+ // enable this layer
+ compositionState.forceClientComposition = false;
+
+ if (isSecure() && !display->isSecure()) {
+ compositionState.forceClientComposition = true;
+ }
// this gives us only the "orientation" component of the transform
const State& s(getDrawingState());
@@ -567,9 +590,8 @@
transformedFrame.left, transformedFrame.top, transformedFrame.right,
transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
} else {
- hwcInfo.displayFrame = transformedFrame;
+ compositionState.displayFrame = transformedFrame;
}
- getBE().compositionInfo.hwc.displayFrame = transformedFrame;
FloatRect sourceCrop = computeCrop(display);
error = hwcLayer->setSourceCrop(sourceCrop);
@@ -579,9 +601,8 @@
mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
to_string(error).c_str(), static_cast<int32_t>(error));
} else {
- hwcInfo.sourceCrop = sourceCrop;
+ compositionState.sourceCrop = sourceCrop;
}
- getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
float alpha = static_cast<float>(getAlpha());
error = hwcLayer->setPlaneAlpha(alpha);
@@ -594,7 +615,7 @@
error = hwcLayer->setZOrder(z);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
to_string(error).c_str(), static_cast<int32_t>(error));
- getBE().compositionInfo.hwc.z = z;
+ compositionState.z = z;
int type = s.metadata.getInt32(METADATA_WINDOW_TYPE, 0);
int appId = s.metadata.getInt32(METADATA_OWNER_UID, 0);
@@ -651,35 +672,39 @@
const uint32_t orientation = transform.getOrientation();
if (orientation & ui::Transform::ROT_INVALID) {
// we can only handle simple transformation
- hwcInfo.forceClientComposition = true;
- getBE().mHwcLayers[*displayId].compositionType = HWC2::Composition::Client;
+ compositionState.forceClientComposition = true;
+ (*compositionState.hwc).hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
} else {
auto transform = static_cast<HWC2::Transform>(orientation);
- hwcInfo.transform = transform;
auto error = hwcLayer->setTransform(transform);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set transform %s: "
"%s (%d)",
mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
- getBE().compositionInfo.hwc.transform = transform;
+ compositionState.bufferTransform = static_cast<Hwc2::Transform>(transform);
}
}
-void Layer::forceClientComposition(DisplayId displayId) {
- RETURN_IF_NO_HWC_LAYER(displayId);
- getBE().mHwcLayers[displayId].forceClientComposition = true;
+void Layer::forceClientComposition(const sp<DisplayDevice>& display) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ outputLayer->editState().forceClientComposition = true;
}
-bool Layer::getForceClientComposition(DisplayId displayId) {
- RETURN_IF_NO_HWC_LAYER(displayId, false);
- return getBE().mHwcLayers[displayId].forceClientComposition;
+bool Layer::getForceClientComposition(const sp<DisplayDevice>& display) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ return outputLayer->getState().forceClientComposition;
}
void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
- if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+
+ if (!outputLayer->getState().hwc ||
+ (*outputLayer->getState().hwc).hwcCompositionType !=
+ Hwc2::IComposerClient::Composition::CURSOR) {
return;
}
@@ -697,8 +722,7 @@
auto position = displayTransform.transform(frame);
auto error =
- getBE().mHwcLayers[*displayId].layer->setCursorPosition(position.left, position.top);
-
+ (*outputLayer->getState().hwc).hwcLayer->setCursorPosition(position.left, position.top);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set cursor position "
"to (%d, %d): %s (%d)",
@@ -769,56 +793,41 @@
clearWithOpenGL(renderArea, 0, 0, 0, 0);
}
-void Layer::setCompositionType(DisplayId displayId, HWC2::Composition type, bool callIntoHwc) {
- if (getBE().mHwcLayers.count(displayId) == 0) {
- ALOGE("setCompositionType called without a valid HWC layer");
- return;
- }
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
- ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (hwcLayer)->getId(), to_string(type).c_str(),
- static_cast<int>(callIntoHwc));
- if (hwcInfo.compositionType != type) {
+void Layer::setCompositionType(const sp<const DisplayDevice>& display,
+ Hwc2::IComposerClient::Composition type) {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ LOG_FATAL_IF(!outputLayer->getState().hwc);
+ auto& compositionState = outputLayer->editState();
+
+ ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", ((*compositionState.hwc).hwcLayer)->getId(),
+ toString(type).c_str(), 1);
+ if ((*compositionState.hwc).hwcCompositionType != type) {
ALOGV(" actually setting");
- hwcInfo.compositionType = type;
- if (callIntoHwc) {
- auto error = (hwcLayer)->setCompositionType(type);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set "
- "composition type %s: %s (%d)",
- mName.string(), to_string(type).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
+ (*compositionState.hwc).hwcCompositionType = type;
+
+ auto error = (*compositionState.hwc)
+ .hwcLayer->setCompositionType(static_cast<HWC2::Composition>(type));
+ ALOGE_IF(error != HWC2::Error::None,
+ "[%s] Failed to set "
+ "composition type %s: %s (%d)",
+ mName.string(), toString(type).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
}
-HWC2::Composition Layer::getCompositionType(const std::optional<DisplayId>& displayId) const {
- if (!displayId) {
- // If we're querying the composition type for a display that does not
- // have a HWC counterpart, then it will always be Client
- return HWC2::Composition::Client;
- }
- if (getBE().mHwcLayers.count(*displayId) == 0) {
- ALOGE("getCompositionType called with an invalid HWC layer");
- return HWC2::Composition::Invalid;
- }
- return getBE().mHwcLayers.at(*displayId).compositionType;
+Hwc2::IComposerClient::Composition Layer::getCompositionType(
+ const sp<const DisplayDevice>& display) const {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ return outputLayer->getState().hwc ? (*outputLayer->getState().hwc).hwcCompositionType
+ : Hwc2::IComposerClient::Composition::CLIENT;
}
-void Layer::setClearClientTarget(DisplayId displayId, bool clear) {
- if (getBE().mHwcLayers.count(displayId) == 0) {
- ALOGE("setClearClientTarget called without a valid HWC layer");
- return;
- }
- getBE().mHwcLayers[displayId].clearClientTarget = clear;
-}
-
-bool Layer::getClearClientTarget(DisplayId displayId) const {
- if (getBE().mHwcLayers.count(displayId) == 0) {
- ALOGE("getClearClientTarget called without a valid HWC layer");
- return false;
- }
- return getBE().mHwcLayers.at(displayId).clearClientTarget;
+bool Layer::getClearClientTarget(const sp<const DisplayDevice>& display) const {
+ const auto outputLayer = findOutputLayerForDisplay(display);
+ LOG_FATAL_IF(!outputLayer);
+ return outputLayer->getState().clearClientTarget;
}
bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
@@ -1535,8 +1544,9 @@
result.append("-----------------------------\n");
}
-void Layer::miniDump(std::string& result, DisplayId displayId) const {
- if (!hasHwcLayer(displayId)) {
+void Layer::miniDump(std::string& result, const sp<DisplayDevice>& displayDevice) const {
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ if (!outputLayer) {
return;
}
@@ -1554,17 +1564,21 @@
StringAppendF(&result, " %s\n", name.c_str());
const State& layerState(getDrawingState());
- const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(displayId);
+ const auto& compositionState = outputLayer->getState();
+
if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) {
StringAppendF(&result, " rel %6d | ", layerState.z);
} else {
StringAppendF(&result, " %10d | ", layerState.z);
}
- StringAppendF(&result, "%10s | ", to_string(getCompositionType(displayId)).c_str());
- StringAppendF(&result, "%10s | ", to_string(hwcInfo.transform).c_str());
- const Rect& frame = hwcInfo.displayFrame;
+ StringAppendF(&result, "%10s | ", toString(getCompositionType(displayDevice)).c_str());
+ StringAppendF(&result, "%10s | ",
+ toString(getCompositionLayer() ? compositionState.bufferTransform
+ : static_cast<Hwc2::Transform>(0))
+ .c_str());
+ const Rect& frame = compositionState.displayFrame;
StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
- const FloatRect& crop = hwcInfo.sourceCrop;
+ const FloatRect& crop = compositionState.sourceCrop;
StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right,
crop.bottom);
@@ -2164,25 +2178,29 @@
LayerProtoHelper::writeToProto(mBounds, layerInfo->mutable_bounds());
}
-void Layer::writeToProto(LayerProto* layerInfo, DisplayId displayId) {
- if (!hasHwcLayer(displayId)) {
+void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice) {
+ auto outputLayer = findOutputLayerForDisplay(displayDevice);
+ if (!outputLayer) {
return;
}
writeToProto(layerInfo, LayerVector::StateSet::Drawing);
- const auto& hwcInfo = getBE().mHwcLayers.at(displayId);
+ const auto& compositionState = outputLayer->getState();
- const Rect& frame = hwcInfo.displayFrame;
+ const Rect& frame = compositionState.displayFrame;
LayerProtoHelper::writeToProto(frame, layerInfo->mutable_hwc_frame());
- const FloatRect& crop = hwcInfo.sourceCrop;
+ const FloatRect& crop = compositionState.sourceCrop;
LayerProtoHelper::writeToProto(crop, layerInfo->mutable_hwc_crop());
- const int32_t transform = static_cast<int32_t>(hwcInfo.transform);
+ const int32_t transform =
+ getCompositionLayer() ? static_cast<int32_t>(compositionState.bufferTransform) : 0;
layerInfo->set_hwc_transform(transform);
- const int32_t compositionType = static_cast<int32_t>(hwcInfo.compositionType);
+ const int32_t compositionType =
+ static_cast<int32_t>(compositionState.hwc ? (*compositionState.hwc).hwcCompositionType
+ : Hwc2::IComposerClient::Composition::CLIENT);
layerInfo->set_hwc_composition_type(compositionType);
if (std::strcmp(getTypeId(), "BufferLayer") == 0 &&
@@ -2249,6 +2267,11 @@
return isVisible();
}
+compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
+ const sp<const DisplayDevice>& display) const {
+ return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionLayer().get());
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9241e71..45e7443 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -51,6 +51,7 @@
#include "SurfaceFlinger.h"
#include "TransactionCompletedThread.h"
+#include "DisplayHardware/ComposerHal.h"
#include "DisplayHardware/HWComposer.h"
#include "RenderArea.h"
@@ -70,6 +71,7 @@
namespace compositionengine {
class Layer;
+class OutputLayer;
}
namespace impl {
@@ -419,7 +421,7 @@
void writeToProto(LayerProto* layerInfo,
LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
- void writeToProto(LayerProto* layerInfo, DisplayId displayId);
+ void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice);
virtual Geometry getActiveGeometry(const Layer::State& s) const { return s.active_legacy; }
virtual uint32_t getActiveWidth(const Layer::State& s) const { return s.active_legacy.w; }
@@ -443,17 +445,19 @@
virtual bool isHdrY410() const { return false; }
void setGeometry(const sp<const DisplayDevice>& display, uint32_t z);
- void forceClientComposition(DisplayId displayId);
- bool getForceClientComposition(DisplayId displayId);
- virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform,
- const Rect& viewport, int32_t supportedPerFrameMetadata) = 0;
+ void forceClientComposition(const sp<DisplayDevice>& display);
+ bool getForceClientComposition(const sp<DisplayDevice>& display);
+ virtual void setPerFrameData(const sp<const DisplayDevice>& display,
+ const ui::Transform& transform, const Rect& viewport,
+ int32_t supportedPerFrameMetadata) = 0;
// callIntoHwc exists so we can update our local state and call
// acceptDisplayChanges without unnecessarily updating the device's state
- void setCompositionType(DisplayId displayId, HWC2::Composition type, bool callIntoHwc = true);
- HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const;
- void setClearClientTarget(DisplayId displayId, bool clear);
- bool getClearClientTarget(DisplayId displayId) const;
+ void setCompositionType(const sp<const DisplayDevice>& display,
+ Hwc2::IComposerClient::Composition type);
+ Hwc2::IComposerClient::Composition getCompositionType(
+ const sp<const DisplayDevice>& display) const;
+ bool getClearClientTarget(const sp<const DisplayDevice>& display) const;
void updateCursorPosition(const sp<const DisplayDevice>& display);
/*
@@ -567,27 +571,13 @@
// -----------------------------------------------------------------------
- bool createHwcLayer(HWComposer* hwc, DisplayId displayId);
- bool destroyHwcLayer(DisplayId displayId);
- void destroyHwcLayersForAllDisplays();
- void destroyAllHwcLayersPlusChildren();
+ bool createHwcLayer(HWComposer* hwc, const sp<DisplayDevice>& display);
+ bool destroyHwcLayer(const sp<DisplayDevice>& display);
+ bool destroyHwcLayersForAllDisplays();
+ bool destroyAllHwcLayersPlusChildren();
- bool hasHwcLayer(DisplayId displayId) const { return getBE().mHwcLayers.count(displayId) > 0; }
-
- HWC2::Layer* getHwcLayer(DisplayId displayId) {
- if (!hasHwcLayer(displayId)) {
- return nullptr;
- }
- return getBE().mHwcLayers[displayId].layer.get();
- }
-
- bool setHwcLayer(DisplayId displayId) {
- if (!hasHwcLayer(displayId)) {
- return false;
- }
- getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[displayId].layer;
- return true;
- }
+ bool hasHwcLayer(const sp<const DisplayDevice>& displayDevice);
+ HWC2::Layer* getHwcLayer(const sp<const DisplayDevice>& displayDevice);
// -----------------------------------------------------------------------
void clearWithOpenGL(const RenderArea& renderArea) const;
@@ -600,7 +590,7 @@
/* always call base class first */
static void miniDumpHeader(std::string& result);
- void miniDump(std::string& result, DisplayId displayId) const;
+ void miniDump(std::string& result, const sp<DisplayDevice>& display) const;
void dumpFrameStats(std::string& result) const;
void dumpFrameEvents(std::string& result);
void clearFrameStats();
@@ -676,6 +666,9 @@
return parentBounds;
}
+ compositionengine::OutputLayer* findOutputLayerForDisplay(
+ const sp<const DisplayDevice>& display) const;
+
protected:
// constant
sp<SurfaceFlinger> mFlinger;
@@ -920,11 +913,11 @@
} // namespace android
-#define RETURN_IF_NO_HWC_LAYER(displayId, ...) \
+#define RETURN_IF_NO_HWC_LAYER(displayDevice, ...) \
do { \
- if (!hasHwcLayer(displayId)) { \
+ if (!hasHwcLayer(displayDevice)) { \
ALOGE("[%s] %s failed: no HWC layer found for display %s", mName.string(), \
- __FUNCTION__, to_string(displayId).c_str()); \
+ __FUNCTION__, displayDevice->getDebugName().c_str()); \
return __VA_ARGS__; \
} \
} while (false)
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index e39babe..4bf5325 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -87,21 +87,12 @@
result += base::StringPrintf("[%s]HWC parameters\n", tag);
}
- result += base::StringPrintf("\thwcLayer=%p\n", static_cast<HWC2::Layer*>(&*hwc.hwcLayer));
result += base::StringPrintf("\tfence=%p\n", hwc.fence.get());
result += base::StringPrintf("\tblendMode=%d\n", hwc.blendMode);
- result += base::StringPrintf("\ttransform=%d\n", hwc.transform);
- result += base::StringPrintf("\tz=%d\n", hwc.z);
result += base::StringPrintf("\ttype=%d\n", hwc.type);
result += base::StringPrintf("\tappId=%d\n", hwc.appId);
- result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left,
- hwc.displayFrame.top, hwc.displayFrame.right,
- hwc.displayFrame.bottom);
result += base::StringPrintf("\talpha=%.3f", hwc.alpha);
- result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left,
- hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
- hwc.visibleRegion.dump(result, "visibleRegion");
hwc.surfaceDamage.dump(result, "surfaceDamage");
result += base::StringPrintf("\tcolor transform matrix:\n"
@@ -146,12 +137,7 @@
getCompositionName(compositionType));
result += base::StringPrintf("\tmBuffer = %p\n", mBuffer.get());
result += base::StringPrintf("\tmBufferSlot=%d\n", mBufferSlot);
- result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left,
- hwc.displayFrame.top, hwc.displayFrame.right,
- hwc.displayFrame.bottom);
result += base::StringPrintf("\talpha=%f\n", hwc.alpha);
- result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left,
- hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
switch (compositionType) {
case HWC2::Composition::Device:
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index 6270efa..e41632c 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -19,8 +19,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <compositionengine/impl/HwcBufferCache.h>
-
#include <renderengine/Mesh.h>
#include <renderengine/RenderEngine.h>
#include <renderengine/Texture.h>
@@ -42,23 +40,17 @@
int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
std::shared_ptr<LayerBE> layer;
struct {
- std::shared_ptr<HWC2::Layer> hwcLayer;
DisplayId displayId;
sp<Fence> fence;
HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid;
- Rect displayFrame;
float alpha;
- FloatRect sourceCrop;
HWC2::Transform transform = HWC2::Transform::None;
- int z;
int type;
int appId;
- Region visibleRegion;
Region surfaceDamage;
sp<NativeHandle> sidebandStream;
ui::Dataspace dataspace;
hwc_color_t color;
- bool clearClientTarget = false;
bool supportedPerFrameMetadata = false;
HdrMetadata hdrMetadata;
mat4 colorTransform;
@@ -104,33 +96,6 @@
// The mesh used to draw the layer in GLES composition mode
renderengine::Mesh mMesh;
- // HWC items, accessed from the main thread
- struct HWCInfo {
- HWCInfo()
- : hwc(nullptr),
- layer(nullptr),
- forceClientComposition(false),
- compositionType(HWC2::Composition::Invalid),
- clearClientTarget(false),
- transform(HWC2::Transform::None) {}
-
- HWComposer* hwc;
- std::shared_ptr<HWC2::Layer> layer;
- bool forceClientComposition;
- HWC2::Composition compositionType;
- bool clearClientTarget;
- Rect displayFrame;
- FloatRect sourceCrop;
- compositionengine::impl::HwcBufferCache bufferCache;
- HWC2::Transform transform;
- };
-
- // A layer can be attached to multiple displays when operating in mirror mode
- // (a.k.a: when several displays are attached with equal layerStack). In this
- // case we need to keep track. In non-mirror mode, a layer will have only one
- // HWCInfo.
- std::unordered_map<DisplayId, HWCInfo> mHwcLayers;
-
CompositionInfo compositionInfo;
};
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 9bad6de..edc6442 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -7,6 +7,8 @@
namespace android {
+class DisplayDevice;
+
// RenderArea describes a rectangular area that layers can be rendered to.
//
// There is a logical render area and a physical render area. When a layer is
@@ -76,6 +78,8 @@
// covered by any rendered layer should be filled with this color.
CaptureFill getCaptureFill() const { return mCaptureFill; };
+ virtual const sp<const DisplayDevice> getDisplayDevice() const = 0;
+
private:
const uint32_t mReqWidth;
const uint32_t mReqHeight;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 85411b6..37f7631 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -44,6 +44,7 @@
#include <compositionengine/OutputLayer.h>
#include <compositionengine/RenderSurface.h>
#include <compositionengine/impl/OutputCompositionState.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <dvr/vr_flinger.h>
#include <gui/BufferQueue.h>
#include <gui/GuiConfig.h>
@@ -1823,11 +1824,6 @@
mVsyncModulator.onRefreshed(mHadClientComposition);
getBE().mEndOfFrameCompositionInfo = std::move(getBE().mCompositionInfo);
- for (const auto& [token, display] : mDisplays) {
- for (auto& compositionInfo : getBE().mEndOfFrameCompositionInfo[token]) {
- compositionInfo.hwc.hwcLayer = nullptr;
- }
- }
mLayersWithQueuedFrames.clear();
}
@@ -1868,16 +1864,16 @@
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
- if (!layer->hasHwcLayer(*displayId)) {
- if (!layer->createHwcLayer(&getHwComposer(), *displayId)) {
- layer->forceClientComposition(*displayId);
+ if (!layer->hasHwcLayer(displayDevice)) {
+ if (!layer->createHwcLayer(&getHwComposer(), displayDevice)) {
+ layer->forceClientComposition(displayDevice);
continue;
}
}
layer->setGeometry(displayDevice, i);
if (mDebugDisableHWC || mDebugRegion) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
}
}
}
@@ -1897,34 +1893,35 @@
}
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
if (layer->isHdrY410()) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
} else if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
!profile->hasHDR10Support()) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
} else if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
!profile->hasHLGSupport()) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
}
// TODO(b/111562338) remove when composer 2.3 is shipped.
if (layer->hasColorTransform()) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
}
if (layer->getRoundedCornerState().radius > 0.0f) {
- layer->forceClientComposition(*displayId);
+ layer->forceClientComposition(displayDevice);
}
- if (layer->getForceClientComposition(*displayId)) {
+ if (layer->getForceClientComposition(displayDevice)) {
ALOGV("[%s] Requesting Client composition", layer->getName().string());
- layer->setCompositionType(*displayId, HWC2::Composition::Client);
+ layer->setCompositionType(displayDevice,
+ Hwc2::IComposerClient::Composition::CLIENT);
continue;
}
const auto& displayState = display->getState();
- layer->setPerFrameData(*displayId, displayState.transform, displayState.viewport,
+ layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport,
displayDevice->getSupportedPerFrameMetadata());
}
@@ -1939,20 +1936,14 @@
mDrawingState.colorMatrixChanged = false;
- for (const auto& [token, display] : mDisplays) {
- for (auto& layer : display->getVisibleLayersSortedByZ()) {
+ for (const auto& [token, displayDevice] : mDisplays) {
+ auto display = displayDevice->getCompositionDisplay();
+ for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
const auto displayId = display->getId();
- layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId);
-
- if (displayId) {
- if (!layer->setHwcLayer(*displayId)) {
- ALOGV("Need to create HWCLayer for %s", layer->getName().string());
- }
- layer->getBE().compositionInfo.hwc.displayId = *displayId;
- }
-
+ layer->getBE().compositionInfo.compositionType =
+ static_cast<HWC2::Composition>(layer->getCompositionType(displayDevice));
+ layer->getBE().compositionInfo.hwc.displayId = *displayId;
getBE().mCompositionInfo[token].push_back(layer->getBE().compositionInfo);
- layer->getBE().compositionInfo.hwc.hwcLayer = nullptr;
}
}
}
@@ -2000,7 +1991,7 @@
if (CC_UNLIKELY(mLayerStats.isEnabled())) {
for (const auto& [token, display] : mDisplays) {
if (display->isPrimary()) {
- mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(*display));
+ mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(display));
return;
}
}
@@ -2397,13 +2388,13 @@
} else {
// Clear out the HWC layer if this layer was
// previously visible, but no longer is
- hwcLayerDestroyed = displayId && layer->destroyHwcLayer(*displayId);
+ hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice);
}
} else {
// WM changes display->layerStack upon sleep/awake.
// Here we make sure we delete the HWC layers even if
// WM changed their layer stack.
- hwcLayerDestroyed = displayId && layer->destroyHwcLayer(*displayId);
+ hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice);
}
// If a layer is not going to get a release fence because
@@ -2562,8 +2553,7 @@
return;
}
- status_t result = display->getRenderSurface()->prepareFrame(
- getBE().mCompositionInfo[displayDevice->getDisplayToken()]);
+ status_t result = display->getRenderSurface()->prepareFrame();
ALOGE_IF(result != NO_ERROR, "prepareFrame failed for %s: %d (%s)",
displayDevice->getDebugName().c_str(), result, strerror(-result));
}
@@ -2621,9 +2611,10 @@
// The layer buffer from the previous frame (if any) is released
// by HWC only when the release fence from this frame (if any) is
// signaled. Always get the release fence from HWC first.
- if (displayId && layer->hasHwcLayer(*displayId)) {
- releaseFence = getHwComposer().getLayerReleaseFence(*displayId,
- layer->getHwcLayer(*displayId));
+ if (displayId && layer->hasHwcLayer(displayDevice)) {
+ releaseFence =
+ getHwComposer().getLayerReleaseFence(*displayId,
+ layer->getHwcLayer(displayDevice));
}
// If the layer was client composited in the previous frame, we
@@ -2631,7 +2622,8 @@
// Since we do not track that, always merge with the current
// client target acquire fence when it is available, even though
// this is suboptimal.
- if (layer->getCompositionType(displayId) == HWC2::Composition::Client) {
+ if (layer->getCompositionType(displayDevice) ==
+ Hwc2::IComposerClient::Composition::CLIENT) {
releaseFence =
Fence::merge("LayerRelease", releaseFence,
display->getRenderSurface()->getClientTargetAcquireFence());
@@ -3542,16 +3534,16 @@
const Region viewportRegion(displayState.viewport);
const Region clip(viewportRegion.intersect(layer->visibleRegion));
ALOGV("Layer: %s", layer->getName().string());
- ALOGV(" Composition type: %s", to_string(layer->getCompositionType(displayId)).c_str());
+ ALOGV(" Composition type: %s", toString(layer->getCompositionType(displayDevice)).c_str());
if (!clip.isEmpty()) {
- switch (layer->getCompositionType(displayId)) {
- case HWC2::Composition::Cursor:
- case HWC2::Composition::Device:
- case HWC2::Composition::Sideband:
- case HWC2::Composition::SolidColor: {
+ switch (layer->getCompositionType(displayDevice)) {
+ case Hwc2::IComposerClient::Composition::CURSOR:
+ case Hwc2::IComposerClient::Composition::DEVICE:
+ case Hwc2::IComposerClient::Composition::SIDEBAND:
+ case Hwc2::IComposerClient::Composition::SOLID_COLOR: {
LOG_ALWAYS_FATAL_IF(!displayId);
const Layer::State& state(layer->getDrawingState());
- if (layer->getClearClientTarget(*displayId) && !firstLayer &&
+ if (layer->getClearClientTarget(displayDevice) && !firstLayer &&
layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
// never clear the very first layer since we're
@@ -3571,7 +3563,7 @@
}
break;
}
- case HWC2::Composition::Client: {
+ case Hwc2::IComposerClient::Composition::CLIENT: {
renderengine::LayerSettings layerSettings;
bool prepared =
layer->prepareClientLayer(renderArea, clip, clearRegion, layerSettings);
@@ -4843,26 +4835,27 @@
return layersProto;
}
-LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(const DisplayDevice& displayDevice) const {
+LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(
+ const sp<DisplayDevice>& displayDevice) const {
LayersProto layersProto;
SizeProto* resolution = layersProto.mutable_resolution();
- resolution->set_w(displayDevice.getWidth());
- resolution->set_h(displayDevice.getHeight());
+ resolution->set_w(displayDevice->getWidth());
+ resolution->set_h(displayDevice->getHeight());
- auto display = displayDevice.getCompositionDisplay();
+ auto display = displayDevice->getCompositionDisplay();
const auto& displayState = display->getState();
layersProto.set_color_mode(decodeColorMode(displayState.colorMode));
layersProto.set_color_transform(decodeColorTransform(displayState.colorTransform));
layersProto.set_global_transform(displayState.orientation);
- const auto displayId = displayDevice.getId();
+ const auto displayId = displayDevice->getId();
LOG_ALWAYS_FATAL_IF(!displayId);
mDrawingState.traverseInZOrder([&](Layer* layer) {
- if (!layer->visibleRegion.isEmpty() && layer->getBE().mHwcLayers.count(*displayId)) {
+ if (!layer->visibleRegion.isEmpty() && !display->getOutputLayersOrderedByZ().empty()) {
LayerProto* layerProto = layersProto.add_layers();
- layer->writeToProto(layerProto, *displayId);
+ layer->writeToProto(layerProto, displayDevice);
}
});
@@ -4998,7 +4991,9 @@
StringAppendF(&result, "Display %s HWC layers:\n", to_string(*displayId).c_str());
Layer::miniDumpHeader(result);
- mCurrentState.traverseInZOrder([&](Layer* layer) { layer->miniDump(result, *displayId); });
+ const sp<DisplayDevice> displayDevice = display;
+ mCurrentState.traverseInZOrder(
+ [&](Layer* layer) { layer->miniDump(result, displayDevice); });
result.append("\n");
}
@@ -5550,6 +5545,7 @@
}
bool isSecure() const override { return false; }
bool needsFiltering() const override { return mNeedsFiltering; }
+ const sp<const DisplayDevice> getDisplayDevice() const override { return nullptr; }
Rect getSourceCrop() const override {
if (mCrop.isEmpty()) {
return getBounds();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 669d3a1..d8d4ca1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -895,7 +895,7 @@
void dumpWideColorInfo(std::string& result) const;
void dumpFrameCompositionInfo(std::string& result) const;
LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const;
- LayersProto dumpVisibleLayersProtoInfo(const DisplayDevice& display) const;
+ LayersProto dumpVisibleLayersProtoInfo(const sp<DisplayDevice>& display) const;
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 68cf61e..a2c0611 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -31,7 +31,6 @@
"libutils",
],
static_libs: [
- "libcompositionengine",
"libgmock",
"librenderengine",
"libtrace_proto",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3fb8708..3addd61 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -17,6 +17,7 @@
#undef LOG_TAG
#define LOG_TAG "CompositionTest"
+#include <compositionengine/Display.h>
#include <compositionengine/mock/DisplaySurface.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -753,12 +754,16 @@
}
static void injectLayer(CompositionTest* test, sp<Layer> layer) {
+ std::vector<std::unique_ptr<compositionengine::OutputLayer>> outputLayers;
+ outputLayers.emplace_back(
+ test->mDisplay->getCompositionDisplay()
+ ->getOrCreateOutputLayer(layer->getCompositionLayer(), layer));
+ test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ(std::move(outputLayers));
+
EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _))
.WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE)));
- const auto displayId = test->mDisplay->getId();
- ASSERT_TRUE(displayId);
- layer->createHwcLayer(&test->mFlinger.getHwComposer(), *displayId);
+ layer->createHwcLayer(&test->mFlinger.getHwComposer(), test->mDisplay);
Mock::VerifyAndClear(test->mComposer);
@@ -771,10 +776,12 @@
static void cleanupInjectedLayers(CompositionTest* test) {
EXPECT_CALL(*test->mComposer, destroyLayer(HWC_DISPLAY, HWC_LAYER))
.WillOnce(Return(Error::NONE));
- const auto displayId = test->mDisplay->getId();
- ASSERT_TRUE(displayId);
+
+ test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ(
+ std::vector<std::unique_ptr<compositionengine::OutputLayer>>());
+
for (auto layer : test->mFlinger.mutableDrawingState().layersSortedByZ) {
- layer->destroyHwcLayer(*displayId);
+ layer->destroyHwcLayer(test->mDisplay);
}
test->mFlinger.mutableDrawingState().layersSortedByZ.clear();
}
@@ -963,8 +970,8 @@
};
struct ForcedClientCompositionResultVariant : public RECompositionResultVariant {
- static void setupLayerState(CompositionTest*, sp<Layer> layer) {
- layer->forceClientComposition(DEFAULT_DISPLAY_ID);
+ static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+ layer->forceClientComposition(test->mDisplay);
}
template <typename Case>
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index e639b4d..bfdd20b 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -16,7 +16,10 @@
#pragma once
+#include <compositionengine/Display.h>
+#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/CompositionEngine.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include "BufferQueueLayer.h"
#include "BufferStateLayer.h"
@@ -206,6 +209,14 @@
layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
}
+ void setLayerCompositionType(sp<Layer> layer, HWC2::Composition type) {
+ auto outputLayer = layer->findOutputLayerForDisplay(mFlinger->getDefaultDisplayDevice());
+ LOG_ALWAYS_FATAL_IF(!outputLayer);
+ auto& state = outputLayer->editState();
+ LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc);
+ (*state.hwc).hwcCompositionType = static_cast<Hwc2::IComposerClient::Composition>(type);
+ };
+
void setLayerPotentialCursor(sp<Layer> layer, bool potentialCursor) {
layer->mPotentialCursor = potentialCursor;
}