diff options
author | Tom Hudson <tomhudson@google.com> | 2014-12-09 15:03:44 -0500 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2015-01-05 15:25:41 -0800 |
commit | 8dfaa4904205772cdceee63ef3989bcdedf1a914 (patch) | |
tree | baf5ea37427770659698766562bbd3b80f9eddf9 /libs | |
parent | c82be5f27f1dd9da665b0ca52590cc30ede4e78a (diff) | |
download | frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.zip frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.tar.gz frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.tar.bz2 |
Make DisplayListRenderer inherit from Canvas, merge JNI
Incrementally unify the upper layers for Skia and HWUI.
Remove redundant code from GLES20Canvas.java; instead
use inherited mNativeCanvasWrapper and superclass method
definitions.
Moves some unrelated SkPaint utility functions from Renderer
to new utils/PaintUtils.
bug: 15672762
Change-Id: I4ddd4214b8e9eeb95289d054ef423f2542bb5fa5
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListOp.h | 3 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 185 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 217 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 22 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/Renderer.h | 34 | ||||
-rw-r--r-- | libs/hwui/tests/main.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/utils/PaintUtils.h | 64 |
8 files changed, 329 insertions, 201 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index e42a9e4..499c113 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -34,6 +34,7 @@ #include "RenderState.h" #include "UvMapper.h" #include "utils/LinearAllocator.h" +#include "utils/PaintUtils.h" // Use OP_LOG for logging with arglist, OP_LOGS if just printing char* #define OP_LOGS(s) OP_LOG("%s", (s)) @@ -203,7 +204,7 @@ protected: if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) { return false; } - if (Renderer::isBlendedColorFilter(mPaint->getColorFilter())) { + if (PaintUtils::isBlendedColorFilter(mPaint->getColorFilter())) { return false; } } diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 1eefa89..5a13293 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -28,6 +28,7 @@ #include "DisplayListOp.h" #include "DisplayListRenderer.h" #include "RenderNode.h" +#include "utils/PaintUtils.h" namespace android { namespace uirenderer { @@ -63,7 +64,7 @@ DisplayListData* DisplayListRenderer::finishRecording() { } void DisplayListRenderer::prepareDirty(float left, float top, - float right, float bottom, bool opaque) { + float right, float bottom) { LOG_ALWAYS_FATAL_IF(mDisplayListData, "prepareDirty called a second time during a recording!"); @@ -72,7 +73,7 @@ void DisplayListRenderer::prepareDirty(float left, float top, mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; - mState.setDirtyClip(opaque); + mState.setDirtyClip(false); mRestoreSaveCount = -1; } @@ -94,9 +95,9 @@ void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { mDisplayListData->functors.add(functor); } -int DisplayListRenderer::save(int flags) { - addStateOp(new (alloc()) SaveOp(flags)); - return mState.save(flags); +int DisplayListRenderer::save(SkCanvas::SaveFlags flags) { + addStateOp(new (alloc()) SaveOp((int) flags)); + return mState.save((int) flags); } void DisplayListRenderer::restore() { @@ -117,22 +118,21 @@ void DisplayListRenderer::restoreToCount(int saveCount) { } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags) { + const SkPaint* paint, SkCanvas::SaveFlags flags) { // force matrix/clip isolation for layer flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; paint = refPaint(paint); - addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); - return mState.save(flags); + addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags)); + return mState.save((int) flags); } -void DisplayListRenderer::translate(float dx, float dy, float dz) { - // ignore dz, not used at defer time +void DisplayListRenderer::translate(float dx, float dy) { mHasDeferredTranslate = true; mTranslateX += dx; mTranslateY += dy; flushRestoreToCount(); - mState.translate(dx, dy, dz); + mState.translate(dx, dy, 0.0f); } void DisplayListRenderer::rotate(float degrees) { @@ -155,11 +155,27 @@ void DisplayListRenderer::setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); } -void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) { +void DisplayListRenderer::concat(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); mState.concatMatrix(matrix); } +bool DisplayListRenderer::getClipBounds(SkRect* outRect) const { + Rect bounds = mState.getLocalClipBounds(); + *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom); + return !(outRect->isEmpty()); +} + +bool DisplayListRenderer::quickRejectRect(float left, float top, float right, float bottom) const { + return mState.quickRejectConservative(left, top, right, bottom); +} + +bool DisplayListRenderer::quickRejectPath(const SkPath& path) const { + SkRect bounds = path.getBounds(); + return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); +} + + bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); @@ -201,23 +217,50 @@ void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* pain addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint)); } -void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, +void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float left, float top, + const SkPaint* paint) { + save(SkCanvas::kMatrix_SaveFlag); + translate(left, top); + drawBitmap(&bitmap, paint); + restore(); +} + +void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, + const SkPaint* paint) { + if (matrix.isIdentity()) { + drawBitmap(&bitmap, paint); + } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))) { + // SkMatrix::isScaleTranslate() not available in L + SkRect src; + SkRect dst; + bitmap.getBounds(&src); + matrix.mapRect(&dst, src); + drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, + dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); + } else { + save(SkCanvas::kMatrix_SaveFlag); + concat(matrix); + drawBitmap(&bitmap, paint); + restore(); + } +} + +void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (srcLeft == 0 && srcTop == 0 - && srcRight == bitmap->width() && srcBottom == bitmap->height() + && srcRight == bitmap.width() && srcBottom == bitmap.height() && (srcBottom - srcTop == dstBottom - dstTop) && (srcRight - srcLeft == dstRight - dstLeft)) { // transform simple rect to rect drawing case into position bitmap ops, since they merge save(SkCanvas::kMatrix_SaveFlag); translate(dstLeft, dstTop); - drawBitmap(bitmap, paint); + drawBitmap(&bitmap, paint); restore(); } else { - bitmap = refBitmap(bitmap); paint = refPaint(paint); - addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, + addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint)); } @@ -230,16 +273,15 @@ void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint)); } -void DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void DisplayListRenderer::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { int vertexCount = (meshWidth + 1) * (meshHeight + 1); - bitmap = refBitmap(bitmap); vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex paint = refPaint(paint); colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex - addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, - vertices, colors, paint)); + addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(&bitmap), meshWidth, meshHeight, + vertices, colors, paint)); } void DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, @@ -255,16 +297,22 @@ void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { addDrawOp(new (alloc()) DrawColorOp(color, mode)); } +void DisplayListRenderer::drawPaint(const SkPaint& paint) { + SkRect bounds; + if (getClipBounds(&bounds)) { + drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); + } +} + + void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, - const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); + const SkPaint& paint) { + addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint))); } void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, - float rx, float ry, const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); + float rx, float ry, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint))); } void DisplayListRenderer::drawRoundRect( @@ -283,9 +331,8 @@ void DisplayListRenderer::drawRoundRect( &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); } -void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); +void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint))); } void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, @@ -299,65 +346,56 @@ void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyP } void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, - const SkPaint* paint) { - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); + const SkPaint& paint) { + addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint))); } void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { + float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { if (fabs(sweepAngle) >= 360.0f) { drawOval(left, top, right, bottom, paint); } else { - paint = refPaint(paint); addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, - startAngle, sweepAngle, useCenter, paint)); + startAngle, sweepAngle, useCenter, refPaint(&paint))); } } -void DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { - path = refPath(path); - paint = refPaint(paint); - - addDrawOp(new (alloc()) DrawPathOp(path, paint)); +void DisplayListRenderer::drawPath(const SkPath& path, const SkPaint& paint) { + addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint))); } -void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint& paint) { points = refBuffer<float>(points, count); - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); + addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint))); } -void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint& paint) { points = refBuffer<float>(points, count); - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); + addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint))); } -void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, - const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (!text || count <= 0) return; - - text = refText(text, bytesCount); - path = refPath(path); - paint = refPaint(paint); +void DisplayListRenderer::drawTextOnPath(const uint16_t* glyphs, int count, + const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { + if (!glyphs || count <= 0) return; - DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, - hOffset, vOffset, paint); + int bytesCount = 2 * count; + DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount), + bytesCount, count, refPath(&path), + hOffset, vOffset, refPaint(&paint)); addDrawOp(op); } -void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint) { +void DisplayListRenderer::drawPosText(const uint16_t* text, const float* positions, + int count, int posCount, const SkPaint& paint) { if (!text || count <= 0) return; - text = refText(text, bytesCount); + int bytesCount = 2 * count; positions = refBuffer<float>(positions, count * 2); - paint = refPaint(paint); - DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); + DrawOp* op = new (alloc()) DrawPosTextOp(refText((const char*) text, bytesCount), + bytesCount, count, positions, refPaint(&paint)); addDrawOp(op); } @@ -371,40 +409,41 @@ static void simplifyPaint(int color, SkPaint* paint) { paint->setLooper(NULL); } -void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, - float x, float y, const float* positions, const SkPaint* paint, - float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { +void DisplayListRenderer::drawText(const uint16_t* glyphs, const float* positions, + int count, const SkPaint& paint, float x, float y, + float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, + float totalAdvance) { - if (!text || count <= 0 || paintWillNotDrawText(*paint)) return; + if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; - text = refText(text, bytesCount); + int bytesCount = count * 2; + const char* text = refText((const char*) glyphs, bytesCount); positions = refBuffer<float>(positions, count * 2); + Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); if (CC_UNLIKELY(mHighContrastText)) { // high contrast draw path - int color = paint->getColor(); + int color = paint.getColor(); int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); bool darken = channelSum < (128 * 3); // outline - SkPaint* outlinePaint = copyPaint(paint); + SkPaint* outlinePaint = copyPaint(&paint); simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? // inner - SkPaint* innerPaint = copyPaint(paint); + SkPaint* innerPaint = copyPaint(&paint); simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); innerPaint->setStyle(SkPaint::kFill_Style); addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, innerPaint, totalAdvance, bounds)); } else { // standard draw path - paint = refPaint(paint); - DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, paint, totalAdvance, bounds); + x, y, positions, refPaint(&paint), totalAdvance, bounds); addDrawOp(op); } } @@ -477,7 +516,7 @@ size_t DisplayListRenderer::addStateOp(StateOp* op) { size_t DisplayListRenderer::addDrawOp(DrawOp* op) { Rect localBounds; if (op->getLocalBounds(localBounds)) { - bool rejected = quickRejectConservative(localBounds.left, localBounds.top, + bool rejected = quickRejectRect(localBounds.left, localBounds.top, localBounds.right, localBounds.bottom); op->setQuickRejected(rejected); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 34f9c38..a798329 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -25,6 +25,8 @@ #include <SkTLazy.h> #include <cutils/compiler.h> +#include <private/graphics/Canvas.h> + #include "CanvasState.h" #include "DisplayList.h" #include "DisplayListLogBuffer.h" @@ -62,7 +64,7 @@ class StateOp; /** * Records drawing commands in a display list for later playback into an OpenGLRenderer. */ -class ANDROID_API DisplayListRenderer: public Renderer, public CanvasStateClient { +class ANDROID_API DisplayListRenderer: public Canvas, public CanvasStateClient { public: DisplayListRenderer(); virtual ~DisplayListRenderer(); @@ -72,126 +74,177 @@ public: DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- -// Frame state operations +// HWUI Frame state operations // ---------------------------------------------------------------------------- - virtual void prepareDirty(float left, float top, float right, - float bottom, bool opaque) override; - virtual void prepare(bool opaque) override { - prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque); - } - virtual bool finish() override; - virtual void interrupt(); - virtual void resume(); + + void prepareDirty(float left, float top, float right, float bottom); + void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); } + bool finish(); + void interrupt(); + void resume(); // ---------------------------------------------------------------------------- -// Canvas state operations +// HWUI Canvas state operations // ---------------------------------------------------------------------------- - virtual void setViewport(int width, int height) override { mState.setViewport(width, height); } - - // Save (layer) - virtual int getSaveCount() const override { return mState.getSaveCount(); } - virtual int save(int flags) override; - virtual void restore() override; - virtual void restoreToCount(int saveCount) override; - virtual int saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags) override; - - // Matrix - virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } - virtual void translate(float dx, float dy, float dz = 0.0f) override; - virtual void rotate(float degrees) override; - virtual void scale(float sx, float sy) override; - virtual void skew(float sx, float sy) override; + void setViewport(int width, int height) { mState.setViewport(width, height); } - virtual void setMatrix(const SkMatrix& matrix) override; - virtual void concatMatrix(const SkMatrix& matrix) override; - - // Clip - virtual bool clipRect(float left, float top, float right, float bottom, - SkRegion::Op op) override; - virtual bool clipPath(const SkPath* path, SkRegion::Op op) override; - virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override; - - // Misc - virtual void setDrawFilter(SkDrawFilter* filter) override; - virtual const Rect& getLocalClipBounds() const override { return mState.getLocalClipBounds(); } const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } - virtual bool quickRejectConservative(float left, float top, - float right, float bottom) const override { - return mState.quickRejectConservative(left, top, right, bottom); - } bool isCurrentTransformSimple() { return mState.currentTransform()->isSimple(); } // ---------------------------------------------------------------------------- -// Canvas draw operations +// HWUI Canvas draw operations // ---------------------------------------------------------------------------- - virtual void drawColor(int color, SkXfermode::Mode mode) override; // Bitmap-based - virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) override; - virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, - float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, const SkPaint* paint) override; - virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) override; - virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, - const float* vertices, const int* colors, const SkPaint* paint) override; - virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, - float left, float top, float right, float bottom, const SkPaint* paint) override; + void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + // TODO: move drawBitmapData() to Canvas.h + void drawBitmapData(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 - virtual void drawRect(float left, float top, float right, float bottom, - const SkPaint* paint) override; - virtual void drawRects(const float* rects, int count, 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 drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, + void drawRects(const float* rects, int count, const SkPaint* paint); + void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, CanvasPropertyPaint* paint); - virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) override; - virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, + void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint); - virtual void drawOval(float left, float top, float right, float bottom, - const SkPaint* paint) override; - virtual void drawArc(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) override; - virtual void drawPath(const SkPath* path, const SkPaint* paint) override; - virtual void drawLines(const float* points, int count, const SkPaint* paint) override; - virtual void drawPoints(const float* points, int count, const SkPaint* paint) override; - // Text - virtual void drawText(const char* text, int bytesCount, int count, float x, float y, - const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, - DrawOpMode drawOpMode = kDrawOpMode_Immediate) override; - virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, - float hOffset, float vOffset, const SkPaint* paint) override; - virtual void drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint) override; // ---------------------------------------------------------------------------- -// Canvas draw operations - special +// HWUI Canvas draw operations - special // ---------------------------------------------------------------------------- - virtual void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); - virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) override; + void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); + void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); // TODO: rename for consistency - virtual void callDrawGLFunction(Functor* functor, Rect& dirty) override; + void callDrawGLFunction(Functor* functor, Rect& dirty); void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } // ---------------------------------------------------------------------------- -// CanvasState callbacks +// CanvasStateClient interface // ---------------------------------------------------------------------------- virtual void onViewportInitialized() override { } virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { } virtual GLuint onGetTargetFbo() const override { return -1; } +// ---------------------------------------------------------------------------- +// android/graphics/Canvas interface +// ---------------------------------------------------------------------------- + virtual SkCanvas* getSkCanvas() { + LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas"); + return NULL; + } + virtual void setBitmap(SkBitmap* bitmap, bool copyState) { + LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap."); + } + + virtual bool isOpaque() { return false; } + virtual int width() { return mState.getWidth(); } + virtual int height() { return mState.getHeight(); } + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas state operations +// ---------------------------------------------------------------------------- + // Save (layer) + virtual int getSaveCount() const { return mState.getSaveCount(); } + virtual int save(SkCanvas::SaveFlags flags); + virtual void restore(); + virtual void restoreToCount(int saveCount); + + virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint, + SkCanvas::SaveFlags flags); + virtual int saveLayerAlpha(float left, float top, float right, float bottom, + int alpha, SkCanvas::SaveFlags flags) { + SkPaint paint; + paint.setAlpha(alpha); + return saveLayer(left, top, right, bottom, &paint, flags); + } + + // Matrix + virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); } + virtual void setMatrix(const SkMatrix& matrix); + + virtual void concat(const SkMatrix& matrix); + virtual void rotate(float degrees); + virtual void scale(float sx, float sy); + virtual void skew(float sx, float sy); + virtual void translate(float dx, float dy); + + // Clip + virtual bool getClipBounds(SkRect* outRect) const; + virtual bool quickRejectRect(float left, float top, float right, float bottom) const; + virtual bool quickRejectPath(const SkPath& path) const; + + virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); + virtual bool clipPath(const SkPath* path, SkRegion::Op op); + virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); + + // Misc + virtual SkDrawFilter* getDrawFilter() { return mDrawFilter.get(); } + virtual void setDrawFilter(SkDrawFilter* filter); + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas draw operations +// ---------------------------------------------------------------------------- + virtual void drawColor(int color, SkXfermode::Mode mode); + virtual void drawPaint(const SkPaint& paint); + + // Geometry + virtual void drawPoint(float x, float y, const SkPaint& paint) { + float points[2] = { x, y }; + drawPoints(points, 2, paint); + } + virtual void drawPoints(const float* points, int count, const SkPaint& paint); + virtual void drawLine(float startX, float startY, float stopX, float stopY, + const SkPaint& paint) { + float points[4] = { startX, startY, stopX, stopY }; + drawLines(points, 4, paint); + } + virtual void drawLines(const float* points, int count, const SkPaint& paint); + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint); + virtual void drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, const SkPaint& paint); + virtual void drawCircle(float x, float y, float radius, const SkPaint& paint); + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint); + virtual void drawArc(float left, float top, float right, float bottom, + float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint); + virtual void drawPath(const SkPath& path, const SkPaint& paint); + virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount, + const float* verts, const float* tex, const int* colors, + const uint16_t* indices, int indexCount, const SkPaint& paint) + { LOG_ALWAYS_FATAL("DisplayListRenderer does not support drawVertices()"); } + + // Bitmap-based + virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint); + virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, + const SkPaint* paint); + virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop, + float srcRight, float srcBottom, float dstLeft, float dstTop, + float dstRight, float dstBottom, const SkPaint* paint); + virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint); + + // Text + virtual void drawText(const uint16_t* glyphs, const float* positions, int count, + const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, + float boundsRight, float boundsBottom, float totalAdvance); + virtual void drawPosText(const uint16_t* text, const float* positions, int count, + int posCount, const SkPaint& paint); + virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + float hOffset, float vOffset, const SkPaint& paint); + virtual bool drawTextAbsolutePos() const { return false; } + + private: CanvasState mState; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index fb3d462..3c8fb8b 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -47,6 +47,7 @@ #include "Vector.h" #include "VertexBuffer.h" #include "utils/GLUtils.h" +#include "utils/PaintUtils.h" #include "utils/TraceUtils.h" #if DEBUG_DETAILED_EVENTS @@ -1667,8 +1668,10 @@ void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) { // argb=1,0,0,0 accountForClear(mode); // TODO: check shader blending, once we have shader drawing support for layers. - bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f || - (mColorSet && mColorA < 1.0f) || isBlendedColorFilter(layer->getColorFilter()); + bool blend = layer->isBlend() + || getLayerAlpha(layer) < 1.0f + || (mColorSet && mColorA < 1.0f) + || PaintUtils::isBlendedColorFilter(layer->getColorFilter()); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1679,7 +1682,7 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw accountForClear(mode); blend |= (mColorSet && mColorA < 1.0f) || (getShader(paint) && !getShader(paint)->isOpaque()) || - isBlendedColorFilter(getColorFilter(paint)); + PaintUtils::isBlendedColorFilter(getColorFilter(paint)); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -2476,7 +2479,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot float rx, float ry, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2495,7 +2498,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } if (p->getPathEffect() != nullptr) { @@ -2517,7 +2520,7 @@ void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2540,7 +2543,7 @@ void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2575,7 +2578,7 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2657,7 +2660,8 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, bool OpenGLRenderer::canSkipText(const SkPaint* paint) const { float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha; - return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; + return MathUtils::isZero(alpha) + && PaintUtils::getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; } void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 9de4149..9d9b3d2 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -49,6 +49,7 @@ #include "UvMapper.h" #include "Vertex.h" #include "Caches.h" +#include "utils/PaintUtils.h" class SkShader; @@ -274,7 +275,7 @@ public: static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) { if (!paint) return SkXfermode::kSrcOver_Mode; - return getXfermode(paint->getXfermode()); + return PaintUtils::getXfermode(paint->getXfermode()); } static inline int getAlphaDirect(const SkPaint* paint) { diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index ee44d7a..3240bbc 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -57,40 +57,6 @@ class ANDROID_API Renderer { public: virtual ~Renderer() {} - /** - * Safely retrieves the mode from the specified xfermode. If the specified - * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode. - */ - static inline SkXfermode::Mode getXfermode(SkXfermode* mode) { - SkXfermode::Mode resultMode; - if (!SkXfermode::AsMode(mode, &resultMode)) { - resultMode = SkXfermode::kSrcOver_Mode; - } - return resultMode; - } - - // TODO: move to a method on android:Paint - static inline bool paintWillNotDraw(const SkPaint& paint) { - return paint.getAlpha() == 0 - && !paint.getColorFilter() - && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; - } - - // TODO: move to a method on android:Paint - static inline bool paintWillNotDrawText(const SkPaint& paint) { - return paint.getAlpha() == 0 - && paint.getLooper() == nullptr - && !paint.getColorFilter() - && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; - } - - static bool isBlendedColorFilter(const SkColorFilter* filter) { - if (filter == nullptr) { - return false; - } - return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; - } - // ---------------------------------------------------------------------------- // Frame state operations // ---------------------------------------------------------------------------- diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index ee16991..4efef6f 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -41,7 +41,7 @@ public: static DisplayListRenderer* startRecording(RenderNode* node) { DisplayListRenderer* renderer = new DisplayListRenderer(); renderer->setViewport(node->getWidth(), node->getHeight()); - renderer->prepare(false); + renderer->prepare(); return renderer; } diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h new file mode 100644 index 0000000..8a4034f --- /dev/null +++ b/libs/hwui/utils/PaintUtils.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PAINT_UTILS_H +#define PAINT_UTILS_H + +namespace android { +namespace uirenderer { + +class PaintUtils { +public: + + /** + * Safely retrieves the mode from the specified xfermode. If the specified + * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode. + */ + static inline SkXfermode::Mode getXfermode(SkXfermode* mode) { + SkXfermode::Mode resultMode; + if (!SkXfermode::AsMode(mode, &resultMode)) { + resultMode = SkXfermode::kSrcOver_Mode; + } + return resultMode; + } + + // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? + static inline bool paintWillNotDraw(const SkPaint& paint) { + return paint.getAlpha() == 0 + && !paint.getColorFilter() + && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; + } + + // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? + static inline bool paintWillNotDrawText(const SkPaint& paint) { + return paint.getAlpha() == 0 + && paint.getLooper() == NULL + && !paint.getColorFilter() + && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode; + } + + static bool isBlendedColorFilter(const SkColorFilter* filter) { + if (filter == NULL) { + return false; + } + return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; + } + +}; // class PaintUtils + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* PAINT_UTILS_H */ |