From cf8675ee176a375f873792684d38a47f78348dff Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 2 Oct 2012 12:32:25 -0700 Subject: Draw stroked rectangle as meshes instead of textures Bug #7233734 Stroked rectangles were rendered using software generated textures which would lead to slightly misaligned results. Instead, let's use the new convex path rendering code that will do the right thing (and save a lot of bandwidth.) Change-Id: Ib95ff581e56c1ecead97e4919298e6fd146ca167 --- .../graphics/drawable/GradientDrawable.java | 10 ++++++++- libs/hwui/OpenGLRenderer.cpp | 25 ++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 2ca54d4..22aa29c 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -513,7 +513,10 @@ public class GradientDrawable extends Drawable { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } } else { - canvas.drawRect(mRect, mFillPaint); + if (mFillPaint.getColor() != 0 || mColorFilter != null || + mFillPaint.getShader() != null) { + canvas.drawRect(mRect, mFillPaint); + } if (haveStroke) { canvas.drawRect(mRect, mStrokePaint); } @@ -1251,6 +1254,11 @@ public class GradientDrawable extends Drawable { private void initializeWithState(GradientState state) { if (state.mHasSolidColor) { mFillPaint.setColor(state.mSolidColor); + } else if (state.mColors == null) { + // If we don't have a solid color and we don't have a gradient, + // the app is stroking the shape, set the color to the default + // value of state.mSolidColor + mFillPaint.setColor(0); } mPadding = state.mPadding; if (state.mStrokeWidth >= 0) { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index c2e6ee3..7c23e4b 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -2440,16 +2440,33 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto return drawShape(left, top, texture, paint); } +// See SkPaintDefaults.h +#define SkPaintDefaults_MiterLimit SkIntToScalar(4) + status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) { if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) { return DrawGlInfo::kStatusDone; } - // only fill style is supported by drawConvexPath, since others have to handle joins if (p->getStyle() != SkPaint::kFill_Style) { - mCaches.activeTexture(0); - const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, p); - return drawShape(left, top, texture, p); + // only fill style is supported by drawConvexPath, since others have to handle joins + if (p->getPathEffect() != 0 || p->getStrokeJoin() != SkPaint::kMiter_Join || + p->getStrokeMiter() != SkPaintDefaults_MiterLimit) { + mCaches.activeTexture(0); + const PathTexture* texture = + mCaches.rectShapeCache.getRect(right - left, bottom - top, p); + return drawShape(left, top, texture, p); + } + + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addRect(rect); + drawConvexPath(path, p); + + return DrawGlInfo::kStatusDrew; } if (p->isAntiAlias() && !mSnapshot->transform->isSimple()) { -- cgit v1.1