diff options
Diffstat (limited to 'libs/hwui/DisplayListOp.h')
| -rw-r--r-- | libs/hwui/DisplayListOp.h | 405 |
1 files changed, 218 insertions, 187 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 842e028..f1d70eb 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -21,6 +21,8 @@ #define LOG_TAG "OpenGLRenderer" #endif +#include <SkPath.h> +#include <SkPathOps.h> #include <SkXfermode.h> #include <private/hwui/DrawGlInfo.h> @@ -111,7 +113,7 @@ public: class DrawOp : public DisplayListOp { friend class MergingDrawBatch; public: - DrawOp(SkPaint* paint) + DrawOp(const SkPaint* paint) : mPaint(paint), mQuickRejected(false) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, @@ -181,14 +183,21 @@ public: return OpenGLRenderer::getAlphaDirect(mPaint); } + virtual bool hasTextShadow() const { + return false; + } + inline float strokeWidthOutset() { - float width = mPaint->getStrokeWidth(); - if (width == 0) return 0.5f; // account for hairline - return width * 0.5f; + // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced + // 1.0 stroke, treat 1.0 as minimum. + + // TODO: it would be nice if this could take scale into account, but scale isn't stable + // since higher levels of the view hierarchy can change scale out from underneath it. + return fmaxf(mPaint->getStrokeWidth(), 1) * 0.5f; } protected: - SkPaint* getPaint(OpenGLRenderer& renderer) { + const SkPaint* getPaint(OpenGLRenderer& renderer) { return renderer.filterPaint(mPaint); } @@ -209,22 +218,22 @@ protected: } - SkPaint* mPaint; // should be accessed via getPaint() when applying + const SkPaint* mPaint; // should be accessed via getPaint() when applying bool mQuickRejected; }; class DrawBoundedOp : public DrawOp { public: - DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint) + DrawBoundedOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} - DrawBoundedOp(const Rect& localBounds, SkPaint* paint) + DrawBoundedOp(const Rect& localBounds, const SkPaint* paint) : DrawOp(paint), mLocalBounds(localBounds) {} // Calculates bounds as smallest rect encompassing all points // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in // subclass' constructor) - DrawBoundedOp(const float* points, int count, SkPaint* paint) + DrawBoundedOp(const float* points, int count, const SkPaint* paint) : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) { for (int i = 2; i < count; i += 2) { mLocalBounds.left = fminf(mLocalBounds.left, points[i]); @@ -235,15 +244,15 @@ public: } // default empty constructor for bounds, to be overridden in child constructor body - DrawBoundedOp(SkPaint* paint): DrawOp(paint) { } + DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { } bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) { localBounds.set(mLocalBounds); - if (drawModifiers.mHasShadow) { - // TODO: inspect paint's looper directly + OpenGLRenderer::TextShadow textShadow; + if (OpenGLRenderer::getTextShadow(mPaint, &textShadow)) { Rect shadow(mLocalBounds); - shadow.translate(drawModifiers.mShadowDx, drawModifiers.mShadowDy); - shadow.outset(drawModifiers.mShadowRadius); + shadow.translate(textShadow.dx, textShadow.dx); + shadow.outset(textShadow.radius); localBounds.unionWith(shadow); } return true; @@ -259,7 +268,6 @@ protected: /////////////////////////////////////////////////////////////////////////////// class SaveOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: SaveOp(int flags) : mFlags(flags) {} @@ -282,17 +290,10 @@ public: int getFlags() const { return mFlags; } private: - SaveOp() {} - DisplayListOp* reinit(int flags) { - mFlags = flags; - return this; - } - int mFlags; }; class RestoreToCountOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: RestoreToCountOp(int count) : mCount(count) {} @@ -315,21 +316,25 @@ public: virtual const char* name() { return "RestoreToCount"; } private: - RestoreToCountOp() {} - DisplayListOp* reinit(int count) { - mCount = count; - return this; - } - int mCount; }; class SaveLayerOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: - SaveLayerOp(float left, float top, float right, float bottom, - int alpha, SkXfermode::Mode mode, int flags) - : mArea(left, top, right, bottom), mAlpha(alpha), mMode(mode), mFlags(flags) {} + SaveLayerOp(float left, float top, float right, float bottom, int alpha, int flags) + : mArea(left, top, right, bottom) + , mPaint(&mCachedPaint) + , mFlags(flags) + , mConvexMask(NULL) { + mCachedPaint.setAlpha(alpha); + } + + SaveLayerOp(float left, float top, float right, float bottom, const SkPaint* paint, int flags) + : mArea(left, top, right, bottom) + , mPaint(paint) + , mFlags(flags) + , mConvexMask(NULL) + {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { @@ -340,11 +345,12 @@ public: // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just // setup the snapshot for deferral, and re-issue the op at flush time deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom, - mAlpha, mMode, mFlags); + mPaint, mFlags); } virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mMode, mFlags); + renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, + mPaint, mFlags, mConvexMask); } virtual void output(int level, uint32_t logFlags) const { @@ -356,23 +362,26 @@ public: int getFlags() { return mFlags; } + // Called to make SaveLayerOp clip to the provided mask when drawing back/restored + void setMask(const SkPath* convexMask) { + mConvexMask = convexMask; + } + private: - // Special case, reserved for direct DisplayList usage - SaveLayerOp() {} - DisplayListOp* reinit(float left, float top, float right, float bottom, - int alpha, SkXfermode::Mode mode, int flags) { - mArea.set(left, top, right, bottom); - mAlpha = alpha; - mMode = mode; - mFlags = flags; - return this; - } - - bool isSaveLayerAlpha() const { return mAlpha < 255 && mMode == SkXfermode::kSrcOver_Mode; } + bool isSaveLayerAlpha() const { + SkXfermode::Mode mode = OpenGLRenderer::getXfermodeDirect(mPaint); + int alpha = OpenGLRenderer::getAlphaDirect(mPaint); + return alpha < 255 && mode == SkXfermode::kSrcOver_Mode; + } + Rect mArea; - int mAlpha; - SkXfermode::Mode mMode; + const SkPaint* mPaint; + SkPaint mCachedPaint; int mFlags; + + // Convex path, points at data in RenderNode, valid for the duration of the frame only + // Only used for masking the SaveLayer which wraps projected RenderNodes + const SkPath* mConvexMask; }; class TranslateOp : public StateOp { @@ -456,7 +465,7 @@ private: class SetMatrixOp : public StateOp { public: - SetMatrixOp(SkMatrix* matrix) + SetMatrixOp(const SkMatrix* matrix) : mMatrix(matrix) {} virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { @@ -465,7 +474,7 @@ public: virtual void output(int level, uint32_t logFlags) const { if (mMatrix) { - OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); + OP_LOG("SetMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(mMatrix)); } else { OP_LOGS("SetMatrix (reset)"); } @@ -474,12 +483,12 @@ public: virtual const char* name() { return "SetMatrix"; } private: - SkMatrix* mMatrix; + const SkMatrix* mMatrix; }; class ConcatMatrixOp : public StateOp { public: - ConcatMatrixOp(SkMatrix* matrix) + ConcatMatrixOp(const SkMatrix* matrix) : mMatrix(matrix) {} virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { @@ -487,13 +496,13 @@ public: } virtual void output(int level, uint32_t logFlags) const { - OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); + OP_LOG("ConcatMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(mMatrix)); } virtual const char* name() { return "ConcatMatrix"; } private: - SkMatrix* mMatrix; + const SkMatrix* mMatrix; }; class ClipOp : public StateOp { @@ -514,14 +523,12 @@ public: } protected: - ClipOp() {} virtual bool isRect() { return false; } SkRegion::Op mOp; }; class ClipRectOp : public ClipOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) : ClipOp(op), mArea(left, top, right, bottom) {} @@ -540,19 +547,12 @@ protected: virtual bool isRect() { return true; } private: - ClipRectOp() {} - DisplayListOp* reinit(float left, float top, float right, float bottom, SkRegion::Op op) { - mOp = op; - mArea.set(left, top, right, bottom); - return this; - } - Rect mArea; }; class ClipPathOp : public ClipOp { public: - ClipPathOp(SkPath* path, SkRegion::Op op) + ClipPathOp(const SkPath* path, SkRegion::Op op) : ClipOp(op), mPath(path) {} virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { @@ -568,12 +568,12 @@ public: virtual const char* name() { return "ClipPath"; } private: - SkPath* mPath; + const SkPath* mPath; }; class ClipRegionOp : public ClipOp { public: - ClipRegionOp(SkRegion* region, SkRegion::Op op) + ClipRegionOp(const SkRegion* region, SkRegion::Op op) : ClipOp(op), mRegion(region) {} virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { @@ -589,7 +589,7 @@ public: virtual const char* name() { return "ClipRegion"; } private: - SkRegion* mRegion; + const SkRegion* mRegion; }; class ResetShaderOp : public StateOp { @@ -623,73 +623,6 @@ private: SkiaShader* mShader; }; -class ResetColorFilterOp : public StateOp { -public: - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.resetColorFilter(); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOGS("ResetColorFilter"); - } - - virtual const char* name() { return "ResetColorFilter"; } -}; - -class SetupColorFilterOp : public StateOp { -public: - SetupColorFilterOp(SkiaColorFilter* colorFilter) - : mColorFilter(colorFilter) {} - - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.setupColorFilter(mColorFilter); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOG("SetupColorFilter, filter %p", mColorFilter); - } - - virtual const char* name() { return "SetupColorFilter"; } - -private: - SkiaColorFilter* mColorFilter; -}; - -class ResetShadowOp : public StateOp { -public: - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.resetShadow(); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOGS("ResetShadow"); - } - - virtual const char* name() { return "ResetShadow"; } -}; - -class SetupShadowOp : public StateOp { -public: - SetupShadowOp(float radius, float dx, float dy, int color) - : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {} - - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.setupShadow(mRadius, mDx, mDy, mColor); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor); - } - - virtual const char* name() { return "SetupShadow"; } - -private: - float mRadius; - float mDx; - float mDy; - int mColor; -}; - class ResetPaintFilterOp : public StateOp { public: virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { @@ -729,7 +662,7 @@ private: class DrawBitmapOp : public DrawBoundedOp { public: - DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) + DrawBitmapOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint) : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint), mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) { mEntry = mAtlas.getEntry(bitmap); @@ -823,12 +756,12 @@ public: deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() && !state.mClipSideFlags && OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode && - (mBitmap->getConfig() != SkBitmap::kA8_Config); + (mBitmap->config() != SkBitmap::kA8_Config); } const SkBitmap* bitmap() { return mBitmap; } protected: - SkBitmap* mBitmap; + const SkBitmap* mBitmap; const AssetAtlas& mAtlas; uint32_t mEntryGenerationId; AssetAtlas::Entry* mEntry; @@ -837,7 +770,7 @@ protected: class DrawBitmapMatrixOp : public DrawBoundedOp { public: - DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) + DrawBitmapMatrixOp(const SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint) : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) { mLocalBounds.set(0, 0, bitmap->width(), bitmap->height()); const mat4 transform(*matrix); @@ -849,7 +782,7 @@ public: } virtual void output(int level, uint32_t logFlags) const { - OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix)); + OP_LOG("Draw bitmap %p matrix " SK_MATRIX_STRING, mBitmap, SK_MATRIX_ARGS(mMatrix)); } virtual const char* name() { return "DrawBitmapMatrix"; } @@ -860,14 +793,15 @@ public: } private: - SkBitmap* mBitmap; - SkMatrix* mMatrix; + const SkBitmap* mBitmap; + const SkMatrix* mMatrix; }; class DrawBitmapRectOp : public DrawBoundedOp { public: - DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, - float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) + DrawBitmapRectOp(const SkBitmap* bitmap, + float srcLeft, float srcTop, float srcRight, float srcBottom, + float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} @@ -890,13 +824,13 @@ public: } private: - SkBitmap* mBitmap; + const SkBitmap* mBitmap; Rect mSrc; }; class DrawBitmapDataOp : public DrawBitmapOp { public: - DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) + DrawBitmapDataOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint) : DrawBitmapOp(bitmap, left, top, paint) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { @@ -918,8 +852,8 @@ public: class DrawBitmapMeshOp : public DrawBoundedOp { public: - DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight, - float* vertices, int* colors, SkPaint* paint) + DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint) : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), mVertices(vertices), mColors(colors) {} @@ -941,17 +875,17 @@ public: } private: - SkBitmap* mBitmap; + const SkBitmap* mBitmap; int mMeshWidth; int mMeshHeight; - float* mVertices; - int* mColors; + const float* mVertices; + const int* mColors; }; class DrawPatchOp : public DrawBoundedOp { public: - DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch, - float left, float top, float right, float bottom, SkPaint* paint) + DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch, + float left, float top, float right, float bottom, const SkPaint* paint) : DrawBoundedOp(left, top, right, bottom, paint), mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL), mAtlas(Caches::getInstance().assetAtlas) { @@ -1028,8 +962,8 @@ public: TextureVertex* opVertices = opMesh->vertices; for (uint32_t j = 0; j < vertexCount; j++, opVertices++) { TextureVertex::set(vertex++, - opVertices->position[0] + tx, opVertices->position[1] + ty, - opVertices->texture[0], opVertices->texture[1]); + opVertices->x + tx, opVertices->y + ty, + opVertices->u, opVertices->v); } // Dirty the current layer if possible. When the 9-patch does not @@ -1083,8 +1017,8 @@ public: } private: - SkBitmap* mBitmap; - Res_png_9patch* mPatch; + const SkBitmap* mBitmap; + const Res_png_9patch* mPatch; uint32_t mGenerationId; const Patch* mMesh; @@ -1097,7 +1031,7 @@ private: class DrawColorOp : public DrawOp { public: DrawColorOp(int color, SkXfermode::Mode mode) - : DrawOp(0), mColor(color), mMode(mode) {}; + : DrawOp(NULL), mColor(color), mMode(mode) {}; virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawColor(mColor, mMode); @@ -1116,7 +1050,7 @@ private: class DrawStrokableOp : public DrawBoundedOp { public: - DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint) + DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawBoundedOp(left, top, right, bottom, paint) {}; bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) { @@ -1141,7 +1075,7 @@ public: class DrawRectOp : public DrawStrokableOp { public: - DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint) + DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { @@ -1165,7 +1099,7 @@ public: class DrawRectsOp : public DrawBoundedOp { public: - DrawRectsOp(const float* rects, int count, SkPaint* paint) + DrawRectsOp(const float* rects, int count, const SkPaint* paint) : DrawBoundedOp(rects, count, paint), mRects(rects), mCount(count) {} @@ -1192,7 +1126,7 @@ private: class DrawRoundRectOp : public DrawStrokableOp { public: DrawRoundRectOp(float left, float top, float right, float bottom, - float rx, float ry, SkPaint* paint) + float rx, float ry, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { @@ -1213,7 +1147,7 @@ private: class DrawCircleOp : public DrawStrokableOp { public: - DrawCircleOp(float x, float y, float radius, SkPaint* paint) + DrawCircleOp(float x, float y, float radius, const SkPaint* paint) : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), mX(x), mY(y), mRadius(radius) {} @@ -1233,9 +1167,30 @@ private: float mRadius; }; +class DrawCirclePropsOp : public DrawOp { +public: + DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint) + : DrawOp(paint), mX(x), mY(y), mRadius(radius) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + return renderer.drawCircle(*mX, *mY, *mRadius, getPaint(renderer)); + } + + virtual void output(int level, uint32_t logFlags) const { + OP_LOG("Draw Circle Props x %p, y %p, r %p", mX, mY, mRadius); + } + + virtual const char* name() { return "DrawCircleProps"; } + +private: + float* mX; + float* mY; + float* mRadius; +}; + class DrawOvalOp : public DrawStrokableOp { public: - DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint) + DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { @@ -1253,7 +1208,7 @@ public: class DrawArcOp : public DrawStrokableOp { public: DrawArcOp(float left, float top, float right, float bottom, - float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) + float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint), mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} @@ -1278,7 +1233,7 @@ private: class DrawPathOp : public DrawBoundedOp { public: - DrawPathOp(SkPath* path, SkPaint* paint) + DrawPathOp(const SkPath* path, const SkPaint* paint) : DrawBoundedOp(paint), mPath(path) { float left, top, offset; uint32_t width, height; @@ -1294,7 +1249,7 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - SkPaint* paint = getPaint(renderer); + const SkPaint* paint = getPaint(renderer); renderer.getCaches().pathCache.precache(mPath, paint); deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; @@ -1307,12 +1262,12 @@ public: virtual const char* name() { return "DrawPath"; } private: - SkPath* mPath; + const SkPath* mPath; }; class DrawLinesOp : public DrawBoundedOp { public: - DrawLinesOp(float* points, int count, SkPaint* paint) + DrawLinesOp(const float* points, int count, const SkPaint* paint) : DrawBoundedOp(points, count, paint), mPoints(points), mCount(count) { mLocalBounds.outset(strokeWidthOutset()); @@ -1336,13 +1291,13 @@ public: } protected: - float* mPoints; + const float* mPoints; int mCount; }; class DrawPointsOp : public DrawLinesOp { public: - DrawPointsOp(float* points, int count, SkPaint* paint) + DrawPointsOp(const float* points, int count, const SkPaint* paint) : DrawLinesOp(points, count, paint) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { @@ -1358,16 +1313,20 @@ public: class DrawSomeTextOp : public DrawOp { public: - DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint) + DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint) : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; virtual void output(int level, uint32_t logFlags) const { OP_LOG("Draw some text, %d bytes", mBytesCount); } + virtual bool hasTextShadow() const { + return OpenGLRenderer::hasTextShadow(mPaint); + } + virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - SkPaint* paint = getPaint(renderer); + const SkPaint* paint = getPaint(renderer); FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); fontRenderer.precache(paint, mText, mCount, mat4::identity()); @@ -1385,7 +1344,7 @@ protected: class DrawTextOnPathOp : public DrawSomeTextOp { public: DrawTextOnPathOp(const char* text, int bytesCount, int count, - SkPath* path, float hOffset, float vOffset, SkPaint* paint) + const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) : DrawSomeTextOp(text, bytesCount, count, paint), mPath(path), mHOffset(hOffset), mVOffset(vOffset) { /* TODO: inherit from DrawBounded and init mLocalBounds */ @@ -1399,7 +1358,7 @@ public: virtual const char* name() { return "DrawTextOnPath"; } private: - SkPath* mPath; + const SkPath* mPath; float mHOffset; float mVOffset; }; @@ -1407,7 +1366,7 @@ private: class DrawPosTextOp : public DrawSomeTextOp { public: DrawPosTextOp(const char* text, int bytesCount, int count, - const float* positions, SkPaint* paint) + const float* positions, const SkPaint* paint) : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) { /* TODO: inherit from DrawBounded and init mLocalBounds */ } @@ -1425,7 +1384,7 @@ private: class DrawTextOp : public DrawBoundedOp { public: DrawTextOp(const char* text, int bytesCount, int count, float x, float y, - const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds) + const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds) : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count), mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) { memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float)); @@ -1433,7 +1392,7 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - SkPaint* paint = getPaint(renderer); + const SkPaint* paint = getPaint(renderer); FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); const mat4& transform = renderer.findBestFontTransform(state.mMatrix); if (mPrecacheTransform != transform) { @@ -1502,7 +1461,7 @@ private: class DrawFunctorOp : public DrawOp { public: DrawFunctorOp(Functor* functor) - : DrawOp(0), mFunctor(functor) {} + : DrawOp(NULL), mFunctor(functor) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { renderer.startMark("GL functor"); @@ -1522,21 +1481,22 @@ private: }; class DrawDisplayListOp : public DrawBoundedOp { + friend class RenderNode; // grant DisplayList access to info of child public: - DrawDisplayListOp(DisplayList* displayList, int flags) + DrawDisplayListOp(RenderNode* displayList, int flags, const mat4& transformFromParent) : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0), - mDisplayList(displayList), mFlags(flags) {} + mDisplayList(displayList), mFlags(flags), mTransformFromParent(transformFromParent) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { - if (mDisplayList && mDisplayList->isRenderable()) { - mDisplayList->defer(deferStruct, level + 1); + if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { + mDisplayList->deferNodeInParent(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) { - if (mDisplayList && mDisplayList->isRenderable()) { - mDisplayList->replay(replayStruct, level + 1); + if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { + mDisplayList->replayNodeInParent(replayStruct, level + 1); } } @@ -1554,15 +1514,86 @@ public: virtual const char* name() { return "DrawDisplayList"; } + RenderNode* renderNode() { return mDisplayList; } + private: - DisplayList* mDisplayList; - int mFlags; + RenderNode* mDisplayList; + const int mFlags; + + /////////////////////////// + // Properties below are used by DisplayList::computeOrderingImpl() and iterate() + /////////////////////////// + /** + * Records transform vs parent, used for computing total transform without rerunning DL contents + */ + const mat4 mTransformFromParent; + + /** + * Holds the transformation between the projection surface ViewGroup and this DisplayList + * drawing instance. Represents any translations / transformations done within the drawing of + * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this + * DisplayList draw instance. + * + * Note: doesn't include any transformation recorded within the DisplayList and its properties. + */ + mat4 mTransformFromCompositingAncestor; + bool mSkipInOrderDraw; +}; + +/** + * Not a canvas operation, used only by 3d / z ordering logic in RenderNode::iterate() + */ +class DrawShadowOp : public DrawOp { +public: + DrawShadowOp(const mat4& transformXY, const mat4& transformZ, + float casterAlpha, bool casterUnclipped, + float fallbackWidth, float fallbackHeight, + const SkPath* outline, const SkPath* revealClip) + : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), + mCasterAlpha(casterAlpha), mCasterUnclipped(casterUnclipped), + mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight), + mOutline(outline), mRevealClip(revealClip) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + SkPath casterPerimeter; + if (!mOutline || mOutline->isEmpty()) { + casterPerimeter.addRect(0, 0, mFallbackWidth, mFallbackHeight); + } else { + casterPerimeter = *mOutline; + } + + if (mRevealClip) { + // intersect the outline with the convex reveal clip + Op(casterPerimeter, *mRevealClip, kIntersect_PathOp, &casterPerimeter); + } + + return renderer.drawShadow(mTransformXY, mTransformZ, + mCasterAlpha, mCasterUnclipped, &casterPerimeter); + } + + virtual void output(int level, uint32_t logFlags) const { + OP_LOG("DrawShadow of outline %p", mOutline); + } + + virtual const char* name() { return "DrawShadow"; } + +private: + const mat4 mTransformXY; + const mat4 mTransformZ; + const float mCasterAlpha; + const bool mCasterUnclipped; + const float mFallbackWidth; + const float mFallbackHeight; + + // these point at convex SkPaths owned by RenderProperties, or null + const SkPath* mOutline; + const SkPath* mRevealClip; }; class DrawLayerOp : public DrawOp { public: DrawLayerOp(Layer* layer, float x, float y) - : DrawOp(0), mLayer(layer), mX(x), mY(y) {} + : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawLayer(mLayer, mX, mY); |
