aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hoisie <hoisie@google.com>2024-05-07 09:38:45 -0700
committerCopybara-Service <copybara-worker@google.com>2024-05-07 09:39:29 -0700
commitccf8c6fd9013537e4ffd8432505d642b10baccc4 (patch)
treec4966084386a384c6fa0c2495c28a61af38393b6
parent4f611e58dd448dc7ab90e351cd57aaccd16006b9 (diff)
downloadrobolectric-ccf8c6fd9013537e4ffd8432505d642b10baccc4.tar.gz
Reuse HardwareRenderer objects when taking HW screenshots
Previously, new HardwareRenderer objects were created each time a HW screenshot was captured. The problem was that if they were GC'd, `HardwareRenderer.nDeleteProxy` was called, which also freed a lot of associated native objects. This caused problems if the same Views were HW rendered again, as the native objects were corrupted. PiperOrigin-RevId: 631452676
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/HardwareRenderingScreenshot.java14
1 files changed, 12 insertions, 2 deletions
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/HardwareRenderingScreenshot.java b/shadows/framework/src/main/java/org/robolectric/shadows/HardwareRenderingScreenshot.java
index 63e9d7bd8..4bb433f90 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/HardwareRenderingScreenshot.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/HardwareRenderingScreenshot.java
@@ -15,7 +15,10 @@ import android.os.Build.VERSION_CODES;
import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.View;
+import android.view.ViewRootImpl;
import com.android.internal.R;
+import com.google.common.base.Preconditions;
+import java.util.WeakHashMap;
import org.robolectric.annotation.GraphicsMode;
import org.robolectric.util.ReflectionHelpers;
@@ -25,6 +28,11 @@ import org.robolectric.util.ReflectionHelpers;
*/
public final class HardwareRenderingScreenshot {
+ // It is important to reuse HardwareRenderer objects, and ensure that after a HardwareRenderer is
+ // collected, no associated views in the same View hierarchy will be rendered as well.
+ private static final WeakHashMap<ViewRootImpl, HardwareRenderer> hardwareRenderers =
+ new WeakHashMap<>();
+
static final String PIXEL_COPY_RENDER_MODE = "robolectric.pixelCopyRenderMode";
private HardwareRenderingScreenshot() {}
@@ -58,8 +66,10 @@ public final class HardwareRenderingScreenshot {
// - ImageReader is configured as RGBA_8888.
// - However the native libs/hwui/pipeline/skia/SkiaHostPipeline.cpp always treats
// the buffer as BGRA_8888, thus matching what the Android Bitmap object requires.
-
- HardwareRenderer renderer = new HardwareRenderer();
+ ViewRootImpl viewRootImpl = view.getViewRootImpl();
+ Preconditions.checkNotNull(viewRootImpl, "View not attached");
+ HardwareRenderer renderer =
+ hardwareRenderers.computeIfAbsent(viewRootImpl, k -> new HardwareRenderer());
Surface surface = imageReader.getSurface();
renderer.setSurface(surface);
Image nativeImage = imageReader.acquireNextImage();