diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 1b52b65457c7d..42e11d0094280 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -249,11 +249,16 @@ public: } // 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 @@ public: } 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 @@ public: 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 ba4c2a0adcc90..90dcf931945e0 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -464,10 +464,12 @@ void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 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::addStateOp(StateOp* op) { 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 1c3bfdc23b063..54f6d76aa5f5a 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -52,6 +52,14 @@ namespace android { namespace uirenderer { struct DrawModifiers { + DrawModifiers() { + reset(); + } + + void reset() { + memset(this, 0, sizeof(DrawModifiers)); + } + SkiaShader* mShader; SkiaColorFilter* mColorFilter; float mOverrideLayerAlpha;