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/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