Move drawRegion from DisplayList to Canvas
Change-Id: I9f401dc5b24732938ac2ca7ed829796e2d7ef3e8
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index a68a193..ac98fa9 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -278,18 +278,4 @@
private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
long propRight, long propBottom, long propRx, long propRy, long propPaint);
-
- // TODO: move this optimization to Canvas.java
- @Override
- public void drawPath(Path path, Paint paint) {
- if (path.isSimplePath) {
- if (path.rects != null) {
- nDrawRects(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
- }
- } else {
- super.drawPath(path, paint);
- }
- }
-
- private static native void nDrawRects(long renderer, long region, long paint);
}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 2116da0..1f01453 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -255,6 +255,13 @@
get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
}
+static void drawRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong regionHandle,
+ jlong paintHandle) {
+ const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+ get_canvas(canvasHandle)->drawRegion(*region, *paint);
+}
+
static void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) {
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
@@ -698,6 +705,7 @@
{"native_drawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
{"native_drawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
{"native_drawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
+ {"native_drawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
{"native_drawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
{"native_drawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
{"native_drawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 71d509c..2c0e790 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -124,36 +124,6 @@
renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
}
-static void android_view_DisplayListCanvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
- SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- if (paint->getStyle() != Paint::kFill_Style ||
- (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
- SkRegion::Iterator it(*region);
- while (!it.done()) {
- const SkIRect& r = it.rect();
- renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, *paint);
- it.next();
- }
- } else {
- int count = 0;
- Vector<float> rects;
- SkRegion::Iterator it(*region);
- while (!it.done()) {
- const SkIRect& r = it.rect();
- rects.push(r.fLeft);
- rects.push(r.fTop);
- rects.push(r.fRight);
- rects.push(r.fBottom);
- count += 4;
- it.next();
- }
- renderer->drawRects(rects.array(), count, paint);
- }
-}
-
// ----------------------------------------------------------------------------
// Display lists
// ----------------------------------------------------------------------------
@@ -235,7 +205,6 @@
{ "nDrawPatch", "(JLandroid/graphics/Bitmap;JFFFFJ)V", (void*) android_view_DisplayListCanvas_drawPatch },
- { "nDrawRects", "(JJJ)V", (void*) android_view_DisplayListCanvas_drawRegionAsRects },
{ "nDrawRoundRect", "(JJJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRoundRectProps },
{ "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 30627bb..73caf68 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1248,7 +1248,11 @@
* @param paint The paint used to draw the path
*/
public void drawPath(@NonNull Path path, @NonNull Paint paint) {
- native_drawPath(mNativeCanvasWrapper, path.ni(), paint.getNativeInstance());
+ if (path.isSimplePath && path.rects != null) {
+ native_drawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
+ } else {
+ native_drawPath(mNativeCanvasWrapper, path.ni(), paint.getNativeInstance());
+ }
}
/**
@@ -2053,6 +2057,8 @@
private static native void native_drawPath(long nativeCanvas,
long nativePath,
long nativePaint);
+ private static native void native_drawRegion(long nativeCanvas,
+ long nativeRegion, long nativePaint);
private native void native_drawBitmap(long nativeCanvas, Bitmap bitmap,
float left, float top,
long nativePaintOrZero,
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 160d9a8..116bc56 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -118,6 +118,7 @@
virtual void drawLines(const float* points, int count, const SkPaint& paint) = 0;
virtual void drawRect(float left, float top, float right, float bottom,
const SkPaint& paint) = 0;
+ virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0;
virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint& paint) = 0;
virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0;
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index b96e555..af18e03 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -486,6 +486,32 @@
}
}
+void DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
+ if (paint.getStyle() != SkPaint::kFill_Style ||
+ (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) {
+ SkRegion::Iterator it(region);
+ while (!it.done()) {
+ const SkIRect& r = it.rect();
+ drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
+ it.next();
+ }
+ } else {
+ int count = 0;
+ Vector<float> rects;
+ SkRegion::Iterator it(region);
+ while (!it.done()) {
+ const SkIRect& r = it.rect();
+ rects.push(r.fLeft);
+ rects.push(r.fTop);
+ rects.push(r.fRight);
+ rects.push(r.fBottom);
+ count += 4;
+ it.next();
+ }
+ drawRects(rects.array(), count, &paint);
+ }
+}
+
void DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) {
if (count <= 0) return;
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 04a65e3..6f2e2b5 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -75,24 +75,15 @@
void insertReorderBarrier(bool enableReorder);
- const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
-
- bool isCurrentTransformSimple() {
- return mState.currentTransform()->isSimple();
- }
-
// ----------------------------------------------------------------------------
// HWUI Canvas draw operations
// ----------------------------------------------------------------------------
- // Bitmap-based
- void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
// TODO: move drawPatch() to Canvas.h
void drawPatch(const SkBitmap& bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint);
// Shapes
- void drawRects(const float* rects, int count, const SkPaint* paint);
void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
@@ -195,6 +186,7 @@
}
virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
+ virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint& paint) override;
virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
@@ -239,6 +231,9 @@
kBarrier_OutOfOrder,
};
+ void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
+ void drawRects(const float* rects, int count, const SkPaint* paint);
+
void flushRestoreToCount();
void flushTranslate();
void flushReorderBarrier();
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 644a4f3..971b53a 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -95,6 +95,7 @@
virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
virtual void drawRect(float left, float top, float right, float bottom,
const SkPaint& paint) override;
+ virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint& paint) override;
virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
@@ -507,6 +508,14 @@
}
+void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
+ SkRegion::Iterator it(region);
+ while (!it.done()) {
+ mCanvas->drawRect(SkRect::Make(it.rect()), paint);
+ it.next();
+ }
+}
+
void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint& paint) {
SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 64d9037..a224376 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -230,21 +230,19 @@
DisplayListCanvas* renderer = startRecording(node.get());
renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode);
+ SkRegion region;
float rects[width * height];
int index = 0;
for (int xOffset = 0; xOffset < width; xOffset+=2) {
for (int yOffset = 0; yOffset < height; yOffset+=2) {
- rects[index++] = xOffset;
- rects[index++] = yOffset;
- rects[index++] = xOffset + 1;
- rects[index++] = yOffset + 1;
+ region.op(xOffset, yOffset, xOffset + 1, yOffset + 1, SkRegion::kUnion_Op);
}
}
int count = width * height;
SkPaint paint;
paint.setColor(0xff00ffff);
- renderer->drawRects(rects, count, &paint);
+ renderer->drawRegion(region, paint);
endRecording(renderer, node.get());
return node;