Merge "Object-based DisplayList recording"
This commit is contained in:
@ -1868,7 +1868,7 @@ public abstract class HardwareRenderer {
|
||||
mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
|
||||
switch (graphType) {
|
||||
case GraphDataProvider.GRAPH_TYPE_BARS:
|
||||
mGlCanvas.drawRects(mProfileShapes[i], count, mProfilePaint);
|
||||
mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
|
||||
break;
|
||||
case GraphDataProvider.GRAPH_TYPE_LINES:
|
||||
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.fRight);
|
||||
rects.push(r.fBottom);
|
||||
count++;
|
||||
count += 4;
|
||||
it.next();
|
||||
}
|
||||
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
|
||||
// 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 {
|
||||
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
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 "OpenGLRenderer.h"
|
||||
#include "utils/LinearAllocator.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@ -60,6 +61,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.
|
||||
@ -69,66 +82,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);
|
||||
@ -138,7 +98,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();
|
||||
|
||||
@ -423,78 +383,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;
|
||||
@ -507,7 +395,7 @@ private:
|
||||
Vector<SkiaShader*> mShaders;
|
||||
Vector<Layer*> mLayers;
|
||||
|
||||
mutable SkFlattenableReadBuffer mReader;
|
||||
sp<DisplayListData> mDisplayListData;
|
||||
|
||||
size_t mSize;
|
||||
|
||||
@ -634,8 +522,8 @@ public:
|
||||
|
||||
ANDROID_API void reset();
|
||||
|
||||
const SkWriter32& writeStream() const {
|
||||
return mWriter;
|
||||
sp<DisplayListData> getDisplayListData() const {
|
||||
return mDisplayListData;
|
||||
}
|
||||
|
||||
const Vector<SkBitmap*>& getBitmapResources() const {
|
||||
@ -683,102 +571,32 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void insertRestoreToCount() {
|
||||
if (mRestoreSaveCount >= 0) {
|
||||
mWriter.writeInt(DisplayList::RestoreToCount);
|
||||
addInt(mRestoreSaveCount);
|
||||
mRestoreSaveCount = -1;
|
||||
}
|
||||
}
|
||||
void insertRestoreToCount();
|
||||
void insertTranslate();
|
||||
|
||||
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) {
|
||||
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();
|
||||
mWriter.writeInt(drawOp);
|
||||
mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
|
||||
insertTranslate();
|
||||
mDisplayListData->displayListOps.add(op);
|
||||
}
|
||||
|
||||
uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
|
||||
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;
|
||||
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 addSkip(uint32_t* location) {
|
||||
if (location) {
|
||||
*location = (int32_t) (mWriter.size() - mBufferSize);
|
||||
}
|
||||
inline char* refText(const char* text, size_t byteLength) {
|
||||
return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
inline SkPath* refPath(SkPath* path) {
|
||||
if (!path) return NULL;
|
||||
|
||||
SkPath* pathCopy = mPathMap.valueFor(path);
|
||||
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
|
||||
@ -792,13 +610,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;
|
||||
}
|
||||
|
||||
@ -810,14 +626,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;
|
||||
}
|
||||
|
||||
@ -830,53 +643,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
|
||||
@ -887,14 +682,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;
|
||||
@ -919,12 +713,10 @@ private:
|
||||
|
||||
Vector<Layer*> mLayers;
|
||||
|
||||
uint32_t mBufferSize;
|
||||
|
||||
int mRestoreSaveCount;
|
||||
|
||||
Caches& mCaches;
|
||||
SkWriter32 mWriter;
|
||||
sp<DisplayListData> mDisplayListData;
|
||||
|
||||
float mTranslateX;
|
||||
float mTranslateY;
|
||||
|
@ -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];
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user