Don't use the QCOM_tiled_rendering extension with functors
Bug #7247880

Change-Id: I4f6c38e37b953c58e6107097c613891a49dac766
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f0f72f9..442c4fb 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -86,6 +86,8 @@
     lastDstMode = GL_ZERO;
     currentProgram = NULL;
 
+    mFunctorsCount = 0;
+
     mInitialized = true;
 }
 
@@ -454,6 +456,22 @@
     }
 }
 
+bool Caches::hasRegisteredFunctors() {
+    return mFunctorsCount > 0;
+}
+
+void Caches::registerFunctors(uint32_t functorCount) {
+    mFunctorsCount += functorCount;
+}
+
+void Caches::unregisterFunctors(uint32_t functorCount) {
+    if (functorCount > mFunctorsCount) {
+        mFunctorsCount = 0;
+    } else {
+        mFunctorsCount -= functorCount;
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Regions
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 48efd10..ac012cf 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -227,6 +227,10 @@
     void dumpMemoryUsage();
     void dumpMemoryUsage(String8& log);
 
+    bool hasRegisteredFunctors();
+    void registerFunctors(uint32_t functorCount);
+    void unregisterFunctors(uint32_t functorCount);
+
     bool blend;
     GLenum lastSrcMode;
     GLenum lastDstMode;
@@ -316,6 +320,8 @@
 
     DebugLevel mDebugLevel;
     bool mInitialized;
+
+    uint32_t mFunctorsCount;
 }; // class Caches
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index cc72df6..6aff8d4 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -157,6 +157,7 @@
     mAnimationMatrix = NULL;
 
     Caches& caches = Caches::getInstance();
+    caches.unregisterFunctors(mFunctorCount);
     caches.resourceCache.lock();
 
     for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -218,6 +219,7 @@
     init();
 
     if (writer.size() == 0) {
+        mFunctorCount = 0;
         return;
     }
 
@@ -232,7 +234,10 @@
     writer.flatten(buffer);
     mReader.setMemory(buffer, mSize);
 
+    mFunctorCount = recorder.getFunctorCount();
+
     Caches& caches = Caches::getInstance();
+    caches.registerFunctors(mFunctorCount);
     caches.resourceCache.lock();
 
     const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
@@ -1340,7 +1345,8 @@
 
 DisplayListRenderer::DisplayListRenderer():
         mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
-        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
+        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
+        mHasDrawOps(false), mFunctorCount(0) {
 }
 
 DisplayListRenderer::~DisplayListRenderer() {
@@ -1397,6 +1403,7 @@
     mLayers.clear();
 
     mHasDrawOps = false;
+    mFunctorCount = 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1453,6 +1460,7 @@
     // Ignore dirty during recording, it matters only when we replay
     addOp(DisplayList::DrawGLFunction);
     addInt((int) functor);
+    mFunctorCount++;
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index a0b1630..39061f4 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -503,6 +503,7 @@
     size_t mSize;
 
     bool mIsRenderable;
+    uint32_t mFunctorCount;
 
     String8 mName;
 
@@ -661,6 +662,10 @@
         return mMatrices;
     }
 
+    uint32_t getFunctorCount() const {
+        return mFunctorCount;
+    }
+
 private:
     void insertRestoreToCount() {
         if (mRestoreSaveCount >= 0) {
@@ -887,6 +892,8 @@
     bool mHasTranslate;
     bool mHasDrawOps;
 
+    uint32_t mFunctorCount;
+
     friend class DisplayList;
 
 }; // class DisplayListRenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 87c3a47..e1a5132 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -193,6 +193,11 @@
 
     syncState();
 
+    // Functors break the tiling extension in pretty spectacular ways
+    // This ensures we don't use tiling when a functor is going to be
+    // invoked during the frame
+    mSuppressTiling = mCaches.hasRegisteredFunctors();
+
     mTilingSnapshot = mSnapshot;
     startTiling(mTilingSnapshot, true);
 
@@ -221,17 +226,19 @@
 }
 
 void OpenGLRenderer::startTiling(const sp<Snapshot>& s, bool opaque) {
-    Rect* clip = mTilingSnapshot->clipRect;
-    if (s->flags & Snapshot::kFlagIsFboLayer) {
-        clip = s->clipRect;
-    }
+    if (!mSuppressTiling) {
+        Rect* clip = mTilingSnapshot->clipRect;
+        if (s->flags & Snapshot::kFlagIsFboLayer) {
+            clip = s->clipRect;
+        }
 
-    mCaches.startTiling(clip->left, s->height - clip->bottom,
-            clip->right - clip->left, clip->bottom - clip->top, opaque);
+        mCaches.startTiling(clip->left, s->height - clip->bottom,
+                clip->right - clip->left, clip->bottom - clip->top, opaque);
+    }
 }
 
 void OpenGLRenderer::endTiling() {
-    mCaches.endTiling();
+    if (!mSuppressTiling) mCaches.endTiling();
 }
 
 void OpenGLRenderer::finish() {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index c29e3fb..f325deb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -814,6 +814,9 @@
     // Properties.h
     bool mScissorOptimizationDisabled;
 
+    // No-ops start/endTiling when set
+    bool mSuppressTiling;
+
     friend class DisplayListRenderer;
 
 }; // class OpenGLRenderer