@@ -838,8 +838,7 @@ void SkiaRenderEngine::drawLayersInternal(
838838 LOG_ALWAYS_FATAL_IF (activeSurface == dstSurface);
839839 LOG_ALWAYS_FATAL_IF (canvas == dstCanvas);
840840
841- // save a snapshot of the activeSurface to use as input to the blur shaders
842- blurInput = activeSurface->makeImageSnapshot ();
841+ blurInput = activeSurface->makeTemporaryImage ();
843842
844843 // blit the offscreen framebuffer into the destination AHB. This ensures that
845844 // even if the blurred image does not cover the screen (for example, during
@@ -853,12 +852,9 @@ void SkiaRenderEngine::drawLayersInternal(
853852 dstCanvas->drawAnnotation (SkRect::Make (dstCanvas->imageInfo ().dimensions ()),
854853 String8::format (" SurfaceID|%" PRId64, id).c_str (),
855854 nullptr );
856- dstCanvas->drawImage (blurInput, 0 , 0 , SkSamplingOptions (), &paint);
857- } else {
858- activeSurface->draw (dstCanvas, 0 , 0 , SkSamplingOptions (), &paint);
859855 }
856+ dstCanvas->drawImage (blurInput, 0 , 0 , SkSamplingOptions (), &paint);
860857 }
861-
862858 // assign dstCanvas to canvas and ensure that the canvas state is up to date
863859 canvas = dstCanvas;
864860 surfaceAutoSaveRestore.replace (canvas);
@@ -891,12 +887,6 @@ void SkiaRenderEngine::drawLayersInternal(
891887 if (mBlurFilter && layerHasBlur (layer, ctModifiesAlpha)) {
892888 std::unordered_map<uint32_t , sk_sp<SkImage>> cachedBlurs;
893889
894- // if multiple layers have blur, then we need to take a snapshot now because
895- // only the lowest layer will have blurImage populated earlier
896- if (!blurInput) {
897- blurInput = activeSurface->makeImageSnapshot ();
898- }
899-
900890 // rect to be blurred in the coordinate space of blurInput
901891 SkRect blurRect = canvas->getTotalMatrix ().mapRect (bounds.rect ());
902892
@@ -920,6 +910,29 @@ void SkiaRenderEngine::drawLayersInternal(
920910
921911 // TODO(b/182216890): Filter out empty layers earlier
922912 if (blurRect.width () > 0 && blurRect.height () > 0 ) {
913+ // if multiple layers have blur, then we need to take a snapshot now because
914+ // only the lowest layer will have blurImage populated earlier
915+ if (!blurInput) {
916+ bool requiresCrossFadeWithBlurInput = false ;
917+ if (layer.backgroundBlurRadius > 0 &&
918+ layer.backgroundBlurRadius < mBlurFilter ->getMaxCrossFadeRadius ()) {
919+ requiresCrossFadeWithBlurInput = true ;
920+ }
921+ for (auto region : layer.blurRegions ) {
922+ if (region.blurRadius < mBlurFilter ->getMaxCrossFadeRadius ()) {
923+ requiresCrossFadeWithBlurInput = true ;
924+ }
925+ }
926+ if (requiresCrossFadeWithBlurInput) {
927+ // If we require cross fading with the blur input, we need to make sure we
928+ // make a copy of the surface to the image since we will be writing to the
929+ // surface while sampling the blurInput.
930+ blurInput = activeSurface->makeImageSnapshot ();
931+ } else {
932+ blurInput = activeSurface->makeTemporaryImage ();
933+ }
934+ }
935+
923936 if (layer.backgroundBlurRadius > 0 ) {
924937 SFTRACE_NAME (" BackgroundBlur" );
925938 auto blurredImage = mBlurFilter ->generate (context, layer.backgroundBlurRadius ,
0 commit comments