Optimize 9patch rendering.
This change detects empty quads in 9patches and removes them from the mesh to avoid unnecessary blending. Change-Id: I4500566fb4cb6845d64dcb59b522c0be7a0ec704
This commit is contained in:
@@ -257,8 +257,9 @@ static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
|
||||
Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
|
||||
Res_png_9patch::deserialize(patch);
|
||||
|
||||
renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0],
|
||||
patch->numXDivs, patch->numYDivs, left, top, right, bottom, paint);
|
||||
renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0], &patch->colors[0],
|
||||
patch->numXDivs, patch->numYDivs, patch->numColors,
|
||||
left, top, right, bottom, paint);
|
||||
|
||||
env->ReleaseByteArrayElements(chunks, storage, 0);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class NinePatch {
|
||||
mPaint != null ? mPaint.mNativePaint : 0,
|
||||
canvas.mDensity, mBitmap.mDensity);
|
||||
} else {
|
||||
canvas.drawPatch(mBitmap, mChunk, location, null);
|
||||
canvas.drawPatch(mBitmap, mChunk, location, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class NinePatch {
|
||||
canvas.mDensity, mBitmap.mDensity);
|
||||
} else {
|
||||
mRect.set(location);
|
||||
canvas.drawPatch(mBitmap, mChunk, mRect, null);
|
||||
canvas.drawPatch(mBitmap, mChunk, mRect, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -236,16 +236,19 @@ void DisplayList::replay(OpenGLRenderer& renderer) {
|
||||
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);
|
||||
|
||||
renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount,
|
||||
getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
|
||||
numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
}
|
||||
break;
|
||||
case DrawColor: {
|
||||
@@ -450,12 +453,13 @@ void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcT
|
||||
}
|
||||
|
||||
void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint) {
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint) {
|
||||
addOp(DisplayList::DrawPatch);
|
||||
addBitmap(bitmap);
|
||||
addInts(xDivs, width);
|
||||
addInts(yDivs, height);
|
||||
addUInts(colors, numColors);
|
||||
addBounds(left, top, right, bottom);
|
||||
addPaint(paint);
|
||||
}
|
||||
|
||||
@@ -169,6 +169,11 @@ private:
|
||||
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(int& count) {
|
||||
count = getInt();
|
||||
return (float*) mReader.skip(count * sizeof(float));
|
||||
@@ -236,8 +241,8 @@ public:
|
||||
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
||||
float dstRight, float dstBottom, const SkPaint* paint);
|
||||
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint);
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
void drawColor(int color, SkXfermode::Mode mode);
|
||||
void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
void drawPath(SkPath* path, SkPaint* paint);
|
||||
@@ -291,6 +296,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void addUInts(const uint32_t* values, int8_t count) {
|
||||
mWriter.writeInt(count);
|
||||
for (int8_t i = 0; i < count; i++) {
|
||||
mWriter.writeInt(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void addFloat(float value) {
|
||||
mWriter.writeScalar(value);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <SkMatrix.h>
|
||||
|
||||
#include "utils/Compare.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
namespace android {
|
||||
@@ -53,9 +54,6 @@ void Matrix4::loadIdentity() {
|
||||
mSimpleMatrix = true;
|
||||
}
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
#define almost(u, v) (fabs((u) - (v)) < EPSILON)
|
||||
|
||||
bool Matrix4::changesBounds() {
|
||||
return !(almost(data[0], 1.0f) && almost(data[1], 0.0f) && almost(data[2], 0.0f) &&
|
||||
almost(data[4], 0.0f) && almost(data[5], 1.0f) && almost(data[6], 0.0f) &&
|
||||
|
||||
@@ -72,11 +72,11 @@ void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcT
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint) {
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawPatch");
|
||||
OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, width, height,
|
||||
OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
|
||||
left, top, right, bottom, paint);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
||||
float dstRight, float dstBottom, const SkPaint* paint);
|
||||
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint);
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
void drawColor(int color, SkXfermode::Mode mode);
|
||||
void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
void drawPath(SkPath* path, SkPaint* paint);
|
||||
|
||||
@@ -689,8 +689,8 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint) {
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint) {
|
||||
if (quickReject(left, top, right, bottom)) {
|
||||
return;
|
||||
}
|
||||
@@ -705,7 +705,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
|
||||
getAlphaAndMode(paint, &alpha, &mode);
|
||||
|
||||
const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
|
||||
right - left, bottom - top, xDivs, yDivs, width, height);
|
||||
right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
|
||||
|
||||
// Specify right and bottom as +1.0f from left/top to prevent scaling since the
|
||||
// patch mesh already defines the final size
|
||||
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
||||
float dstRight, float dstBottom, const SkPaint* paint);
|
||||
virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
|
||||
const SkPaint* paint);
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
virtual void drawColor(int color, SkXfermode::Mode mode);
|
||||
virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
|
||||
virtual void drawPath(SkPath* path, SkPaint* paint);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "Patch.h"
|
||||
|
||||
namespace android {
|
||||
@@ -27,9 +29,9 @@ namespace uirenderer {
|
||||
// Constructors/destructor
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Patch::Patch(const uint32_t xCount, const uint32_t yCount) {
|
||||
Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads) {
|
||||
// 2 triangles per patch, 3 vertices per triangle
|
||||
verticesCount = (xCount + 1) * (yCount + 1) * 2 * 3;
|
||||
verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
|
||||
vertices = new TextureVertex[verticesCount];
|
||||
}
|
||||
|
||||
@@ -43,7 +45,8 @@ Patch::~Patch() {
|
||||
|
||||
void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
float left, float top, float right, float bottom,
|
||||
const int32_t* xDivs, const int32_t* yDivs, const uint32_t width, const uint32_t height) {
|
||||
const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t width, const uint32_t height, const uint32_t colorKey) {
|
||||
const uint32_t xStretchCount = (width + 1) >> 1;
|
||||
const uint32_t yStretchCount = (height + 1) >> 1;
|
||||
|
||||
@@ -75,6 +78,7 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
}
|
||||
|
||||
TextureVertex* vertex = vertices;
|
||||
uint32_t quadCount = 0;
|
||||
|
||||
float previousStepY = 0.0f;
|
||||
|
||||
@@ -94,7 +98,7 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
|
||||
|
||||
generateRow(vertex, y1, y2, v1, v2, xDivs, width, stretchX,
|
||||
right - left, bitmapWidth);
|
||||
right - left, bitmapWidth, quadCount, colorKey);
|
||||
|
||||
y1 = y2;
|
||||
v1 = (stepY + 0.5f) / bitmapHeight;
|
||||
@@ -103,11 +107,12 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
}
|
||||
|
||||
generateRow(vertex, y1, bottom - top, v1, 1.0f, xDivs, width, stretchX,
|
||||
right - left, bitmapWidth);
|
||||
right - left, bitmapWidth, quadCount, colorKey);
|
||||
}
|
||||
|
||||
inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
|
||||
const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth) {
|
||||
const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth,
|
||||
uint32_t& quadCount, const uint32_t colorKey) {
|
||||
float previousStepX = 0.0f;
|
||||
|
||||
float x1 = 0.0f;
|
||||
@@ -126,7 +131,7 @@ inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float
|
||||
}
|
||||
float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
|
||||
|
||||
generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2);
|
||||
generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount, colorKey);
|
||||
|
||||
x1 = x2;
|
||||
u1 = (stepX + 0.5f) / bitmapWidth;
|
||||
@@ -134,11 +139,15 @@ inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float
|
||||
previousStepX = stepX;
|
||||
}
|
||||
|
||||
generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2);
|
||||
generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, colorKey);
|
||||
}
|
||||
|
||||
inline void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
|
||||
float u1, float v1, float u2, float v2) {
|
||||
float u1, float v1, float u2, float v2, uint32_t& quadCount, const uint32_t colorKey) {
|
||||
if (((colorKey >> quadCount++) & 0x1) == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Left triangle
|
||||
TextureVertex::set(vertex++, x1, y1, u1, v1);
|
||||
TextureVertex::set(vertex++, x2, y1, u2, v1);
|
||||
|
||||
@@ -18,29 +18,36 @@
|
||||
#define ANDROID_UI_PATCH_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "Vertex.h"
|
||||
#include "utils/Compare.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 9-patch structures
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Description of a patch.
|
||||
*/
|
||||
struct PatchDescription {
|
||||
PatchDescription(): bitmapWidth(0), bitmapHeight(0),
|
||||
pixelWidth(0), pixelHeight(0), xCount(0), yCount(0) { }
|
||||
PatchDescription(): bitmapWidth(0), bitmapHeight(0), pixelWidth(0), pixelHeight(0),
|
||||
xCount(0), yCount(0), emptyCount(0), colorKey(0) { }
|
||||
PatchDescription(const float bitmapWidth, const float bitmapHeight,
|
||||
const float pixelWidth, const float pixelHeight,
|
||||
const uint32_t xCount, const uint32_t yCount):
|
||||
const uint32_t xCount, const uint32_t yCount,
|
||||
const int8_t emptyCount, const uint32_t colorKey):
|
||||
bitmapWidth(bitmapWidth), bitmapHeight(bitmapHeight),
|
||||
pixelWidth(pixelWidth), pixelHeight(pixelHeight),
|
||||
xCount(xCount), yCount(yCount) { }
|
||||
xCount(xCount), yCount(yCount),
|
||||
emptyCount(emptyCount), colorKey(colorKey) { }
|
||||
PatchDescription(const PatchDescription& description):
|
||||
bitmapWidth(description.bitmapWidth), bitmapHeight(description.bitmapHeight),
|
||||
pixelWidth(description.pixelWidth), pixelHeight(description.pixelHeight),
|
||||
xCount(description.xCount), yCount(description.yCount) { }
|
||||
xCount(description.xCount), yCount(description.yCount),
|
||||
emptyCount(description.emptyCount), colorKey(description.colorKey) { }
|
||||
|
||||
float bitmapWidth;
|
||||
float bitmapHeight;
|
||||
@@ -48,9 +55,26 @@ struct PatchDescription {
|
||||
float pixelHeight;
|
||||
uint32_t xCount;
|
||||
uint32_t yCount;
|
||||
int8_t emptyCount;
|
||||
uint32_t colorKey;
|
||||
|
||||
bool operator<(const PatchDescription& rhs) const {
|
||||
return memcmp(this, &rhs, sizeof(PatchDescription)) < 0;
|
||||
compare(bitmapWidth) {
|
||||
compare(bitmapHeight) {
|
||||
compare(pixelWidth) {
|
||||
compare(pixelHeight) {
|
||||
compareI(xCount) {
|
||||
compareI(yCount) {
|
||||
compareI(emptyCount) {
|
||||
compareI(colorKey) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}; // struct PatchDescription
|
||||
|
||||
@@ -59,13 +83,14 @@ struct PatchDescription {
|
||||
* indices to render the vertices.
|
||||
*/
|
||||
struct Patch {
|
||||
Patch(const uint32_t xCount, const uint32_t yCount);
|
||||
Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads = 0);
|
||||
~Patch();
|
||||
|
||||
void updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
float left, float top, float right, float bottom,
|
||||
const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t width, const uint32_t height);
|
||||
const uint32_t width, const uint32_t height,
|
||||
const uint32_t colorKey = 0);
|
||||
|
||||
TextureVertex* vertices;
|
||||
uint32_t verticesCount;
|
||||
@@ -73,10 +98,12 @@ struct Patch {
|
||||
private:
|
||||
static inline void generateRow(TextureVertex*& vertex, float y1, float y2,
|
||||
float v1, float v2, const int32_t xDivs[], uint32_t xCount,
|
||||
float stretchX, float width, float bitmapWidth);
|
||||
float stretchX, float width, float bitmapWidth,
|
||||
uint32_t& quadCount, const uint32_t colorKey);
|
||||
static inline void generateQuad(TextureVertex*& vertex,
|
||||
float x1, float y1, float x2, float y2,
|
||||
float u1, float v1, float u2, float v2);
|
||||
float u1, float v1, float u2, float v2,
|
||||
uint32_t& quadCount, const uint32_t colorKey);
|
||||
}; // struct Patch
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define LOG_TAG "OpenGLRenderer"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ResourceTypes.h>
|
||||
|
||||
#include "PatchCache.h"
|
||||
#include "Properties.h"
|
||||
@@ -45,7 +44,7 @@ PatchCache::~PatchCache() {
|
||||
|
||||
void PatchCache::clear() {
|
||||
size_t count = mCache.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
delete mCache.valueAt(i);
|
||||
}
|
||||
mCache.clear();
|
||||
@@ -53,11 +52,23 @@ void PatchCache::clear() {
|
||||
|
||||
Patch* PatchCache::get(const float bitmapWidth, const float bitmapHeight,
|
||||
const float pixelWidth, const float pixelHeight,
|
||||
const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t width, const uint32_t height) {
|
||||
const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors,
|
||||
const uint32_t width, const uint32_t height, const int8_t numColors) {
|
||||
|
||||
int8_t transparentQuads = 0;
|
||||
uint32_t colorKey = 0;
|
||||
|
||||
if (uint8_t(numColors) < sizeof(uint32_t) * 4) {
|
||||
for (int8_t i = 0; i < numColors; i++) {
|
||||
if (colors[i] == 0x0) {
|
||||
transparentQuads++;
|
||||
colorKey |= 0x1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const PatchDescription description(bitmapWidth, bitmapHeight,
|
||||
pixelWidth, pixelHeight, width, height);
|
||||
pixelWidth, pixelHeight, width, height, transparentQuads, colorKey);
|
||||
|
||||
ssize_t index = mCache.indexOfKey(description);
|
||||
Patch* mesh = NULL;
|
||||
@@ -66,11 +77,13 @@ Patch* PatchCache::get(const float bitmapWidth, const float bitmapHeight,
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
PATCH_LOGD("Creating new patch mesh, w=%d h=%d", width, height);
|
||||
PATCH_LOGD("New patch mesh "
|
||||
"xCount=%d yCount=%d, w=%.2f h=%.2f, bw=%.2f bh=%.2f",
|
||||
width, height, pixelWidth, pixelHeight, bitmapWidth, bitmapHeight);
|
||||
|
||||
mesh = new Patch(width, height);
|
||||
mesh = new Patch(width, height, transparentQuads);
|
||||
mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f,
|
||||
pixelWidth, pixelHeight, xDivs, yDivs, width, height);
|
||||
pixelWidth, pixelHeight, xDivs, yDivs, width, height, colorKey);
|
||||
|
||||
if (mCache.size() >= mMaxEntries) {
|
||||
delete mCache.valueAt(mCache.size() - 1);
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace uirenderer {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Debug
|
||||
#define DEBUG_PATCHES 0
|
||||
#define DEBUG_PATCHES 1
|
||||
|
||||
// Debug
|
||||
#if DEBUG_PATCHES
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
|
||||
Patch* get(const float bitmapWidth, const float bitmapHeight,
|
||||
const float pixelWidth, const float pixelHeight,
|
||||
const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t width, const uint32_t height);
|
||||
const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors,
|
||||
const uint32_t width, const uint32_t height, const int8_t numColors);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <SkPath.h>
|
||||
|
||||
#include "Texture.h"
|
||||
#include "utils/Compare.h"
|
||||
#include "utils/GenerationCache.h"
|
||||
|
||||
namespace android {
|
||||
@@ -63,7 +64,18 @@ struct PathCacheEntry {
|
||||
float strokeWidth;
|
||||
|
||||
bool operator<(const PathCacheEntry& rhs) const {
|
||||
return memcmp(this, &rhs, sizeof(PathCacheEntry)) < 0;
|
||||
compareI(path) {
|
||||
compareI(join) {
|
||||
compareI(cap) {
|
||||
compareI(style) {
|
||||
compare(miter) {
|
||||
compare(strokeWidth) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}; // struct PathCacheEntry
|
||||
|
||||
|
||||
40
libs/hwui/utils/Compare.h
Normal file
40
libs/hwui/utils/Compare.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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_UI_COMPARE_H
|
||||
#define ANDROID_UI_COMPARE_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
|
||||
#define almost(u, v) (fabs((u) - (v)) < EPSILON)
|
||||
|
||||
/**
|
||||
* Compare floats.
|
||||
*/
|
||||
#define compare(a) \
|
||||
if (a < rhs.a) return true; \
|
||||
if (almost(a, rhs.a))
|
||||
|
||||
/**
|
||||
* Compare integers.
|
||||
*/
|
||||
#define compareI(a) \
|
||||
if (a < rhs.a) return true; \
|
||||
if (a == rhs.a)
|
||||
|
||||
#endif // ANDROID_UI_COMPARE_H
|
||||
Reference in New Issue
Block a user