Take shadow bounds into account for quick rejects
Bug #8634346

Change-Id: I995c5205c2959d8e4da638ae47fedcda92eb1b36
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 1b52b65..42e11d0 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -249,11 +249,16 @@
     }
 
     // default empty constructor for bounds, to be overridden in child constructor body
-    DrawBoundedOp(SkPaint* paint)
-            : DrawOp(paint) {}
+    DrawBoundedOp(SkPaint* paint): DrawOp(paint) { }
 
     bool getLocalBounds(Rect& localBounds) {
         localBounds.set(mLocalBounds);
+        if (state.mDrawModifiers.mHasShadow) {
+            Rect shadow(mLocalBounds);
+            shadow.translate(state.mDrawModifiers.mShadowDx, state.mDrawModifiers.mShadowDy);
+            shadow.outset(state.mDrawModifiers.mShadowRadius);
+            localBounds.unionWith(shadow);
+        }
         return true;
     }
 
@@ -1442,8 +1447,10 @@
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+        Rect bounds;
+        getLocalBounds(bounds);
         return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
-                mPositions, getPaint(renderer), mTotalAdvance, mLocalBounds);
+                mPositions, getPaint(renderer), mTotalAdvance, bounds);
     }
 
     virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
@@ -1454,6 +1461,8 @@
             renderer.restoreDisplayState(ops[i]->state, true); // restore all but the clip
 
             DrawTextOp& op = *((DrawTextOp*)ops[i]);
+            // quickReject() will not occure in drawText() so we can use mLocalBounds
+            // directly, we do not need to account for shadow by calling getLocalBounds()
             status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
                     op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds,
                     drawOpMode);
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ba4c2a0..90dcf93 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -464,10 +464,12 @@
 
 void DisplayListRenderer::resetShadow() {
     addStateOp(new (alloc()) ResetShadowOp());
+    OpenGLRenderer::resetShadow();
 }
 
 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
     addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
+    OpenGLRenderer::setupShadow(radius, dx, dy, color);
 }
 
 void DisplayListRenderer::resetPaintFilter() {
@@ -503,11 +505,17 @@
 
 void DisplayListRenderer::addDrawOp(DrawOp* op) {
     Rect localBounds;
+    if (mDrawModifiers.mHasShadow) {
+        op->state.mDrawModifiers = mDrawModifiers;
+    }
     if (op->getLocalBounds(localBounds)) {
         bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
                 localBounds.right, localBounds.bottom);
         op->setQuickRejected(rejected);
     }
+    if (mDrawModifiers.mHasShadow) {
+        op->state.mDrawModifiers.reset();
+    }
     mHasDrawOps = true;
     addOpInternal(op);
 }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 1c3bfdc..54f6d76 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -52,6 +52,14 @@
 namespace uirenderer {
 
 struct DrawModifiers {
+    DrawModifiers() {
+        reset();
+    }
+
+    void reset() {
+        memset(this, 0, sizeof(DrawModifiers));
+    }
+
     SkiaShader* mShader;
     SkiaColorFilter* mColorFilter;
     float mOverrideLayerAlpha;