diff options
author | 2011-01-23 14:18:41 -0800 | |
---|---|---|
committer | 2011-01-23 14:18:41 -0800 | |
commit | c1cd9ba335b293f11e1082447ef08e474710a05f (patch) | |
tree | 3f07bf1887e0cd5602c2f1e356e3efe92d7f766b | |
parent | f6834478b379856d3e5de92ddce7de0e6ba9fa4a (diff) |
Add support for ovals and stroked rectangles.
Change-Id: I1292e241386763c82e6622c8f7ed90b0f5b7bd4f
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 17 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 2 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 12 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 46 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 4 | ||||
-rw-r--r-- | libs/hwui/ShapeCache.cpp | 46 | ||||
-rw-r--r-- | libs/hwui/ShapeCache.h | 80 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java | 25 |
10 files changed, 220 insertions, 21 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index e47dc93db4a3..936e9d2413f2 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -525,7 +525,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) { - throw new UnsupportedOperationException(); + // TODO: Implement } @Override @@ -705,9 +705,14 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawOval(RectF oval, Paint paint) { - throw new UnsupportedOperationException(); + boolean hasModifier = setupModifiers(paint); + nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint); + if (hasModifier) nResetModifiers(mRenderer); } + private native void nDrawOval(int renderer, float left, float top, float right, float bottom, + int paint); + @Override public void drawPaint(Paint paint) { final Rect r = mClipBounds; @@ -765,12 +770,12 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { - throw new UnsupportedOperationException(); + // TODO: Implement } @Override public void drawPosText(String text, float[] pos, Paint paint) { - throw new UnsupportedOperationException(); + // TODO: Implement } @Override @@ -879,12 +884,12 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) { - throw new UnsupportedOperationException(); + // TODO: Implement } @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { - throw new UnsupportedOperationException(); + // TODO: Implement } @Override diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 554e336f8f0a..2daffbb47416 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -326,6 +326,12 @@ static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas, renderer->drawCircle(x, y, radius, paint); } +static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, + SkPaint* paint) { + renderer->drawOval(left, top, right, bottom, paint); +} + static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) { SkRegion::Iterator it(*region); @@ -602,6 +608,7 @@ static JNINativeMethod gMethods[] = { { "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects }, { "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect }, { "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle }, + { "nDrawOval", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawOval }, { "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath }, { "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines }, diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 24585d5a14e9..3bac422015c5 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -162,6 +162,8 @@ public: PathCache pathCache; RoundRectShapeCache roundRectShapeCache; CircleShapeCache circleShapeCache; + OvalShapeCache ovalShapeCache; + RectShapeCache rectShapeCache; PatchCache patchCache; TextDropShadowCache dropShadowCache; FboCache fboCache; diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 58ef7b3a1689..871499703667 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -107,6 +107,7 @@ const char* DisplayList::OP_NAMES[] = { "DrawRect", "DrawRoundRect", "DrawCircle", + "DrawOval", "DrawPath", "DrawLines", "DrawText", @@ -358,6 +359,10 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) { renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint()); } break; + case DrawOval: { + renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); + } + break; case DrawPath: { renderer.drawPath(getPath(), getPaint()); } @@ -663,6 +668,13 @@ void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* pa addPaint(paint); } +void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, + SkPaint* paint) { + addOp(DisplayList::DrawOval); + addBounds(left, top, right, bottom); + addPaint(paint); +} + void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { addOp(DisplayList::DrawPath); addPath(path); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 68e4359ee90c..8183e253b452 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -113,6 +113,7 @@ public: DrawRect, DrawRoundRect, DrawCircle, + DrawOval, DrawPath, DrawLines, DrawText, @@ -279,6 +280,7 @@ public: void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint); void drawCircle(float x, float y, float radius, SkPaint* paint); + void drawOval(float left, float top, float right, float bottom, SkPaint* paint); void drawPath(SkPath* path, SkPaint* paint); void drawLines(float* points, int count, SkPaint* paint); void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 9aa3e7cffc61..99c0600ae3eb 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1360,14 +1360,7 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true); } -void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, - float rx, float ry, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; - - glActiveTexture(gTextureUnits[0]); - - const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect( - right - left, bottom - top, rx, ry, paint); +void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, SkPaint* paint) { if (!texture) return; const AutoTexture autoCleanup(texture); @@ -1377,22 +1370,47 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot drawPathTexture(texture, x, y, paint); } -void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { +void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, SkPaint* paint) { if (mSnapshot->isIgnored()) return; glActiveTexture(gTextureUnits[0]); + const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect( + right - left, bottom - top, rx, ry, paint); + drawShape(left, top, texture, paint); +} +void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { + if (mSnapshot->isIgnored()) return; + + glActiveTexture(gTextureUnits[0]); const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint); - if (!texture) return; - const AutoTexture autoCleanup(texture); + drawShape(x - radius, y - radius, texture, paint); +} - const float left = (x - radius) + texture->left - texture->offset; - const float top = (y - radius) + texture->top - texture->offset; +void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { + if (mSnapshot->isIgnored()) return; - drawPathTexture(texture, left, top, paint); + glActiveTexture(gTextureUnits[0]); + const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint); + drawShape(left, top, texture, paint); +} + +void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom, + SkPaint* paint) { + if (mSnapshot->isIgnored()) return; + + glActiveTexture(gTextureUnits[0]); + const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint); + drawShape(left, top, texture, paint); } void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) { + if (p->getStyle() != SkPaint::kFill_Style) { + drawRectAsShape(left, top, right, bottom, p); + return; + } + if (quickReject(left, top, right, bottom)) { return; } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 42e93adfef22..30cf10224e9d 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -112,6 +112,7 @@ public: virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint); virtual void drawCircle(float x, float y, float radius, SkPaint* paint); + virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint); virtual void drawPath(SkPath* path, SkPaint* paint); virtual void drawLines(float* points, int count, SkPaint* paint); virtual void drawText(const char* text, int bytesCount, int count, float x, float y, @@ -277,6 +278,9 @@ private: void drawColorRect(float left, float top, float right, float bottom, int color, SkXfermode::Mode mode, bool ignoreTransform = false); + void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint); + void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p); + /** * Draws a textured rectangle with the specified texture. The specified coordinates * are transformed by the current snapshot's transform matrix. diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp index b78eecba5215..da86075602bc 100644 --- a/libs/hwui/ShapeCache.cpp +++ b/libs/hwui/ShapeCache.cpp @@ -68,5 +68,51 @@ PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) { return texture; } +/////////////////////////////////////////////////////////////////////////////// +// Ovals +/////////////////////////////////////////////////////////////////////////////// + +OvalShapeCache::OvalShapeCache(): ShapeCache<OvalShapeCacheEntry>( + "oval", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) { +} + +PathTexture* OvalShapeCache::getOval(float width, float height, SkPaint* paint) { + OvalShapeCacheEntry entry(width, height, paint); + PathTexture* texture = get(entry); + + if (!texture) { + SkPath path; + SkRect r; + r.set(0.0f, 0.0f, width, height); + path.addOval(r, SkPath::kCW_Direction); + + texture = addTexture(entry, &path, paint); + } + + return texture; +} + +/////////////////////////////////////////////////////////////////////////////// +// Rects +/////////////////////////////////////////////////////////////////////////////// + +RectShapeCache::RectShapeCache(): ShapeCache<RectShapeCacheEntry>( + "rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) { +} + +PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) { + RectShapeCacheEntry entry(width, height, paint); + PathTexture* texture = get(entry); + + if (!texture) { + SkPath path; + path.addRect(0.0f, 0.0f, width, height, SkPath::kCW_Direction); + + texture = addTexture(entry, &path, paint); + } + + return texture; +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h index c62793180838..a4aff9df117c 100644 --- a/libs/hwui/ShapeCache.h +++ b/libs/hwui/ShapeCache.h @@ -76,6 +76,7 @@ struct PathTexture: public Texture { struct ShapeCacheEntry { enum ShapeType { kShapeNone, + kShapeRect, kShapeRoundRect, kShapeCircle, kShapeOval, @@ -216,6 +217,70 @@ private: uint32_t mRadius; }; // CircleShapeCacheEntry +struct OvalShapeCacheEntry: public ShapeCacheEntry { + OvalShapeCacheEntry(float width, float height, SkPaint* paint): + ShapeCacheEntry(ShapeCacheEntry::kShapeOval, paint) { + mWidth = *(uint32_t*) &width; + mHeight = *(uint32_t*) &height; + } + + OvalShapeCacheEntry(): ShapeCacheEntry() { + mWidth = mHeight = 0; + } + + OvalShapeCacheEntry(const OvalShapeCacheEntry& entry): + ShapeCacheEntry(entry) { + mWidth = entry.mWidth; + mHeight = entry.mHeight; + } + + bool lessThan(const ShapeCacheEntry& r) const { + const OvalShapeCacheEntry& rhs = (const OvalShapeCacheEntry&) r; + LTE_INT(mWidth) { + LTE_INT(mHeight) { + return false; + } + } + return false; + } + +private: + uint32_t mWidth; + uint32_t mHeight; +}; // OvalShapeCacheEntry + +struct RectShapeCacheEntry: public ShapeCacheEntry { + RectShapeCacheEntry(float width, float height, SkPaint* paint): + ShapeCacheEntry(ShapeCacheEntry::kShapeRect, paint) { + mWidth = *(uint32_t*) &width; + mHeight = *(uint32_t*) &height; + } + + RectShapeCacheEntry(): ShapeCacheEntry() { + mWidth = mHeight = 0; + } + + RectShapeCacheEntry(const RectShapeCacheEntry& entry): + ShapeCacheEntry(entry) { + mWidth = entry.mWidth; + mHeight = entry.mHeight; + } + + bool lessThan(const ShapeCacheEntry& r) const { + const RectShapeCacheEntry& rhs = (const RectShapeCacheEntry&) r; + LTE_INT(mWidth) { + LTE_INT(mHeight) { + return false; + } + } + return false; + } + +private: + uint32_t mWidth; + uint32_t mHeight; +}; // RectShapeCacheEntry + /** * A simple LRU shape cache. The cache has a maximum size expressed in bytes. * Any texture added to the cache causing the cache to grow beyond the maximum @@ -289,8 +354,21 @@ public: CircleShapeCache(); PathTexture* getCircle(float radius, SkPaint* paint); -}; // class RoundRectShapeCache +}; // class CircleShapeCache + +class OvalShapeCache: public ShapeCache<OvalShapeCacheEntry> { +public: + OvalShapeCache(); + + PathTexture* getOval(float width, float height, SkPaint* paint); +}; // class OvalShapeCache + +class RectShapeCache: public ShapeCache<RectShapeCacheEntry> { +public: + RectShapeCache(); + PathTexture* getRect(float width, float height, SkPaint* paint); +}; // class RectShapeCache /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java index 536a669cba19..ddf43d77739e 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java @@ -38,6 +38,7 @@ public class ShapesActivity extends Activity { private Paint mStrokePaint; private Paint mFillPaint; private RectF mRect; + private RectF mOval; ShapesView(Context c) { super(c); @@ -60,6 +61,8 @@ public class ShapesActivity extends Activity { mFillPaint.setAntiAlias(true); mFillPaint.setColor(0xff0000ff); mFillPaint.setStyle(Paint.Style.FILL); + + mOval = new RectF(0.0f, 0.0f, 80.0f, 45.0f); } @Override @@ -87,6 +90,28 @@ public class ShapesActivity extends Activity { canvas.translate(0.0f, 110.0f); canvas.drawCircle(80.0f, 45.0f, 45.0f, mFillPaint); canvas.restore(); + + canvas.save(); + canvas.translate(450.0f, 50.0f); + canvas.drawOval(mOval, mNormalPaint); + + canvas.translate(0.0f, 110.0f); + canvas.drawOval(mOval, mStrokePaint); + + canvas.translate(0.0f, 110.0f); + canvas.drawOval(mOval, mFillPaint); + canvas.restore(); + + canvas.save(); + canvas.translate(650.0f, 50.0f); + canvas.drawRect(0.0f, 0.0f, 160.0f, 90.0f, mNormalPaint); + + canvas.translate(0.0f, 110.0f); + canvas.drawRect(0.0f, 0.0f, 160.0f, 90.0f, mStrokePaint); + + canvas.translate(0.0f, 110.0f); + canvas.drawRect(0.0f, 0.0f, 160.0f, 90.0f, mFillPaint); + canvas.restore(); } } } |