Merge "Object-based DisplayList recording"
This commit is contained in:
@ -1868,7 +1868,7 @@ public abstract class HardwareRenderer {
|
|||||||
mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
|
mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
|
||||||
switch (graphType) {
|
switch (graphType) {
|
||||||
case GraphDataProvider.GRAPH_TYPE_BARS:
|
case GraphDataProvider.GRAPH_TYPE_BARS:
|
||||||
mGlCanvas.drawRects(mProfileShapes[i], count, mProfilePaint);
|
mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
|
||||||
break;
|
break;
|
||||||
case GraphDataProvider.GRAPH_TYPE_LINES:
|
case GraphDataProvider.GRAPH_TYPE_LINES:
|
||||||
mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
|
mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
|
||||||
|
@ -479,7 +479,7 @@ static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject cla
|
|||||||
rects.push(r.fTop);
|
rects.push(r.fTop);
|
||||||
rects.push(r.fRight);
|
rects.push(r.fRight);
|
||||||
rects.push(r.fBottom);
|
rects.push(r.fBottom);
|
||||||
count++;
|
count += 4;
|
||||||
it.next();
|
it.next();
|
||||||
}
|
}
|
||||||
renderer->drawRects(rects.array(), count, paint);
|
renderer->drawRects(rects.array(), count, paint);
|
||||||
|
@ -18,9 +18,8 @@
|
|||||||
|
|
||||||
// BUFFER_SIZE size must be one more than a multiple of COMMAND_SIZE to ensure
|
// 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
|
// that mStart always points at the next command, not just the next item
|
||||||
#define COMMAND_SIZE 2
|
|
||||||
#define NUM_COMMANDS 50
|
#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
|
* DisplayListLogBuffer is a utility class which logs the most recent display
|
||||||
@ -57,7 +56,7 @@ namespace uirenderer {
|
|||||||
|
|
||||||
|
|
||||||
DisplayListLogBuffer::DisplayListLogBuffer() {
|
DisplayListLogBuffer::DisplayListLogBuffer() {
|
||||||
mBufferFirst = (int*) malloc(BUFFER_SIZE * sizeof(int));
|
mBufferFirst = (OpLog*) malloc(BUFFER_SIZE * sizeof(OpLog));
|
||||||
mStart = mBufferFirst;
|
mStart = mBufferFirst;
|
||||||
mBufferLast = mBufferFirst + BUFFER_SIZE - 1;
|
mBufferLast = mBufferFirst + BUFFER_SIZE - 1;
|
||||||
mEnd = mStart;
|
mEnd = mStart;
|
||||||
@ -71,42 +70,30 @@ DisplayListLogBuffer::~DisplayListLogBuffer() {
|
|||||||
* Called from DisplayListRenderer to output the current buffer into the
|
* Called from DisplayListRenderer to output the current buffer into the
|
||||||
* specified FILE. This only happens in a dumpsys/bugreport operation.
|
* 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) {
|
while (true) {
|
||||||
if (tmpBufferPtr == mEnd) {
|
if (tmpBufferPtr == mEnd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int level = *tmpBufferPtr++;
|
OpLog* nextOp = tmpBufferPtr++;
|
||||||
if (tmpBufferPtr > mBufferLast) {
|
if (tmpBufferPtr > mBufferLast) {
|
||||||
tmpBufferPtr = mBufferFirst;
|
tmpBufferPtr = mBufferFirst;
|
||||||
}
|
}
|
||||||
int op = *tmpBufferPtr++;
|
|
||||||
if (tmpBufferPtr > mBufferLast) {
|
fprintf(file, "%*s%s\n", tmpBufferPtr->level*2, "", tmpBufferPtr->label);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the given value in the buffer and increment/wrap the mEnd
|
* Store the given level and label in the buffer and increment/wrap the mEnd
|
||||||
* and mStart values as appropriate.
|
* and mStart values as appropriate. Label should point to static memory.
|
||||||
*/
|
*/
|
||||||
void DisplayListLogBuffer::writeInt(int value) {
|
void DisplayListLogBuffer::writeCommand(int level, const char* label) {
|
||||||
*((int*)mEnd) = value;
|
mEnd->level = level;
|
||||||
|
mEnd->label = label;
|
||||||
|
|
||||||
if (mEnd == mBufferLast) {
|
if (mEnd == mBufferLast) {
|
||||||
mEnd = mBufferFirst;
|
mEnd = mBufferFirst;
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,19 +31,23 @@ class DisplayListLogBuffer: public Singleton<DisplayListLogBuffer> {
|
|||||||
friend class Singleton<DisplayListLogBuffer>;
|
friend class Singleton<DisplayListLogBuffer>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void writeCommand(int level, int op);
|
void writeCommand(int level, const char* label);
|
||||||
void writeInt(int value);
|
void outputCommands(FILE *file);
|
||||||
void outputCommands(FILE *file, const char* opNames[]);
|
|
||||||
|
|
||||||
bool isEmpty() {
|
bool isEmpty() {
|
||||||
return (mStart == mEnd);
|
return (mStart == mEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OpLog {
|
||||||
|
int level;
|
||||||
|
const char* label;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int *mBufferFirst; // where the memory starts
|
OpLog* mBufferFirst; // where the memory starts
|
||||||
int* mStart; // where the current command stream starts
|
OpLog* mStart; // where the current command stream starts
|
||||||
int* mEnd; // where the current commands end
|
OpLog* mEnd; // where the current commands end
|
||||||
int* mBufferLast; // where the buffer memory ends
|
OpLog* mBufferLast; // where the buffer memory ends
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
1138
libs/hwui/DisplayListOp.h
Normal file
1138
libs/hwui/DisplayListOp.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "DisplayListLogBuffer.h"
|
#include "DisplayListLogBuffer.h"
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
|
#include "utils/LinearAllocator.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
@ -60,6 +61,18 @@ namespace uirenderer {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class DisplayListRenderer;
|
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.
|
* Replays recorded drawing commands.
|
||||||
@ -69,66 +82,13 @@ public:
|
|||||||
DisplayList(const DisplayListRenderer& recorder);
|
DisplayList(const DisplayListRenderer& recorder);
|
||||||
ANDROID_API ~DisplayList();
|
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
|
// See flags defined in DisplayList.java
|
||||||
enum ReplayFlag {
|
enum ReplayFlag {
|
||||||
kReplayFlag_ClipChildren = 0x1
|
kReplayFlag_ClipChildren = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* OP_NAMES[];
|
|
||||||
|
|
||||||
void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
|
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 size_t getSize();
|
||||||
ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
|
ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
|
||||||
@ -138,7 +98,7 @@ public:
|
|||||||
|
|
||||||
status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
|
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();
|
ANDROID_API void reset();
|
||||||
|
|
||||||
@ -423,78 +383,6 @@ private:
|
|||||||
const char* mText;
|
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*> mBitmapResources;
|
||||||
Vector<SkBitmap*> mOwnedBitmapResources;
|
Vector<SkBitmap*> mOwnedBitmapResources;
|
||||||
Vector<SkiaColorFilter*> mFilterResources;
|
Vector<SkiaColorFilter*> mFilterResources;
|
||||||
@ -507,7 +395,7 @@ private:
|
|||||||
Vector<SkiaShader*> mShaders;
|
Vector<SkiaShader*> mShaders;
|
||||||
Vector<Layer*> mLayers;
|
Vector<Layer*> mLayers;
|
||||||
|
|
||||||
mutable SkFlattenableReadBuffer mReader;
|
sp<DisplayListData> mDisplayListData;
|
||||||
|
|
||||||
size_t mSize;
|
size_t mSize;
|
||||||
|
|
||||||
@ -634,8 +522,8 @@ public:
|
|||||||
|
|
||||||
ANDROID_API void reset();
|
ANDROID_API void reset();
|
||||||
|
|
||||||
const SkWriter32& writeStream() const {
|
sp<DisplayListData> getDisplayListData() const {
|
||||||
return mWriter;
|
return mDisplayListData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector<SkBitmap*>& getBitmapResources() const {
|
const Vector<SkBitmap*>& getBitmapResources() const {
|
||||||
@ -683,102 +571,32 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void insertRestoreToCount() {
|
void insertRestoreToCount();
|
||||||
if (mRestoreSaveCount >= 0) {
|
void insertTranslate();
|
||||||
mWriter.writeInt(DisplayList::RestoreToCount);
|
|
||||||
addInt(mRestoreSaveCount);
|
|
||||||
mRestoreSaveCount = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void insertTranlate() {
|
LinearAllocator& alloc() { return mDisplayListData->allocator; }
|
||||||
if (mHasTranslate) {
|
void addStateOp(StateOp* op);
|
||||||
if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
|
bool addDrawOp(DrawOp* op); // returns true if op not rejected
|
||||||
mWriter.writeInt(DisplayList::Translate);
|
void addOpInternal(DisplayListOp* op) {
|
||||||
addPoint(mTranslateX, mTranslateY);
|
|
||||||
mTranslateX = mTranslateY = 0.0f;
|
|
||||||
}
|
|
||||||
mHasTranslate = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addOp(const DisplayList::Op drawOp) {
|
|
||||||
insertRestoreToCount();
|
insertRestoreToCount();
|
||||||
insertTranlate();
|
insertTranslate();
|
||||||
mWriter.writeInt(drawOp);
|
mDisplayListData->displayListOps.add(op);
|
||||||
mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
|
template<class T>
|
||||||
insertRestoreToCount();
|
inline T* refBuffer(const T* srcBuffer, int32_t count) {
|
||||||
insertTranlate();
|
if (srcBuffer == NULL) return NULL;
|
||||||
mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
|
T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
|
||||||
if (reject) {
|
memcpy(dstBuffer, srcBuffer, count * sizeof(T));
|
||||||
mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
|
return dstBuffer;
|
||||||
mWriter.writeInt(0xdeaddead);
|
|
||||||
mBufferSize = mWriter.size();
|
|
||||||
return mWriter.peek32(mBufferSize - sizeof(int32_t));
|
|
||||||
}
|
|
||||||
mWriter.writeInt(drawOp);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addSkip(uint32_t* location) {
|
inline char* refText(const char* text, size_t byteLength) {
|
||||||
if (location) {
|
return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
|
||||||
*location = (int32_t) (mWriter.size() - mBufferSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addInt(int32_t value) {
|
inline SkPath* refPath(SkPath* path) {
|
||||||
mWriter.writeInt(value);
|
if (!path) return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addFloats(const float* values, int32_t count) {
|
|
||||||
mWriter.writeInt(count);
|
|
||||||
mWriter.write(values, count * sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addPoint(float x, float y) {
|
|
||||||
mWriter.writeScalar(x);
|
|
||||||
mWriter.writeScalar(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPath* pathCopy = mPathMap.valueFor(path);
|
SkPath* pathCopy = mPathMap.valueFor(path);
|
||||||
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
|
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
|
||||||
@ -792,13 +610,11 @@ private:
|
|||||||
mCaches.resourceCache.incrementRefcount(path);
|
mCaches.resourceCache.incrementRefcount(path);
|
||||||
mSourcePaths.add(path);
|
mSourcePaths.add(path);
|
||||||
}
|
}
|
||||||
|
return pathCopy;
|
||||||
addInt((int) pathCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SkPaint* addPaint(SkPaint* paint) {
|
inline SkPaint* refPaint(SkPaint* paint) {
|
||||||
if (!paint) {
|
if (!paint) {
|
||||||
addInt((int) NULL);
|
|
||||||
return paint;
|
return paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,14 +626,11 @@ private:
|
|||||||
mPaints.add(paintCopy);
|
mPaints.add(paintCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
addInt((int) paintCopy);
|
|
||||||
|
|
||||||
return paintCopy;
|
return paintCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SkRegion* addRegion(SkRegion* region) {
|
inline SkRegion* refRegion(SkRegion* region) {
|
||||||
if (!region) {
|
if (!region) {
|
||||||
addInt((int) NULL);
|
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,53 +643,35 @@ private:
|
|||||||
mRegions.add(regionCopy);
|
mRegions.add(regionCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
addInt((int) regionCopy);
|
|
||||||
|
|
||||||
return regionCopy;
|
return regionCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addDisplayList(DisplayList* displayList) {
|
inline SkMatrix* refMatrix(SkMatrix* matrix) {
|
||||||
// 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) {
|
|
||||||
// Copying the matrix is cheap and prevents against the user changing the original
|
// Copying the matrix is cheap and prevents against the user changing the original
|
||||||
// matrix before the operation that uses it
|
// matrix before the operation that uses it
|
||||||
SkMatrix* copy = new SkMatrix(*matrix);
|
SkMatrix* copy = new SkMatrix(*matrix);
|
||||||
addInt((int) copy);
|
|
||||||
mMatrices.add(copy);
|
mMatrices.add(copy);
|
||||||
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addLayer(Layer* layer) {
|
inline SkBitmap* refBitmap(SkBitmap* bitmap) {
|
||||||
addInt((int) layer);
|
|
||||||
mLayers.add(layer);
|
|
||||||
mCaches.resourceCache.incrementRefcount(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addBitmap(SkBitmap* bitmap) {
|
|
||||||
// Note that this assumes the bitmap is immutable. There are cases this won't handle
|
// 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
|
// 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,
|
// 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.
|
// which doesn't seem worth the extra cycles for this unlikely case.
|
||||||
addInt((int) bitmap);
|
|
||||||
mBitmapResources.add(bitmap);
|
mBitmapResources.add(bitmap);
|
||||||
mCaches.resourceCache.incrementRefcount(bitmap);
|
mCaches.resourceCache.incrementRefcount(bitmap);
|
||||||
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addBitmapData(SkBitmap* bitmap) {
|
inline SkBitmap* refBitmapData(SkBitmap* bitmap) {
|
||||||
addInt((int) bitmap);
|
|
||||||
mOwnedBitmapResources.add(bitmap);
|
mOwnedBitmapResources.add(bitmap);
|
||||||
mCaches.resourceCache.incrementRefcount(bitmap);
|
mCaches.resourceCache.incrementRefcount(bitmap);
|
||||||
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addShader(SkiaShader* shader) {
|
inline SkiaShader* refShader(SkiaShader* shader) {
|
||||||
if (!shader) {
|
if (!shader) return NULL;
|
||||||
addInt((int) NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
|
SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
|
||||||
// TODO: We also need to handle generation ID changes in compose shaders
|
// TODO: We also need to handle generation ID changes in compose shaders
|
||||||
@ -887,14 +682,13 @@ private:
|
|||||||
mShaders.add(shaderCopy);
|
mShaders.add(shaderCopy);
|
||||||
mCaches.resourceCache.incrementRefcount(shaderCopy);
|
mCaches.resourceCache.incrementRefcount(shaderCopy);
|
||||||
}
|
}
|
||||||
|
return shaderCopy;
|
||||||
addInt((int) shaderCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addColorFilter(SkiaColorFilter* colorFilter) {
|
inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) {
|
||||||
addInt((int) colorFilter);
|
|
||||||
mFilterResources.add(colorFilter);
|
mFilterResources.add(colorFilter);
|
||||||
mCaches.resourceCache.incrementRefcount(colorFilter);
|
mCaches.resourceCache.incrementRefcount(colorFilter);
|
||||||
|
return colorFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<SkBitmap*> mBitmapResources;
|
Vector<SkBitmap*> mBitmapResources;
|
||||||
@ -919,12 +713,10 @@ private:
|
|||||||
|
|
||||||
Vector<Layer*> mLayers;
|
Vector<Layer*> mLayers;
|
||||||
|
|
||||||
uint32_t mBufferSize;
|
|
||||||
|
|
||||||
int mRestoreSaveCount;
|
int mRestoreSaveCount;
|
||||||
|
|
||||||
Caches& mCaches;
|
Caches& mCaches;
|
||||||
SkWriter32 mWriter;
|
sp<DisplayListData> mDisplayListData;
|
||||||
|
|
||||||
float mTranslateX;
|
float mTranslateX;
|
||||||
float mTranslateY;
|
float mTranslateY;
|
||||||
|
@ -1101,7 +1101,7 @@ void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
|
|||||||
rects.push(r.fTop);
|
rects.push(r.fTop);
|
||||||
rects.push(r.fRight);
|
rects.push(r.fRight);
|
||||||
rects.push(r.fBottom);
|
rects.push(r.fBottom);
|
||||||
count++;
|
count += 4;
|
||||||
it.next();
|
it.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1744,7 +1744,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList,
|
|||||||
|
|
||||||
void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) {
|
void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) {
|
||||||
if (displayList) {
|
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) {
|
void OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
|
||||||
int color = paint->getColor();
|
int color = paint->getColor();
|
||||||
SkPaint::Style style = paint->getStyle();
|
|
||||||
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
|
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
|
||||||
bool isAA = paint->isAntiAlias();
|
bool isAA = paint->isAntiAlias();
|
||||||
|
|
||||||
@ -3205,8 +3204,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
|
|||||||
Vertex mesh[count * 6];
|
Vertex mesh[count * 6];
|
||||||
Vertex* vertex = mesh;
|
Vertex* vertex = mesh;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int index = 0; index < count; index += 4) {
|
||||||
int index = i * 4;
|
|
||||||
float l = rects[index + 0];
|
float l = rects[index + 0];
|
||||||
float t = rects[index + 1];
|
float t = rects[index + 1];
|
||||||
float r = rects[index + 2];
|
float r = rects[index + 2];
|
||||||
|
@ -122,8 +122,6 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
|||||||
float rescaleX = 1.0f;
|
float rescaleX = 1.0f;
|
||||||
float rescaleY = 1.0f;
|
float rescaleY = 1.0f;
|
||||||
|
|
||||||
const float meshWidth = right - left;
|
|
||||||
|
|
||||||
if (xStretchCount > 0) {
|
if (xStretchCount > 0) {
|
||||||
uint32_t stretchSize = 0;
|
uint32_t stretchSize = 0;
|
||||||
for (uint32_t i = 1; i < mXCount; i += 2) {
|
for (uint32_t i = 1; i < mXCount; i += 2) {
|
||||||
|
@ -596,7 +596,6 @@ bool PathRenderer::convexPathPerimeterVertices(const SkPath& path, bool forceClo
|
|||||||
SkPath::Iter iter(path, forceClose);
|
SkPath::Iter iter(path, forceClose);
|
||||||
SkPoint pts[4];
|
SkPoint pts[4];
|
||||||
SkPath::Verb v;
|
SkPath::Verb v;
|
||||||
Vertex* newVertex = 0;
|
|
||||||
while (SkPath::kDone_Verb != (v = iter.next(pts))) {
|
while (SkPath::kDone_Verb != (v = iter.next(pts))) {
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case SkPath::kMove_Verb:
|
case SkPath::kMove_Verb:
|
||||||
|
@ -171,22 +171,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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 {
|
void intersectWith(Rect& tmp) const {
|
||||||
tmp.left = max(left, tmp.left);
|
tmp.left = fmaxf(left, tmp.left);
|
||||||
tmp.top = max(top, tmp.top);
|
tmp.top = fmaxf(top, tmp.top);
|
||||||
tmp.right = min(right, tmp.right);
|
tmp.right = fminf(right, tmp.right);
|
||||||
tmp.bottom = min(bottom, tmp.bottom);
|
tmp.bottom = fminf(bottom, tmp.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect intersectWith(float l, float t, float r, float b) const {
|
Rect intersectWith(float l, float t, float r, float b) const {
|
||||||
Rect tmp;
|
Rect tmp;
|
||||||
tmp.left = max(left, l);
|
tmp.left = fmaxf(left, l);
|
||||||
tmp.top = max(top, t);
|
tmp.top = fmaxf(top, t);
|
||||||
tmp.right = min(right, r);
|
tmp.right = fminf(right, r);
|
||||||
tmp.bottom = min(bottom, b);
|
tmp.bottom = fminf(bottom, b);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user