diff options
author | 2021-08-20 16:28:35 -0700 | |
---|---|---|
committer | 2021-10-11 16:46:01 -0700 | |
commit | 403a05bc88c5aa6671adcf4214c2a531f77ac2a4 (patch) | |
tree | f5d93d3b2d3815af4f7d5db4fb67936fa33ac5de | |
parent | 5795d387464674f24e842ac2ea3477507748b5de (diff) |
Second Patch for async RenderEngine
- pass a vector of <LayerSettings> instead of a vector of pointers to
drawLayers function to ensure lifecycle safety.
- capture all local variables to call drawLayerInternals in the render
engine thread to avoid of pointers being invalidated if it takes long
time to pop mFunctions calls.
- change renderScreenImplLocked return type as a shared_future
object to unblock SF main thread for screen capture events.
- block region sampling thread only when SF main thread hasn't
completed capture screen event.
Bug: 180657548
Test: SurfaceFlinger_test, android.hardware.graphics.composer@2.2-vts, libcompositionengine_test, librenderengine_test, libsurfaceflinger_unittest pass
Change-Id: I615f2927d30524988fb12df22fe331e7217c3058
31 files changed, 513 insertions, 457 deletions
diff --git a/libs/renderengine/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp index 2174df5515..a9ea690a7c 100644 --- a/libs/renderengine/RenderEngine.cpp +++ b/libs/renderengine/RenderEngine.cpp @@ -96,7 +96,7 @@ void RenderEngine::validateOutputBufferUsage(const sp<GraphicBuffer>& buffer) { } std::future<RenderEngineResult> RenderEngine::drawLayers( - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) { const auto resultPromise = std::make_shared<std::promise<RenderEngineResult>>(); diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index 2375cb7bf1..22dd86698b 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -1080,7 +1080,7 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer void GLESRenderEngine::drawLayersInternal( const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) { ATRACE_CALL(); @@ -1110,10 +1110,10 @@ void GLESRenderEngine::drawLayersInternal( std::unique_ptr<BindNativeBufferAsFramebuffer> fbo; // Gathering layers that requested blur, we'll need them to decide when to render to an // offscreen buffer, and when to render to the native buffer. - std::deque<const LayerSettings*> blurLayers; + std::deque<const LayerSettings> blurLayers; if (CC_LIKELY(mBlurFilter != nullptr)) { - for (auto layer : layers) { - if (layer->backgroundBlurRadius > 0) { + for (const auto& layer : layers) { + if (layer.backgroundBlurRadius > 0) { blurLayers.push_back(layer); } } @@ -1137,7 +1137,7 @@ void GLESRenderEngine::drawLayersInternal( } else { setViewportAndProjection(display.physicalDisplay, display.clip); auto status = - mBlurFilter->setAsDrawTarget(display, blurLayers.front()->backgroundBlurRadius); + mBlurFilter->setAsDrawTarget(display, blurLayers.front().backgroundBlurRadius); if (status != NO_ERROR) { ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).", buffer->getBuffer()->handle); @@ -1167,7 +1167,7 @@ void GLESRenderEngine::drawLayersInternal( .setTexCoords(2 /* size */) .setCropCoords(2 /* size */) .build(); - for (auto const layer : layers) { + for (const auto& layer : layers) { if (blurLayers.size() > 0 && blurLayers.front() == layer) { blurLayers.pop_front(); @@ -1193,7 +1193,7 @@ void GLESRenderEngine::drawLayersInternal( // There's still something else to blur, so let's keep rendering to our FBO // instead of to the display. status = mBlurFilter->setAsDrawTarget(display, - blurLayers.front()->backgroundBlurRadius); + blurLayers.front().backgroundBlurRadius); } if (status != NO_ERROR) { ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).", @@ -1214,42 +1214,42 @@ void GLESRenderEngine::drawLayersInternal( } // Ensure luminance is at least 100 nits to avoid div-by-zero - const float maxLuminance = std::max(100.f, layer->source.buffer.maxLuminanceNits); + const float maxLuminance = std::max(100.f, layer.source.buffer.maxLuminanceNits); mState.maxMasteringLuminance = maxLuminance; mState.maxContentLuminance = maxLuminance; - mState.projectionMatrix = projectionMatrix * layer->geometry.positionTransform; + mState.projectionMatrix = projectionMatrix * layer.geometry.positionTransform; - const FloatRect bounds = layer->geometry.boundaries; + const FloatRect bounds = layer.geometry.boundaries; Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); position[0] = vec2(bounds.left, bounds.top); position[1] = vec2(bounds.left, bounds.bottom); position[2] = vec2(bounds.right, bounds.bottom); position[3] = vec2(bounds.right, bounds.top); - setupLayerCropping(*layer, mesh); - setColorTransform(layer->colorTransform); + setupLayerCropping(layer, mesh); + setColorTransform(layer.colorTransform); bool usePremultipliedAlpha = true; bool disableTexture = true; bool isOpaque = false; - if (layer->source.buffer.buffer != nullptr) { + if (layer.source.buffer.buffer != nullptr) { disableTexture = false; - isOpaque = layer->source.buffer.isOpaque; + isOpaque = layer.source.buffer.isOpaque; - sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer(); + sp<GraphicBuffer> gBuf = layer.source.buffer.buffer->getBuffer(); validateInputBufferUsage(gBuf); - bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf, - layer->source.buffer.fence); + bindExternalTextureBuffer(layer.source.buffer.textureName, gBuf, + layer.source.buffer.fence); - usePremultipliedAlpha = layer->source.buffer.usePremultipliedAlpha; - Texture texture(Texture::TEXTURE_EXTERNAL, layer->source.buffer.textureName); - mat4 texMatrix = layer->source.buffer.textureTransform; + usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha; + Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName); + mat4 texMatrix = layer.source.buffer.textureTransform; texture.setMatrix(texMatrix.asArray()); - texture.setFiltering(layer->source.buffer.useTextureFiltering); + texture.setFiltering(layer.source.buffer.useTextureFiltering); texture.setDimensions(gBuf->getWidth(), gBuf->getHeight()); - setSourceY410BT2020(layer->source.buffer.isY410BT2020); + setSourceY410BT2020(layer.source.buffer.isY410BT2020); renderengine::Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>()); texCoords[0] = vec2(0.0, 0.0); @@ -1264,32 +1264,32 @@ void GLESRenderEngine::drawLayersInternal( } } - const half3 solidColor = layer->source.solidColor; - const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer->alpha); + const half3 solidColor = layer.source.solidColor; + const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha); // Buffer sources will have a black solid color ignored in the shader, // so in that scenario the solid color passed here is arbitrary. setupLayerBlending(usePremultipliedAlpha, isOpaque, disableTexture, color, - layer->geometry.roundedCornersRadius); - if (layer->disableBlending) { + layer.geometry.roundedCornersRadius); + if (layer.disableBlending) { glDisable(GL_BLEND); } - setSourceDataSpace(layer->sourceDataspace); + setSourceDataSpace(layer.sourceDataspace); - if (layer->shadow.length > 0.0f) { - handleShadow(layer->geometry.boundaries, layer->geometry.roundedCornersRadius, - layer->shadow); + if (layer.shadow.length > 0.0f) { + handleShadow(layer.geometry.boundaries, layer.geometry.roundedCornersRadius, + layer.shadow); } // We only want to do a special handling for rounded corners when having rounded corners // is the only reason it needs to turn on blending, otherwise, we handle it like the // usual way since it needs to turn on blending anyway. - else if (layer->geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) { - handleRoundedCorners(display, *layer, mesh); + else if (layer.geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) { + handleRoundedCorners(display, layer, mesh); } else { drawMesh(mesh); } // Cleanup if there's a buffer source - if (layer->source.buffer.buffer != nullptr) { + if (layer.source.buffer.buffer != nullptr) { disableBlending(); setSourceY410BT2020(false); disableTexturing(); diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index c4adfdf752..1d7c2cafb5 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -104,7 +104,7 @@ protected: bool canSkipPostRenderCleanup() const override; void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, const DisplaySettings& display, - const std::vector<const LayerSettings*>& layers, + const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override; diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index 701c1f2071..b9cc6485e5 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -160,7 +160,7 @@ public: // @return A future object of RenderEngineResult struct indicating whether // drawing was successful in async mode. virtual std::future<RenderEngineResult> drawLayers( - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence); @@ -231,7 +231,7 @@ protected: virtual void drawLayersInternal( const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) = 0; }; diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index a7e6809223..248bd652c0 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -49,12 +49,12 @@ public: MOCK_CONST_METHOD0(canSkipPostRenderCleanup, bool()); MOCK_METHOD5(drawLayers, std::future<RenderEngineResult>(const DisplaySettings&, - const std::vector<const LayerSettings*>&, + const std::vector<LayerSettings>&, const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&)); MOCK_METHOD6(drawLayersInternal, void(const std::shared_ptr<std::promise<RenderEngineResult>>&&, - const DisplaySettings&, const std::vector<const LayerSettings*>&, + const DisplaySettings&, const std::vector<LayerSettings>&, const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&)); MOCK_METHOD0(cleanFramebufferCache, void()); MOCK_METHOD0(getContextPriority, int()); diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp index c4fa1bb091..b18a872836 100644 --- a/libs/renderengine/skia/Cache.cpp +++ b/libs/renderengine/skia/Cache.cpp @@ -95,7 +95,7 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin .alpha = 1, }; - auto layers = std::vector<const LayerSettings*>{&layer, &caster}; + auto layers = std::vector<LayerSettings>{layer, caster}; // Four combinations of settings are used (two transforms here, and drawShadowLayers is // called with two different destination data spaces) They're all rounded rect. // Three of these are cache misses that generate new shaders. @@ -140,7 +140,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting }}, }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { layer.sourceDataspace = dataspace; // Cache shaders for both rects and round rects. @@ -176,7 +176,7 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting .alpha = 0.5, }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; for (auto transform : {mat4(), kScaleAndTranslate}) { layer.geometry.positionTransform = transform; for (float roundedCornersRadius : {0.0f, 50.f}) { @@ -201,7 +201,7 @@ static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings .skipContentDraw = true, }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; // Different blur code is invoked for radii less and greater than 30 pixels for (int radius : {9, 60}) { layer.backgroundBlurRadius = radius; @@ -242,7 +242,7 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti }, }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) { layer.source = pixelSource; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { @@ -289,7 +289,7 @@ static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySetti }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } @@ -317,7 +317,7 @@ static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySett }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } @@ -429,7 +429,7 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { LayerSettings layer{ .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)}, }; - auto layers = std::vector<const LayerSettings*>{&layer}; + auto layers = std::vector<LayerSettings>{layer}; // call get() to make it synchronous renderengine ->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()) diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index cb686a643a..d5ec774e9c 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -610,17 +610,18 @@ private: AutoBackendTexture::CleanupManager& mMgr; }; -sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader( - sk_sp<SkShader> shader, - const LayerSettings* layer, const DisplaySettings& display, bool undoPremultipliedAlpha, - bool requiresLinearEffect) { - const auto stretchEffect = layer->stretchEffect; +sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader, + const LayerSettings& layer, + const DisplaySettings& display, + bool undoPremultipliedAlpha, + bool requiresLinearEffect) { + const auto stretchEffect = layer.stretchEffect; // The given surface will be stretched by HWUI via matrix transformation // which gets similar results for most surfaces // Determine later on if we need to leverage the stertch shader within // surface flinger if (stretchEffect.hasEffect()) { - const auto targetBuffer = layer->source.buffer.buffer; + const auto targetBuffer = layer.source.buffer.buffer; const auto graphicBuffer = targetBuffer ? targetBuffer->getBuffer() : nullptr; if (graphicBuffer && shader) { shader = mStretchShaderFactory.createSkShader(shader, stretchEffect); @@ -629,7 +630,7 @@ sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader( if (requiresLinearEffect) { const ui::Dataspace inputDataspace = - mUseColorManagement ? layer->sourceDataspace : ui::Dataspace::V0_SRGB_LINEAR; + mUseColorManagement ? layer.sourceDataspace : ui::Dataspace::V0_SRGB_LINEAR; const ui::Dataspace outputDataspace = mUseColorManagement ? display.outputDataspace : ui::Dataspace::V0_SRGB_LINEAR; @@ -645,13 +646,13 @@ sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader( } else { runtimeEffect = effectIter->second; } - float maxLuminance = layer->source.buffer.maxLuminanceNits; + float maxLuminance = layer.source.buffer.maxLuminanceNits; // If the buffer doesn't have a max luminance, treat it as SDR & use the display's SDR // white point if (maxLuminance <= 0.f) { maxLuminance = display.sdrWhitePointNits; } - return createLinearEffectShader(shader, effect, runtimeEffect, layer->colorTransform, + return createLinearEffectShader(shader, effect, runtimeEffect, layer.colorTransform, display.maxLuminance, maxLuminance); } return shader; @@ -729,7 +730,7 @@ static SkRRect getBlurRRect(const BlurRegion& region) { void SkiaGLRenderEngine::drawLayersInternal( const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool /*useFramebufferCache*/, base::unique_fd&& bufferFence) { ATRACE_NAME("SkiaGL::drawLayers"); @@ -801,11 +802,11 @@ void SkiaGLRenderEngine::drawLayersInternal( if (!layerHasBlur(layer, ctModifiesAlpha)) { continue; } - if (layer->backgroundBlurRadius > 0 && - layer->backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius) { + if (layer.backgroundBlurRadius > 0 && + layer.backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius) { requiresCompositionLayer = true; } - for (auto region : layer->blurRegions) { + for (auto region : layer.blurRegions) { if (region.blurRadius < BlurFilter::kMaxCrossFadeRadius) { requiresCompositionLayer = true; } @@ -813,7 +814,7 @@ void SkiaGLRenderEngine::drawLayersInternal( if (requiresCompositionLayer) { activeSurface = dstSurface->makeSurface(dstSurface->imageInfo()); canvas = mCapture->tryOffscreenCapture(activeSurface.get(), &offscreenCaptureState); - blurCompositionLayer = layer; + blurCompositionLayer = &layer; break; } } @@ -825,11 +826,11 @@ void SkiaGLRenderEngine::drawLayersInternal( initCanvas(canvas, display); for (const auto& layer : layers) { - ATRACE_FORMAT("DrawLayer: %s", layer->name.c_str()); + ATRACE_FORMAT("DrawLayer: %s", layer.name.c_str()); if (kPrintLayerSettings) { std::stringstream ls; - PrintTo(*layer, &ls); + PrintTo(layer, &ls); auto debugs = ls.str(); int pos = 0; while (pos < debugs.size()) { @@ -839,7 +840,7 @@ void SkiaGLRenderEngine::drawLayersInternal( } sk_sp<SkImage> blurInput; - if (blurCompositionLayer == layer) { + if (blurCompositionLayer == &layer) { LOG_ALWAYS_FATAL_IF(activeSurface == dstSurface); LOG_ALWAYS_FATAL_IF(canvas == dstCanvas); @@ -878,17 +879,17 @@ void SkiaGLRenderEngine::drawLayersInternal( if (CC_UNLIKELY(mCapture->isCaptureRunning())) { // Record the name of the layer if the capture is running. std::stringstream layerSettings; - PrintTo(*layer, &layerSettings); + PrintTo(layer, &layerSettings); // Store the LayerSettings in additional information. - canvas->drawAnnotation(SkRect::MakeEmpty(), layer->name.c_str(), + canvas->drawAnnotation(SkRect::MakeEmpty(), layer.name.c_str(), SkData::MakeWithCString(layerSettings.str().c_str())); } // Layers have a local transform that should be applied to them - canvas->concat(getSkM44(layer->geometry.positionTransform).asM33()); + canvas->concat(getSkM44(layer.geometry.positionTransform).asM33()); const auto [bounds, roundRectClip] = - getBoundsAndClip(layer->geometry.boundaries, layer->geometry.roundedCornersCrop, - layer->geometry.roundedCornersRadius); + getBoundsAndClip(layer.geometry.boundaries, layer.geometry.roundedCornersCrop, + layer.geometry.roundedCornersRadius); if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) { std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs; @@ -909,20 +910,19 @@ void SkiaGLRenderEngine::drawLayersInternal( // TODO(b/182216890): Filter out empty layers earlier if (blurRect.width() > 0 && blurRect.height() > 0) { - if (layer->backgroundBlurRadius > 0) { + if (layer.backgroundBlurRadius > 0) { ATRACE_NAME("BackgroundBlur"); - auto blurredImage = - mBlurFilter->generate(grContext, layer->backgroundBlurRadius, blurInput, - blurRect); + auto blurredImage = mBlurFilter->generate(grContext, layer.backgroundBlurRadius, + blurInput, blurRect); - cachedBlurs[layer->backgroundBlurRadius] = blurredImage; + cachedBlurs[layer.backgroundBlurRadius] = blurredImage; - mBlurFilter->drawBlurRegion(canvas, bounds, layer->backgroundBlurRadius, 1.0f, + mBlurFilter->drawBlurRegion(canvas, bounds, layer.backgroundBlurRadius, 1.0f, blurRect, blurredImage, blurInput); } - canvas->concat(getSkM44(layer->blurRegionTransform).asM33()); - for (auto region : layer->blurRegions) { + canvas->concat(getSkM44(layer.blurRegionTransform).asM33()); + for (auto region : layer.blurRegions) { if (cachedBlurs[region.blurRadius] == nullptr) { ATRACE_NAME("BlurRegion"); cachedBlurs[region.blurRadius] = @@ -937,19 +937,18 @@ void SkiaGLRenderEngine::drawLayersInternal( } } - if (layer->shadow.length > 0) { + if (layer.shadow.length > 0) { // This would require a new parameter/flag to SkShadowUtils::DrawShadow - LOG_ALWAYS_FATAL_IF(layer->disableBlending, "Cannot disableBlending with a shadow"); + LOG_ALWAYS_FATAL_IF(layer.disableBlending, "Cannot disableBlending with a shadow"); SkRRect shadowBounds, shadowClip; - if (layer->geometry.boundaries == layer->shadow.boundaries) { + if (layer.geometry.boundaries == layer.shadow.boundaries) { shadowBounds = bounds; shadowClip = roundRectClip; } else { std::tie(shadowBounds, shadowClip) = - getBoundsAndClip(layer->shadow.boundaries, - layer->geometry.roundedCornersCrop, - layer->geometry.roundedCornersRadius); + getBoundsAndClip(layer.shadow.boundaries, layer.geometry.roundedCornersCrop, + layer.geometry.roundedCornersRadius); } // Technically, if bounds is a rect and roundRectClip is not empty, @@ -960,18 +959,18 @@ void SkiaGLRenderEngine::drawLayersInternal( // looks more like the intent. const auto& rrect = shadowBounds.isRect() && !shadowClip.isEmpty() ? shadowClip : shadowBounds; - drawShadow(canvas, rrect, layer->shadow); + drawShadow(canvas, rrect, layer.shadow); } - const bool requiresLinearEffect = layer->colorTransform != mat4() || + const bool requiresLinearEffect = layer.colorTransform != mat4() || (mUseColorManagement && - needsToneMapping(layer->sourceDataspace, display.outputDataspace)) || + needsToneMapping(layer.sourceDataspace, display.outputDataspace)) || (display.sdrWhitePointNits > 0.f && display.sdrWhitePointNits != display.maxLuminance); // quick abort from drawing the remaining portion of the layer - if (layer->skipContentDraw || - (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && + if (layer.skipContentDraw || + (layer.alpha == 0 && !requiresLinearEffect && !layer.disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged()))) { continue; } @@ -981,13 +980,13 @@ void SkiaGLRenderEngine::drawLayersInternal( // management is a no-op. const ui::Dataspace layerDataspace = (!mUseColorManagement || requiresLinearEffect) ? dstDataspace - : layer->sourceDataspace; + : layer.sourceDataspace; SkPaint paint; - if (layer->source.buffer.buffer) { + if (layer.source.buffer.buffer) { ATRACE_NAME("DrawImage"); - validateInputBufferUsage(layer->source.buffer.buffer->getBuffer()); - const auto& item = layer->source.buffer; + validateInputBufferUsage(layer.source.buffer.buffer->getBuffer()); + const auto& item = layer.source.buffer; std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr; if (const auto& iter = cache.find(item.buffer->getBuffer()->getId()); @@ -1006,8 +1005,8 @@ void SkiaGLRenderEngine::drawLayersInternal( // if the layer's buffer has a fence, then we must must respect the fence prior to using // the buffer. - if (layer->source.buffer.fence != nullptr) { - waitFence(layer->source.buffer.fence->get()); + if (layer.source.buffer.fence != nullptr) { + waitFence(layer.source.buffer.fence->get()); } // isOpaque means we need to ignore the alpha in the image, @@ -1051,7 +1050,7 @@ void SkiaGLRenderEngine::drawLayersInternal( sk_sp<SkShader> shader; - if (layer->source.buffer.useTextureFiltering) { + if (layer.source.buffer.useTextureFiltering) { shader = image->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions( {SkFilterMode::kLinear, SkMipmapMode::kNone}), @@ -1069,21 +1068,21 @@ void SkiaGLRenderEngine::drawLayersInternal( paint.setShader(createRuntimeEffectShader(shader, layer, display, !item.isOpaque && item.usePremultipliedAlpha, requiresLinearEffect)); - paint.setAlphaf(layer->alpha); + paint.setAlphaf(layer.alpha); } else { ATRACE_NAME("DrawColor"); - const auto color = layer->source.solidColor; + const auto color = layer.source.solidColor; sk_sp<SkShader> shader = SkShaders::Color(SkColor4f{.fR = color.r, .fG = color.g, .fB = color.b, - .fA = layer->alpha}, + .fA = layer.alpha}, toSkColorSpace(layerDataspace)); paint.setShader(createRuntimeEffectShader(shader, layer, display, /* undoPremultipliedAlpha */ false, requiresLinearEffect)); } - if (layer->disableBlending) { + if (layer.disableBlending) { paint.setBlendMode(SkBlendMode::kSrc); } @@ -1251,13 +1250,13 @@ inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const Fl return {SkRRect::MakeRect(bounds), clip}; } -inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings* layer, +inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings& layer, bool colorTransformModifiesAlpha) { - if (layer->backgroundBlurRadius > 0 || layer->blurRegions.size()) { + if (layer.backgroundBlurRadius > 0 || layer.blurRegions.size()) { // return false if the content is opaque and would therefore occlude the blur - const bool opaqueContent = !layer->source.buffer.buffer || layer->source.buffer.isOpaque; - const bool opaqueAlpha = layer->alpha == 1.0f && !colorTransformModifiesAlpha; - return layer->skipContentDraw || !(opaqueContent && opaqueAlpha); + const bool opaqueContent = !layer.source.buffer.buffer || layer.source.buffer.isOpaque; + const bool opaqueAlpha = layer.alpha == 1.0f && !colorTransformModifiesAlpha; + return layer.skipContentDraw || !(opaqueContent && opaqueAlpha); } return false; } diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h index e010c35c13..74ce6513e9 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.h +++ b/libs/renderengine/skia/SkiaGLRenderEngine.h @@ -74,7 +74,7 @@ protected: bool canSkipPostRenderCleanup() const override; void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, const DisplaySettings& display, - const std::vector<const LayerSettings*>& layers, + const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override; @@ -92,7 +92,7 @@ private: inline SkRect getSkRect(const Rect& layer); inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds, const FloatRect& crop, float cornerRadius); - inline bool layerHasBlur(const LayerSettings* layer, bool colorTransformModifiesAlpha); + inline bool layerHasBlur(const LayerSettings& layer, bool colorTransformModifiesAlpha); inline SkColor getSkColor(const vec4& color); inline SkM44 getSkM44(const mat4& matrix); inline SkPoint3 getSkPoint3(const vec3& vector); @@ -108,8 +108,7 @@ private: const ShadowSettings& shadowSettings); // If requiresLinearEffect is true or the layer has a stretchEffect a new shader is returned. // Otherwise it returns the input shader. - sk_sp<SkShader> createRuntimeEffectShader(sk_sp<SkShader> shader, - const LayerSettings* layer, + sk_sp<SkShader> createRuntimeEffectShader(sk_sp<SkShader> shader, const LayerSettings& layer, const DisplaySettings& display, bool undoPremultipliedAlpha, bool requiresLinearEffect); diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h index f61653b940..eb65e83324 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.h +++ b/libs/renderengine/skia/SkiaRenderEngine.h @@ -55,7 +55,7 @@ protected: virtual void drawLayersInternal( const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override { resultPromise->set_value({NO_ERROR, base::unique_fd()}); diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index 694bda65d4..c2c05f41b7 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -417,10 +417,11 @@ public: DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET); } - void invokeDraw(renderengine::DisplaySettings settings, - std::vector<const renderengine::LayerSettings*> layers) { + void invokeDraw(const renderengine::DisplaySettings& settings, + const std::vector<renderengine::LayerSettings>& layers) { std::future<renderengine::RenderEngineResult> result = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd()); + ASSERT_TRUE(result.valid()); auto [status, fence] = result.get(); @@ -436,7 +437,7 @@ public: void drawEmptyLayers() { renderengine::DisplaySettings settings; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; invokeDraw(settings, layers); } @@ -629,7 +630,7 @@ void RenderEngineTest::fillBuffer(half r, half g, half b, half a) { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -637,7 +638,7 @@ void RenderEngineTest::fillBuffer(half r, half g, half b, half a) { SourceVariant::fillColor(layer, r, g, b, this); layer.alpha = a; - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -673,7 +674,7 @@ void RenderEngineTest::fillRedOffsetBuffer() { settings.physicalDisplay = offsetRect(); settings.clip = offsetRectAtZero(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -681,7 +682,7 @@ void RenderEngineTest::fillRedOffsetBuffer() { SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0f; - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -708,7 +709,7 @@ void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) { settings.clip = Rect(2, 2); settings.orientation = orientationFlag; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layerOne; layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -731,9 +732,9 @@ void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) { SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this); layerThree.alpha = 1.0f; - layers.push_back(&layerOne); - layers.push_back(&layerTwo); - layers.push_back(&layerThree); + layers.push_back(layerOne); + layers.push_back(layerTwo); + layers.push_back(layerThree); invokeDraw(settings, layers); } @@ -810,7 +811,7 @@ void RenderEngineTest::fillBufferWithLayerTransform() { settings.clip = Rect(2, 2); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -821,7 +822,7 @@ void RenderEngineTest::fillBufferWithLayerTransform() { layer.source.solidColor = half3(1.0f, 0.0f, 0.0f); layer.alpha = 1.0f; - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -843,7 +844,7 @@ void RenderEngineTest::fillBufferWithColorTransform() { settings.clip = Rect(1, 1); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -860,7 +861,7 @@ void RenderEngineTest::fillBufferWithColorTransform() { layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -877,7 +878,7 @@ void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); @@ -890,7 +891,7 @@ void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { layer.geometry.boundaries = Rect(1, 1).toFloatRect(); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -908,7 +909,7 @@ void RenderEngineTest::fillRedBufferWithRoundedCorners() { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -918,7 +919,7 @@ void RenderEngineTest::fillRedBufferWithRoundedCorners() { SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0f; - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -949,14 +950,14 @@ void RenderEngineTest::fillBufferAndBlurBackground() { settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings backgroundLayer; backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect(); SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this); backgroundLayer.alpha = 1.0f; - layers.push_back(&backgroundLayer); + layers.emplace_back(backgroundLayer); renderengine::LayerSettings leftLayer; leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -964,7 +965,7 @@ void RenderEngineTest::fillBufferAndBlurBackground() { Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect(); SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this); leftLayer.alpha = 1.0f; - layers.push_back(&leftLayer); + layers.emplace_back(leftLayer); renderengine::LayerSettings blurLayer; blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -972,7 +973,7 @@ void RenderEngineTest::fillBufferAndBlurBackground() { blurLayer.backgroundBlurRadius = blurRadius; SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this); blurLayer.alpha = 0; - layers.push_back(&blurLayer); + layers.emplace_back(blurLayer); invokeDraw(settings, layers); @@ -994,14 +995,14 @@ void RenderEngineTest::fillSmallLayerAndBlurBackground() { settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings backgroundLayer; backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect(); SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this); backgroundLayer.alpha = 1.0f; - layers.push_back(&backgroundLayer); + layers.push_back(backgroundLayer); renderengine::LayerSettings blurLayer; blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1009,7 +1010,7 @@ void RenderEngineTest::fillSmallLayerAndBlurBackground() { blurLayer.backgroundBlurRadius = blurRadius; SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this); blurLayer.alpha = 0; - layers.push_back(&blurLayer); + layers.push_back(blurLayer); invokeDraw(settings, layers); @@ -1026,7 +1027,7 @@ void RenderEngineTest::overlayCorners() { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layersFirst; + std::vector<renderengine::LayerSettings> layersFirst; renderengine::LayerSettings layerOne; layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1035,14 +1036,14 @@ void RenderEngineTest::overlayCorners() { SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this); layerOne.alpha = 0.2; - layersFirst.push_back(&layerOne); + layersFirst.push_back(layerOne); invokeDraw(settings, layersFirst); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); - std::vector<const renderengine::LayerSettings*> layersSecond; + std::vector<renderengine::LayerSettings> layersSecond; renderengine::LayerSettings layerTwo; layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; layerTwo.geometry.boundaries = @@ -1051,7 +1052,7 @@ void RenderEngineTest::overlayCorners() { SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this); layerTwo.alpha = 1.0f; - layersSecond.push_back(&layerTwo); + layersSecond.push_back(layerTwo); invokeDraw(settings, layersSecond); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0); @@ -1066,7 +1067,7 @@ void RenderEngineTest::fillRedBufferTextureTransform() { settings.clip = Rect(1, 1); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1102,7 +1103,7 @@ void RenderEngineTest::fillRedBufferTextureTransform() { layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -1118,7 +1119,7 @@ void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() { // Here logical space is 1x1 settings.clip = Rect(1, 1); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; const auto buf = allocateSourceBuffer(1, 1); @@ -1141,7 +1142,7 @@ void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() { layer.alpha = 0.5f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -1157,7 +1158,7 @@ void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() { // Here logical space is 1x1 settings.clip = Rect(1, 1); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; const auto buf = allocateSourceBuffer(1, 1); @@ -1180,7 +1181,7 @@ void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() { layer.alpha = 0.5f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -1199,7 +1200,7 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; // add background layer renderengine::LayerSettings bgLayer; @@ -1208,7 +1209,7 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f, backgroundColor.b / 255.0f, this); bgLayer.alpha = backgroundColor.a / 255.0f; - layers.push_back(&bgLayer); + layers.push_back(bgLayer); // add shadow layer renderengine::LayerSettings shadowLayer; @@ -1216,14 +1217,14 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries; shadowLayer.alpha = castingLayer.alpha; shadowLayer.shadow = shadow; - layers.push_back(&shadowLayer); + layers.push_back(shadowLayer); // add layer casting the shadow renderengine::LayerSettings layer = castingLayer; layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f, casterColor.b / 255.0f, this); - layers.push_back(&layer); + layers.push_back(layer); invokeDraw(settings, layers); } @@ -1236,7 +1237,7 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; // add background layer renderengine::LayerSettings bgLayer; @@ -1245,7 +1246,7 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f, backgroundColor.b / 255.0f, this); bgLayer.alpha = backgroundColor.a / 255.0f; - layers.push_back(&bgLayer); + layers.push_back(bgLayer); // add shadow layer renderengine::LayerSettings shadowLayer; @@ -1255,7 +1256,7 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, shadowLayer.alpha = 1.0f; ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this); shadowLayer.shadow = shadow; - layers.push_back(&shadowLayer); + layers.push_back(shadowLayer); invokeDraw(settings, layers); } @@ -1291,8 +1292,8 @@ TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) { // Transform the red color. bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - std::vector<const renderengine::LayerSettings*> layers; - layers.push_back(&bgLayer); + std::vector<renderengine::LayerSettings> layers; + layers.push_back(bgLayer); invokeDraw(settings, layers); @@ -1306,11 +1307,11 @@ TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) { renderengine::DisplaySettings settings; settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = fullscreenRect().toFloatRect(); BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); - layers.push_back(&layer); + layers.push_back(layer); std::future<renderengine::RenderEngineResult> result = mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd()); @@ -1335,12 +1336,12 @@ TEST_P(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) { settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = fullscreenRect().toFloatRect(); BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0; - layers.push_back(&layer); + layers.push_back(layer); std::future<renderengine::RenderEngineResult> result = mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd()); @@ -1743,12 +1744,12 @@ TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = fullscreenRect().toFloatRect(); BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0; - layers.push_back(&layer); + layers.push_back(layer); std::future<renderengine::RenderEngineResult> resultOne = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd()); @@ -1779,7 +1780,7 @@ TEST_P(RenderEngineTest, testRoundedCornersCrop) { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings redLayer; redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1790,7 +1791,7 @@ TEST_P(RenderEngineTest, testRoundedCornersCrop) { redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f); redLayer.alpha = 1.0f; - layers.push_back(&redLayer); + layers.push_back(redLayer); // Green layer with 1/3 size. renderengine::LayerSettings greenLayer; @@ -1805,7 +1806,7 @@ TEST_P(RenderEngineTest, testRoundedCornersCrop) { greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f); greenLayer.alpha = 1.0f; - layers.push_back(&greenLayer); + layers.push_back(greenLayer); invokeDraw(settings, layers); @@ -1828,7 +1829,7 @@ TEST_P(RenderEngineTest, testRoundedCornersParentCrop) { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings redLayer; redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1839,7 +1840,7 @@ TEST_P(RenderEngineTest, testRoundedCornersParentCrop) { redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f); redLayer.alpha = 1.0f; - layers.push_back(&redLayer); + layers.push_back(redLayer); // Green layer with 1/2 size with parent crop rect. renderengine::LayerSettings greenLayer = redLayer; @@ -1847,7 +1848,7 @@ TEST_P(RenderEngineTest, testRoundedCornersParentCrop) { FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2); greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f); - layers.push_back(&greenLayer); + layers.push_back(greenLayer); invokeDraw(settings, layers); @@ -1873,7 +1874,7 @@ TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) { settings.clip = fullscreenRect(); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings redLayer; redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1884,7 +1885,7 @@ TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) { redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f); redLayer.alpha = 1.0f; - layers.push_back(&redLayer); + layers.push_back(redLayer); invokeDraw(settings, layers); // Due to roundedCornersRadius, the top corners are untouched. @@ -1923,7 +1924,7 @@ TEST_P(RenderEngineTest, testClear) { .disableBlending = true, }; - std::vector<const renderengine::LayerSettings*> layers{&redLayer, &clearLayer}; + std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer}; invokeDraw(display, layers); expectBufferColor(rect, 0, 0, 0, 0); } @@ -1971,7 +1972,7 @@ TEST_P(RenderEngineTest, testDisableBlendingBuffer) { .disableBlending = true, }; - std::vector<const renderengine::LayerSettings*> layers{&redLayer, &greenLayer}; + std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer}; invokeDraw(display, layers); expectBufferColor(rect, 0, 128, 0, 128); } @@ -2017,7 +2018,7 @@ TEST_P(RenderEngineTest, test_isOpaque) { .alpha = 1.0f, }; - std::vector<const renderengine::LayerSettings*> layers{&greenLayer}; + std::vector<renderengine::LayerSettings> layers{greenLayer}; invokeDraw(display, layers); if (GetParam()->useColorManagement()) { diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp index 99250c1412..db7e12b71b 100644 --- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp +++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp @@ -172,20 +172,21 @@ TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsTrue) { TEST_F(RenderEngineThreadedTest, drawLayers) { renderengine::DisplaySettings settings; - std::vector<const renderengine::LayerSettings*> layers; + std::vector<renderengine::LayerSettings> layers; std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared< renderengine::ExternalTexture>(new GraphicBuffer(), *mRenderEngine, renderengine::ExternalTexture::Usage::READABLE | renderengine::ExternalTexture::Usage::WRITEABLE); + base::unique_fd bufferFence; EXPECT_CALL(*mRenderEngine, drawLayersInternal) .WillOnce([&](const std::shared_ptr<std::promise<renderengine::RenderEngineResult>>&& resultPromise, const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> void { + base::unique_fd&&) -> void { resultPromise->set_value({NO_ERROR, base::unique_fd()}); }); diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp index a549672259..3d446e8e72 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.cpp +++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp @@ -306,7 +306,7 @@ bool RenderEngineThreaded::canSkipPostRenderCleanup() const { void RenderEngineThreaded::drawLayersInternal( const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) { resultPromise->set_value({NO_ERROR, base::unique_fd()}); @@ -314,19 +314,20 @@ void RenderEngineThreaded::drawLayersInternal( } std::future<RenderEngineResult> RenderEngineThreaded::drawLayers( - const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, + const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) { ATRACE_CALL(); const auto resultPromise = std::make_shared<std::promise<RenderEngineResult>>(); std::future<RenderEngineResult> resultFuture = resultPromise->get_future(); + int fd = bufferFence.release(); { std::lock_guard lock(mThreadMutex); - mFunctionCalls.push([resultPromise, &display, &layers, &buffer, useFramebufferCache, - &bufferFence](renderengine::RenderEngine& instance) { + mFunctionCalls.push([resultPromise, display, layers, buffer, useFramebufferCache, + fd](renderengine::RenderEngine& instance) { ATRACE_NAME("REThreaded::drawLayers"); instance.drawLayersInternal(std::move(resultPromise), display, layers, buffer, - useFramebufferCache, std::move(bufferFence)); + useFramebufferCache, base::unique_fd(fd)); }); } mCondition.notify_one(); diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h index 2303caa7eb..0159cfaece 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.h +++ b/libs/renderengine/threaded/RenderEngineThreaded.h @@ -57,7 +57,7 @@ public: void cleanupPostRender() override; std::future<RenderEngineResult> drawLayers(const DisplaySettings& display, - const std::vector<const LayerSettings*>& layers, + const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override; @@ -73,7 +73,7 @@ protected: bool canSkipPostRenderCleanup() const override; void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise, const DisplaySettings& display, - const std::vector<const LayerSettings*>& layers, + const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index f98681e1ce..6c60e53841 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -48,7 +48,9 @@ BufferQueueLayer::~BufferQueueLayer() { // Interface implementation for Layer // ----------------------------------------------------------------------- -void BufferQueueLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { +void BufferQueueLayer::onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) { + sp<Fence> releaseFence = new Fence(dup(futureRenderEngineResult.get().drawFence)); mConsumer->setReleaseFence(releaseFence); // Prevent tracing the same release multiple times. diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index a3bd725cfe..dfdb5c055d 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -42,7 +42,8 @@ public: // Implements Layer. const char* getType() const override { return "BufferQueueLayer"; } - void onLayerDisplayed(const sp<Fence>& releaseFence) override; + void onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override; // If a buffer was replaced this frame, release the former buffer void releasePendingBuffer(nsecs_t dequeueReadyTime) override; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 132ee9d71b..454363ac3f 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -70,69 +70,11 @@ BufferStateLayer::~BufferStateLayer() { } } -status_t BufferStateLayer::addReleaseFence(const sp<CallbackHandle>& ch, - const sp<Fence>& fence) { - if (ch == nullptr) { - return OK; - } - ch->previousReleaseCallbackId = mPreviousReleaseCallbackId; - if (!ch->previousReleaseFence.get()) { - ch->previousReleaseFence = fence; - return OK; - } - - // Below logic is lifted from ConsumerBase.cpp: - // Check status of fences first because merging is expensive. - // Merging an invalid fence with any other fence results in an - // invalid fence. - auto currentStatus = ch->previousReleaseFence->getStatus(); - if (currentStatus == Fence::Status::Invalid) { - ALOGE("Existing fence has invalid state, layer: %s", mName.c_str()); - return BAD_VALUE; - } - - auto incomingStatus = fence->getStatus(); - if (incomingStatus == Fence::Status::Invalid) { - ALOGE("New fence has invalid state, layer: %s", mName.c_str()); - ch->previousReleaseFence = fence; - return BAD_VALUE; - } - - // If both fences are signaled or both are unsignaled, we need to merge - // them to get an accurate timestamp. - if (currentStatus == incomingStatus) { - char fenceName[32] = {}; - snprintf(fenceName, 32, "%.28s", mName.c_str()); - sp<Fence> mergedFence = Fence::merge( - fenceName, ch->previousReleaseFence, fence); - if (!mergedFence.get()) { - ALOGE("failed to merge release fences, layer: %s", mName.c_str()); - // synchronization is broken, the best we can do is hope fences - // signal in order so the new fence will act like a union - ch->previousReleaseFence = fence; - return BAD_VALUE; - } - ch->previousReleaseFence = mergedFence; - } else if (incomingStatus == Fence::Status::Unsignaled) { - // If one fence has signaled and the other hasn't, the unsignaled - // fence will approximately correspond with the correct timestamp. - // There's a small race if both fences signal at about the same time - // and their statuses are retrieved with unfortunate timing. However, - // by this point, they will have both signaled and only the timestamp - // will be slightly off; any dependencies after this point will - // already have been met. - ch->previousReleaseFence = fence; - } - // else if (currentStatus == Fence::Status::Unsignaled) is a no-op. - - return OK; -} - // ----------------------------------------------------------------------- // Interface implementation for Layer // ----------------------------------------------------------------------- -void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { - +void BufferStateLayer::onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) { // If a layer has been displayed again we may need to clear // the mLastClientComposition fence that we use for early release in setBuffer // (as we now have a new fence which won't pass through the client composition path in some cases @@ -146,9 +88,6 @@ void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { mLastClientCompositionDisplayed = true; } - if (!releaseFence->isValid()) { - return; - } // The previous release fence notifies the client that SurfaceFlinger is done with the previous // buffer that was presented on this layer. The first transaction that came in this frame that // replaced the previous buffer on this layer needs this release fence, because the fence will @@ -173,17 +112,19 @@ void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { break; } } - auto status = addReleaseFence(ch, releaseFence); - if (status != OK) { - ALOGE("Failed to add release fence for layer %s", getName().c_str()); - } - mPreviousReleaseFence = releaseFence; + mListPreviousReleaseFences.emplace_back(futureRenderEngineResult); // Prevent tracing the same release multiple times. if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) { mPreviousReleasedFrameNumber = mPreviousFrameNumber; } + + if (ch != nullptr) { + ch->previousReleaseCallbackId = mPreviousReleaseCallbackId; + ch->previousReleaseFences.emplace_back(futureRenderEngineResult); + ch->name = mName; + } } void BufferStateLayer::onSurfaceFrameCreated( @@ -231,9 +172,18 @@ void BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { mFlinger->getTransactionCallbackInvoker().addCallbackHandles( mDrawingState.callbackHandles, jankData); + sp<Fence> releaseFence = Fence::NO_FENCE; + for (auto& handle : mDrawingState.callbackHandles) { + if (handle->releasePreviousBuffer && + mDrawingState.releaseBufferEndpoint == handle->listener) { + releaseFence = + handle->previousReleaseFence ? handle->previousReleaseFence : Fence::NO_FENCE; + break; + } + } + mDrawingState.callbackHandles = {}; - const sp<Fence>& releaseFence(mPreviousReleaseFence); std::shared_ptr<FenceTime> releaseFenceTime = std::make_shared<FenceTime>(releaseFence); { Mutex::Autolock lock(mFrameEventHistoryMutex); diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 87b68ea71b..6cb9b352f8 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -39,7 +39,9 @@ public: // Implements Layer. const char* getType() const override { return "BufferStateLayer"; } - void onLayerDisplayed(const sp<Fence>& releaseFence) override; + void onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override; + void releasePendingBuffer(nsecs_t dequeueReadyTime) override; void finalizeFrameEventHistory(const std::shared_ptr<FenceTime>& glDoneFence, @@ -115,8 +117,6 @@ private: bool updateFrameEventHistory(const sp<Fence>& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime); - status_t addReleaseFence(const sp<CallbackHandle>& ch, const sp<Fence>& releaseFence); - bool latchSidebandStream(bool& recomputeVisibleRegions) override; bool hasFrameUpdate() const override; @@ -139,7 +139,7 @@ private: std::shared_ptr<renderengine::ExternalTexture> getBufferFromBufferData( const BufferData& bufferData); - sp<Fence> mPreviousReleaseFence; + std::vector<std::shared_future<renderengine::RenderEngineResult>> mListPreviousReleaseFences; ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID; uint64_t mPreviousReleasedFrameNumber = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h index f7b71cf9fe..ac243c0a17 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -16,6 +16,7 @@ #pragma once +#include <future> #include <optional> #include <ostream> #include <unordered_set> @@ -26,6 +27,7 @@ #pragma clang diagnostic ignored "-Wextra" #include <renderengine/LayerSettings.h> +#include <renderengine/RenderEngine.h> // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" @@ -151,7 +153,7 @@ public: ClientCompositionTargetSettings&) = 0; // Called after the layer is displayed to update the presentation fence - virtual void onLayerDisplayed(const sp<Fence>&) = 0; + virtual void onLayerDisplayed(std::shared_future<renderengine::RenderEngineResult>) = 0; // Gets some kind of identifier for the layer for debug purposes. virtual const char* getDebugName() const = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h index d215bda891..16aebef9f3 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h @@ -39,7 +39,7 @@ public: std::vector<compositionengine::LayerFE::LayerSettings>( compositionengine::LayerFE::ClientCompositionTargetSettings&)); - MOCK_METHOD1(onLayerDisplayed, void(const sp<Fence>&)); + MOCK_METHOD1(onLayerDisplayed, void(std::shared_future<renderengine::RenderEngineResult>)); MOCK_CONST_METHOD0(getDebugName, const char*()); MOCK_CONST_METHOD0(getSequence, int32_t()); diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 048d7c2b4a..7ea1aa2f92 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -27,6 +27,7 @@ #include <compositionengine/impl/OutputLayer.h> #include <compositionengine/impl/OutputLayerCompositionState.h> #include <compositionengine/impl/planner/Planner.h> +#include <ftl/future.h> #include <thread> @@ -1097,12 +1098,12 @@ std::optional<base::unique_fd> Output::composeSurfaces( setExpensiveRenderingExpected(true); } - std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers; - clientCompositionLayerPointers.reserve(clientCompositionLayers.size()); + std::vector<renderengine::LayerSettings> clientRenderEngineLayers; + clientRenderEngineLayers.reserve(clientCompositionLayers.size()); std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(), - std::back_inserter(clientCompositionLayerPointers), - [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings* { - return &settings; + std::back_inserter(clientRenderEngineLayers), + [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings { + return settings; }); const nsecs_t renderEngineStart = systemTime(); @@ -1115,7 +1116,7 @@ std::optional<base::unique_fd> Output::composeSurfaces( const bool useFramebufferCache = outputState.layerFilter.toInternalDisplay; auto [status, drawFence] = renderEngine - .drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex, + .drawLayers(clientCompositionDisplay, clientRenderEngineLayers, tex, useFramebufferCache, std::move(fd)) .get(); @@ -1295,8 +1296,10 @@ void Output::postFramebuffer() { releaseFence = Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence); } - - layer->getLayerFE().onLayerDisplayed(releaseFence); + layer->getLayerFE().onLayerDisplayed( + ftl::yield<renderengine::RenderEngineResult>( + {NO_ERROR, base::unique_fd(releaseFence->dup())}) + .share()); } // We've got a list of layers needing fences, that are disjoint with @@ -1304,7 +1307,9 @@ void Output::postFramebuffer() { // supply them with the present fence. for (auto& weakLayer : mReleasedLayers) { if (auto layer = weakLayer.promote(); layer != nullptr) { - layer->onLayerDisplayed(frame.presentFence); + layer->onLayerDisplayed(ftl::yield<renderengine::RenderEngineResult>( + {NO_ERROR, base::unique_fd(frame.presentFence->dup())}) + .share()); } } diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index e6b716e8f2..ec52e59ab0 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -193,11 +193,6 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te clientCompositionList.cend()); } - std::vector<const renderengine::LayerSettings*> layerSettingsPointers; - std::transform(layerSettings.cbegin(), layerSettings.cend(), - std::back_inserter(layerSettingsPointers), - [](const renderengine::LayerSettings& settings) { return &settings; }); - renderengine::LayerSettings blurLayerSettings; if (mBlurLayer) { auto blurSettings = targetSettings; @@ -212,7 +207,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te blurLayerSettings.name = std::string("blur layer"); // Clear out the shadow settings blurLayerSettings.shadow = {}; - layerSettingsPointers.push_back(&blurLayerSettings); + layerSettings.push_back(blurLayerSettings); } renderengine::LayerSettings holePunchSettings; @@ -230,7 +225,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te holePunchSettings.disableBlending = true; holePunchSettings.alpha = 0.0f; holePunchSettings.name = std::string("hole punch layer"); - layerSettingsPointers.push_back(&holePunchSettings); + layerSettings.push_back(holePunchSettings); // Add a solid background as the first layer in case there is no opaque // buffer behind the punch hole @@ -239,7 +234,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te holePunchBackgroundSettings.geometry.boundaries = holePunchSettings.geometry.boundaries; holePunchBackgroundSettings.geometry.positionTransform = holePunchSettings.geometry.positionTransform; - layerSettingsPointers.insert(layerSettingsPointers.begin(), &holePunchBackgroundSettings); + layerSettings.emplace(layerSettings.begin(), holePunchBackgroundSettings); } if (sDebugHighlighLayers) { @@ -257,7 +252,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te .alpha = half(0.05f), }; - layerSettingsPointers.emplace_back(&highlight); + layerSettings.emplace_back(highlight); } auto texture = texturePool.borrowTexture(); @@ -273,8 +268,8 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te } auto [status, drawFence] = renderEngine - .drawLayers(displaySettings, layerSettingsPointers, - texture->get(), false, std::move(bufferFence)) + .drawLayers(displaySettings, layerSettings, texture->get(), + false, std::move(bufferFence)) .get(); if (status == NO_ERROR) { diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 8f0028c399..cf63ef5183 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -24,6 +24,7 @@ #include <compositionengine/mock/LayerFE.h> #include <compositionengine/mock/OutputLayer.h> #include <compositionengine/mock/RenderSurface.h> +#include <ftl/future.h> #include <gtest/gtest.h> #include <renderengine/mock/RenderEngine.h> #include <ui/Rect.h> @@ -2884,12 +2885,24 @@ TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) { // are passed. This happens to work with the current implementation, but // would not survive certain calls like Fence::merge() which would return a // new instance. - EXPECT_CALL(*mLayer1.layerFE, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get())))); - EXPECT_CALL(*mLayer2.layerFE, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get())))); - EXPECT_CALL(*mLayer3.layerFE, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get())))); + base::unique_fd layer1FD(layer1Fence->dup()); + base::unique_fd layer2FD(layer2Fence->dup()); + base::unique_fd layer3FD(layer3Fence->dup()); + EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_)) + .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence); + }); + EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_)) + .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence); + }); + EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_)) + .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence); + }); mOutput.postFramebuffer(); } @@ -2915,9 +2928,9 @@ TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) // Fence::merge is called, and since none of the fences are actually valid, // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call. // This is the best we can do without creating a real kernel fence object. - EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE)); - EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE)); - EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE)); + EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return()); + EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return()); + EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return()); mOutput.postFramebuffer(); } @@ -2949,12 +2962,22 @@ TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) { EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted()); // Each released layer should be given the presentFence. - EXPECT_CALL(*releasedLayer1, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get())))); - EXPECT_CALL(*releasedLayer2, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get())))); - EXPECT_CALL(*releasedLayer3, - onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get())))); + base::unique_fd layerFD(presentFence.get()->dup()); + EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_)) + .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence); + }); + EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_)) + .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence); + }); + EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_)) + .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult> + futureRenderEngineResult) { + EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence); + }); mOutput.postFramebuffer(); @@ -3131,9 +3154,9 @@ TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) { EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _)) .WillRepeatedly([&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }); @@ -3161,11 +3184,11 @@ TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) { })); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _)) .WillRepeatedly([&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }); @@ -3196,11 +3219,11 @@ TEST_F(OutputComposeSurfacesTest, })); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _)) .WillRepeatedly([&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }); @@ -3226,7 +3249,7 @@ TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithou .WillRepeatedly(Return()); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _)) .Times(2) .WillOnce(Return(ByMove( futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})))) @@ -3258,7 +3281,7 @@ TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) { .WillRepeatedly(Return()); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _)) .WillOnce(Return(ByMove( futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})))); EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)); @@ -3294,11 +3317,11 @@ TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) { EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)) .WillOnce(Return(mOutputBuffer)) .WillOnce(Return(otherOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _)) .WillRepeatedly([&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }); @@ -3330,10 +3353,10 @@ TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) { .WillRepeatedly(Return()); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer)); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _)) .WillOnce(Return(ByMove( futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})))); - EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _)) + EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _)) .WillOnce(Return(ByMove( futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})))); @@ -3487,9 +3510,9 @@ struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeS EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _)) .WillRepeatedly( [&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { return futureOf<renderengine::RenderEngineResult>( {NO_ERROR, base::unique_fd()}); }); diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp index ecb05f8e5f..42b3d972a8 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp @@ -346,15 +346,15 @@ TEST_F(CachedSetTest, renderUnsecureOutput) { const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay); EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip); EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()), displaySettings.orientation); - EXPECT_EQ(0.5f, layers[0]->alpha); - EXPECT_EQ(0.75f, layers[1]->alpha); + EXPECT_EQ(0.5f, layers[0].alpha); + EXPECT_EQ(0.75f, layers[1].alpha); EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace); return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }; @@ -398,15 +398,15 @@ TEST_F(CachedSetTest, renderSecureOutput) { const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay); EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip); EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()), displaySettings.orientation); - EXPECT_EQ(0.5f, layers[0]->alpha); - EXPECT_EQ(0.75f, layers[1]->alpha); + EXPECT_EQ(0.5f, layers[0].alpha); + EXPECT_EQ(0.75f, layers[1].alpha); EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace); return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); @@ -453,15 +453,15 @@ TEST_F(CachedSetTest, rendersWithOffsetFramebufferContent) { const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay); EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip); EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()), displaySettings.orientation); - EXPECT_EQ(0.5f, layers[0]->alpha); - EXPECT_EQ(0.75f, layers[1]->alpha); + EXPECT_EQ(0.5f, layers[0].alpha); + EXPECT_EQ(0.75f, layers[1].alpha); EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace); return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); @@ -656,26 +656,26 @@ TEST_F(CachedSetTest, addHolePunch) { const auto drawLayers = [&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { // If the highlight layer is enabled, it will increase the size by 1. // We're interested in the third layer either way. EXPECT_GE(layers.size(), 4u); { - const auto* holePunchSettings = layers[3]; - EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor); - EXPECT_TRUE(holePunchSettings->disableBlending); - EXPECT_EQ(0.0f, holePunchSettings->alpha); + const auto holePunchSettings = layers[3]; + EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor); + EXPECT_TRUE(holePunchSettings.disableBlending); + EXPECT_EQ(0.0f, holePunchSettings.alpha); } { - const auto* holePunchBackgroundSettings = layers[0]; - EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor); - EXPECT_FALSE(holePunchBackgroundSettings->disableBlending); - EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha); + const auto holePunchBackgroundSettings = layers[0]; + EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor); + EXPECT_FALSE(holePunchBackgroundSettings.disableBlending); + EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha); } return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); @@ -717,27 +717,27 @@ TEST_F(CachedSetTest, addHolePunch_noBuffer) { const auto drawLayers = [&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { // If the highlight layer is enabled, it will increase the size by 1. // We're interested in the third layer either way. EXPECT_GE(layers.size(), 4u); { - const auto* holePunchSettings = layers[3]; - EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor); - EXPECT_TRUE(holePunchSettings->disableBlending); - EXPECT_EQ(0.0f, holePunchSettings->alpha); + const auto holePunchSettings = layers[3]; + EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor); + EXPECT_TRUE(holePunchSettings.disableBlending); + EXPECT_EQ(0.0f, holePunchSettings.alpha); } { - const auto* holePunchBackgroundSettings = layers[0]; - EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor); - EXPECT_FALSE(holePunchBackgroundSettings->disableBlending); - EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha); + const auto holePunchBackgroundSettings = layers[0]; + EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor); + EXPECT_FALSE(holePunchBackgroundSettings.disableBlending); + EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha); } return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); @@ -867,16 +867,16 @@ TEST_F(CachedSetTest, addBlur) { const auto drawLayers = [&](const renderengine::DisplaySettings&, - const std::vector<const renderengine::LayerSettings*>& layers, + const std::vector<renderengine::LayerSettings>& layers, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { // If the highlight layer is enabled, it will increase the size by 1. // We're interested in the third layer either way. EXPECT_GE(layers.size(), 3u); - const auto* blurSettings = layers[2]; - EXPECT_TRUE(blurSettings->skipContentDraw); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings->source.solidColor); - EXPECT_EQ(0.0f, blurSettings->alpha); + const auto blurSettings = layers[2]; + EXPECT_TRUE(blurSettings.skipContentDraw); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings.source.solidColor); + EXPECT_EQ(0.0f, blurSettings.alpha); return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}); }; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5707c67a56..d68cf9720f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -221,7 +221,8 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, * Layer. So, the implementation is done in BufferLayer. When called on a * EffectLayer object, it's essentially a NOP. */ -void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} +void Layer::onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> /*futureRenderEngineResult*/) {} void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) { if (mDrawingState.zOrderRelativeOf == nullptr) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 07b2eb5130..4569f9af23 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -616,7 +616,8 @@ public: void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override; std::vector<compositionengine::LayerFE::LayerSettings> prepareClientCompositionList( compositionengine::LayerFE::ClientCompositionTargetSettings&) override; - void onLayerDisplayed(const sp<Fence>& releaseFence) override; + void onLayerDisplayed( + std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override; void setWasClientComposed(const sp<Fence>& fence) override { mLastClientCompositionFence = fence; diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index aa2fec56ad..d0f56b5bdd 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -356,10 +356,13 @@ void RegionSamplingThread::captureSample() { renderengine::ExternalTexture::Usage::WRITEABLE); } - const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); - mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, - true /* regionSampling */, false /* grayscale */, captureListener); - ScreenCaptureResults captureResults = captureListener->waitForResults(); + auto captureScreenResultFuture = + mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, + true /* regionSampling */, false /* grayscale */, nullptr); + auto& captureScreenResult = captureScreenResultFuture.get(); + if (captureScreenResult.drawFence.ok()) { + sync_wait(captureScreenResult.drawFence.get(), -1); + } std::vector<Descriptor> activeDescriptors; for (const auto& descriptor : descriptors) { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index acb81dc41c..638458cfd3 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -5972,9 +5972,10 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, traverseLayersInLayerStack(layerStack, args.uid, visitor); }; - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, - args.pixelFormat, args.allowProtected, args.grayscale, - captureListener); + auto captureResultFuture = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, + reqSize, args.pixelFormat, args.allowProtected, + args.grayscale, captureListener); + return captureResultFuture.get().status; } status_t SurfaceFlinger::captureDisplay(DisplayId displayId, @@ -6009,9 +6010,15 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor); }; - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size, - ui::PixelFormat::RGBA_8888, false /* allowProtected */, - false /* grayscale */, captureListener); + if (captureListener == nullptr) { + ALOGE("capture screen must provide a capture listener callback"); + return BAD_VALUE; + } + auto captureResultFuture = + captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size, + ui::PixelFormat::RGBA_8888, false /* allowProtected */, + false /* grayscale */, captureListener); + return captureResultFuture.get().status; } status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, @@ -6138,23 +6145,28 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, }); }; - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, - args.pixelFormat, args.allowProtected, args.grayscale, - captureListener); + if (captureListener == nullptr) { + ALOGE("capture screen must provide a capture listener callback"); + return BAD_VALUE; + } + + auto captureResultFuture = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, + reqSize, args.pixelFormat, args.allowProtected, + args.grayscale, captureListener); + return captureResultFuture.get().status; } -status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, - TraverseLayersFunction traverseLayers, - ui::Size bufferSize, ui::PixelFormat reqPixelFormat, - bool allowProtected, bool grayscale, - const sp<IScreenCaptureListener>& captureListener) { +std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::captureScreenCommon( + RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers, + ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, + const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) { ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ") that exceeds render target size limit.", bufferSize.getWidth(), bufferSize.getHeight()); - return BAD_VALUE; + return ftl::yield<renderengine::RenderEngineResult>({BAD_VALUE, base::unique_fd()}).share(); } // Loop over all visible layers to see whether there's any protected layer. A protected layer is @@ -6194,25 +6206,23 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, false /* regionSampling */, grayscale, captureListener); } -status_t SurfaceFlinger::captureScreenCommon( +std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::captureScreenCommon( RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); - if (captureListener == nullptr) { - ALOGE("capture screen must provide a capture listener callback"); - return BAD_VALUE; - } - bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission(); - static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable { + auto scheduleResultFuture = schedule([=, + renderAreaFuture = std::move(renderAreaFuture)]() mutable + -> std::shared_future<renderengine::RenderEngineResult> { if (mRefreshPending) { ALOGW("Skipping screenshot for now"); captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, regionSampling, grayscale, captureListener); - return; + return ftl::yield<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}) + .share(); } ScreenCaptureResults captureResults; std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get(); @@ -6220,24 +6230,44 @@ status_t SurfaceFlinger::captureScreenCommon( ALOGW("Skipping screen capture because of invalid render area."); captureResults.result = NO_MEMORY; captureListener->onScreenCaptureCompleted(captureResults); - return; + return ftl::yield<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}) + .share(); } - status_t result = NO_ERROR; + std::shared_future<renderengine::RenderEngineResult> renderEngineResultFuture; + renderArea->render([&] { - result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, - canCaptureBlackoutContent, regionSampling, grayscale, - captureResults); + renderEngineResultFuture = + renderScreenImplLocked(*renderArea, traverseLayers, buffer, + canCaptureBlackoutContent, regionSampling, grayscale, + captureResults); }); + // spring up a thread to unblock SF main thread and wait for + // RenderEngineResult to be available + if (captureListener != nullptr) { + std::async([=]() mutable { + ATRACE_NAME("captureListener is nonnull!"); + auto& [status, drawFence] = renderEngineResultFuture.get(); + captureResults.result = status; + captureResults.fence = new Fence(dup(drawFence)); + captureListener->onScreenCaptureCompleted(captureResults); + }); + } + return renderEngineResultFuture; + }); - captureResults.result = result; - captureListener->onScreenCaptureCompleted(captureResults); - })); - - return NO_ERROR; + // flatten scheduleResultFuture object to single shared_future object + std::future<renderengine::RenderEngineResult> captureScreenResultFuture = + ftl::chain(std::move(scheduleResultFuture)) + .then([=](std::shared_future<renderengine::RenderEngineResult> futureObject) + -> renderengine::RenderEngineResult { + auto& [status, drawFence] = futureObject.get(); + return {status, base::unique_fd(dup(drawFence))}; + }); + return captureScreenResultFuture.share(); } -status_t SurfaceFlinger::renderScreenImplLocked( +std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::renderScreenImplLocked( const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, @@ -6256,7 +6286,8 @@ status_t SurfaceFlinger::renderScreenImplLocked( // the impetus on WindowManager to not persist them. if (captureResults.capturedSecureLayers && !canCaptureBlackoutContent) { ALOGW("FB is protected: PERMISSION_DENIED"); - return PERMISSION_DENIED; + return ftl::yield<renderengine::RenderEngineResult>({PERMISSION_DENIED, base::unique_fd()}) + .share(); } captureResults.buffer = buffer->getBuffer(); @@ -6338,11 +6369,12 @@ status_t SurfaceFlinger::renderScreenImplLocked( }); - std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers( - clientCompositionLayers.size()); + std::vector<renderengine::LayerSettings> clientRenderEngineLayers; + clientRenderEngineLayers.reserve(clientCompositionLayers.size()); std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(), - clientCompositionLayerPointers.begin(), - std::pointer_traits<renderengine::LayerSettings*>::pointer_to); + std::back_inserter(clientRenderEngineLayers), + [](compositionengine::LayerFE::LayerSettings& settings) + -> renderengine::LayerSettings { return settings; }); // Use an empty fence for the buffer fence, since we just created the buffer so // there is no need for synchronization with the GPU. @@ -6350,24 +6382,22 @@ status_t SurfaceFlinger::renderScreenImplLocked( getRenderEngine().useProtectedContext(useProtected); const constexpr bool kUseFramebufferCache = false; - auto [status, drawFence] = - getRenderEngine() - .drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer, - kUseFramebufferCache, std::move(bufferFence)) - .get(); + std::future<renderengine::RenderEngineResult> drawLayersResult = + getRenderEngine().drawLayers(clientCompositionDisplay, clientRenderEngineLayers, buffer, + kUseFramebufferCache, std::move(bufferFence)); - if (drawFence >= 0) { - sp<Fence> releaseFence = new Fence(dup(drawFence)); - for (auto* layer : renderedLayers) { - layer->onLayerDisplayed(releaseFence); - } + std::shared_future<renderengine::RenderEngineResult> drawLayersResultFuture = + drawLayersResult.share(); // drawLayersResult will be moved to shared one + + for (auto* layer : renderedLayers) { + // make a copy of shared_future object for each layer + layer->onLayerDisplayed(drawLayersResultFuture); } - captureResults.fence = new Fence(drawFence.release()); // Always switch back to unprotected context. getRenderEngine().useProtectedContext(false); - return status; + return drawLayersResultFuture; } void SurfaceFlinger::windowInfosReported() { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1f0e42ddf3..45fd94e50c 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -906,17 +906,17 @@ private: // Boot animation, on/off animations and screen capture void startBootAnim(); - status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, - ui::PixelFormat, bool allowProtected, bool grayscale, - const sp<IScreenCaptureListener>&); - status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool regionSampling, bool grayscale, - const sp<IScreenCaptureListener>&); - status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool canCaptureBlackoutContent, bool regionSampling, - bool grayscale, ScreenCaptureResults&); + std::shared_future<renderengine::RenderEngineResult> captureScreenCommon( + RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, ui::PixelFormat, + bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>&); + std::shared_future<renderengine::RenderEngineResult> captureScreenCommon( + RenderAreaFuture, TraverseLayersFunction, + const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling, + bool grayscale, const sp<IScreenCaptureListener>&); + std::shared_future<renderengine::RenderEngineResult> renderScreenImplLocked( + const RenderArea&, TraverseLayersFunction, + const std::shared_ptr<renderengine::ExternalTexture>&, bool canCaptureBlackoutContent, + bool regionSampling, bool grayscale, ScreenCaptureResults&); // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a // matching ownerUid diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp index c1eb8966d1..8fbf0b4d07 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.cpp +++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp @@ -154,6 +154,38 @@ status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>& // destroyed the client side is dead and there won't be anyone to send the callback to. sp<IBinder> surfaceControl = handle->surfaceControl.promote(); if (surfaceControl) { + sp<Fence> prevFence = nullptr; + + for (const auto& futureStruct : handle->previousReleaseFences) { + sp<Fence> currentFence = sp<Fence>::make(dup(futureStruct.get().drawFence)); + if (prevFence == nullptr && currentFence->getStatus() != Fence::Status::Invalid) { + prevFence = currentFence; + handle->previousReleaseFence = prevFence; + } else if (prevFence != nullptr) { + // If both fences are signaled or both are unsignaled, we need to merge + // them to get an accurate timestamp. + if (prevFence->getStatus() != Fence::Status::Invalid && + prevFence->getStatus() == currentFence->getStatus()) { + char fenceName[32] = {}; + snprintf(fenceName, 32, "%.28s", handle->name.c_str()); + sp<Fence> mergedFence = Fence::merge(fenceName, prevFence, currentFence); + if (mergedFence->isValid()) { + handle->previousReleaseFence = mergedFence; + prevFence = handle->previousReleaseFence; + } + } else if (currentFence->getStatus() == Fence::Status::Unsignaled) { + // If one fence has signaled and the other hasn't, the unsignaled + // fence will approximately correspond with the correct timestamp. + // There's a small race if both fences signal at about the same time + // and their statuses are retrieved with unfortunate timing. However, + // by this point, they will have both signaled and only the timestamp + // will be slightly off; any dependencies after this point will + // already have been met. + handle->previousReleaseFence = currentFence; + } + } + } + handle->previousReleaseFences = {}; FrameEventHistoryStats eventStats(handle->frameNumber, handle->gpuCompositionDoneFence->getSnapshot().fence, handle->compositorTiming, handle->refreshStartTime, diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h index 7e879e119b..100dbfa8aa 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.h +++ b/services/surfaceflinger/TransactionCallbackInvoker.h @@ -18,8 +18,9 @@ #include <condition_variable> #include <deque> -#include <queue> +#include <future> #include <mutex> +#include <queue> #include <thread> #include <unordered_map> #include <unordered_set> @@ -28,6 +29,7 @@ #include <binder/IBinder.h> #include <gui/ITransactionCompletedListener.h> +#include <renderengine/RenderEngine.h> #include <ui/Fence.h> namespace android { @@ -42,7 +44,9 @@ public: wp<IBinder> surfaceControl; bool releasePreviousBuffer = false; + std::string name; sp<Fence> previousReleaseFence; + std::vector<std::shared_future<renderengine::RenderEngineResult>> previousReleaseFences; nsecs_t acquireTime = -1; nsecs_t latchTime = -1; uint32_t transformHint = 0; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 5135ff952f..61c7c398dd 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -247,10 +247,16 @@ void CompositionTest::captureScreenComposition() { "screenshot"), *mRenderEngine, true); - status_t result = - mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer, - forSystem, regionSampling); - EXPECT_EQ(NO_ERROR, result); + auto result = mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer, + forSystem, regionSampling); + EXPECT_TRUE(result.valid()); + + auto& [status, drawFence] = result.get(); + + EXPECT_EQ(NO_ERROR, status); + if (drawFence.ok()) { + sync_wait(drawFence.get(), -1); + } LayerCase::cleanup(this); } @@ -346,9 +352,9 @@ struct BaseDisplayVariant { static void setupCommonScreensCaptureCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly([&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, - const bool, base::unique_fd &&) + const bool, base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), @@ -397,9 +403,9 @@ struct BaseDisplayVariant { Return(0))); EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly([&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>&, + const std::vector<renderengine::LayerSettings>&, const std::shared_ptr<renderengine::ExternalTexture>&, - const bool, base::unique_fd &&) + const bool, base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), @@ -633,9 +639,9 @@ struct BaseLayerProperties { static void setupREBufferCompositionCommonCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layerSettings, + const std::vector<renderengine::LayerSettings>& layerSettings, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -652,16 +658,16 @@ struct BaseLayerProperties { "verification lambda"; return resultFuture; } - const renderengine::LayerSettings* layer = layerSettings.back(); - EXPECT_THAT(layer->source.buffer.buffer, Not(IsNull())); - EXPECT_THAT(layer->source.buffer.fence, Not(IsNull())); - EXPECT_EQ(DEFAULT_TEXTURE_ID, layer->source.buffer.textureName); - EXPECT_EQ(false, layer->source.buffer.isY410BT2020); - EXPECT_EQ(true, layer->source.buffer.usePremultipliedAlpha); - EXPECT_EQ(false, layer->source.buffer.isOpaque); - EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius); - EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace); - EXPECT_EQ(LayerProperties::COLOR[3], layer->alpha); + const renderengine::LayerSettings layer = layerSettings.back(); + EXPECT_THAT(layer.source.buffer.buffer, Not(IsNull())); + EXPECT_THAT(layer.source.buffer.fence, Not(IsNull())); + EXPECT_EQ(DEFAULT_TEXTURE_ID, layer.source.buffer.textureName); + EXPECT_EQ(false, layer.source.buffer.isY410BT2020); + EXPECT_EQ(true, layer.source.buffer.usePremultipliedAlpha); + EXPECT_EQ(false, layer.source.buffer.isOpaque); + EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius); + EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace); + EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha); return resultFuture; }); } @@ -685,9 +691,9 @@ struct BaseLayerProperties { static void setupREColorCompositionCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layerSettings, + const std::vector<renderengine::LayerSettings>& layerSettings, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -704,14 +710,14 @@ struct BaseLayerProperties { "setupREColorCompositionCallExpectations verification lambda"; return resultFuture; } - const renderengine::LayerSettings* layer = layerSettings.back(); - EXPECT_THAT(layer->source.buffer.buffer, IsNull()); + const renderengine::LayerSettings layer = layerSettings.back(); + EXPECT_THAT(layer.source.buffer.buffer, IsNull()); EXPECT_EQ(half3(LayerProperties::COLOR[0], LayerProperties::COLOR[1], LayerProperties::COLOR[2]), - layer->source.solidColor); - EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius); - EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace); - EXPECT_EQ(LayerProperties::COLOR[3], layer->alpha); + layer.source.solidColor); + EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius); + EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace); + EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha); return resultFuture; }); } @@ -765,9 +771,9 @@ struct CommonSecureLayerProperties : public BaseLayerProperties<LayerProperties> static void setupInsecureREBufferCompositionCommonCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([&](const renderengine::DisplaySettings& displaySettings, - const std::vector<const renderengine::LayerSettings*>& layerSettings, + const std::vector<renderengine::LayerSettings>& layerSettings, const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> { + base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -784,12 +790,12 @@ struct CommonSecureLayerProperties : public BaseLayerProperties<LayerProperties> "verification lambda"; return resultFuture; } - const renderengine::LayerSettings* layer = layerSettings.back(); - EXPECT_THAT(layer->source.buffer.buffer, IsNull()); - EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), layer->source.solidColor); - EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius); - EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace); - EXPECT_EQ(1.0f, layer->alpha); + const renderengine::LayerSettings layer = layerSettings.back(); + EXPECT_THAT(layer.source.buffer.buffer, IsNull()); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), layer.source.solidColor); + EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius); + EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace); + EXPECT_EQ(1.0f, layer.alpha); return resultFuture; }); } |