diff options
Diffstat (limited to 'libs/hwui/DisplayListOp.h')
-rw-r--r-- | libs/hwui/DisplayListOp.h | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index a0290e3..028decd 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -26,8 +26,10 @@ #include <private/hwui/DrawGlInfo.h> #include "OpenGLRenderer.h" +#include "AssetAtlas.h" #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" +#include "UvMapper.h" #include "utils/LinearAllocator.h" #define CRASH() do { \ @@ -218,6 +220,9 @@ public: DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint) : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} + DrawBoundedOp(const Rect& localBounds, 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) @@ -721,7 +726,6 @@ private: int mSetBits; }; - /////////////////////////////////////////////////////////////////////////////// // DRAW OPERATIONS - these are operations that can draw to the canvas's device /////////////////////////////////////////////////////////////////////////////// @@ -729,9 +733,16 @@ private: class DrawBitmapOp : public DrawBoundedOp { public: DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) - : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), - paint), - mBitmap(bitmap) {} + : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint), + mBitmap(bitmap), mAtlasEntry(NULL) { + } + + DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint, + const AssetAtlas::Entry* entry) + : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint), + mBitmap(bitmap), mAtlasEntry(entry) { + if (entry) mUvMapper = entry->uvMapper; + } virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, @@ -749,14 +760,20 @@ public: TextureVertex vertices[6 * ops.size()]; TextureVertex* vertex = &vertices[0]; - // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op, and allowing - // them to be merged in getBatchId() - const Rect texCoords(0, 0, 1, 1); + bool transformed = false; - const float width = mBitmap->width(); - const float height = mBitmap->height(); + // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op, + // and allowing them to be merged in getBatchId() for (unsigned int i = 0; i < ops.size(); i++) { const Rect& opBounds = ops[i]->state.mBounds; + // When we reach multiDraw(), the matrix can be either + // pureTranslate or simple (translate and/or scale). + // If the matrix is not pureTranslate, then we have a scale + if (!ops[i]->state.mMatrix.isPureTranslate()) transformed = true; + + Rect texCoords(0, 0, 1, 1); + ((DrawBitmapOp*) ops[i])->mUvMapper.map(texCoords); + SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top); SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top); SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom); @@ -766,7 +783,8 @@ public: SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom); } - return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], bounds, mPaint); + return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], + transformed, bounds, mPaint); } virtual void output(int level, uint32_t logFlags) { @@ -775,18 +793,25 @@ public: virtual const char* name() { return "DrawBitmap"; } + bool bitmapMergeAllowed() { + return state.mMatrix.isSimple() && !state.mClipped && + OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; + } + virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) { *batchId = DeferredDisplayList::kOpBatch_Bitmap; - *mergeId = (mergeid_t)mBitmap; + *mergeId = mAtlasEntry ? (mergeid_t) &mAtlasEntry->atlas : (mergeid_t) mBitmap; // don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in // MergingDrawBatch::canMergeWith - return mergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config); + return bitmapMergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config); } const SkBitmap* bitmap() { return mBitmap; } protected: SkBitmap* mBitmap; + const AssetAtlas::Entry* mAtlasEntry; + UvMapper mUvMapper; }; class DrawBitmapMatrixOp : public DrawBoundedOp { @@ -904,20 +929,25 @@ private: class DrawPatchOp : public DrawBoundedOp { public: - DrawPatchOp(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, - int alpha, SkXfermode::Mode mode) + DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch, + float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode) : DrawBoundedOp(left, top, right, bottom, 0), - mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs), - mColors(colors), mxDivsCount(width), myDivsCount(height), - mNumColors(numColors), mAlpha(alpha), mMode(mode) {}; + mBitmap(bitmap), mPatch(patch), mAlpha(alpha), mMode(mode), + mGenerationId(0), mMesh(NULL) { + mEntry = Caches::getInstance().assetAtlas.getEntry(bitmap); + }; virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - // NOTE: not calling the virtual method, which takes a paint - return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors, - mxDivsCount, myDivsCount, mNumColors, - mLocalBounds.left, mLocalBounds.top, + if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) { + PatchCache& cache = renderer.getCaches().patchCache; + mMesh = cache.get(mEntry, mBitmap->width(), mBitmap->height(), + mLocalBounds.right - mLocalBounds.left, mLocalBounds.bottom - mLocalBounds.top, + mPatch); + mGenerationId = cache.getGenerationId(); + } + // We're not calling the public variant of drawPatch() here + // This method won't perform the quickReject() since we've already done it at this point + return renderer.drawPatch(mBitmap, mMesh, mEntry, mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode); } @@ -929,20 +959,20 @@ public: virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) { *batchId = DeferredDisplayList::kOpBatch_Patch; - *mergeId = (mergeid_t)mBitmap; + *mergeId = (mergeid_t) mBitmap; return true; } private: SkBitmap* mBitmap; - const int32_t* mxDivs; - const int32_t* myDivs; - const uint32_t* mColors; - uint32_t mxDivsCount; - uint32_t myDivsCount; - int8_t mNumColors; + Res_png_9patch* mPatch; + int mAlpha; SkXfermode::Mode mMode; + + uint32_t mGenerationId; + const Patch* mMesh; + AssetAtlas::Entry* mEntry; }; class DrawColorOp : public DrawOp { @@ -1270,23 +1300,10 @@ private: class DrawTextOp : public DrawBoundedOp { public: DrawTextOp(const char* text, int bytesCount, int count, float x, float y, - const float* positions, SkPaint* paint, float length) - : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count), - mX(x), mY(y), mPositions(positions), mLength(length) { - // duplicates bounds calculation from OpenGLRenderer::drawText, but doesn't alter mX - SkPaint::FontMetrics metrics; - paint->getFontMetrics(&metrics, 0.0f); - switch (paint->getTextAlign()) { - case SkPaint::kCenter_Align: - x -= length / 2.0f; - break; - case SkPaint::kRight_Align: - x -= length; - break; - default: - break; - } - mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom); + const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds) + : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count), + mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) { + mLocalBounds.translate(x,y); memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float)); } @@ -1312,7 +1329,7 @@ public: virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawText(mText, mBytesCount, mCount, mX, mY, - mPositions, getPaint(renderer), mLength); + mPositions, getPaint(renderer), mTotalAdvance, mLocalBounds); } virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, @@ -1325,7 +1342,8 @@ public: DrawTextOp& op = *((DrawTextOp*)ops[i]); status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, - op.mPositions, op.getPaint(renderer), op.mLength, drawOpMode); + op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds, + drawOpMode); } return status; } @@ -1343,7 +1361,7 @@ private: float mX; float mY; const float* mPositions; - float mLength; + float mTotalAdvance; mat4 mPrecacheTransform; }; |