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;