Merge "hwui: send TextureView hint to SF" into udc-dev am: 444e936bf5 am: 99c0540dd0

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23117498

Change-Id: I3df164961422747fe04151ef9cbde289f19adcac
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 15e0cce..bdd0a9c 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -206,6 +206,7 @@
      */
     public TextureView(@NonNull Context context) {
         super(context);
+        mRenderNode.setIsTextureView();
     }
 
     /**
@@ -216,6 +217,7 @@
      */
     public TextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
+        mRenderNode.setIsTextureView();
     }
 
     /**
@@ -229,6 +231,7 @@
      */
     public TextureView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        mRenderNode.setIsTextureView();
     }
 
     /**
@@ -247,6 +250,7 @@
     public TextureView(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        mRenderNode.setIsTextureView();
     }
 
     /**
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index dadbd8d..2e91c24 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -1561,6 +1561,16 @@
         return nGetUniqueId(mNativeRenderNode);
     }
 
+    /**
+     * Captures whether this RenderNote represents a TextureView
+     * TODO(b/281695725): Clean this up once TextureView use setFrameRate API
+     *
+     * @hide
+     */
+    public void setIsTextureView() {
+        nSetIsTextureView(mNativeRenderNode);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Animations
     ///////////////////////////////////////////////////////////////////////////
@@ -1891,4 +1901,7 @@
 
     @CriticalNative
     private static native long nGetUniqueId(long renderNode);
+
+    @CriticalNative
+    private static native void nSetIsTextureView(long renderNode);
 }
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index b348a6e..1c39db3 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -152,6 +152,9 @@
             // TODO: Get this from the display list ops or something
             info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
         }
+        if (!mIsTextureView) {
+            info.out.solelyTextureViewUpdates = false;
+        }
     }
 }
 
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index bdc48e9..d1e04ad 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -221,6 +221,8 @@
 
     int64_t uniqueId() const { return mUniqueId; }
 
+    void setIsTextureView() { mIsTextureView = true; }
+
     void markDrawStart(SkCanvas& canvas);
     void markDrawEnd(SkCanvas& canvas);
 
@@ -290,6 +292,8 @@
     bool mHasHolePunches;
     StretchMask mStretchMask;
 
+    bool mIsTextureView = false;
+
     // METHODS & FIELDS ONLY USED BY THE SKIA RENDERER
 public:
     /**
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 6b8f439..2bff9cb 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -123,6 +123,10 @@
         // This is used to post a message to redraw when it is time to draw the
         // next frame of an AnimatedImageDrawable.
         nsecs_t animatedImageDelay = kNoAnimatedImageDelay;
+        // This is used to determine if there were only TextureView updates in this frame.
+        // This info is passed to SurfaceFlinger to determine whether it should use vsyncIds
+        // for refresh rate selection.
+        bool solelyTextureViewUpdates = true;
     } out;
 
     // This flag helps to disable projection for receiver nodes that do not have any backward
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 24a785c..8c7b9a4 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -526,6 +526,11 @@
     return reinterpret_cast<RenderNode*>(renderNodePtr)->uniqueId();
 }
 
+static void android_view_RenderNode_setIsTextureView(
+        CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
+    reinterpret_cast<RenderNode*>(renderNodePtr)->setIsTextureView();
+}
+
 // ----------------------------------------------------------------------------
 // RenderProperties - Animations
 // ----------------------------------------------------------------------------
@@ -844,6 +849,7 @@
         {"nSetAllowForceDark", "(JZ)Z", (void*)android_view_RenderNode_setAllowForceDark},
         {"nGetAllowForceDark", "(J)Z", (void*)android_view_RenderNode_getAllowForceDark},
         {"nGetUniqueId", "(J)J", (void*)android_view_RenderNode_getUniqueId},
+        {"nSetIsTextureView", "(J)V", (void*)android_view_RenderNode_setIsTextureView},
 };
 
 int register_android_view_RenderNode(JNIEnv* env) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f60c1f3..2bd400d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -531,7 +531,7 @@
     }
 }
 
-void CanvasContext::draw() {
+void CanvasContext::draw(bool solelyTextureViewUpdates) {
     if (auto grContext = getGrContext()) {
         if (grContext->abandoned()) {
             LOG_ALWAYS_FATAL("GrContext is abandoned/device lost at start of CanvasContext::draw");
@@ -604,7 +604,8 @@
                     static_cast<int32_t>(mCurrentFrameInfo->get(FrameInfoIndex::InputEventId));
             native_window_set_frame_timeline_info(
                     mNativeSurface->getNativeWindow(), frameCompleteNr, vsyncId, inputEventId,
-                    mCurrentFrameInfo->get(FrameInfoIndex::FrameStartTime));
+                    mCurrentFrameInfo->get(FrameInfoIndex::FrameStartTime),
+                    solelyTextureViewUpdates);
         }
     }
 
@@ -885,7 +886,7 @@
     TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
     prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
     if (info.out.canDrawThisFrame) {
-        draw();
+        draw(info.out.solelyTextureViewUpdates);
     } else {
         // wait on fences so tasks don't overlap next frame
         waitOnFences();
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index d7215de..08e2424 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -143,7 +143,7 @@
     bool makeCurrent();
     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued, RenderNode* target);
     // Returns the DequeueBufferDuration.
-    void draw();
+    void draw(bool solelyTextureViewUpdates);
     void destroy();
 
     // IFrameCallback, Choreographer-driven frame callback entry point
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index fab2f46..53b43ba 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -98,12 +98,14 @@
     IRenderPipeline* pipeline = mContext->getRenderPipeline();
     bool canUnblockUiThread;
     bool canDrawThisFrame;
+    bool solelyTextureViewUpdates;
     {
         TreeInfo info(TreeInfo::MODE_FULL, *mContext);
         info.forceDrawFrame = mForceDrawFrame;
         mForceDrawFrame = false;
         canUnblockUiThread = syncFrameState(info);
         canDrawThisFrame = info.out.canDrawThisFrame;
+        solelyTextureViewUpdates = info.out.solelyTextureViewUpdates;
 
         if (mFrameCommitCallback) {
             mContext->addFrameCommitListener(std::move(mFrameCommitCallback));
@@ -136,7 +138,7 @@
     }
 
     if (CC_LIKELY(canDrawThisFrame)) {
-        context->draw();
+        context->draw(solelyTextureViewUpdates);
     } else {
         // Do a flush in case syncFrameState performed any texture uploads. Since we skipped
         // the draw() call, those uploads (or deletes) will end up sitting in the queue.
@@ -179,6 +181,7 @@
             mLayers[i]->apply();
         }
     }
+
     mLayers.clear();
     mContext->setContentDrawBounds(mContentDrawBounds);
     mContext->prepareTree(info, mFrameInfo, mSyncQueued, mTargetNode);