diff options
Diffstat (limited to 'services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp')
-rw-r--r-- | services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp | 243 |
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; |