diff options
-rw-r--r-- | core/api/current.txt | 2 | ||||
-rw-r--r-- | graphics/java/android/graphics/HardwareRenderer.java | 41 | ||||
-rw-r--r-- | libs/hwui/Properties.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 14 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 10 |
7 files changed, 100 insertions, 3 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 7a00119faefa..d62ec169d9a0 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -15261,9 +15261,11 @@ package android.graphics { method public void clearContent(); method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest(); method public void destroy(); + method public static boolean isDrawingEnabled(); method public boolean isOpaque(); method public void notifyFramePending(); method public void setContentRoot(@Nullable android.graphics.RenderNode); + method public static void setDrawingEnabled(boolean); method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float); method public void setLightSourceGeometry(float, float, float, float); method public void setName(@NonNull String); diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index fe04f0dd4c83..187ddd892034 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -1106,6 +1106,43 @@ public class HardwareRenderer { ProcessInitializer.sInstance.setContext(context); } + /** + * Returns true if HardwareRender will produce output. + * + * This value is global to the process and affects all uses of HardwareRenderer, + * including + * those created by the system such as those used by the View tree when using hardware + * accelerated rendering. + * + * Default is true in all production environments, but may be false in testing-focused + * emulators or if {@link #setDrawingEnabled(boolean)} is used. + */ + public static boolean isDrawingEnabled() { + return nIsDrawingEnabled(); + } + + /** + * Toggles whether or not HardwareRenderer will produce drawing output globally in the current + * process. + * + * This applies to all HardwareRenderer instances, including those created by the platform such + * as those used by the system for hardware accelerated View rendering. + * + * The capability to disable drawing output is intended for test environments, primarily + * headless ones. By setting this to false, tests that launch activities or interact with Views + * can be quicker with less RAM usage by skipping the final step of View drawing. All View + * lifecycle events will occur as normal, only the final step of rendering on the GPU to the + * display will be skipped. + * + * This can be toggled on and off at will, so screenshot tests can also run in this same + * environment by toggling drawing back on and forcing a frame to be drawn such as by calling + * view#invalidate(). Once drawn and the screenshot captured, this can then be turned back off. + */ + // TODO: Add link to androidx's Screenshot library for help with this + public static void setDrawingEnabled(boolean drawingEnabled) { + nSetDrawingEnabled(drawingEnabled); + } + private static final class DestroyContextRunnable implements Runnable { private final long mNativeInstance; @@ -1438,4 +1475,8 @@ public class HardwareRenderer { private static native void nInitDisplayInfo(int width, int height, float refreshRate, int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos); + + private static native void nSetDrawingEnabled(boolean drawingEnabled); + + private static native boolean nIsDrawingEnabled(); } diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index b8fa55a18dac..18fab8ee5f92 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -88,6 +88,9 @@ bool Properties::enableWebViewOverlays = false; StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI; +bool Properties::drawingEnabled = true; +OverrideDrawingEnabled Properties::overrideDrawingEnabled = OverrideDrawingEnabled::Default; + bool Properties::load() { bool prevDebugLayersUpdates = debugLayersUpdates; bool prevDebugOverdraw = debugOverdraw; @@ -141,6 +144,11 @@ bool Properties::load() { enableWebViewOverlays = base::GetBoolProperty(PROPERTY_WEBVIEW_OVERLAYS_ENABLED, false); + drawingEnabled = base::GetBoolProperty(PROPERTY_DRAWING_ENABLED, true); + if (!drawingEnabled) { + enableRTAnimations = false; + } + return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw); } @@ -210,5 +218,18 @@ void Properties::overrideRenderPipelineType(RenderPipelineType type, bool inUnit sRenderPipelineType = type; } +void Properties::setDrawingEnabled(bool newDrawingEnabled) { + overrideDrawingEnabled = + newDrawingEnabled ? OverrideDrawingEnabled::On : OverrideDrawingEnabled::Off; + enableRTAnimations = newDrawingEnabled; +} + +bool Properties::isDrawingEnabled() { + if (overrideDrawingEnabled == OverrideDrawingEnabled::Default) { + return drawingEnabled; + } + return overrideDrawingEnabled == OverrideDrawingEnabled::On; +} + } // namespace uirenderer } // namespace android diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 7df6e2c92247..73fccb67800b 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -187,6 +187,12 @@ enum DebugLevel { */ #define PROPERTY_WEBVIEW_OVERLAYS_ENABLED "debug.hwui.webview_overlays_enabled" +/** + * Property for globally GL drawing state. Can be overridden per process with + * setDrawingEnabled. + */ +#define PROPERTY_DRAWING_ENABLED "debug.hwui.drawing_enabled" + /////////////////////////////////////////////////////////////////////////////// // Misc /////////////////////////////////////////////////////////////////////////////// @@ -208,6 +214,8 @@ enum class StretchEffectBehavior { UniformScale // Uniform scale stretch everywhere }; +enum class OverrideDrawingEnabled { Default, On, Off }; + /** * Renderthread-only singleton which manages several static rendering properties. Most of these * are driven by system properties which are queried once at initialization, and again if init() @@ -301,6 +309,12 @@ public: stretchEffectBehavior = behavior; } + // Represents if GL drawing is enabled. Should only be false in headless testing environments + static bool drawingEnabled; + static OverrideDrawingEnabled overrideDrawingEnabled; + static bool isDrawingEnabled(); + static void setDrawingEnabled(bool enable); + private: static StretchEffectBehavior stretchEffectBehavior; static ProfileType sProfileType; diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index ef3a11c13469..78f67799e291 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -896,6 +896,14 @@ static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv*, jclass, jint DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos); } +static void android_view_ThreadedRenderer_setDrawingEnabled(JNIEnv*, jclass, jboolean enabled) { + Properties::setDrawingEnabled(enabled); +} + +static jboolean android_view_ThreadedRenderer_isDrawingEnabled(JNIEnv*, jclass) { + return Properties::isDrawingEnabled(); +} + // ---------------------------------------------------------------------------- // HardwareRendererObserver // ---------------------------------------------------------------------------- @@ -1032,6 +1040,8 @@ static const JNINativeMethod gMethods[] = { {"preload", "()V", (void*)android_view_ThreadedRenderer_preload}, {"isWebViewOverlaysEnabled", "()Z", (void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled}, + {"nSetDrawingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDrawingEnabled}, + {"nIsDrawingEnabled", "()Z", (void*)android_view_ThreadedRenderer_isDrawingEnabled}, }; static JavaVM* mJvm = nullptr; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 025be7b2b6c1..ab9d0b2244e2 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -256,7 +256,7 @@ void CanvasContext::setStopped(bool stopped) { } void CanvasContext::allocateBuffers() { - if (mNativeSurface) { + if (mNativeSurface && Properties::isDrawingEnabled()) { ANativeWindow_tryAllocateBuffers(mNativeSurface->getNativeWindow()); } } @@ -480,7 +480,8 @@ nsecs_t CanvasContext::draw() { SkRect dirty; mDamageAccumulator.finish(&dirty); - if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) { + if (!Properties::isDrawingEnabled() || + (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw())) { mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); // Notify the callbacks, even if there's nothing to draw so they aren't waiting // indefinitely diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 6dbfcc349d50..2fed4686f16e 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -90,9 +90,17 @@ public: * and false otherwise (e.g. cache limits have been exceeded). */ bool pinImages(std::vector<SkImage*>& mutableImages) { + if (!Properties::isDrawingEnabled()) { + return true; + } return mRenderPipeline->pinImages(mutableImages); } - bool pinImages(LsaVector<sk_sp<Bitmap>>& images) { return mRenderPipeline->pinImages(images); } + bool pinImages(LsaVector<sk_sp<Bitmap>>& images) { + if (!Properties::isDrawingEnabled()) { + return true; + } + return mRenderPipeline->pinImages(images); + } /** * Unpin any image that had be previously pinned to the GPU cache |