Merge "Avoid setting high contrast in every view draw"
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
index 519d1f4..eed1db0 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
@@ -51,7 +51,6 @@
 
         while (state.keepRunning()) {
             canvas = node.start(200, 200);
-            canvas.setHighContrastText(false);
             int save = canvas.save();
             canvas.clipRect(1, 1, 199, 199);
             canvas.insertReorderBarrier();
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 489de56..2166f6e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -914,6 +914,14 @@
         return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
     }
 
+    /**
+     * Sets whether or not high contrast text rendering is enabled. The setting is global
+     * but only affects content rendered after the change is made.
+     */
+    public static void setHighContrastText(boolean highContrastText) {
+        nSetHighContrastText(highContrastText);
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -1063,4 +1071,5 @@
             int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
 
     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
+    private static native void nSetHighContrastText(boolean enabled);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2c41bf6..d640236 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18055,7 +18055,6 @@
             int layerType = getLayerType();
 
             final DisplayListCanvas canvas = renderNode.start(width, height);
-            canvas.setHighContrastText(mAttachInfo.mHighContrastText);
 
             try {
                 if (layerType == LAYER_TYPE_SOFTWARE) {
@@ -25365,11 +25364,6 @@
         boolean mViewScrollChanged;
 
         /**
-         * Set to true if high contrast mode enabled
-         */
-        boolean mHighContrastText;
-
-        /**
          * Set to true if a pointer event is currently being handled.
          */
         boolean mHandlingPointerEvent;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 22faeed..415aad5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -7749,11 +7749,11 @@
 
     final class HighContrastTextManager implements HighTextContrastChangeListener {
         HighContrastTextManager() {
-            mAttachInfo.mHighContrastText = mAccessibilityManager.isHighTextContrastEnabled();
+            ThreadedRenderer.setHighContrastText(mAccessibilityManager.isHighTextContrastEnabled());
         }
         @Override
         public void onHighTextContrastStateChanged(boolean enabled) {
-            mAttachInfo.mHighContrastText = enabled;
+            ThreadedRenderer.setHighContrastText(enabled);
 
             // Destroy Displaylists so they can be recreated with high contrast recordings
             destroyHardwareResources();
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index c3d5af8..fba0721 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -77,11 +77,6 @@
     return static_cast<jint>(get_canvas(canvasHandle)->height());
 }
 
-static void setHighContrastText(jlong canvasHandle, jboolean highContrastText) {
-    Canvas* canvas = get_canvas(canvasHandle);
-    canvas->setHighContrastText(highContrastText);
-}
-
 static jint save(jlong canvasHandle, jint flagsHandle) {
     SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
     return static_cast<jint>(get_canvas(canvasHandle)->save(flags));
@@ -588,7 +583,6 @@
     {"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
     {"nGetWidth","(J)I", (void*) CanvasJNI::getWidth},
     {"nGetHeight","(J)I", (void*) CanvasJNI::getHeight},
-    {"nSetHighContrastText","(JZ)V", (void*) CanvasJNI::setHighContrastText},
     {"nSave","(JI)I", (void*) CanvasJNI::save},
     {"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
     {"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index cc738f9..2f5b2e2 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -47,6 +47,7 @@
 #include <FrameInfo.h>
 #include <FrameMetricsObserver.h>
 #include <IContextFactory.h>
+#include <Properties.h>
 #include <PropertyValuesAnimatorSet.h>
 #include <RenderNode.h>
 #include <renderthread/CanvasContext.h>
@@ -931,6 +932,10 @@
     RenderProxy::disableVsync();
 }
 
+static void android_view_ThreadedRenderer_setHighContrastText(JNIEnv*, jclass, jboolean enable) {
+    Properties::enableHighContrastText = enable;
+}
+
 // ----------------------------------------------------------------------------
 // FrameMetricsObserver
 // ----------------------------------------------------------------------------
@@ -1030,6 +1035,7 @@
     { "nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
             (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode },
     { "disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync },
+    { "nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText },
 };
 
 int register_android_view_ThreadedRenderer(JNIEnv* env) {
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 0301f2e..f5e8633 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -200,11 +200,6 @@
     }
 
     /** @hide */
-    public void setHighContrastText(boolean highContrastText) {
-        nSetHighContrastText(mNativeCanvasWrapper, highContrastText);
-    }
-
-    /** @hide */
     public void insertReorderBarrier() {}
 
     /** @hide */
@@ -1242,8 +1237,6 @@
     @CriticalNative
     private static native boolean nIsOpaque(long canvasHandle);
     @CriticalNative
-    private static native void nSetHighContrastText(long renderer, boolean highContrastText);
-    @CriticalNative
     private static native int nGetWidth(long canvasHandle);
     @CriticalNative
     private static native int nGetHeight(long canvasHandle);
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index acc7539..fe291d2 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -51,6 +51,7 @@
 ProfileType Properties::sProfileType = ProfileType::None;
 bool Properties::sDisableProfileBars = false;
 RenderPipelineType Properties::sRenderPipelineType = RenderPipelineType::NotInitialized;
+bool Properties::enableHighContrastText = false;
 
 bool Properties::waitForGpuCompletion = false;
 bool Properties::forceDrawFrame = false;
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 47ae9e9..0fe4c77 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HWUI_PROPERTIES_H
 #define ANDROID_HWUI_PROPERTIES_H
 
+#include <cutils/compiler.h>
 #include <cutils/properties.h>
 
 /**
@@ -237,6 +238,8 @@
     static RenderPipelineType getRenderPipelineType();
     static bool isSkiaEnabled();
 
+    ANDROID_API static bool enableHighContrastText;
+
     // Should be used only by test apps
     static bool waitForGpuCompletion;
     static bool forceDrawFrame;
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index ccdb4b0..79db496 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -93,11 +93,6 @@
     virtual int width() override { return mState.getWidth(); }
     virtual int height() override { return mState.getHeight(); }
 
-    virtual void setHighContrastText(bool highContrastText) override {
-        mHighContrastText = highContrastText;
-    }
-    virtual bool isHighContrastText() override { return mHighContrastText; }
-
 // ----------------------------------------------------------------------------
 // android/graphics/Canvas state operations
 // ----------------------------------------------------------------------------
@@ -311,7 +306,6 @@
     DeferredBarrierType mDeferredBarrierType = DeferredBarrierType::None;
     const ClipBase* mDeferredBarrierClip = nullptr;
     DisplayList* mDisplayList = nullptr;
-    bool mHighContrastText = false;
     sk_sp<SkDrawFilter> mDrawFilter;
 }; // class RecordingCanvas
 
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index eb844cb..1f5f733 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -85,7 +85,6 @@
         mCanvasWrapper.reset();
     }
     mSaveStack.reset(nullptr);
-    mHighContrastText = false;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 6a01f96..e17f835 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -65,11 +65,6 @@
     virtual int width() override;
     virtual int height() override;
 
-    virtual void setHighContrastText(bool highContrastText) override {
-        mHighContrastText = highContrastText;
-    }
-    virtual bool isHighContrastText() override { return mHighContrastText; }
-
     virtual int getSaveCount() const override;
     virtual int save(SaveFlags::Flags flags) override;
     virtual void restore() override;
@@ -166,8 +161,6 @@
         size_t           clipIndex;
     };
 
-    bool mHighContrastText = false;
-
     const SaveRec* currentSaveRec() const;
     void recordPartialSave(SaveFlags::Flags flags);
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 0b8155c..fbd8960 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -20,6 +20,7 @@
 #include <utils/Functor.h>
 
 #include "GlFunctorLifecycleListener.h"
+#include "Properties.h"
 #include "utils/Macros.h"
 #include <androidfw/ResourceTypes.h>
 
@@ -140,8 +141,7 @@
     virtual uirenderer::DisplayList* finishRecording() = 0;
     virtual void insertReorderBarrier(bool enableReorder) = 0;
 
-    virtual void setHighContrastText(bool highContrastText) = 0;
-    virtual bool isHighContrastText() = 0;
+    bool isHighContrastText() const { return uirenderer::Properties::enableHighContrastText; }
 
     virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
             uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index f166c5c..3089447 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -171,7 +171,6 @@
 
     while (benchState.KeepRunning()) {
         canvas->resetRecording(200, 200);
-        canvas->setHighContrastText(false);
         canvas->translate(0, 0); // mScrollX, mScrollY
 
         // Clip to padding
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index d36bca0..c4e4195 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -822,8 +822,8 @@
 }
 
 OPENGL_PIPELINE_TEST(RecordingCanvas, drawTextInHighContrast) {
+    Properties::enableHighContrastText = true;
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.setHighContrastText(true);
         Paint paint;
         paint.setColor(SK_ColorWHITE);
         paint.setAntiAlias(true);
@@ -832,6 +832,7 @@
         std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO");
         canvas.drawText(dst.get(), 0, 5, 5, 25, 25, minikin::kBidi_Force_LTR, paint, NULL);
     });
+    Properties::enableHighContrastText = false;
 
     int count = 0;
     playbackOps(*dl, [&count](const RecordedOp& op) {