From 486590963e2207d68eebd6944fec70d50d41116a Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Thu, 31 May 2012 15:21:51 -0700 Subject: [PATCH] Skip eglSwapBuffers() call when we do not draw to GL The fix is to track when we issue GL drawing commands, and to skip the call to eglSwapBuffers() when a DisplayList does not result in any actual rendering calls to GL. Issue #6364143 QuickMuni list items and buttons flicker instead of fade Change-Id: I60a02c61a58c32d92481a1e814b4c8a49c6a37a3 --- core/java/android/view/DisplayList.java | 7 + core/java/android/view/HardwareRenderer.java | 32 ++-- include/private/hwui/DrawGlInfo.h | 9 +- libs/hwui/DisplayListRenderer.cpp | 115 ++++++++------ libs/hwui/DisplayListRenderer.h | 40 ++--- libs/hwui/OpenGLRenderer.cpp | 152 +++++++++++-------- libs/hwui/OpenGLRenderer.h | 42 ++--- 7 files changed, 235 insertions(+), 162 deletions(-) diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index da666b5ecadb8..a42e15677c39d 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -61,6 +61,13 @@ public abstract class DisplayList { */ public static final int STATUS_INVOKE = 0x2; + /** + * Indicates that the display list performed GL drawing operations. + * + * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) + */ + public static final int STATUS_DREW = 0x4; + /** * Starts recording the display list. All operations performed on the * returned canvas are recorded and stored in this display list. diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index f986d15144f21..931b5e6e15e9c 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1102,6 +1102,7 @@ boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callba onPreDraw(dirty); + int status = DisplayList.STATUS_DONE; int saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); @@ -1135,7 +1136,7 @@ boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callba drawDisplayListStartTime = System.nanoTime(); } - int status = canvas.drawDisplayList(displayList, mRedrawClip, + status = canvas.drawDisplayList(displayList, mRedrawClip, DisplayList.FLAG_CLIP_CHILDREN); if (mProfileEnabled) { @@ -1171,22 +1172,25 @@ boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callba onPostDraw(); attachInfo.mIgnoreDirtyState = false; + + if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) { - long eglSwapBuffersStartTime = 0; - if (mProfileEnabled) { - eglSwapBuffersStartTime = System.nanoTime(); - } - - sEgl.eglSwapBuffers(sEglDisplay, mEglSurface); - - if (mProfileEnabled) { - long now = System.nanoTime(); - float total = (now - eglSwapBuffersStartTime) * 0.000001f; - mProfileData[mProfileCurrentFrame + 2] = total; + long eglSwapBuffersStartTime = 0; + if (mProfileEnabled) { + eglSwapBuffersStartTime = System.nanoTime(); + } + + sEgl.eglSwapBuffers(sEglDisplay, mEglSurface); + + if (mProfileEnabled) { + long now = System.nanoTime(); + float total = (now - eglSwapBuffersStartTime) * 0.000001f; + mProfileData[mProfileCurrentFrame + 2] = total; + } + + checkEglErrors(); } - checkEglErrors(); - return dirty == null; } } diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h index e33823e96b9e8..fc810be8dc627 100644 --- a/include/private/hwui/DrawGlInfo.h +++ b/include/private/hwui/DrawGlInfo.h @@ -72,7 +72,14 @@ struct DrawGlInfo { // The functor needs to be invoked again but will // not redraw. Only the functor is invoked again // (unless another functor requests a redraw.) - kStatusInvoke = 0x2 + kStatusInvoke = 0x2, + // DisplayList actually issued GL drawing commands. + // This is used to signal the HardwareRenderer that the + // buffers should be flipped - otherwise, there were no + // changes to the buffer, so no need to flip. Some hardware + // has issues with stale buffer contents when no GL + // commands are issued. + kStatusDrew = 0x4 }; }; // struct DrawGlInfo diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 546925e6b9637..88d2209154c11 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -833,7 +833,7 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) { * purposes of logging display list info for a given view. */ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) { - status_t drawGlStatus = 0; + status_t drawGlStatus = DrawGlInfo::kStatusDone; TextContainer text; mReader.rewind(); @@ -859,7 +859,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo); renderer.restoreToCount(restoreTo); renderer.endMark(); - return false; + return drawGlStatus; } DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); @@ -1002,7 +1002,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag } DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], layer, x, y, paint); - renderer.drawLayer(layer, x, y, paint); + drawGlStatus |= renderer.drawLayer(layer, x, y, paint); } break; case DrawBitmap: { @@ -1015,7 +1015,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag } DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, x, y, paint); - renderer.drawBitmap(bitmap, x, y, paint); + drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); } break; case DrawBitmapMatrix: { @@ -1024,7 +1024,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], bitmap, matrix, paint); - renderer.drawBitmap(bitmap, matrix, paint); + drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint); } break; case DrawBitmapRect: { @@ -1041,7 +1041,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8,paint); - renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); + drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); } break; case DrawBitmapData: { @@ -1051,7 +1051,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, x, y, paint); - renderer.drawBitmap(bitmap, x, y, paint); + drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); } break; case DrawBitmapMesh: { @@ -1067,7 +1067,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint); + drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, + colors, paint); } break; case DrawPatch: { @@ -1091,15 +1092,15 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount, - numColors, left, top, right, bottom, paint); + drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors, + xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint); } break; case DrawColor: { int32_t color = getInt(); int32_t xferMode = getInt(); DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); - renderer.drawColor(color, (SkXfermode::Mode) xferMode); + drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode); } break; case DrawRect: { @@ -1110,7 +1111,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); - renderer.drawRect(f1, f2, f3, f4, paint); + drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint); } break; case DrawRoundRect: { @@ -1123,7 +1124,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint); - renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint); + drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint); } break; case DrawCircle: { @@ -1133,7 +1134,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, paint); - renderer.drawCircle(f1, f2, f3, paint); + drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint); } break; case DrawOval: { @@ -1144,7 +1145,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); - renderer.drawOval(f1, f2, f3, f4, paint); + drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint); } break; case DrawArc: { @@ -1158,14 +1159,14 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); - renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint); + drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint); } break; case DrawPath: { SkPath* path = getPath(); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint); - renderer.drawPath(path, paint); + drawGlStatus |= renderer.drawPath(path, paint); } break; case DrawLines: { @@ -1173,7 +1174,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag float* points = getFloats(count); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.drawLines(points, count, paint); + drawGlStatus |= renderer.drawLines(points, count, paint); } break; case DrawPoints: { @@ -1181,7 +1182,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag float* points = getFloats(count); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.drawPoints(points, count, paint); + drawGlStatus |= renderer.drawPoints(points, count, paint); } break; case DrawText: { @@ -1193,7 +1194,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag float length = getFloat(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); - renderer.drawText(text.text(), text.length(), count, x, y, paint, length); + drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y, + paint, length); } break; case DrawTextOnPath: { @@ -1205,7 +1207,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); - renderer.drawTextOnPath(text.text(), text.length(), count, path, + drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path, hOffset, vOffset, paint); } break; @@ -1217,7 +1219,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); - renderer.drawPosText(text.text(), text.length(), count, positions, paint); + drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count, + positions, paint); } break; case ResetShader: { @@ -1490,23 +1493,25 @@ status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { +status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { addOp(DisplayList::DrawLayer); addInt((int) layer); addPoint(x, y); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { +status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height()); uint32_t* location = addOp(DisplayList::DrawBitmap, reject); addBitmap(bitmap); addPoint(left, top); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { +status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); const mat4 transform(*matrix); transform.mapRect(r); @@ -1517,9 +1522,10 @@ void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint addMatrix(matrix); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, +status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom); @@ -1529,18 +1535,21 @@ void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcT addBounds(dstLeft, dstTop, dstRight, dstBottom); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) { +status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, + SkPaint* paint) { const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height()); uint32_t* location = addOp(DisplayList::DrawBitmapData, reject); addBitmapData(bitmap); addPoint(left, top); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, +status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { addOp(DisplayList::DrawBitmapMesh); addBitmap(bitmap); @@ -1554,11 +1563,12 @@ void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int me addInt(0); } addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, - const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, - float left, float top, float right, float bottom, SkPaint* paint) { +status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, + const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, + int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { const bool reject = quickReject(left, top, right, bottom); uint32_t* location = addOp(DisplayList::DrawPatch, reject); addBitmap(bitmap); @@ -1568,15 +1578,17 @@ void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, cons addBounds(left, top, right, bottom); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { +status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { addOp(DisplayList::DrawColor); addInt(color); addInt(mode); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, +status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { const bool reject = paint->getStyle() == SkPaint::kFill_Style && quickReject(left, top, right, bottom); @@ -1584,9 +1596,10 @@ void DisplayListRenderer::drawRect(float left, float top, float right, float bot addBounds(left, top, right, bottom); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, +status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint) { const bool reject = paint->getStyle() == SkPaint::kFill_Style && quickReject(left, top, right, bottom); @@ -1595,32 +1608,36 @@ void DisplayListRenderer::drawRoundRect(float left, float top, float right, floa addPoint(rx, ry); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { +status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { addOp(DisplayList::DrawCircle); addPoint(x, y); addFloat(radius); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, +status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { addOp(DisplayList::DrawOval); addBounds(left, top, right, bottom); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, +status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { addOp(DisplayList::DrawArc); addBounds(left, top, right, bottom); addPoint(startAngle, sweepAngle); addInt(useCenter ? 1 : 0); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { +status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { float left, top, offset; uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); @@ -1630,23 +1647,26 @@ void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { addPath(path); addPaint(paint); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { +status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { addOp(DisplayList::DrawLines); addFloats(points, count); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { +status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { addOp(DisplayList::DrawPoints); addFloats(points, count); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, +status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { - if (!text || count <= 0) return; + if (!text || count <= 0) return DrawGlInfo::kStatusDone; // TODO: We should probably make a copy of the paint instead of modifying // it; modifying the paint will change its generationID the first @@ -1672,11 +1692,12 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, addPaint(paint); addFloat(length); addSkip(location); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { - if (!text || count <= 0) return; + if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawTextOnPath); addText(text, bytesCount); addInt(count); @@ -1685,17 +1706,19 @@ void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int c addFloat(vOffset); paint->setAntiAlias(true); addPaint(paint); + return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, +status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { - if (!text || count <= 0) return; + if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); addFloats(positions, count * 2); paint->setAntiAlias(true); addPaint(paint); + return DrawGlInfo::kStatusDone; } void DisplayListRenderer::resetShader() { diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 0ba4078e61e8d..4fa1baa741994 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -576,35 +576,35 @@ class DisplayListRenderer: public OpenGLRenderer { virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags, uint32_t level = 0); - virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, + virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint); - virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); - virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); + virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint); - virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, + virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint); - virtual void drawColor(int color, SkXfermode::Mode mode); - virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint); - virtual void drawRoundRect(float left, float top, float right, float bottom, + virtual status_t drawColor(int color, SkXfermode::Mode mode); + virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint); + virtual status_t 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 drawArc(float left, float top, float right, float bottom, + virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint); + virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint); + virtual status_t drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); - virtual void drawPath(SkPath* path, SkPaint* paint); - virtual void drawLines(float* points, int count, SkPaint* paint); - virtual void drawPoints(float* points, int count, SkPaint* paint); - virtual void drawText(const char* text, int bytesCount, int count, float x, float y, + virtual status_t drawPath(SkPath* path, SkPaint* paint); + virtual status_t drawLines(float* points, int count, SkPaint* paint); + virtual status_t drawPoints(float* points, int count, SkPaint* paint); + virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); - virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); - virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, - SkPaint* paint); + virtual status_t drawPosText(const char* text, int bytesCount, int count, + const float* positions, SkPaint* paint); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2a8b32c4721ae..2dc9726ab9cad 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -336,7 +336,7 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.height = getSnapshot()->height; getSnapshot()->transform->copyTo(&info.transform[0]); - status_t result = (*functor)(DrawGlInfo::kModeDraw, &info); + status_t result = (*functor)(DrawGlInfo::kModeDraw, &info) | DrawGlInfo::kStatusDrew; if (result != DrawGlInfo::kStatusDone) { Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom); @@ -1472,17 +1472,17 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk finishDrawTexture(); } -void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { +status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { const float right = left + bitmap->width(); const float bottom = top + bitmap->height(); if (quickReject(left, top, right, bottom)) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { @@ -1490,20 +1490,22 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint } else { drawTextureRect(left, top, right, bottom, texture, paint); } + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { +status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); const mat4 transform(*matrix); transform.mapRect(r); if (quickReject(r.left, r.top, r.right, r.bottom)) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); // This could be done in a cheaper way, all we need is pass the matrix @@ -1512,14 +1514,16 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai concatMatrix(matrix); drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint); restore(); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) { +status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) { const float right = left + bitmap->width(); const float bottom = top + bitmap->height(); if (quickReject(left, top, right, bottom)) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); @@ -1527,18 +1531,20 @@ void OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkP const AutoTexture autoCleanup(texture); drawTextureRect(left, top, right, bottom, texture, paint); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, +status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { // TODO: Do a quickReject if (!vertices || mSnapshot->isIgnored()) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -1611,19 +1617,21 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei drawTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f, mode, texture->blend, &mesh[0].position[0], &mesh[0].texture[0], GL_TRIANGLES, count, false, false, 0, false, false); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, +status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); const float width = texture->width; @@ -1666,18 +1674,20 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, } resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, +status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { if (quickReject(left, top, right, bottom)) { - return; + return DrawGlInfo::kStatusDone; } mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(GL_LINEAR, true); @@ -1726,6 +1736,8 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int true, !mesh->hasEmptyQuads); } } + + return DrawGlInfo::kStatusDrew; } /** @@ -1826,8 +1838,8 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom * 'inside' the line area being filled opaquely and the other pixels being filled according to * how far into the boundary region they are, which is determined by shader interpolation. */ -void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; +status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; const bool isAA = paint->isAntiAlias(); // We use half the stroke width here because we're going to position the quad @@ -2083,10 +2095,12 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { if (isAA) { finishDrawAALine(widthSlot, lengthSlot); } + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; +status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; // TODO: The paint's cap style defines whether the points are square or circular // TODO: Handle AA for round points @@ -2138,86 +2152,92 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { } glDrawArrays(GL_POINTS, 0, generatedVerticesCount); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { +status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region - if (mSnapshot->isIgnored()) return; + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; Rect& clip(*mSnapshot->clipRect); clip.snapToPixelBoundaries(); drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, SkPaint* paint) { - if (!texture) return; +status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, + SkPaint* paint) { + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); const float x = left + texture->left - texture->offset; const float y = top + texture->top - texture->offset; drawPathTexture(texture, x, y, paint); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, +status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; mCaches.activeTexture(0); const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect( right - left, bottom - top, rx, ry, paint); - drawShape(left, top, texture, paint); + return drawShape(left, top, texture, paint); } -void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; +status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; mCaches.activeTexture(0); const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint); - drawShape(x - radius, y - radius, texture, paint); + return drawShape(x - radius, y - radius, texture, paint); } -void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; +status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom, + SkPaint* paint) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; mCaches.activeTexture(0); const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint); - drawShape(left, top, texture, paint); + return drawShape(left, top, texture, paint); } -void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, +status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; if (fabs(sweepAngle) >= 360.0f) { - drawOval(left, top, right, bottom, paint); - return; + return drawOval(left, top, right, bottom, paint); } mCaches.activeTexture(0); const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top, startAngle, sweepAngle, useCenter, paint); - drawShape(left, top, texture, paint); + return drawShape(left, top, texture, paint); } -void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom, +status_t OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; mCaches.activeTexture(0); const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint); - drawShape(left, top, texture, paint); + return drawShape(left, top, texture, paint); } -void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) { +status_t 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; + return drawRectAsShape(left, top, right, bottom, p); } if (quickReject(left, top, right, bottom)) { - return; + return DrawGlInfo::kStatusDone; } SkXfermode::Mode mode; @@ -2237,18 +2257,20 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, } else { drawColorRect(left, top, right, bottom, color, mode); } + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, +status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { - return; + return DrawGlInfo::kStatusDone; } // NOTE: Skia does not support perspective transform on drawPosText yet if (!mSnapshot->transform->isSimple()) { - return; + return DrawGlInfo::kStatusDone; } float x = 0.0f; @@ -2308,13 +2330,15 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, } #endif } + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, +status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { - return; + return DrawGlInfo::kStatusDone; } if (length < 0.0f) length = paint->measureText(text, bytesCount); @@ -2332,7 +2356,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, SkPaint::FontMetrics metrics; paint->getFontMetrics(&metrics, 0.0f); if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) { - return; + return DrawGlInfo::kStatusDone; } const float oldX = x; @@ -2432,13 +2456,15 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, +status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { - return; + return DrawGlInfo::kStatusDone; } FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint); @@ -2482,27 +2508,31 @@ void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, } #endif } + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; +status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; mCaches.activeTexture(0); // TODO: Perform early clip test before we rasterize the path const PathTexture* texture = mCaches.pathCache.get(path, paint); - if (!texture) return; + if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); const float x = texture->left - texture->offset; const float y = texture->top - texture->offset; drawPathTexture(texture, x, y, paint); + + return DrawGlInfo::kStatusDrew; } -void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { +status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) { - return; + return DrawGlInfo::kStatusDone; } if (layer->deferredUpdateScheduled && layer->renderer && layer->displayList) { @@ -2575,6 +2605,8 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); composeLayerRect(layer, r); #endif + + return DrawGlInfo::kStatusDrew; } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index ad83b312bf3fc..7703e805d04c4 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -111,34 +111,34 @@ class OpenGLRenderer { virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags, uint32_t level = 0); virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0); - virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); - virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, + virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); + virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint); - virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); - virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); + virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint); - virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, + virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint); - virtual void drawColor(int color, SkXfermode::Mode mode); - virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint); - virtual void drawRoundRect(float left, float top, float right, float bottom, + virtual status_t drawColor(int color, SkXfermode::Mode mode); + virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint); + virtual status_t 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 drawArc(float left, float top, float right, float bottom, + virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint); + virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint); + virtual status_t drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); - virtual void drawPath(SkPath* path, SkPaint* paint); - virtual void drawLines(float* points, int count, SkPaint* paint); - virtual void drawPoints(float* points, int count, SkPaint* paint); - virtual void drawText(const char* text, int bytesCount, int count, float x, float y, + virtual status_t drawPath(SkPath* path, SkPaint* paint); + virtual status_t drawLines(float* points, int count, SkPaint* paint); + virtual status_t drawPoints(float* points, int count, SkPaint* paint); + virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); - virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); - virtual void drawPosText(const char* text, int bytesCount, int count, + virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); virtual void resetShader(); @@ -336,7 +336,7 @@ class OpenGLRenderer { * @param texture The texture reprsenting the shape * @param paint The paint to draw the shape with */ - void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint); + status_t drawShape(float left, float top, const PathTexture* texture, SkPaint* paint); /** * Renders the rect defined by the specified bounds as a shape. @@ -349,7 +349,7 @@ class OpenGLRenderer { * @param bottom The bottom coordinate of the rect to draw * @param p The paint to draw the rect with */ - void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p); + status_t drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p); /** * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey