diff options
| author | 2023-02-14 19:58:22 +0000 | |
|---|---|---|
| committer | 2023-02-14 19:58:22 +0000 | |
| commit | b9aadd30183ae763a5f4ac92dcc216c8a1663fe5 (patch) | |
| tree | dfd83da5573efd9f0685c3a1073eab54569fc265 | |
| parent | a0b010330ef96850ee0e8544699648db5f4d5919 (diff) | |
| parent | 545da0e1040dabe238140c2ccdced5b3d60b0366 (diff) | |
Merge "Some fixes to TrustedPresentationListener"
8 files changed, 110 insertions, 13 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h index 4777f13598..a8322d8572 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h @@ -97,6 +97,8 @@ struct CompositionRefreshArgs { std::optional<std::chrono::steady_clock::time_point> scheduledFrameTime; std::vector<BorderRenderInfo> borderInfoList; + + bool hasTrustedPresentationListener = false; }; } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h index 5bb249719e..32684fc3b7 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h @@ -212,6 +212,8 @@ struct LayerFECompositionState { float currentSdrHdrRatio = 1.f; float desiredSdrHdrRatio = 1.f; + bool isInternalDisplayOverlay = false; + virtual ~LayerFECompositionState(); // Debugging diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h index 52ebd9ebec..a3d86398cf 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h @@ -153,6 +153,10 @@ public: Region aboveOpaqueLayers; // The region of the output which should be considered dirty Region dirtyRegion; + // The region of the output which is covered by layers, excluding display overlays. This + // only has a value if there's something needing it, like when a TrustedPresentationListener + // is set + std::optional<Region> aboveCoveredLayersExcludingOverlays; }; virtual ~Output(); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h index b86782f417..7b0af3a248 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h @@ -63,9 +63,15 @@ struct OutputLayerCompositionState { // The portion of the layer that is not obscured and is also opaque Region visibleNonTransparentRegion; - // The portion of the layer that is obscured by opaque layers on top + // The portion of the layer that is obscured by all layers on top. This includes transparent and + // opaque. Region coveredRegion; + // The portion of the layer that is obscured by all layers on top excluding display overlays. + // This only has a value if there's something needing it, like when a + // TrustedPresentationListener is set. + std::optional<Region> coveredRegionExcludingDisplayOverlays; + // The visibleRegion transformed to output space Region outputSpaceVisibleRegion; diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 403385ea8c..7d9431605d 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -31,6 +31,7 @@ #include <ftl/future.h> #include <gui/TraceUtils.h> +#include <optional> #include <thread> #include "renderengine/ExternalTexture.h" @@ -480,6 +481,9 @@ void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& // Process the layers to determine visibility and coverage compositionengine::Output::CoverageState coverage{layerFESet}; + coverage.aboveCoveredLayersExcludingOverlays = refreshArgs.hasTrustedPresentationListener + ? std::make_optional<Region>() + : std::nullopt; collectVisibleLayers(refreshArgs, coverage); // Compute the resulting coverage for this output, and store it for later @@ -534,6 +538,9 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE, return; } + bool computeAboveCoveredExcludingOverlays = + coverage.aboveCoveredLayersExcludingOverlays && !layerFEState->isInternalDisplayOverlay; + /* * opaqueRegion: area of a surface that is fully opaque. */ @@ -575,6 +582,11 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE, */ Region shadowRegion; + /** + * covered region above excluding internal display overlay layers + */ + std::optional<Region> coveredRegionExcludingDisplayOverlays = std::nullopt; + const ui::Transform& tr = layerFEState->geomLayerTransform; // Get the visible region @@ -647,6 +659,12 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE, // Update accumAboveCoveredLayers for next (lower) layer coverage.aboveCoveredLayers.orSelf(visibleRegion); + if (CC_UNLIKELY(computeAboveCoveredExcludingOverlays)) { + coveredRegionExcludingDisplayOverlays = + coverage.aboveCoveredLayersExcludingOverlays->intersect(visibleRegion); + coverage.aboveCoveredLayersExcludingOverlays->orSelf(visibleRegion); + } + // subtract the opaque region covered by the layers above us visibleRegion.subtractSelf(coverage.aboveOpaqueLayers); @@ -733,6 +751,10 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE, ? outputState.transform.transform( transparentRegion.intersect(outputState.layerStackSpace.getContent())) : Region(); + if (CC_UNLIKELY(computeAboveCoveredExcludingOverlays)) { + outputLayerState.coveredRegionExcludingDisplayOverlays = + std::move(coveredRegionExcludingDisplayOverlays); + } } void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 704f336544..084d9b93db 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -393,14 +393,22 @@ void Layer::updateTrustedPresentationState(const DisplayDevice* display, if (!leaveState) { const auto outputLayer = findOutputLayerForDisplay(display); - if (outputLayer != nullptr && snapshot != nullptr) { - mLastComputedTrustedPresentationState = - computeTrustedPresentationState(snapshot->geomLayerBounds, - snapshot->sourceBounds(), - outputLayer->getState().coveredRegion, - snapshot->transformedBounds, snapshot->alpha, - snapshot->geomLayerTransform, - mTrustedPresentationThresholds); + if (outputLayer != nullptr) { + if (outputLayer->getState().coveredRegionExcludingDisplayOverlays) { + Region coveredRegion = + *outputLayer->getState().coveredRegionExcludingDisplayOverlays; + mLastComputedTrustedPresentationState = + computeTrustedPresentationState(snapshot->geomLayerBounds, + snapshot->sourceBounds(), coveredRegion, + snapshot->transformedBounds, + snapshot->alpha, + snapshot->geomLayerTransform, + mTrustedPresentationThresholds); + } else { + ALOGE("CoveredRegionExcludingDisplayOverlays was not set for %s. Don't compute " + "TrustedPresentationState", + getDebugName()); + } } } const bool newState = mLastComputedTrustedPresentationState; @@ -457,10 +465,15 @@ bool Layer::computeTrustedPresentationState(const FloatRect& bounds, const Float float boundsOverSourceH = bounds.getHeight() / (float)sourceBounds.getHeight(); fractionRendered *= boundsOverSourceW * boundsOverSourceH; - Rect coveredBounds = coveredRegion.bounds(); - fractionRendered *= (1 - - ((coveredBounds.width() / (float)screenBounds.getWidth()) * - coveredBounds.height() / (float)screenBounds.getHeight())); + Region tJunctionFreeRegion = Region::createTJunctionFreeRegion(coveredRegion); + // Compute the size of all the rects since they may be disconnected. + float coveredSize = 0; + for (auto rect = tJunctionFreeRegion.begin(); rect < tJunctionFreeRegion.end(); rect++) { + float size = rect->width() * rect->height(); + coveredSize += size; + } + + fractionRendered *= (1 - (coveredSize / (screenBounds.getWidth() * screenBounds.getHeight()))); if (fractionRendered < thresholds.minFractionRendered) { return false; @@ -3993,6 +4006,7 @@ void Layer::updateSnapshot(bool updateGeometry) { snapshot->bufferSize = getBufferSize(mDrawingState); snapshot->externalTexture = mBufferInfo.mBuffer; snapshot->hasReadyFrame = hasReadyFrame(); + snapshot->isInternalDisplayOverlay = isInternalDisplayOverlay(); preparePerFrameCompositionState(); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b42576fd8e..732390e929 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2517,6 +2517,7 @@ void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId) refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime; refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime(); refreshArgs.expectedPresentTime = mExpectedPresentTime.ns(); + refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0; // Store the present time just before calling to the composition engine so we could notify // the scheduler. diff --git a/services/surfaceflinger/tests/LayerTrustedPresentationListener_test.cpp b/services/surfaceflinger/tests/LayerTrustedPresentationListener_test.cpp index a843fd17b1..2be8d3b013 100644 --- a/services/surfaceflinger/tests/LayerTrustedPresentationListener_test.cpp +++ b/services/surfaceflinger/tests/LayerTrustedPresentationListener_test.cpp @@ -238,4 +238,50 @@ TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_alpha) { EXPECT_TRUE(pch.awaitCallback()); } +TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_display_overlay) { + auto otherLayer = makeLayer(); + t.show(otherLayer) + .setPosition(otherLayer, 100, 100) + .setLayer(otherLayer, INT32_MAX) + .setFlags(otherLayer, layer_state_t::eLayerSkipScreenshot, + layer_state_t::eLayerSkipScreenshot) + .setLayer(mainLayer, INT32_MAX - 1) + .show(mainLayer) + .setPosition(mainLayer, 100, 100) + .setTrustedPresentationCallback( + mainLayer, + [&](void* context, bool state) { + PresentationCallbackHelper* helper = (PresentationCallbackHelper*)context; + helper->callbackArrived(state); + }, + thresholds, &pch, mCallback) + .apply(); + EXPECT_TRUE(pch.awaitCallback()); +} + +TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_non_overlapping_bounds) { + thresholds.minFractionRendered = 0.5; + auto otherLayer1 = makeLayer(); + auto otherLayer2 = makeLayer(); + t.show(otherLayer1) + .show(otherLayer2) + .setPosition(otherLayer1, 100, 25) + .setLayer(otherLayer1, INT32_MAX) + .setPosition(otherLayer2, 100, 175) + .setLayer(otherLayer2, INT32_MAX) + .setLayer(mainLayer, INT32_MAX - 1) + .show(mainLayer) + .setPosition(mainLayer, 100, 100) + .setTrustedPresentationCallback( + mainLayer, + [&](void* context, bool state) { + PresentationCallbackHelper* helper = (PresentationCallbackHelper*)context; + helper->callbackArrived(state); + }, + thresholds, &pch, mCallback) + .apply(); + + EXPECT_TRUE(pch.awaitCallback()); +} + } // namespace android |