summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp')
-rw-r--r--services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp243
1 files changed, 71 insertions, 172 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 56e9d27f14..1faf775ed3 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -14,16 +14,14 @@
* limitations under the License.
*/
-#include <DisplayHardware/Hal.h>
#include <android-base/stringprintf.h>
#include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/Output.h>
-#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
-#include <cstdint>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -79,7 +77,7 @@ Rect OutputLayer::calculateInitialCrop() const {
FloatRect activeCropFloat =
reduce(layerState.geomLayerBounds, layerState.transparentRegionHint);
- const Rect& viewport = getOutput().getState().layerStackSpace.content;
+ const Rect& viewport = getOutput().getState().viewport;
const ui::Transform& layerTransform = layerState.geomLayerTransform;
const ui::Transform& inverseLayerTransform = layerState.geomInverseLayerTransform;
// Transform to screen space.
@@ -135,8 +133,7 @@ FloatRect OutputLayer::calculateOutputSourceCrop() const {
* the code below applies the primary display's inverse transform to the
* buffer
*/
- uint32_t invTransformOrient =
- ui::Transform::toRotationFlags(outputState.displaySpace.orientation);
+ uint32_t invTransformOrient = outputState.orientation;
// calculate the inverse transform
if (invTransformOrient & HAL_TRANSFORM_ROT_90) {
invTransformOrient ^= HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H;
@@ -192,7 +189,7 @@ Rect OutputLayer::calculateOutputDisplayFrame() const {
Rect activeCrop = layerState.geomCrop;
if (!activeCrop.isEmpty() && bufferSize.isValid()) {
activeCrop = layerTransform.transform(activeCrop);
- if (!activeCrop.intersect(outputState.layerStackSpace.content, &activeCrop)) {
+ if (!activeCrop.intersect(outputState.viewport, &activeCrop)) {
activeCrop.clear();
}
activeCrop = inverseLayerTransform.transform(activeCrop, true);
@@ -216,19 +213,9 @@ Rect OutputLayer::calculateOutputDisplayFrame() const {
// reduce uses a FloatRect to provide more accuracy during the
// transformation. We then round upon constructing 'frame'.
- FloatRect geomLayerBounds = layerState.geomLayerBounds;
-
- // Some HWCs may clip client composited input to its displayFrame. Make sure
- // that this does not cut off the shadow.
- if (layerState.forceClientComposition && layerState.shadowRadius > 0.0f) {
- const auto outset = layerState.shadowRadius;
- geomLayerBounds.left -= outset;
- geomLayerBounds.top -= outset;
- geomLayerBounds.right += outset;
- geomLayerBounds.bottom += outset;
- }
- Rect frame{layerTransform.transform(reduce(geomLayerBounds, activeTransparentRegion))};
- if (!frame.intersect(outputState.layerStackSpace.content, &frame)) {
+ Rect frame{
+ layerTransform.transform(reduce(layerState.geomLayerBounds, activeTransparentRegion))};
+ if (!frame.intersect(outputState.viewport, &frame)) {
frame.clear();
}
const ui::Transform displayTransform{outputState.transform};
@@ -325,8 +312,7 @@ void OutputLayer::updateCompositionState(
}
}
-void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,
- bool zIsOverridden, bool isPeekingThrough) {
+void OutputLayer::writeStateToHWC(bool includeGeometry) {
const auto& state = getState();
// Skip doing this if there is no HWC interface
if (!state.hwc) {
@@ -347,72 +333,50 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t
auto requestedCompositionType = outputIndependentState->compositionType;
- // TODO(b/181172795): We now update geometry for all flattened layers. We should update it
- // only when the geometry actually changes
- const bool isOverridden =
- state.overrideInfo.buffer != nullptr || isPeekingThrough || zIsOverridden;
- const bool prevOverridden = state.hwc->stateOverridden;
- if (isOverridden || prevOverridden || skipLayer || includeGeometry) {
- writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType, z);
- writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState,
- skipLayer);
+ if (includeGeometry) {
+ writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType);
+ writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState);
}
writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
- writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer);
+ writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState);
- writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
- skipLayer);
+ writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType);
// Always set the layer color after setting the composition type.
writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
-
- editState().hwc->stateOverridden = isOverridden;
- editState().hwc->layerSkipped = skipLayer;
}
-void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer,
- hal::Composition requestedCompositionType,
- uint32_t z) {
+void OutputLayer::writeOutputDependentGeometryStateToHWC(
+ HWC2::Layer* hwcLayer, hal::Composition requestedCompositionType) {
const auto& outputDependentState = getState();
- Rect displayFrame = outputDependentState.displayFrame;
- FloatRect sourceCrop = outputDependentState.sourceCrop;
-
- if (outputDependentState.overrideInfo.buffer != nullptr) {
- displayFrame = outputDependentState.overrideInfo.displayFrame;
- sourceCrop =
- FloatRect(0.f, 0.f,
- static_cast<float>(outputDependentState.overrideInfo.buffer->getBuffer()
- ->getWidth()),
- static_cast<float>(outputDependentState.overrideInfo.buffer->getBuffer()
- ->getHeight()));
- }
-
- ALOGV("Writing display frame [%d, %d, %d, %d]", displayFrame.left, displayFrame.top,
- displayFrame.right, displayFrame.bottom);
-
- if (auto error = hwcLayer->setDisplayFrame(displayFrame); error != hal::Error::NONE) {
+ if (auto error = hwcLayer->setDisplayFrame(outputDependentState.displayFrame);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
- getLayerFE().getDebugName(), displayFrame.left, displayFrame.top, displayFrame.right,
- displayFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
+ getLayerFE().getDebugName(), outputDependentState.displayFrame.left,
+ outputDependentState.displayFrame.top, outputDependentState.displayFrame.right,
+ outputDependentState.displayFrame.bottom, to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
- if (auto error = hwcLayer->setSourceCrop(sourceCrop); error != hal::Error::NONE) {
+ if (auto error = hwcLayer->setSourceCrop(outputDependentState.sourceCrop);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
"%s (%d)",
- getLayerFE().getDebugName(), sourceCrop.left, sourceCrop.top, sourceCrop.right,
- sourceCrop.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
+ getLayerFE().getDebugName(), outputDependentState.sourceCrop.left,
+ outputDependentState.sourceCrop.top, outputDependentState.sourceCrop.right,
+ outputDependentState.sourceCrop.bottom, to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
- if (auto error = hwcLayer->setZOrder(z); error != hal::Error::NONE) {
- ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(), z,
- to_string(error).c_str(), static_cast<int32_t>(error));
+ if (auto error = hwcLayer->setZOrder(outputDependentState.z); error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(),
+ outputDependentState.z, to_string(error).c_str(), static_cast<int32_t>(error));
}
- // Solid-color layers and overridden buffers should always use an identity transform.
- const auto bufferTransform = (requestedCompositionType != hal::Composition::SOLID_COLOR &&
- getState().overrideInfo.buffer == nullptr)
+ // Solid-color layers should always use an identity transform.
+ const auto bufferTransform = requestedCompositionType != hal::Composition::SOLID_COLOR
? outputDependentState.bufferTransform
: static_cast<hal::Transform>(0);
if (auto error = hwcLayer->setTransform(static_cast<hal::Transform>(bufferTransform));
@@ -424,26 +388,24 @@ void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer,
}
void OutputLayer::writeOutputIndependentGeometryStateToHWC(
- HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
- bool skipLayer) {
- // If there is a peekThroughLayer, then this layer has a hole in it. We need to use
- // PREMULTIPLIED so it will peek through.
- const auto& overrideInfo = getState().overrideInfo;
- const auto blendMode = overrideInfo.buffer || overrideInfo.peekThroughLayer
- ? hardware::graphics::composer::hal::BlendMode::PREMULTIPLIED
- : outputIndependentState.blendMode;
- if (auto error = hwcLayer->setBlendMode(blendMode); error != hal::Error::NONE) {
+ HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) {
+ if (auto error = hwcLayer->setBlendMode(outputIndependentState.blendMode);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set blend mode %s: %s (%d)", getLayerFE().getDebugName(),
- toString(blendMode).c_str(), to_string(error).c_str(), static_cast<int32_t>(error));
+ toString(outputIndependentState.blendMode).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
- const float alpha = skipLayer
- ? 0.0f
- : (getState().overrideInfo.buffer ? 1.0f : outputIndependentState.alpha);
- ALOGV("Writing alpha %f", alpha);
+ if (auto error = hwcLayer->setPlaneAlpha(outputIndependentState.alpha);
+ error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set plane alpha %.3f: %s (%d)", getLayerFE().getDebugName(),
+ outputIndependentState.alpha, to_string(error).c_str(), static_cast<int32_t>(error));
+ }
- if (auto error = hwcLayer->setPlaneAlpha(alpha); error != hal::Error::NONE) {
- ALOGE("[%s] Failed to set plane alpha %.3f: %s (%d)", getLayerFE().getDebugName(), alpha,
+ if (auto error = hwcLayer->setInfo(static_cast<uint32_t>(outputIndependentState.type),
+ static_cast<uint32_t>(outputIndependentState.appId));
+ error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set info %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -461,28 +423,23 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer)
// TODO(lpique): b/121291683 outputSpaceVisibleRegion is output-dependent geometry
// state and should not change every frame.
- Region visibleRegion = outputDependentState.overrideInfo.buffer
- ? Region(outputDependentState.overrideInfo.visibleRegion)
- : outputDependentState.outputSpaceVisibleRegion;
- if (auto error = hwcLayer->setVisibleRegion(visibleRegion); error != hal::Error::NONE) {
+ if (auto error = hwcLayer->setVisibleRegion(outputDependentState.outputSpaceVisibleRegion);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG);
}
- const auto dataspace = outputDependentState.overrideInfo.buffer
- ? outputDependentState.overrideInfo.dataspace
- : outputDependentState.dataspace;
-
- if (auto error = hwcLayer->setDataspace(dataspace); error != hal::Error::NONE) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(), dataspace,
- to_string(error).c_str(), static_cast<int32_t>(error));
+ if (auto error = hwcLayer->setDataspace(outputDependentState.dataspace);
+ error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(),
+ outputDependentState.dataspace, to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
}
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
- HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
- bool skipLayer) {
+ HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) {
switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
case hal::Error::NONE:
break;
@@ -494,12 +451,8 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
to_string(error).c_str(), static_cast<int32_t>(error));
}
- const Region& surfaceDamage = getState().overrideInfo.buffer
- ? getState().overrideInfo.damageRegion
- : (getState().hwc->stateOverridden ? Region::INVALID_REGION
- : outputIndependentState.surfaceDamage);
-
- if (auto error = hwcLayer->setSurfaceDamage(surfaceDamage); error != hal::Error::NONE) {
+ if (auto error = hwcLayer->setSurfaceDamage(outputIndependentState.surfaceDamage);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set surface damage: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputIndependentState.surfaceDamage.dump(LOG_TAG);
@@ -515,7 +468,7 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
break;
case hal::Composition::CURSOR:
case hal::Composition::DEVICE:
- writeBufferStateToHWC(hwcLayer, outputIndependentState, skipLayer);
+ writeBufferStateToHWC(hwcLayer, outputIndependentState);
break;
case hal::Composition::INVALID:
case hal::Composition::CLIENT:
@@ -552,8 +505,7 @@ void OutputLayer::writeSidebandStateToHWC(HWC2::Layer* hwcLayer,
}
void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
- const LayerFECompositionState& outputIndependentState,
- bool skipLayer) {
+ const LayerFECompositionState& outputIndependentState) {
auto supportedPerFrameMetadata =
getOutput().getDisplayColorProfile()->getSupportedPerFrameMetadata();
if (auto error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata,
@@ -563,45 +515,33 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
to_string(error).c_str(), static_cast<int32_t>(error));
}
- sp<GraphicBuffer> buffer = outputIndependentState.buffer;
- sp<Fence> acquireFence = outputIndependentState.acquireFence;
- int slot = outputIndependentState.bufferSlot;
- if (getState().overrideInfo.buffer != nullptr && !skipLayer) {
- buffer = getState().overrideInfo.buffer->getBuffer();
- acquireFence = getState().overrideInfo.acquireFence;
- slot = HwcBufferCache::FLATTENER_CACHING_SLOT;
- }
-
- ALOGV("Writing buffer %p", buffer.get());
-
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
// We need access to the output-dependent state for the buffer cache there,
// though otherwise the buffer is not output-dependent.
- editState().hwc->hwcBufferCache.getHwcBuffer(slot, buffer, &hwcSlot, &hwcBuffer);
+ editState().hwc->hwcBufferCache.getHwcBuffer(outputIndependentState.bufferSlot,
+ outputIndependentState.buffer, &hwcSlot,
+ &hwcBuffer);
- if (auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
+ if (auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, outputIndependentState.acquireFence);
error != hal::Error::NONE) {
- ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(), buffer->handle,
- to_string(error).c_str(), static_cast<int32_t>(error));
+ ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(),
+ outputIndependentState.buffer->handle, to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
}
void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
- hal::Composition requestedCompositionType,
- bool isPeekingThrough, bool skipLayer) {
+ hal::Composition requestedCompositionType) {
auto& outputDependentState = editState();
- if (isClientCompositionForced(isPeekingThrough)) {
- // If we are forcing client composition, we need to tell the HWC
+ // If we are forcing client composition, we need to tell the HWC
+ if (outputDependentState.forceClientComposition) {
requestedCompositionType = hal::Composition::CLIENT;
}
// Set the requested composition type with the HWC whenever it changes
- // We also resend the composition type when this layer was previously skipped, to ensure that
- // the composition type is up-to-date.
- if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
- (outputDependentState.hwc->layerSkipped && !skipLayer)) {
+ if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType) {
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
@@ -628,7 +568,7 @@ void OutputLayer::writeCursorPositionToHWC() const {
const auto& outputState = getOutput().getState();
Rect frame = layerFEState->cursorFrame;
- frame.intersect(outputState.layerStackSpace.content, &frame);
+ frame.intersect(outputState.viewport, &frame);
Rect position = outputState.transform.transform(frame);
if (auto error = hwcLayer->setCursorPosition(position.left, position.top);
@@ -681,22 +621,12 @@ void OutputLayer::detectDisallowedCompositionTypeChange(hal::Composition from,
}
}
-bool OutputLayer::isClientCompositionForced(bool isPeekingThrough) const {
- return getState().forceClientComposition ||
- (!isPeekingThrough && getLayerFE().hasRoundedCorners());
-}
-
void OutputLayer::applyDeviceCompositionTypeChange(hal::Composition compositionType) {
auto& state = editState();
LOG_FATAL_IF(!state.hwc);
auto& hwcState = *state.hwc;
- // Only detected disallowed changes if this was not a skip layer, because the
- // validated composition type may be arbitrary (usually DEVICE, to reflect that there were
- // fewer GPU layers)
- if (!hwcState.layerSkipped) {
- detectDisallowedCompositionTypeChange(hwcState.hwcCompositionType, compositionType);
- }
+ detectDisallowedCompositionTypeChange(hwcState.hwcCompositionType, compositionType);
hwcState.hwcCompositionType = compositionType;
}
@@ -728,37 +658,6 @@ bool OutputLayer::needsFiltering() const {
sourceCrop.getWidth() != displayFrame.getWidth();
}
-std::vector<LayerFE::LayerSettings> OutputLayer::getOverrideCompositionList() const {
- if (getState().overrideInfo.buffer == nullptr) {
- return {};
- }
-
- // Compute the geometry boundaries in layer stack space: we need to transform from the
- // framebuffer space of the override buffer to layer space.
- const ProjectionSpace& layerSpace = getOutput().getState().layerStackSpace;
- const ui::Transform transform = getState().overrideInfo.displaySpace.getTransform(layerSpace);
- const Rect boundaries = transform.transform(getState().overrideInfo.displayFrame);
-
- LayerFE::LayerSettings settings;
- settings.geometry = renderengine::Geometry{
- .boundaries = boundaries.toFloatRect(),
- };
- settings.bufferId = getState().overrideInfo.buffer->getBuffer()->getId();
- settings.source = renderengine::PixelSource{
- .buffer = renderengine::Buffer{
- .buffer = getState().overrideInfo.buffer,
- .fence = getState().overrideInfo.acquireFence,
- // If the transform from layer space to display space contains a rotation, we
- // need to undo the rotation in the texture transform
- .textureTransform =
- ui::Transform(transform.inverse().getOrientation(), 1, 1).asMatrix4(),
- }};
- settings.sourceDataspace = getState().overrideInfo.dataspace;
- settings.alpha = 1.0f;
-
- return {static_cast<LayerFE::LayerSettings>(settings)};
-}
-
void OutputLayer::dump(std::string& out) const {
using android::base::StringAppendF;