Backport 'Add ability to disable GL draws'.

This feature is intended for use in headless test environments,
where disabling drawing has minimal compatibility impact and can
save significant resource usage when running UI tests.

This feature is controlled via a new system property
'debug.hwui.drawing_enabled', and a HardwareRenderer API that can
override the property value on a per-process basis.

Bug: 201691826
Test: boot emulator
Merged-In: I93c21e680382e03342f235dbf58bd7a5c8a6f767
Change-Id: I391c841e3a0cdcfcc6c7910a316a4dd5e970547d
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index b8fa55a..18fab8e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -88,6 +88,9 @@
 
 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 @@
 
     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 @@
     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 7df6e2c..73fccb6 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -187,6 +187,12 @@
  */
 #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 @@
     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 @@
         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 54367b8..9e56584 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -817,6 +817,14 @@
     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
 // ----------------------------------------------------------------------------
@@ -953,6 +961,9 @@
         {"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 2f3a509..bb0b135 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -256,7 +256,7 @@
 }
 
 void CanvasContext::allocateBuffers() {
-    if (mNativeSurface) {
+    if (mNativeSurface && Properties::isDrawingEnabled()) {
         ANativeWindow_tryAllocateBuffers(mNativeSurface->getNativeWindow());
     }
 }
@@ -480,7 +480,8 @@
     SkRect dirty;
     mDamageAccumulator.finish(&dirty);
 
-    if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) {
+    if (!Properties::isDrawingEnabled() ||
+        (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw())) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
         if (auto grContext = getGrContext()) {
             // Submit to ensure that any texture uploads complete and Skia can
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6dbfcc3..2fed468 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -90,9 +90,17 @@
      *         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