diff options
author | Derek Sollenberger <djsollen@google.com> | 2013-01-30 14:32:29 -0500 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2013-01-30 14:32:29 -0500 |
commit | 2dbd185fd0e5dfe9addb677f42716c442b7e62bd (patch) | |
tree | 6aac1ed40b80d003c8d5d6469d21092cd26d7141 /libs | |
parent | 1de9023190691b44df0f45eaaf501ced6177ca09 (diff) | |
parent | c93c6aa5553203f05df871804517885fcc071cfd (diff) | |
download | frameworks_base-2dbd185fd0e5dfe9addb677f42716c442b7e62bd.zip frameworks_base-2dbd185fd0e5dfe9addb677f42716c442b7e62bd.tar.gz frameworks_base-2dbd185fd0e5dfe9addb677f42716c442b7e62bd.tar.bz2 |
resolved conflicts for merge of c93c6aa5 to master-chromium
Change-Id: I51429ed5359355025f873ccab11bfabbbe772a46
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListLogBuffer.cpp | 39 | ||||
-rw-r--r-- | libs/hwui/DisplayListLogBuffer.h | 18 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 1138 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 1385 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 310 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/Patch.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/PathRenderer.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/Rect.h | 19 |
9 files changed, 1434 insertions, 1486 deletions
diff --git a/libs/hwui/DisplayListLogBuffer.cpp b/libs/hwui/DisplayListLogBuffer.cpp index f204644..f039fcd 100644 --- a/libs/hwui/DisplayListLogBuffer.cpp +++ b/libs/hwui/DisplayListLogBuffer.cpp @@ -18,9 +18,8 @@ // BUFFER_SIZE size must be one more than a multiple of COMMAND_SIZE to ensure // that mStart always points at the next command, not just the next item -#define COMMAND_SIZE 2 #define NUM_COMMANDS 50 -#define BUFFER_SIZE ((NUM_COMMANDS * COMMAND_SIZE) + 1) +#define BUFFER_SIZE ((NUM_COMMANDS) + 1) /** * DisplayListLogBuffer is a utility class which logs the most recent display @@ -57,7 +56,7 @@ namespace uirenderer { DisplayListLogBuffer::DisplayListLogBuffer() { - mBufferFirst = (int*) malloc(BUFFER_SIZE * sizeof(int)); + mBufferFirst = (OpLog*) malloc(BUFFER_SIZE * sizeof(OpLog)); mStart = mBufferFirst; mBufferLast = mBufferFirst + BUFFER_SIZE - 1; mEnd = mStart; @@ -71,42 +70,30 @@ DisplayListLogBuffer::~DisplayListLogBuffer() { * Called from DisplayListRenderer to output the current buffer into the * specified FILE. This only happens in a dumpsys/bugreport operation. */ -void DisplayListLogBuffer::outputCommands(FILE *file, const char* opNames[]) +void DisplayListLogBuffer::outputCommands(FILE *file) { - int *tmpBufferPtr = mStart; + OpLog* tmpBufferPtr = mStart; while (true) { if (tmpBufferPtr == mEnd) { break; } - int level = *tmpBufferPtr++; + OpLog* nextOp = tmpBufferPtr++; if (tmpBufferPtr > mBufferLast) { tmpBufferPtr = mBufferFirst; } - int op = *tmpBufferPtr++; - if (tmpBufferPtr > mBufferLast) { - tmpBufferPtr = mBufferFirst; - } - uint32_t count = (level + 1) * 2; - char indent[count + 1]; - for (uint32_t i = 0; i < count; i++) { - indent[i] = ' '; - } - indent[count] = '\0'; - fprintf(file, "%s%s\n", indent, opNames[op]); - } -} -void DisplayListLogBuffer::writeCommand(int level, int op) { - writeInt(level); - writeInt(op); + fprintf(file, "%*s%s\n", tmpBufferPtr->level*2, "", tmpBufferPtr->label); + } } /** - * Store the given value in the buffer and increment/wrap the mEnd - * and mStart values as appropriate. + * Store the given level and label in the buffer and increment/wrap the mEnd + * and mStart values as appropriate. Label should point to static memory. */ -void DisplayListLogBuffer::writeInt(int value) { - *((int*)mEnd) = value; +void DisplayListLogBuffer::writeCommand(int level, const char* label) { + mEnd->level = level; + mEnd->label = label; + if (mEnd == mBufferLast) { mEnd = mBufferFirst; } else { diff --git a/libs/hwui/DisplayListLogBuffer.h b/libs/hwui/DisplayListLogBuffer.h index 5d689bb..c884789 100644 --- a/libs/hwui/DisplayListLogBuffer.h +++ b/libs/hwui/DisplayListLogBuffer.h @@ -31,19 +31,23 @@ class DisplayListLogBuffer: public Singleton<DisplayListLogBuffer> { friend class Singleton<DisplayListLogBuffer>; public: - void writeCommand(int level, int op); - void writeInt(int value); - void outputCommands(FILE *file, const char* opNames[]); + void writeCommand(int level, const char* label); + void outputCommands(FILE *file); bool isEmpty() { return (mStart == mEnd); } + struct OpLog { + int level; + const char* label; + }; + private: - int *mBufferFirst; // where the memory starts - int* mStart; // where the current command stream starts - int* mEnd; // where the current commands end - int* mBufferLast; // where the buffer memory ends + OpLog* mBufferFirst; // where the memory starts + OpLog* mStart; // where the current command stream starts + OpLog* mEnd; // where the current commands end + OpLog* mBufferLast; // where the buffer memory ends }; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h new file mode 100644 index 0000000..a4de56d --- /dev/null +++ b/libs/hwui/DisplayListOp.h @@ -0,0 +1,1138 @@ +/* + * Copyright (C) 2012 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 ANDROID_HWUI_DISPLAY_OPERATION_H +#define ANDROID_HWUI_DISPLAY_OPERATION_H + +#include <SkXfermode.h> + +#include "OpenGLRenderer.h" +#include "DisplayListRenderer.h" +#include "utils/LinearAllocator.h" + +#define CRASH() do { \ + *(int *)(uintptr_t)0xbbadbeef = 0; \ + ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ +} while(false) + +#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" +#define MATRIX_ARGS(m) \ + m->get(0), m->get(1), m->get(2), \ + m->get(3), m->get(4), m->get(5), \ + m->get(6), m->get(7), m->get(8) +#define RECT_STRING "%.2f %.2f %.2f %.2f" +#define RECT_ARGS(r) \ + r.left, r.top, r.right, r.bottom + +// Use OP_LOG for logging with arglist, OP_LOGS if just printing char* +#define OP_LOGS(s) OP_LOG("%s", s) +#define OP_LOG(s, ...) ALOGD( "%*s--%p " s, level * 2, "", this, __VA_ARGS__ ) + + +namespace android { +namespace uirenderer { + +/** + * Structure for storing canvas operations when they are recorded into a DisplayList, so that they + * may be replayed to an OpenGLRenderer. + * + * To avoid individual memory allocations, DisplayListOps may only be allocated into a + * LinearAllocator's managed memory buffers. Each pointer held by a DisplayListOp is either a + * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or + * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is + * never called as LinearAllocators are simply discarded, so no memory management should be done in + * this class. + */ +class DisplayListOp { +public: + // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted. + // standard new() intentionally not implemented, and delete/deconstructor should never be used. + virtual ~DisplayListOp() { CRASH(); } + static void operator delete(void* ptr) { CRASH(); } + /** static void* operator new(size_t size); PURPOSELY OMITTED **/ + static void* operator new(size_t size, LinearAllocator& allocator) { + return allocator.alloc(size); + } + + enum OpLogFlag { + kOpLogFlag_Recurse = 0x1, + kOpLogFlag_JSON = 0x2 // TODO: add? + }; + + //TODO: for draw batching, DrawOps should override a virtual sub-method, with + // DrawOps::apply deferring operations to a different list if possible + virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, + uint32_t level, bool caching, int multipliedAlpha) = 0; + + virtual void output(int level, uint32_t flags = 0) = 0; + + // NOTE: it would be nice to declare constants and overriding the implementation in each op to + // point at the constants, but that seems to require a .cpp file + virtual const char* name() = 0; +}; + +class StateOp : public DisplayListOp { +public: + StateOp() {}; + + virtual ~StateOp() {} + + virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, + uint32_t level, bool caching, int multipliedAlpha) { + applyState(renderer, saveCount); + return DrawGlInfo::kStatusDone; + } + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0; +}; + +class DrawOp : public DisplayListOp { +public: + DrawOp(SkPaint* paint) + : mPaint(paint), mQuickRejected(false) {} + + virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, + uint32_t level, bool caching, int multipliedAlpha) { + if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) { + return DrawGlInfo::kStatusDone; + } + + return applyDraw(renderer, dirty, level, caching, multipliedAlpha); + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) = 0; + + // returns true if bounds exist + virtual bool getLocalBounds(Rect& localBounds) { return false; } + + // TODO: better refine localbounds usage + void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; } + bool getQuickRejected() { return mQuickRejected; } + +protected: + SkPaint* getPaint(OpenGLRenderer& renderer) { + return renderer.filterPaint(mPaint); + } + + 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) + : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} + + // default constructor for area, to be overridden in child constructor body + DrawBoundedOp(SkPaint* paint) + : DrawOp(paint) {} + + bool getLocalBounds(Rect& localBounds) { + localBounds.set(mLocalBounds); + return true; + } + +protected: + Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint +}; + +/////////////////////////////////////////////////////////////////////////////// +// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do +// not directly draw or alter output +/////////////////////////////////////////////////////////////////////////////// + +class SaveOp : public StateOp { +public: + SaveOp(int flags) + : mFlags(flags) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.save(mFlags); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Save flags %x", mFlags); + } + + virtual const char* name() { return "Save"; } + +private: + int mFlags; +}; + +class RestoreToCountOp : public StateOp { +public: + RestoreToCountOp(int count) + : mCount(count) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.restoreToCount(saveCount + mCount); + + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Restore to count %d", mCount); + } + + virtual const char* name() { return "RestoreToCount"; } + +private: + int mCount; +}; + +class SaveLayerOp : public StateOp { +public: + SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags) + : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + SkPaint* paint = renderer.filterPaint(mPaint); + renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea)); + } + + virtual const char* name() { return "SaveLayer"; } + +private: + Rect mArea; + SkPaint* mPaint; + int mFlags; +}; + +class SaveLayerAlphaOp : public StateOp { +public: + SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags) + : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea)); + } + + virtual const char* name() { return "SaveLayerAlpha"; } +private: + Rect mArea; + int mAlpha; + int mFlags; +}; + +class TranslateOp : public StateOp { +public: + TranslateOp(float dx, float dy) + : mDx(dx), mDy(dy) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.translate(mDx, mDy); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Translate by %f %f", mDx, mDy); + } + + virtual const char* name() { return "Translate"; } + +private: + float mDx; + float mDy; +}; + +class RotateOp : public StateOp { +public: + RotateOp(float degrees) + : mDegrees(degrees) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.rotate(mDegrees); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Rotate by %f degrees", mDegrees); + } + + virtual const char* name() { return "Rotate"; } + +private: + float mDegrees; +}; + +class ScaleOp : public StateOp { +public: + ScaleOp(float sx, float sy) + : mSx(sx), mSy(sy) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.scale(mSx, mSy); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Scale by %f %f", mSx, mSy); + } + + virtual const char* name() { return "Scale"; } + +private: + float mSx; + float mSy; +}; + +class SkewOp : public StateOp { +public: + SkewOp(float sx, float sy) + : mSx(sx), mSy(sy) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.skew(mSx, mSy); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("Skew by %f %f", mSx, mSy); + } + + virtual const char* name() { return "Skew"; } + +private: + float mSx; + float mSy; +}; + +class SetMatrixOp : public StateOp { +public: + SetMatrixOp(SkMatrix* matrix) + : mMatrix(matrix) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.setMatrix(mMatrix); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); + } + + virtual const char* name() { return "SetMatrix"; } + +private: + SkMatrix* mMatrix; +}; + +class ConcatMatrixOp : public StateOp { +public: + ConcatMatrixOp(SkMatrix* matrix) + : mMatrix(matrix) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.concatMatrix(mMatrix); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); + } + + virtual const char* name() { return "ConcatMatrix"; } + +private: + SkMatrix* mMatrix; +}; + +class ClipRectOp : public StateOp { +public: + ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) + : mArea(left, top, right, bottom), mOp(op) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea)); + } + + virtual const char* name() { return "ClipRect"; } + +private: + Rect mArea; + SkRegion::Op mOp; +}; + +class ClipPathOp : public StateOp { +public: + ClipPathOp(SkPath* path, SkRegion::Op op) + : mPath(path), mOp(op) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.clipPath(mPath, mOp); + } + + virtual void output(int level, uint32_t flags = 0) { + SkRect bounds = mPath->getBounds(); + OP_LOG("ClipPath bounds " RECT_STRING, + bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); + } + + virtual const char* name() { return "ClipPath"; } + +private: + SkPath* mPath; + SkRegion::Op mOp; +}; + +class ClipRegionOp : public StateOp { +public: + ClipRegionOp(SkRegion* region, SkRegion::Op op) + : mRegion(region), mOp(op) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.clipRegion(mRegion, mOp); + } + + virtual void output(int level, uint32_t flags = 0) { + SkIRect bounds = mRegion->getBounds(); + OP_LOG("ClipRegion bounds %d %d %d %d", + bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); + } + + virtual const char* name() { return "ClipRegion"; } + +private: + SkRegion* mRegion; + SkRegion::Op mOp; +}; + +class ResetShaderOp : public StateOp { +public: + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.resetShader(); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOGS("ResetShader"); + } + + virtual const char* name() { return "ResetShader"; } +}; + +class SetupShaderOp : public StateOp { +public: + SetupShaderOp(SkiaShader* shader) + : mShader(shader) {} + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.setupShader(mShader); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("SetupShader, shader %p", mShader); + } + + virtual const char* name() { return "SetupShader"; } + +private: + SkiaShader* mShader; +}; + +class ResetColorFilterOp : public StateOp { +public: + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.resetColorFilter(); + } + + virtual void output(int level, uint32_t flags = 0) { + 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) { + renderer.setupColorFilter(mColorFilter); + } + + virtual void output(int level, uint32_t flags = 0) { + 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) { + renderer.resetShadow(); + } + + virtual void output(int level, uint32_t flags = 0) { + 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) { + renderer.setupShadow(mRadius, mDx, mDy, mColor); + } + + virtual void output(int level, uint32_t flags = 0) { + 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) { + renderer.resetPaintFilter(); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOGS("ResetPaintFilter"); + } + + virtual const char* name() { return "ResetPaintFilter"; } +}; + +class SetupPaintFilterOp : public StateOp { +public: + SetupPaintFilterOp(int clearBits, int setBits) + : mClearBits(clearBits), mSetBits(setBits) {} + + virtual void applyState(OpenGLRenderer& renderer, int saveCount) { + renderer.setupPaintFilter(mClearBits, mSetBits); + } + + virtual void output(int level, uint32_t flags = 0) { + OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); + } + + virtual const char* name() { return "SetupPaintFilter"; } + +private: + int mClearBits; + int mSetBits; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// DRAW OPERATIONS - these are operations that can draw to the canvas's device +/////////////////////////////////////////////////////////////////////////////// + +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) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + SkPaint* paint = getPaint(renderer); + int oldAlpha = -1; + if (caching && multipliedAlpha < 255) { + oldAlpha = paint->getAlpha(); + paint->setAlpha(multipliedAlpha); + } + status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint); + if (oldAlpha >= 0) { + paint->setAlpha(oldAlpha); + } + return ret; + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top); + } + + virtual const char* name() { return "DrawBitmap"; } + +protected: + SkBitmap* mBitmap; +}; + +class DrawBitmapMatrixOp : public DrawBoundedOp { +public: + DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) + : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) { + mLocalBounds.set(0, 0, bitmap->width(), bitmap->height()); + const mat4 transform(*matrix); + transform.mapRect(mLocalBounds); + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix)); + } + + virtual const char* name() { return "DrawBitmap"; } + +private: + SkBitmap* mBitmap; + 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) + : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), + mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, + mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, + getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING, + mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); + } + + virtual const char* name() { return "DrawBitmapRect"; } + +private: + SkBitmap* mBitmap; + Rect mSrc; +}; + +class DrawBitmapDataOp : public DrawBitmapOp { +public: + DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) + : DrawBitmapOp(bitmap, left, top, paint) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawBitmapData(mBitmap, mLocalBounds.left, + mLocalBounds.top, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw bitmap %p", mBitmap); + } + + virtual const char* name() { return "DrawBitmapData"; } +}; + +class DrawBitmapMeshOp : public DrawOp { +public: + DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight, + float* vertices, int* colors, SkPaint* paint) + : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), + mVertices(vertices), mColors(colors) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, + mVertices, mColors, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); + } + + virtual const char* name() { return "DrawBitmapMesh"; } + +private: + SkBitmap* mBitmap; + int mMeshWidth; + int mMeshHeight; + float* mVertices; + int* mColors; +}; + +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) + : DrawBoundedOp(left, top, right, bottom, 0), + mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs), + mColors(colors), mxDivsCount(width), myDivsCount(height), + mNumColors(numColors), mAlpha(alpha), mMode(mode) {}; + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + // NOTE: not calling the virtual method, which takes a paint + return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors, + mxDivsCount, myDivsCount, mNumColors, + mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds)); + } + + virtual const char* name() { return "DrawPatch"; } + +private: + SkBitmap* mBitmap; + const int32_t* mxDivs; + const int32_t* myDivs; + const uint32_t* mColors; + uint32_t mxDivsCount; + uint32_t myDivsCount; + int8_t mNumColors; + int mAlpha; + SkXfermode::Mode mMode; +}; + +class DrawColorOp : public DrawOp { +public: + DrawColorOp(int color, SkXfermode::Mode mode) + : DrawOp(0), mColor(color), mMode(mode) {}; + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawColor(mColor, mMode); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw color %#x, mode %d", mColor, mMode); + } + + virtual const char* name() { return "DrawColor"; } + +private: + int mColor; + SkXfermode::Mode mMode; +}; + +class DrawStrokableOp : public DrawBoundedOp { +public: + DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint) + : DrawBoundedOp(left, top, right, bottom, paint) {}; + + bool getLocalBounds(Rect& localBounds) { + if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { + float outset = mPaint->getStrokeWidth() * 0.5f; + localBounds.set(mLocalBounds.left - outset, mLocalBounds.top - outset, + mLocalBounds.right + outset, mLocalBounds.bottom + outset); + } else { + localBounds.set(mLocalBounds); + } + return true; + } +}; + +class DrawRectOp : public DrawStrokableOp { +public: + DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint) + : DrawStrokableOp(left, top, right, bottom, paint) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds)); + } + + virtual const char* name() { return "DrawRect"; } +}; + +class DrawRectsOp : public DrawOp { +public: + DrawRectsOp(const float* rects, int count, SkPaint* paint) + : DrawOp(paint), mRects(rects), mCount(count) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawRects(mRects, mCount, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Rects count %d", mCount); + } + + virtual const char* name() { return "DrawRects"; } + +private: + const float* mRects; + int mCount; +}; + +class DrawRoundRectOp : public DrawStrokableOp { +public: + DrawRoundRectOp(float left, float top, float right, float bottom, + float rx, float ry, SkPaint* paint) + : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); + } + + virtual const char* name() { return "DrawRoundRect"; } + +private: + float mRx; + float mRy; +}; + +class DrawCircleOp : public DrawStrokableOp { +public: + DrawCircleOp(float x, float y, float radius, SkPaint* paint) + : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), + mX(x), mY(y), mRadius(radius) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); + } + + virtual const char* name() { return "DrawCircle"; } + +private: + float mX; + float mY; + float mRadius; +}; + +class DrawOvalOp : public DrawStrokableOp { +public: + DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint) + : DrawStrokableOp(left, top, right, bottom, paint) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds)); + } + + virtual const char* name() { return "DrawOval"; } +}; + +class DrawArcOp : public DrawStrokableOp { +public: + DrawArcOp(float left, float top, float right, float bottom, + float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) + : DrawStrokableOp(left, top, right, bottom, paint), + mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, + mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d", + RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); + } + + virtual const char* name() { return "DrawArc"; } + +private: + float mStartAngle; + float mSweepAngle; + bool mUseCenter; +}; + +class DrawPathOp : public DrawBoundedOp { +public: + DrawPathOp(SkPath* path, SkPaint* paint) + : DrawBoundedOp(paint), mPath(path) { + float left, top, offset; + uint32_t width, height; + computePathBounds(path, paint, left, top, offset, width, height); + left -= offset; + top -= offset; + mLocalBounds.set(left, top, left + width, top + height); + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawPath(mPath, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); + } + + virtual const char* name() { return "DrawPath"; } + +private: + SkPath* mPath; +}; + +class DrawLinesOp : public DrawOp { +public: + DrawLinesOp(float* points, int count, SkPaint* paint) + : DrawOp(paint), mPoints(points), mCount(count) { + /* TODO: inherit from DrawBoundedOp and calculate localbounds something like: + for (int i = 0; i < count; i += 2) { + mLocalBounds.left = fminf(mLocalBounds.left, points[i]); + mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]); + mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]); + mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]); + } + */ + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawLines(mPoints, mCount, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Lines count %d", mCount); + } + + virtual const char* name() { return "DrawLines"; } + +protected: + float* mPoints; + int mCount; +}; + +class DrawPointsOp : public DrawLinesOp { +public: + DrawPointsOp(float* points, int count, SkPaint* paint) + : DrawLinesOp(points, count, paint) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawPoints(mPoints, mCount, getPaint(renderer)); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Points count %d", mCount); + } + + virtual const char* name() { return "DrawPoints"; } +}; + +class DrawSomeTextOp : public DrawOp { +public: + DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint) + : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw some text, %d bytes", mBytesCount); + } +protected: + const char* mText; + int mBytesCount; + int mCount; +}; + +class DrawTextOnPathOp : public DrawSomeTextOp { +public: + DrawTextOnPathOp(const char* text, int bytesCount, int count, + SkPath* path, float hOffset, float vOffset, SkPaint* paint) + : DrawSomeTextOp(text, bytesCount, count, paint), + mPath(path), mHOffset(hOffset), mVOffset(vOffset) { + /* TODO: inherit from DrawBounded and init mLocalBounds */ + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, + mHOffset, mVOffset, getPaint(renderer)); + } + + virtual const char* name() { return "DrawTextOnPath"; } + +private: + SkPath* mPath; + float mHOffset; + float mVOffset; +}; + +class DrawPosTextOp : public DrawSomeTextOp { +public: + DrawPosTextOp(const char* text, int bytesCount, int count, + const float* positions, SkPaint* paint) + : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) { + /* TODO: inherit from DrawBounded and init mLocalBounds */ + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer)); + } + + virtual const char* name() { return "DrawPosText"; } + +private: + const float* mPositions; +}; + +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) { + SkPaint::FontMetrics metrics; + paint->getFontMetrics(&metrics, 0.0f); + mLocalBounds.set(mX, mY + metrics.fTop, mX + length, mY + metrics.fBottom); + } + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawText(mText, mBytesCount, mCount, mX, mY, + mPositions, getPaint(renderer), mLength); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount); + } + + virtual const char* name() { return "DrawText"; } + +private: + const char* mText; + int mBytesCount; + int mCount; + float mX; + float mY; + const float* mPositions; + float mLength; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SPECIAL DRAW OPERATIONS +/////////////////////////////////////////////////////////////////////////////// + +class DrawFunctorOp : public DrawOp { +public: + DrawFunctorOp(Functor* functor) + : DrawOp(0), mFunctor(functor) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + renderer.startMark("GL functor"); + status_t ret = renderer.callDrawGLFunction(mFunctor, dirty); + renderer.endMark(); + return ret; + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Functor %p", mFunctor); + } + + virtual const char* name() { return "DrawFunctor"; } + +private: + Functor* mFunctor; +}; + +class DrawDisplayListOp : public DrawOp { +public: + DrawDisplayListOp(DisplayList* displayList, int flags) + : DrawOp(0), mDisplayList(displayList), mFlags(flags) {} + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + return renderer.drawDisplayList(mDisplayList, dirty, mFlags, level + 1); + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags); + if (mDisplayList && (flags & kOpLogFlag_Recurse)) { + mDisplayList->output(level + 1); + } + } + + virtual const char* name() { return "DrawDisplayList"; } + +private: + DisplayList* mDisplayList; + int mFlags; +}; + +class DrawLayerOp : public DrawOp { +public: + DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint) + : DrawOp(paint), mLayer(layer), mX(x), mY(y) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, + bool caching, int multipliedAlpha) { + int oldAlpha = -1; + + if (caching && multipliedAlpha < 255) { + oldAlpha = mLayer->getAlpha(); + mLayer->setAlpha(multipliedAlpha); + } + status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer)); + if (oldAlpha >= 0) { + mLayer->setAlpha(oldAlpha); + } + return ret; + } + + virtual void output(int level, uint32_t flags) { + OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY); + } + + virtual const char* name() { return "DrawLayer"; } + +private: + Layer* mLayer; + float mX; + float mY; +}; + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_DISPLAY_OPERATION_H diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index f0c9ce4..5cb629e 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -21,6 +21,7 @@ #include <private/hwui/DrawGlInfo.h> #include "DisplayListLogBuffer.h" +#include "DisplayListOp.h" #include "DisplayListRenderer.h" #include "Caches.h" @@ -31,53 +32,6 @@ namespace uirenderer { // Display list /////////////////////////////////////////////////////////////////////////////// -const char* DisplayList::OP_NAMES[] = { - "Save", - "Restore", - "RestoreToCount", - "SaveLayer", - "SaveLayerAlpha", - "Translate", - "Rotate", - "Scale", - "Skew", - "SetMatrix", - "ConcatMatrix", - "ClipRect", - "ClipPath", - "ClipRegion", - "DrawDisplayList", - "DrawLayer", - "DrawBitmap", - "DrawBitmapMatrix", - "DrawBitmapRect", - "DrawBitmapData", - "DrawBitmapMesh", - "DrawPatch", - "DrawColor", - "DrawRect", - "DrawRoundRect", - "DrawCircle", - "DrawOval", - "DrawArc", - "DrawPath", - "DrawLines", - "DrawPoints", - "DrawTextOnPath", - "DrawPosText", - "DrawText", - "DrawRects", - "ResetShader", - "SetupShader", - "ResetColorFilter", - "SetupColorFilter", - "ResetShadow", - "SetupShadow", - "ResetPaintFilter", - "SetupPaintFilter", - "DrawGLFunction" -}; - void DisplayList::outputLogBuffer(int fd) { DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); if (logBuffer.isEmpty()) { @@ -87,7 +41,7 @@ void DisplayList::outputLogBuffer(int fd) { FILE *file = fdopen(fd, "a"); fprintf(file, "\nRecent DisplayList operations\n"); - logBuffer.outputCommands(file, OP_NAMES); + logBuffer.outputCommands(file); String8 cachesLog; Caches::getInstance().dumpMemoryUsage(cachesLog); @@ -116,9 +70,7 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { } void DisplayList::clearResources() { - sk_free((void*) mReader.base()); - mReader.setMemory(NULL, 0); - + mDisplayListData = NULL; delete mTransformMatrix; delete mTransformCamera; delete mTransformMatrix3D; @@ -200,7 +152,6 @@ void DisplayList::reset() { } void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { - if (reusing) { // re-using display list - clear out previous allocations clearResources(); @@ -208,16 +159,13 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde init(); - const SkWriter32& writer = recorder.writeStream(); - if (writer.size() == 0) { + mDisplayListData = recorder.getDisplayListData(); + mSize = mDisplayListData->allocator.usedSize(); + + if (mSize == 0) { return; } - mSize = writer.size(); - void* buffer = sk_malloc_throw(mSize); - writer.flatten(buffer); - mReader.setMemory(buffer, mSize); - mFunctorCount = recorder.getFunctorCount(); Caches& caches = Caches::getInstance(); @@ -312,392 +260,17 @@ size_t DisplayList::getSize() { * This function is a simplified version of replay(), where we simply retrieve and log the * display list. This function should remain in sync with the replay() function. */ -void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { - TextContainer text; - - uint32_t count = (level + 1) * 2; - char indent[count + 1]; - for (uint32_t i = 0; i < count; i++) { - indent[i] = ' '; - } - indent[count] = '\0'; - ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this, +void DisplayList::output(uint32_t level) { + ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this, mName.string(), isRenderable()); - ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); - int saveCount = renderer.getSaveCount() - 1; - - outputViewProperties(renderer, (char*) indent); - mReader.rewind(); - - while (!mReader.eof()) { - int op = mReader.readInt(); - if (op & OP_MAY_BE_SKIPPED_MASK) { - int skip = mReader.readInt(); - ALOGD("%sSkip %d", (char*) indent, skip); - op &= ~OP_MAY_BE_SKIPPED_MASK; - } - - switch (op) { - case DrawGLFunction: { - Functor *functor = (Functor *) getInt(); - ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor); - } - break; - case Save: { - int rendererNum = getInt(); - ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); - } - break; - case Restore: { - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case RestoreToCount: { - int restoreCount = saveCount + getInt(); - ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); - } - break; - case SaveLayer: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - int flags = getInt(); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, - OP_NAMES[op], f1, f2, f3, f4, paint, flags); - } - break; - case SaveLayerAlpha: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - int alpha = getInt(); - int flags = getInt(); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, - OP_NAMES[op], f1, f2, f3, f4, alpha, flags); - } - break; - case Translate: { - float f1 = getFloat(); - float f2 = getFloat(); - ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2); - } - break; - case Rotate: { - float rotation = getFloat(); - ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation); - } - break; - case Scale: { - float sx = getFloat(); - float sy = getFloat(); - ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); - } - break; - case Skew: { - float sx = getFloat(); - float sy = getFloat(); - ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); - } - break; - case SetMatrix: { - SkMatrix* matrix = getMatrix(); - ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); - } - break; - case ConcatMatrix: { - SkMatrix* matrix = getMatrix(); - ALOGD("%s%s new concat %p: [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]", - (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1), - matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5), - matrix->get(6), matrix->get(7), matrix->get(8)); - } - break; - case ClipRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - int regionOp = getInt(); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], - f1, f2, f3, f4, regionOp); - } - break; - case ClipPath: { - SkPath* path = getPath(); - int regionOp = getInt(); - ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp); - } - break; - case ClipRegion: { - SkRegion* region = getRegion(); - int regionOp = getInt(); - ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp); - } - break; - case DrawDisplayList: { - DisplayList* displayList = getDisplayList(); - int32_t flags = getInt(); - ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op], - displayList, mWidth, mHeight, flags, level + 1); - renderer.outputDisplayList(displayList, level + 1); - } - break; - case DrawLayer: { - Layer* layer = (Layer*) getInt(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - layer, x, y, paint); - } - break; - case DrawBitmap: { - SkBitmap* bitmap = getBitmap(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - bitmap, x, y, paint); - } - break; - case DrawBitmapMatrix: { - SkBitmap* bitmap = getBitmap(); - SkMatrix* matrix = getMatrix(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], - bitmap, matrix, paint); - } - break; - case DrawBitmapRect: { - SkBitmap* bitmap = getBitmap(); - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - float f7 = getFloat(); - float f8 = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%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); - } - break; - case DrawBitmapData: { - SkBitmap* bitmap = getBitmapData(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint); - } - break; - case DrawBitmapMesh: { - int verticesCount = 0; - uint32_t colorsCount = 0; - SkBitmap* bitmap = getBitmap(); - uint32_t meshWidth = getInt(); - uint32_t meshHeight = getInt(); - float* vertices = getFloats(verticesCount); - bool hasColors = getInt(); - int* colors = hasColors ? getInts(colorsCount) : NULL; - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case DrawPatch: { - int32_t* xDivs = NULL; - int32_t* yDivs = NULL; - uint32_t* colors = NULL; - uint32_t xDivsCount = 0; - uint32_t yDivsCount = 0; - int8_t numColors = 0; - SkBitmap* bitmap = getBitmap(); - xDivs = getInts(xDivsCount); - yDivs = getInts(yDivsCount); - colors = getUInts(numColors); - float left = getFloat(); - float top = getFloat(); - float right = getFloat(); - float bottom = getFloat(); - int alpha = getInt(); - SkXfermode::Mode mode = (SkXfermode::Mode) getInt(); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op], - left, top, right, bottom); - } - break; - case DrawColor: { - int color = getInt(); - int xferMode = getInt(); - ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); - } - break; - case DrawRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - f1, f2, f3, f4, paint); - } - break; - case DrawRoundRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint); - } - break; - case DrawCircle: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %.2f, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, paint); - } - break; - case DrawOval: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); - } - break; - case DrawArc: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - int i1 = getInt(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); - } - break; - case DrawPath: { - SkPath* path = getPath(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint); - } - break; - case DrawLines: { - int count = 0; - float* points = getFloats(count); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case DrawPoints: { - int count = 0; - float* points = getFloats(count); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case DrawTextOnPath: { - getText(&text); - int32_t count = getInt(); - SkPath* path = getPath(); - float hOffset = getFloat(); - float vOffset = getFloat(); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], - text.text(), text.length(), count, paint); - } - break; - case DrawPosText: { - getText(&text); - int count = getInt(); - int positionsCount = 0; - float* positions = getFloats(positionsCount); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], - text.text(), text.length(), count, paint); - } - break; - case DrawText: { - getText(&text); - int32_t count = getInt(); - float x = getFloat(); - float y = getFloat(); - int32_t positionsCount = 0; - float* positions = getFloats(positionsCount); - SkPaint* paint = getPaint(renderer); - float length = getFloat(); - ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], - text.text(), text.length(), count, paint); - } - break; - case DrawRects: { - int32_t count = 0; - float* rects = getFloats(count); - SkPaint* paint = getPaint(renderer); - ALOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count / 4, paint); - } - break; - case ResetShader: { - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case SetupShader: { - SkiaShader* shader = getShader(); - ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader); - } - break; - case ResetColorFilter: { - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case SetupColorFilter: { - SkiaColorFilter *colorFilter = getColorFilter(); - ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter); - } - break; - case ResetShadow: { - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case SetupShadow: { - float radius = getFloat(); - float dx = getFloat(); - float dy = getFloat(); - int color = getInt(); - ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], - radius, dx, dy, color); - } - break; - case ResetPaintFilter: { - ALOGD("%s%s", (char*) indent, OP_NAMES[op]); - } - break; - case SetupPaintFilter: { - int clearBits = getInt(); - int setBits = getInt(); - ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits); - } - break; - default: - ALOGD("Display List error: op not handled: %s%s", - (char*) indent, OP_NAMES[op]); - break; - } + ALOGD("%*s%s %d", level * 4, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); + outputViewProperties(level); + int flags = DisplayListOp::kOpLogFlag_Recurse; + for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { + mDisplayListData->displayListOps[i]->output(level, flags); } - ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string()); + ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string()); } void DisplayList::updateMatrix() { @@ -743,115 +316,68 @@ void DisplayList::updateMatrix() { } } -void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) { +void DisplayList::outputViewProperties(uint32_t level) { updateMatrix(); if (mLeft != 0 || mTop != 0) { - ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop); + ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop); } if (mStaticMatrix) { - ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix (static)", mStaticMatrix, - mStaticMatrix->get(0), mStaticMatrix->get(1), - mStaticMatrix->get(2), mStaticMatrix->get(3), - mStaticMatrix->get(4), mStaticMatrix->get(5), - mStaticMatrix->get(6), mStaticMatrix->get(7), - mStaticMatrix->get(8)); + ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING, + level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix)); } if (mAnimationMatrix) { - ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix (animation)", mAnimationMatrix, - mAnimationMatrix->get(0), mAnimationMatrix->get(1), - mAnimationMatrix->get(2), mAnimationMatrix->get(3), - mAnimationMatrix->get(4), mAnimationMatrix->get(5), - mAnimationMatrix->get(6), mAnimationMatrix->get(7), - mAnimationMatrix->get(8)); + ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING, + level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix)); } if (mMatrixFlags != 0) { if (mMatrixFlags == TRANSLATION) { - ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY); + ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY); } else { - ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix", mTransformMatrix, - mTransformMatrix->get(0), mTransformMatrix->get(1), - mTransformMatrix->get(2), mTransformMatrix->get(3), - mTransformMatrix->get(4), mTransformMatrix->get(5), - mTransformMatrix->get(6), mTransformMatrix->get(7), - mTransformMatrix->get(8)); + ALOGD("%*sConcatMatrix %p: " MATRIX_STRING, + level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix)); } } if (mAlpha < 1 && !mCaching) { if (!mHasOverlappingRendering) { - ALOGD("%s%s %.2f", indent, "SetAlpha", mAlpha); + ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha); } else { int flags = SkCanvas::kHasAlphaLayer_SaveFlag; if (mClipChildren) { flags |= SkCanvas::kClipToLayer_SaveFlag; } - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha", + ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "", (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, mMultipliedAlpha, flags); } } if (mClipChildren) { - ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f, + ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f, (float) mRight - mLeft, (float) mBottom - mTop); } } void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) { -#if DEBUG_DISPLAY_LIST - uint32_t count = (level + 1) * 2; - char indent[count + 1]; - for (uint32_t i = 0; i < count; i++) { - indent[i] = ' '; - } - indent[count] = '\0'; +#if DEBUG_DISPLAYLIST + outputViewProperties(level); #endif updateMatrix(); if (mLeft != 0 || mTop != 0) { - DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop); renderer.translate(mLeft, mTop); } if (mStaticMatrix) { - DISPLAY_LIST_LOGD( - "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix (static)", mStaticMatrix, - mStaticMatrix->get(0), mStaticMatrix->get(1), - mStaticMatrix->get(2), mStaticMatrix->get(3), - mStaticMatrix->get(4), mStaticMatrix->get(5), - mStaticMatrix->get(6), mStaticMatrix->get(7), - mStaticMatrix->get(8)); renderer.concatMatrix(mStaticMatrix); } else if (mAnimationMatrix) { - DISPLAY_LIST_LOGD( - "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix (animation)", mAnimationMatrix, - mAnimationMatrix->get(0), mAnimationMatrix->get(1), - mAnimationMatrix->get(2), mAnimationMatrix->get(3), - mAnimationMatrix->get(4), mAnimationMatrix->get(5), - mAnimationMatrix->get(6), mAnimationMatrix->get(7), - mAnimationMatrix->get(8)); renderer.concatMatrix(mAnimationMatrix); } if (mMatrixFlags != 0) { if (mMatrixFlags == TRANSLATION) { - DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY); renderer.translate(mTranslationX, mTranslationY); } else { - DISPLAY_LIST_LOGD( - "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - indent, "ConcatMatrix", mTransformMatrix, - mTransformMatrix->get(0), mTransformMatrix->get(1), - mTransformMatrix->get(2), mTransformMatrix->get(3), - mTransformMatrix->get(4), mTransformMatrix->get(5), - mTransformMatrix->get(6), mTransformMatrix->get(7), - mTransformMatrix->get(8)); renderer.concatMatrix(mTransformMatrix); } } if (mAlpha < 1 && !mCaching) { if (!mHasOverlappingRendering) { - DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha); renderer.setAlpha(mAlpha); } else { // TODO: should be able to store the size of a DL at record time and not @@ -861,53 +387,35 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) { if (mClipChildren) { flags |= SkCanvas::kClipToLayer_SaveFlag; } - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha", - (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, - mMultipliedAlpha, flags); renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop, mMultipliedAlpha, flags); } } if (mClipChildren) { - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f, - (float) mRight - mLeft, (float) mBottom - mTop); renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op); } } -/** - * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked - * in the output() function, since that function processes the same list of opcodes for the - * 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 = DrawGlInfo::kStatusDone; - TextContainer text; - mReader.rewind(); #if DEBUG_DISPLAY_LIST - uint32_t count = (level + 1) * 2; - char indent[count + 1]; - for (uint32_t i = 0; i < count; i++) { - indent[i] = ' '; - } - indent[count] = '\0'; Rect* clipRect = renderer.getClipRect(); - DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f", - (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top, + DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f", + (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); #endif renderer.startMark(mName.string()); int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); - DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save", + DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo); setViewProperties(renderer, level); if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) { - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo); + DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo); renderer.restoreToCount(restoreTo); renderer.endMark(); return drawGlStatus; @@ -915,469 +423,22 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); int saveCount = renderer.getSaveCount() - 1; - - while (!mReader.eof()) { - int op = mReader.readInt(); - if (op & OP_MAY_BE_SKIPPED_MASK) { - int32_t skip = mReader.readInt(); - if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) { - mReader.skip(skip); - DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent, - OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip); - continue; - } else { - op &= ~OP_MAY_BE_SKIPPED_MASK; - } - } - logBuffer.writeCommand(level, op); - + for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { + DisplayListOp *op = mDisplayListData->displayListOps[i]; #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS - Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]); + Caches::getInstance().eventMark(strlen(op->name()), op->name()); #endif - switch (op) { - case DrawGLFunction: { - Functor *functor = (Functor *) getInt(); - DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor); - renderer.startMark("GL functor"); - drawGlStatus |= renderer.callDrawGLFunction(functor, dirty); - renderer.endMark(); - } - break; - case Save: { - int32_t rendererNum = getInt(); - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); - renderer.save(rendererNum); - } - break; - case Restore: { - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.restore(); - } - break; - case RestoreToCount: { - int32_t restoreCount = saveCount + getInt(); - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); - renderer.restoreToCount(restoreCount); - } - break; - case SaveLayer: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - int32_t flags = getInt(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, - OP_NAMES[op], f1, f2, f3, f4, paint, flags); - renderer.saveLayer(f1, f2, f3, f4, paint, flags); - } - break; - case SaveLayerAlpha: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - int32_t alpha = getInt(); - int32_t flags = getInt(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, - OP_NAMES[op], f1, f2, f3, f4, alpha, flags); - renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags); - } - break; - case Translate: { - float f1 = getFloat(); - float f2 = getFloat(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2); - renderer.translate(f1, f2); - } - break; - case Rotate: { - float rotation = getFloat(); - DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation); - renderer.rotate(rotation); - } - break; - case Scale: { - float sx = getFloat(); - float sy = getFloat(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); - renderer.scale(sx, sy); - } - break; - case Skew: { - float sx = getFloat(); - float sy = getFloat(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); - renderer.skew(sx, sy); - } - break; - case SetMatrix: { - SkMatrix* matrix = getMatrix(); - DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); - renderer.setMatrix(matrix); - } - break; - case ConcatMatrix: { - SkMatrix* matrix = getMatrix(); - DISPLAY_LIST_LOGD( - "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", - (char*) indent, OP_NAMES[op], matrix, - matrix->get(0), matrix->get(1), matrix->get(2), - matrix->get(3), matrix->get(4), matrix->get(5), - matrix->get(6), matrix->get(7), matrix->get(8)); - renderer.concatMatrix(matrix); - } - break; - case ClipRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - int32_t regionOp = getInt(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], - f1, f2, f3, f4, regionOp); - renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp); - } - break; - case ClipPath: { - SkPath* path = getPath(); - int32_t regionOp = getInt(); - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp); - renderer.clipPath(path, (SkRegion::Op) regionOp); - } - break; - case ClipRegion: { - SkRegion* region = getRegion(); - int32_t regionOp = getInt(); - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp); - renderer.clipRegion(region, (SkRegion::Op) regionOp); - } - break; - case DrawDisplayList: { - DisplayList* displayList = getDisplayList(); - int32_t flags = getInt(); - DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op], - displayList, mWidth, mHeight, flags, level + 1); - drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1); - } - break; - case DrawLayer: { - int oldAlpha = -1; - Layer* layer = (Layer*) getInt(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - if (mCaching && mMultipliedAlpha < 255) { - oldAlpha = layer->getAlpha(); - layer->setAlpha(mMultipliedAlpha); - } - DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - layer, x, y, paint); - drawGlStatus |= renderer.drawLayer(layer, x, y, paint); - if (oldAlpha >= 0) { - layer->setAlpha(oldAlpha); - } - } - break; - case DrawBitmap: { - int oldAlpha = -1; - SkBitmap* bitmap = getBitmap(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - if (mCaching && mMultipliedAlpha < 255) { - oldAlpha = paint->getAlpha(); - paint->setAlpha(mMultipliedAlpha); - } - DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - bitmap, x, y, paint); - drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); - if (oldAlpha >= 0) { - paint->setAlpha(oldAlpha); - } - } - break; - case DrawBitmapMatrix: { - SkBitmap* bitmap = getBitmap(); - SkMatrix* matrix = getMatrix(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], - bitmap, matrix, paint); - drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint); - } - break; - case DrawBitmapRect: { - SkBitmap* bitmap = getBitmap(); - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - float f7 = getFloat(); - float f8 = getFloat(); - SkPaint* paint = getPaint(renderer); - 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); - drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); - } - break; - case DrawBitmapData: { - SkBitmap* bitmap = getBitmapData(); - float x = getFloat(); - float y = getFloat(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - bitmap, x, y, paint); - drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); - } - break; - case DrawBitmapMesh: { - int32_t verticesCount = 0; - uint32_t colorsCount = 0; - - SkBitmap* bitmap = getBitmap(); - uint32_t meshWidth = getInt(); - uint32_t meshHeight = getInt(); - float* vertices = getFloats(verticesCount); - bool hasColors = getInt(); - int32_t* colors = hasColors ? getInts(colorsCount) : NULL; - SkPaint* paint = getPaint(renderer); - - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, - colors, paint); - } - break; - case DrawPatch: { - int32_t* xDivs = NULL; - int32_t* yDivs = NULL; - uint32_t* colors = NULL; - uint32_t xDivsCount = 0; - uint32_t yDivsCount = 0; - int8_t numColors = 0; - - SkBitmap* bitmap = getBitmap(); - - xDivs = getInts(xDivsCount); - yDivs = getInts(yDivsCount); - colors = getUInts(numColors); - - float left = getFloat(); - float top = getFloat(); - float right = getFloat(); - float bottom = getFloat(); - - int alpha = getInt(); - SkXfermode::Mode mode = (SkXfermode::Mode) getInt(); - - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors, - xDivsCount, yDivsCount, numColors, left, top, right, bottom, - alpha, mode); - } - 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); - drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode); - } - break; - case DrawRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], - f1, f2, f3, f4, paint); - drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint); - } - break; - case DrawRoundRect: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - 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); - drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint); - } - break; - case DrawCircle: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, paint); - drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint); - } - break; - case DrawOval: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", - (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); - drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint); - } - break; - case DrawArc: { - float f1 = getFloat(); - float f2 = getFloat(); - float f3 = getFloat(); - float f4 = getFloat(); - float f5 = getFloat(); - float f6 = getFloat(); - int32_t i1 = getInt(); - 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); - 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); - drawGlStatus |= renderer.drawPath(path, paint); - } - break; - case DrawLines: { - int32_t count = 0; - float* points = getFloats(count); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - drawGlStatus |= renderer.drawLines(points, count, paint); - } - break; - case DrawPoints: { - int32_t count = 0; - float* points = getFloats(count); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - drawGlStatus |= renderer.drawPoints(points, count, paint); - } - break; - case DrawTextOnPath: { - getText(&text); - int32_t count = getInt(); - SkPath* path = getPath(); - float hOffset = getFloat(); - float vOffset = getFloat(); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], - text.text(), text.length(), count, paint); - drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path, - hOffset, vOffset, paint); - } - break; - case DrawPosText: { - getText(&text); - int32_t count = getInt(); - int32_t positionsCount = 0; - float* positions = getFloats(positionsCount); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, - OP_NAMES[op], text.text(), text.length(), count, paint); - drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count, - positions, paint); - } - break; - case DrawText: { - getText(&text); - int32_t count = getInt(); - float x = getFloat(); - float y = getFloat(); - int32_t positionsCount = 0; - float* positions = getFloats(positionsCount); - SkPaint* paint = getPaint(renderer); - 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); - drawGlStatus |= renderer.drawText(text.text(), text.length(), count, - x, y, positions, paint, length); - } - break; - case DrawRects: { - int32_t count = 0; - float* rects = getFloats(count); - SkPaint* paint = getPaint(renderer); - DISPLAY_LIST_LOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count, paint); - drawGlStatus |= renderer.drawRects(rects, count / 4, paint); - } - break; - case ResetShader: { - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.resetShader(); - } - break; - case SetupShader: { - SkiaShader* shader = getShader(); - DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader); - renderer.setupShader(shader); - } - break; - case ResetColorFilter: { - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.resetColorFilter(); - } - break; - case SetupColorFilter: { - SkiaColorFilter *colorFilter = getColorFilter(); - DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter); - renderer.setupColorFilter(colorFilter); - } - break; - case ResetShadow: { - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.resetShadow(); - } - break; - case SetupShadow: { - float radius = getFloat(); - float dx = getFloat(); - float dy = getFloat(); - int32_t color = getInt(); - DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], - radius, dx, dy, color); - renderer.setupShadow(radius, dx, dy, color); - } - break; - case ResetPaintFilter: { - DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); - renderer.resetPaintFilter(); - } - break; - case SetupPaintFilter: { - int32_t clearBits = getInt(); - int32_t setBits = getInt(); - DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], - clearBits, setBits); - renderer.setupPaintFilter(clearBits, setBits); - } - break; - default: - DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s", - (char*) indent, OP_NAMES[op]); - break; - } + drawGlStatus |= op->replay(renderer, dirty, flags, + saveCount, level, mCaching, mMultipliedAlpha); + logBuffer.writeCommand(level, op->name()); } - DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo); + DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo); renderer.restoreToCount(restoreTo); renderer.endMark(); - DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(), + DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(), drawGlStatus); return drawGlStatus; } @@ -1387,7 +448,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag /////////////////////////////////////////////////////////////////////////////// DisplayListRenderer::DisplayListRenderer(): - mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE), + mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData), mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false), mFunctorCount(0) { } @@ -1397,8 +458,7 @@ DisplayListRenderer::~DisplayListRenderer() { } void DisplayListRenderer::reset() { - mWriter.reset(); - + mDisplayListData = new DisplayListData(); mCaches.resourceCache.lock(); for (size_t i = 0; i < mBitmapResources.size(); i++) { @@ -1493,7 +553,7 @@ status_t DisplayListRenderer::prepareDirty(float left, float top, void DisplayListRenderer::finish() { insertRestoreToCount(); - insertTranlate(); + insertTranslate(); } void DisplayListRenderer::interrupt() { @@ -1504,15 +564,13 @@ void DisplayListRenderer::resume() { status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay - addOp(DisplayList::DrawGLFunction); - addInt((int) functor); + addDrawOp(new (alloc()) DrawFunctorOp(functor)); mFunctorCount++; return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } int DisplayListRenderer::save(int flags) { - addOp(DisplayList::Save); - addInt(flags); + addStateOp(new (alloc()) SaveOp(flags)); return OpenGLRenderer::save(flags); } @@ -1523,31 +581,25 @@ void DisplayListRenderer::restore() { } mRestoreSaveCount--; - insertTranlate(); + insertTranslate(); OpenGLRenderer::restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; - insertTranlate(); + insertTranslate(); OpenGLRenderer::restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, SkPaint* p, int flags) { - addOp(DisplayList::SaveLayer); - addBounds(left, top, right, bottom); - addPaint(p); - addInt(flags); + addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, p, flags)); return OpenGLRenderer::save(flags); } int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int flags) { - addOp(DisplayList::SaveLayerAlpha); - addBounds(left, top, right, bottom); - addInt(alpha); - addInt(flags); + addStateOp(new (alloc()) SaveLayerAlphaOp(left, top, right, bottom, alpha, flags)); return OpenGLRenderer::save(flags); } @@ -1560,54 +612,47 @@ void DisplayListRenderer::translate(float dx, float dy) { } void DisplayListRenderer::rotate(float degrees) { - addOp(DisplayList::Rotate); - addFloat(degrees); + addStateOp(new (alloc()) RotateOp(degrees)); OpenGLRenderer::rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { - addOp(DisplayList::Scale); - addPoint(sx, sy); + addStateOp(new (alloc()) ScaleOp(sx, sy)); OpenGLRenderer::scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { - addOp(DisplayList::Skew); - addPoint(sx, sy); + addStateOp(new (alloc()) SkewOp(sx, sy)); OpenGLRenderer::skew(sx, sy); } void DisplayListRenderer::setMatrix(SkMatrix* matrix) { - addOp(DisplayList::SetMatrix); - addMatrix(matrix); + matrix = refMatrix(matrix); + addStateOp(new (alloc()) SetMatrixOp(matrix)); OpenGLRenderer::setMatrix(matrix); } void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { - addOp(DisplayList::ConcatMatrix); - addMatrix(matrix); + matrix = refMatrix(matrix); + addStateOp(new (alloc()) ConcatMatrixOp(matrix)); OpenGLRenderer::concatMatrix(matrix); } bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { - addOp(DisplayList::ClipRect); - addBounds(left, top, right, bottom); - addInt(op); + addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); return OpenGLRenderer::clipRect(left, top, right, bottom, op); } bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) { - addOp(DisplayList::ClipPath); - addPath(path); - addInt(op); + path = refPath(path); + addStateOp(new (alloc()) ClipPathOp(path, op)); return OpenGLRenderer::clipPath(path, op); } bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) { - addOp(DisplayList::ClipRegion); - addRegion(region); - addInt(op); + region = refRegion(region); + addStateOp(new (alloc()) ClipRegionOp(region, op)); return OpenGLRenderer::clipRegion(region, op); } @@ -1616,84 +661,71 @@ status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list - addOp(DisplayList::DrawDisplayList); - addDisplayList(displayList); - addInt(flags); + // TODO: To be safe, the display list should be ref-counted in the + // resources cache, but we rely on the caller (UI toolkit) to + // do the right thing for now + + addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { - addOp(DisplayList::DrawLayer); - addLayer(layer); - addPoint(x, y); - addPaint(paint); + mLayers.add(layer); + mCaches.resourceCache.incrementRefcount(layer); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawLayerOp(layer, x, y, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { - const bool reject = quickRejectNoScissor(left, top, - left + bitmap->width(), top + bitmap->height()); - uint32_t* location = addOp(DisplayList::DrawBitmap, reject); - addBitmap(bitmap); - addPoint(left, top); - addPaint(paint); - addSkip(location); + bitmap = refBitmap(bitmap); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint)); return DrawGlInfo::kStatusDone; } 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); - - const bool reject = quickRejectNoScissor(r.left, r.top, r.right, r.bottom); - uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject); - addBitmap(bitmap); - addMatrix(matrix); - addPaint(paint); - addSkip(location); + bitmap = refBitmap(bitmap); + matrix = refMatrix(matrix); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint)); return DrawGlInfo::kStatusDone; } 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 = quickRejectNoScissor(dstLeft, dstTop, dstRight, dstBottom); - uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject); - addBitmap(bitmap); - addBounds(srcLeft, srcTop, srcRight, srcBottom); - addBounds(dstLeft, dstTop, dstRight, dstBottom); - addPaint(paint); - addSkip(location); + bitmap = refBitmap(bitmap); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, + srcLeft, srcTop, srcRight, srcBottom, + dstLeft, dstTop, dstRight, dstBottom, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) { - const bool reject = quickRejectNoScissor(left, top, - left + bitmap->width(), top + bitmap->height()); - uint32_t* location = addOp(DisplayList::DrawBitmapData, reject); - addBitmapData(bitmap); - addPoint(left, top); - addPaint(paint); - addSkip(location); + bitmap = refBitmapData(bitmap); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { - addOp(DisplayList::DrawBitmapMesh); - addBitmap(bitmap); - addInt(meshWidth); - addInt(meshHeight); - addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2); - if (colors) { - addInt(1); - addInts(colors, (meshWidth + 1) * (meshHeight + 1)); - } else { - addInt(0); - } - addPaint(paint); + int count = (meshWidth + 1) * (meshHeight + 1) * 2; + bitmap = refBitmap(bitmap); + vertices = refBuffer<float>(vertices, count); + paint = refPaint(paint); + colors = refBuffer<int>(colors, count); + + addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, + vertices, colors, paint)); return DrawGlInfo::kStatusDone; } @@ -1704,132 +736,114 @@ status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, SkXfermode::Mode mode; OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); - const bool reject = quickRejectNoScissor(left, top, right, bottom); - uint32_t* location = addOp(DisplayList::DrawPatch, reject); - addBitmap(bitmap); - addInts(xDivs, width); - addInts(yDivs, height); - addUInts(colors, numColors); - addBounds(left, top, right, bottom); - addInt(alpha); - addInt(mode); - addSkip(location); + bitmap = refBitmap(bitmap); + xDivs = refBuffer<int>(xDivs, width); + yDivs = refBuffer<int>(yDivs, height); + colors = refBuffer<uint32_t>(colors, numColors); + + addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors, + left, top, right, bottom, alpha, mode)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { - addOp(DisplayList::DrawColor); - addInt(color); - addInt(mode); + addDrawOp(new (alloc()) DrawColorOp(color, mode)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { - const bool reject = paint->getStyle() == SkPaint::kFill_Style && - quickRejectNoScissor(left, top, right, bottom); - uint32_t* location = addOp(DisplayList::DrawRect, reject); - addBounds(left, top, right, bottom); - addPaint(paint); - addSkip(location); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); return DrawGlInfo::kStatusDone; } 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 && - quickRejectNoScissor(left, top, right, bottom); - uint32_t* location = addOp(DisplayList::DrawRoundRect, reject); - addBounds(left, top, right, bottom); - addPoint(rx, ry); - addPaint(paint); - addSkip(location); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { - addOp(DisplayList::DrawCircle); - addPoint(x, y); - addFloat(radius); - addPaint(paint); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { - addOp(DisplayList::DrawOval); - addBounds(left, top, right, bottom); - addPaint(paint); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); return DrawGlInfo::kStatusDone; } 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); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, + startAngle, sweepAngle, useCenter, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { - float left, top, offset; - uint32_t width, height; - computePathBounds(path, paint, left, top, offset, width, height); - - left -= offset; - top -= offset; - - const bool reject = quickRejectNoScissor(left, top, left + width, top + height); - uint32_t* location = addOp(DisplayList::DrawPath, reject); - addPath(path); - addPaint(paint); - addSkip(location); + path = refPath(path); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawPathOp(path, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { - addOp(DisplayList::DrawLines); - addFloats(points, count); - addPaint(paint); + points = refBuffer<float>(points, count); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { - addOp(DisplayList::DrawPoints); - addFloats(points, count); - addPaint(paint); + points = refBuffer<float>(points, count); + paint = refPaint(paint); + + addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; - addOp(DisplayList::DrawTextOnPath); - addText(text, bytesCount); - addInt(count); - addPath(path); - addFloat(hOffset); - addFloat(vOffset); + paint->setAntiAlias(true); - SkPaint* addedPaint = addPaint(paint); - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint); - fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform); + text = refText(text, bytesCount); + path = refPath(path); + paint = refPaint(paint); + + DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, + hOffset, vOffset, paint); + if (addDrawOp(op)) { + // precache if draw operation is visible + FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); + fontRenderer.precache(paint, text, count, *mSnapshot->transform); + } return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; - addOp(DisplayList::DrawPosText); - addText(text, bytesCount); - addInt(count); - addFloats(positions, count * 2); + paint->setAntiAlias(true); - SkPaint* addedPaint = addPaint(paint); - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint); - fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform); + text = refText(text, bytesCount); + positions = refBuffer<float>(positions, count * 2); + paint = refPaint(paint); + + DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); + if (addDrawOp(op)) { + // precache if draw operation is visible + FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); + fontRenderer.precache(paint, text, count, *mSnapshot->transform); + } return DrawGlInfo::kStatusDone; } @@ -1847,75 +861,96 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou paint->setAntiAlias(true); if (length < 0.0f) length = paint->measureText(text, bytesCount); - bool reject = false; - if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) { - SkPaint::FontMetrics metrics; - paint->getFontMetrics(&metrics, 0.0f); - reject = quickRejectNoScissor(x, y + metrics.fTop, x + length, y + metrics.fBottom); - } + text = refText(text, bytesCount); + positions = refBuffer<float>(positions, count * 2); + paint = refPaint(paint); - uint32_t* location = addOp(DisplayList::DrawText, reject); - addText(text, bytesCount); - addInt(count); - addFloat(x); - addFloat(y); - addFloats(positions, count * 2); - SkPaint* addedPaint = addPaint(paint); - if (!reject) { - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint); - fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform); + DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length); + if (addDrawOp(op)) { + // precache if draw operation is visible + FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); + fontRenderer.precache(paint, text, count, *mSnapshot->transform); } - addFloat(length); - addSkip(location); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) { if (count <= 0) return DrawGlInfo::kStatusDone; - addOp(DisplayList::DrawRects); - addFloats(rects, count * 4); - addPaint(paint); + rects = refBuffer<float>(rects, count); + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); return DrawGlInfo::kStatusDone; } void DisplayListRenderer::resetShader() { - addOp(DisplayList::ResetShader); + addStateOp(new (alloc()) ResetShaderOp()); } void DisplayListRenderer::setupShader(SkiaShader* shader) { - addOp(DisplayList::SetupShader); - addShader(shader); + shader = refShader(shader); + addStateOp(new (alloc()) SetupShaderOp(shader)); } void DisplayListRenderer::resetColorFilter() { - addOp(DisplayList::ResetColorFilter); + addStateOp(new (alloc()) ResetColorFilterOp()); } void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { - addOp(DisplayList::SetupColorFilter); - addColorFilter(filter); + filter = refColorFilter(filter); + addStateOp(new (alloc()) SetupColorFilterOp(filter)); } void DisplayListRenderer::resetShadow() { - addOp(DisplayList::ResetShadow); + addStateOp(new (alloc()) ResetShadowOp()); } void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { - addOp(DisplayList::SetupShadow); - addFloat(radius); - addPoint(dx, dy); - addInt(color); + addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color)); } void DisplayListRenderer::resetPaintFilter() { - addOp(DisplayList::ResetPaintFilter); + addStateOp(new (alloc()) ResetPaintFilterOp()); } void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { - addOp(DisplayList::SetupPaintFilter); - addInt(clearBits); - addInt(setBits); + addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); +} + +void DisplayListRenderer::insertRestoreToCount() { + if (mRestoreSaveCount >= 0) { + DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount); + mDisplayListData->displayListOps.add(op); + mRestoreSaveCount = -1; + } +} + +void DisplayListRenderer::insertTranslate() { + if (mHasTranslate) { + if (mTranslateX != 0.0f || mTranslateY != 0.0f) { + DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY); + mDisplayListData->displayListOps.add(op); + mTranslateX = mTranslateY = 0.0f; + } + mHasTranslate = false; + } +} + +void DisplayListRenderer::addStateOp(StateOp* op) { + addOpInternal(op); +} + +bool DisplayListRenderer::addDrawOp(DrawOp* op) { + bool rejected = false; + Rect localBounds; + if (op->getLocalBounds(localBounds)) { + rejected = quickRejectNoScissor(localBounds.left, localBounds.top, + localBounds.right, localBounds.bottom); + op->setQuickRejected(rejected); + } + mHasDrawOps = true; + addOpInternal(op); + return !rejected; } }; // namespace uirenderer diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index d78d54e..f3bd188 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -32,6 +32,7 @@ #include "DisplayListLogBuffer.h" #include "OpenGLRenderer.h" +#include "utils/LinearAllocator.h" namespace android { namespace uirenderer { @@ -61,6 +62,18 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// class DisplayListRenderer; +class DisplayListOp; +class DrawOp; +class StateOp; + +/** + * Refcounted structure that holds data used in display list stream + */ +class DisplayListData: public LightRefBase<DisplayListData> { +public: + LinearAllocator allocator; + Vector<DisplayListOp*> displayListOps; +}; /** * Replays recorded drawing commands. @@ -70,66 +83,13 @@ public: DisplayList(const DisplayListRenderer& recorder); ANDROID_API ~DisplayList(); - // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file - // when modifying this file - enum Op { - // Non-drawing operations - Save = 0, - Restore, - RestoreToCount, - SaveLayer, - SaveLayerAlpha, - Translate, - Rotate, - Scale, - Skew, - SetMatrix, - ConcatMatrix, - ClipRect, - ClipPath, - ClipRegion, - // Drawing operations - DrawDisplayList, - DrawLayer, - DrawBitmap, - DrawBitmapMatrix, - DrawBitmapRect, - DrawBitmapData, - DrawBitmapMesh, - DrawPatch, - DrawColor, - DrawRect, - DrawRoundRect, - DrawCircle, - DrawOval, - DrawArc, - DrawPath, - DrawLines, - DrawPoints, - DrawTextOnPath, - DrawPosText, - DrawText, - DrawRects, - ResetShader, - SetupShader, - ResetColorFilter, - SetupColorFilter, - ResetShadow, - SetupShadow, - ResetPaintFilter, - SetupPaintFilter, - DrawGLFunction, - }; - // See flags defined in DisplayList.java enum ReplayFlag { kReplayFlag_ClipChildren = 0x1 }; - static const char* OP_NAMES[]; - void setViewProperties(OpenGLRenderer& renderer, uint32_t level); - void outputViewProperties(OpenGLRenderer& renderer, char* indent); + void outputViewProperties(uint32_t level); ANDROID_API size_t getSize(); ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); @@ -139,7 +99,7 @@ public: status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0); - void output(OpenGLRenderer& renderer, uint32_t level = 0); + void output(uint32_t level = 0); ANDROID_API void reset(); @@ -424,78 +384,6 @@ private: const char* mText; }; - SkBitmap* getBitmap() { - return (SkBitmap*) getInt(); - } - - SkBitmap* getBitmapData() { - return (SkBitmap*) getInt(); - } - - SkiaShader* getShader() { - return (SkiaShader*) getInt(); - } - - SkiaColorFilter* getColorFilter() { - return (SkiaColorFilter*) getInt(); - } - - inline int32_t getIndex() { - return mReader.readInt(); - } - - inline int32_t getInt() { - return mReader.readInt(); - } - - inline uint32_t getUInt() { - return mReader.readU32(); - } - - SkMatrix* getMatrix() { - return (SkMatrix*) getInt(); - } - - SkPath* getPath() { - return (SkPath*) getInt(); - } - - SkRegion* getRegion() { - return (SkRegion*) getInt(); - } - - SkPaint* getPaint(OpenGLRenderer& renderer) { - return renderer.filterPaint((SkPaint*) getInt()); - } - - DisplayList* getDisplayList() { - return (DisplayList*) getInt(); - } - - inline float getFloat() { - return mReader.readScalar(); - } - - int32_t* getInts(uint32_t& count) { - count = getInt(); - return (int32_t*) mReader.skip(count * sizeof(int32_t)); - } - - uint32_t* getUInts(int8_t& count) { - count = getInt(); - return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); - } - - float* getFloats(int32_t& count) { - count = getInt(); - return (float*) mReader.skip(count * sizeof(float)); - } - - void getText(TextContainer* text) { - size_t length = text->mByteLength = getInt(); - text->mText = (const char*) mReader.skip(length); - } - Vector<SkBitmap*> mBitmapResources; Vector<SkBitmap*> mOwnedBitmapResources; Vector<SkiaColorFilter*> mFilterResources; @@ -508,7 +396,7 @@ private: Vector<SkiaShader*> mShaders; Vector<Layer*> mLayers; - mutable SkReader32 mReader; + sp<DisplayListData> mDisplayListData; size_t mSize; @@ -635,8 +523,8 @@ public: ANDROID_API void reset(); - const SkWriter32& writeStream() const { - return mWriter; + sp<DisplayListData> getDisplayListData() const { + return mDisplayListData; } const Vector<SkBitmap*>& getBitmapResources() const { @@ -684,102 +572,32 @@ public: } private: - void insertRestoreToCount() { - if (mRestoreSaveCount >= 0) { - mWriter.writeInt(DisplayList::RestoreToCount); - addInt(mRestoreSaveCount); - mRestoreSaveCount = -1; - } - } - - void insertTranlate() { - if (mHasTranslate) { - if (mTranslateX != 0.0f || mTranslateY != 0.0f) { - mWriter.writeInt(DisplayList::Translate); - addPoint(mTranslateX, mTranslateY); - mTranslateX = mTranslateY = 0.0f; - } - mHasTranslate = false; - } - } - - inline void addOp(const DisplayList::Op drawOp) { - insertRestoreToCount(); - insertTranlate(); - mWriter.writeInt(drawOp); - mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; - } + void insertRestoreToCount(); + void insertTranslate(); - uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) { + LinearAllocator& alloc() { return mDisplayListData->allocator; } + void addStateOp(StateOp* op); + bool addDrawOp(DrawOp* op); // returns true if op not rejected + void addOpInternal(DisplayListOp* op) { insertRestoreToCount(); - insertTranlate(); - mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; - if (reject) { - mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp); - mWriter.writeInt(0xdeaddead); - mBufferSize = mWriter.size(); - return mWriter.peek32(mBufferSize - sizeof(int32_t)); - } - mWriter.writeInt(drawOp); - return NULL; - } - - inline void addSkip(uint32_t* location) { - if (location) { - *location = (int32_t) (mWriter.size() - mBufferSize); - } - } - - inline void addInt(int32_t value) { - mWriter.writeInt(value); - } - - inline void addSize(uint32_t w, uint32_t h) { - mWriter.writeInt(w); - mWriter.writeInt(h); - } - - void addInts(const int32_t* values, uint32_t count) { - mWriter.writeInt(count); - mWriter.write(values, count * sizeof(int32_t)); - } - - void addUInts(const uint32_t* values, int8_t count) { - mWriter.writeInt(count); - mWriter.write(values, count * sizeof(uint32_t)); - } - - inline void addFloat(float value) { - mWriter.writeScalar(value); + insertTranslate(); + mDisplayListData->displayListOps.add(op); } - void addFloats(const float* values, int32_t count) { - mWriter.writeInt(count); - mWriter.write(values, count * sizeof(float)); + template<class T> + inline T* refBuffer(const T* srcBuffer, int32_t count) { + if (srcBuffer == NULL) return NULL; + T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T)); + memcpy(dstBuffer, srcBuffer, count * sizeof(T)); + return dstBuffer; } - inline void addPoint(float x, float y) { - mWriter.writeScalar(x); - mWriter.writeScalar(y); + inline char* refText(const char* text, size_t byteLength) { + return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength); } - inline void addBounds(float left, float top, float right, float bottom) { - mWriter.writeScalar(left); - mWriter.writeScalar(top); - mWriter.writeScalar(right); - mWriter.writeScalar(bottom); - } - - inline void addText(const void* text, size_t byteLength) { - mWriter.writeInt(byteLength); - mWriter.writePad(text, byteLength); - } - - inline void addPath(SkPath* path) { - if (!path) { - addInt((int) NULL); - return; - } + inline SkPath* refPath(SkPath* path) { + if (!path) return NULL; SkPath* pathCopy = mPathMap.valueFor(path); if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { @@ -793,13 +611,11 @@ private: mCaches.resourceCache.incrementRefcount(path); mSourcePaths.add(path); } - - addInt((int) pathCopy); + return pathCopy; } - inline SkPaint* addPaint(SkPaint* paint) { + inline SkPaint* refPaint(SkPaint* paint) { if (!paint) { - addInt((int) NULL); return paint; } @@ -811,14 +627,11 @@ private: mPaints.add(paintCopy); } - addInt((int) paintCopy); - return paintCopy; } - inline SkRegion* addRegion(SkRegion* region) { + inline SkRegion* refRegion(SkRegion* region) { if (!region) { - addInt((int) NULL); return region; } @@ -831,53 +644,35 @@ private: mRegions.add(regionCopy); } - addInt((int) regionCopy); - return regionCopy; } - inline void addDisplayList(DisplayList* displayList) { - // TODO: To be safe, the display list should be ref-counted in the - // resources cache, but we rely on the caller (UI toolkit) to - // do the right thing for now - addInt((int) displayList); - } - - inline void addMatrix(SkMatrix* matrix) { + inline SkMatrix* refMatrix(SkMatrix* matrix) { // Copying the matrix is cheap and prevents against the user changing the original // matrix before the operation that uses it SkMatrix* copy = new SkMatrix(*matrix); - addInt((int) copy); mMatrices.add(copy); + return copy; } - inline void addLayer(Layer* layer) { - addInt((int) layer); - mLayers.add(layer); - mCaches.resourceCache.incrementRefcount(layer); - } - - inline void addBitmap(SkBitmap* bitmap) { + inline SkBitmap* refBitmap(SkBitmap* bitmap) { // Note that this assumes the bitmap is immutable. There are cases this won't handle // correctly, such as creating the bitmap from scratch, drawing with it, changing its // contents, and drawing again. The only fix would be to always copy it the first time, // which doesn't seem worth the extra cycles for this unlikely case. - addInt((int) bitmap); mBitmapResources.add(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); + return bitmap; } - void addBitmapData(SkBitmap* bitmap) { - addInt((int) bitmap); + inline SkBitmap* refBitmapData(SkBitmap* bitmap) { mOwnedBitmapResources.add(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); + return bitmap; } - inline void addShader(SkiaShader* shader) { - if (!shader) { - addInt((int) NULL); - return; - } + inline SkiaShader* refShader(SkiaShader* shader) { + if (!shader) return NULL; SkiaShader* shaderCopy = mShaderMap.valueFor(shader); // TODO: We also need to handle generation ID changes in compose shaders @@ -888,14 +683,13 @@ private: mShaders.add(shaderCopy); mCaches.resourceCache.incrementRefcount(shaderCopy); } - - addInt((int) shaderCopy); + return shaderCopy; } - inline void addColorFilter(SkiaColorFilter* colorFilter) { - addInt((int) colorFilter); + inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) { mFilterResources.add(colorFilter); mCaches.resourceCache.incrementRefcount(colorFilter); + return colorFilter; } Vector<SkBitmap*> mBitmapResources; @@ -920,12 +714,10 @@ private: Vector<Layer*> mLayers; - uint32_t mBufferSize; - int mRestoreSaveCount; Caches& mCaches; - SkWriter32 mWriter; + sp<DisplayListData> mDisplayListData; float mTranslateX; float mTranslateY; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 1fa1b20..7772f3a 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1101,7 +1101,7 @@ void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color, rects.push(r.fTop); rects.push(r.fRight); rects.push(r.fBottom); - count++; + count += 4; it.next(); } @@ -1744,7 +1744,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) { if (displayList) { - displayList->output(*this, level); + displayList->output(level); } } @@ -2094,7 +2094,6 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const */ void OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) { int color = paint->getColor(); - SkPaint::Style style = paint->getStyle(); SkXfermode::Mode mode = getXfermode(paint->getXfermode()); bool isAA = paint->isAntiAlias(); @@ -3205,8 +3204,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color Vertex mesh[count * 6]; Vertex* vertex = mesh; - for (int i = 0; i < count; i++) { - int index = i * 4; + for (int index = 0; index < count; index += 4) { float l = rects[index + 0]; float t = rects[index + 1]; float r = rects[index + 2]; diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index e490151..45c619e 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -122,8 +122,6 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight, float rescaleX = 1.0f; float rescaleY = 1.0f; - const float meshWidth = right - left; - if (xStretchCount > 0) { uint32_t stretchSize = 0; for (uint32_t i = 1; i < mXCount; i += 2) { diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp index dd13d79..d59e36f 100644 --- a/libs/hwui/PathRenderer.cpp +++ b/libs/hwui/PathRenderer.cpp @@ -596,7 +596,6 @@ bool PathRenderer::convexPathPerimeterVertices(const SkPath& path, bool forceClo SkPath::Iter iter(path, forceClose); SkPoint pts[4]; SkPath::Verb v; - Vertex* newVertex = 0; while (SkPath::kDone_Verb != (v = iter.next(pts))) { switch (v) { case SkPath::kMove_Verb: diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h index 80f39ff..5f4bb5a 100644 --- a/libs/hwui/Rect.h +++ b/libs/hwui/Rect.h @@ -171,22 +171,19 @@ public: } private: - static inline float min(float a, float b) { return (a < b) ? a : b; } - static inline float max(float a, float b) { return (a > b) ? a : b; } - void intersectWith(Rect& tmp) const { - tmp.left = max(left, tmp.left); - tmp.top = max(top, tmp.top); - tmp.right = min(right, tmp.right); - tmp.bottom = min(bottom, tmp.bottom); + tmp.left = fmaxf(left, tmp.left); + tmp.top = fmaxf(top, tmp.top); + tmp.right = fminf(right, tmp.right); + tmp.bottom = fminf(bottom, tmp.bottom); } Rect intersectWith(float l, float t, float r, float b) const { Rect tmp; - tmp.left = max(left, l); - tmp.top = max(top, t); - tmp.right = min(right, r); - tmp.bottom = min(bottom, b); + tmp.left = fmaxf(left, l); + tmp.top = fmaxf(top, t); + tmp.right = fminf(right, r); + tmp.bottom = fminf(bottom, b); return tmp; } |