summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2013-01-30 14:32:29 -0500
committerDerek Sollenberger <djsollen@google.com>2013-01-30 14:32:29 -0500
commit2dbd185fd0e5dfe9addb677f42716c442b7e62bd (patch)
tree6aac1ed40b80d003c8d5d6469d21092cd26d7141 /libs
parent1de9023190691b44df0f45eaaf501ced6177ca09 (diff)
parentc93c6aa5553203f05df871804517885fcc071cfd (diff)
downloadframeworks_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.cpp39
-rw-r--r--libs/hwui/DisplayListLogBuffer.h18
-rw-r--r--libs/hwui/DisplayListOp.h1138
-rw-r--r--libs/hwui/DisplayListRenderer.cpp1385
-rw-r--r--libs/hwui/DisplayListRenderer.h310
-rw-r--r--libs/hwui/OpenGLRenderer.cpp8
-rw-r--r--libs/hwui/Patch.cpp2
-rw-r--r--libs/hwui/PathRenderer.cpp1
-rw-r--r--libs/hwui/Rect.h19
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;
}