summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2013-05-08 18:35:44 -0700
committerChris Craik <ccraik@google.com>2013-05-14 14:12:55 -0700
commit6d29c8d5218cac0fb35f3b7c253f2bdebd44f15a (patch)
treee7b76c068ff3e8485fdc164118914ee3b53a2368 /libs
parent0ace0aa7d643b5b9952d32827575f041ba563c58 (diff)
downloadframeworks_base-6d29c8d5218cac0fb35f3b7c253f2bdebd44f15a.zip
frameworks_base-6d29c8d5218cac0fb35f3b7c253f2bdebd44f15a.tar.gz
frameworks_base-6d29c8d5218cac0fb35f3b7c253f2bdebd44f15a.tar.bz2
Add tessellation path for points
bug:4351353 bug:8185479 Point tessellation is similar to line special case, except that we only tessellate one point (as a circle or rect) and duplicate it across other instances. Additionally: Fixes square caps for AA=false lines Cleanup in CanvasCompare, disabling interpolation on zoomed-in comparison view Change-Id: I0756fcc4b20f77878fed0d8057297c80e82ed9dc
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp77
-rw-r--r--libs/hwui/OpenGLRenderer.h2
-rw-r--r--libs/hwui/PathTessellator.cpp145
-rw-r--r--libs/hwui/PathTessellator.h35
-rw-r--r--libs/hwui/Program.h27
-rw-r--r--libs/hwui/ProgramCache.cpp42
-rw-r--r--libs/hwui/Vertex.h17
7 files changed, 168 insertions, 177 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f220e4f..038df07 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1703,11 +1703,6 @@ void OpenGLRenderer::setupDrawAA() {
mDescription.isAA = true;
}
-void OpenGLRenderer::setupDrawPoint(float pointSize) {
- mDescription.isPoint = true;
- mDescription.pointSize = pointSize;
-}
-
void OpenGLRenderer::setupDrawColor(int color, int alpha) {
mColorA = alpha / 255.0f;
mColorR = mColorA * ((color >> 16) & 0xFF) / 255.0f;
@@ -1822,11 +1817,6 @@ void OpenGLRenderer::setupDrawModelView(float left, float top, float right, floa
}
}
-void OpenGLRenderer::setupDrawPointUniforms() {
- int slot = mCaches.currentProgram->getUniform("pointSize");
- glUniform1f(slot, mDescription.pointSize);
-}
-
void OpenGLRenderer::setupDrawColorUniforms() {
if ((mColorSet && !mDrawModifiers.mShader) || (mDrawModifiers.mShader && mSetShaderColor)) {
mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
@@ -2409,7 +2399,7 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
bool useOffset) {
- if (!vertexBuffer.getSize()) {
+ if (!vertexBuffer.getVertexCount()) {
// no vertices to draw
return DrawGlInfo::kStatusDone;
}
@@ -2447,7 +2437,7 @@ status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPa
glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
}
- glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getSize());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
if (isAA) {
glDisableVertexAttribArray(alphaSlot);
@@ -2510,65 +2500,22 @@ status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
}
status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
-
- // TODO: The paint's cap style defines whether the points are square or circular
- // TODO: Handle AA for round points
-
- // A stroke width of 0 has a special meaning in Skia:
- // it draws an unscaled 1px point
- float strokeWidth = paint->getStrokeWidth();
- const bool isHairLine = paint->getStrokeWidth() == 0.0f;
- if (isHairLine) {
- // Now that we know it's hairline, we can set the effective width, to be used later
- strokeWidth = 1.0f;
- }
- const float halfWidth = strokeWidth / 2;
-
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
+ if (mSnapshot->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
- int verticesCount = count >> 1;
- int generatedVerticesCount = 0;
+ count &= ~0x1; // round down to nearest two
- TextureVertex pointsData[verticesCount];
- TextureVertex* vertex = &pointsData[0];
-
- // TODO: We should optimize this method to not generate vertices for points
- // that lie outside of the clip.
- mCaches.enableScissor();
-
- setupDraw();
- setupDrawNoTexture();
- setupDrawPoint(strokeWidth);
- setupDrawColor(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(mode);
- setupDrawProgram();
- setupDrawModelViewIdentity(true);
- setupDrawColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawPointUniforms();
- setupDrawShaderIdentityUniforms();
- setupDrawMesh(vertex);
-
- for (int i = 0; i < count; i += 2) {
- TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
- generatedVerticesCount++;
-
- float left = points[i] - halfWidth;
- float right = points[i] + halfWidth;
- float top = points[i + 1] - halfWidth;
- float bottom = points [i + 1] + halfWidth;
+ VertexBuffer buffer;
+ SkRect bounds;
+ PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer);
- dirtyLayer(left, top, right, bottom, currentTransform());
+ if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+ return DrawGlInfo::kStatusDone;
}
- glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+ dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
- return DrawGlInfo::kStatusDrew;
+ bool useOffset = !paint->isAntiAlias();
+ return drawVertexBuffer(buffer, paint, useOffset);
}
status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index df275d7..597e458 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -927,7 +927,6 @@ private:
void setupDrawWithExternalTexture();
void setupDrawNoTexture();
void setupDrawAA();
- void setupDrawPoint(float pointSize);
void setupDrawColor(int color, int alpha);
void setupDrawColor(float r, float g, float b, float a);
void setupDrawAlpha8Color(int color, int alpha);
@@ -945,7 +944,6 @@ private:
bool ignoreTransform = false, bool ignoreModelView = false);
void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
bool ignoreTransform = false);
- void setupDrawPointUniforms();
void setupDrawColorUniforms();
void setupDrawPureColorUniforms();
void setupDrawShaderIdentityUniforms();
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 0879b1b..3970913 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -66,11 +66,11 @@ void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint
}
}
-inline void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
+inline static void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
}
-inline void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
+inline static void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
}
@@ -84,7 +84,7 @@ inline void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
*
* NOTE: assumes angles between normals 90 degrees or less
*/
-inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
+inline static vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
}
@@ -224,6 +224,20 @@ void getStrokeVerticesFromPerimeter(const PaintInfo& paintInfo, const Vector<Ver
DEBUG_DUMP_BUFFER();
}
+static inline void storeBeginEnd(const PaintInfo& paintInfo, const Vertex& center,
+ const vec2& normal, Vertex* buffer, int& currentIndex, bool begin) {
+ vec2 strokeOffset = normal;
+ paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
+
+ vec2 referencePoint(center.position[0], center.position[1]);
+ if (paintInfo.cap == SkPaint::kSquare_Cap) {
+ referencePoint += vec2(-strokeOffset.y, strokeOffset.x) * (begin ? -1 : 1);
+ }
+
+ Vertex::set(&buffer[currentIndex++], referencePoint + strokeOffset);
+ Vertex::set(&buffer[currentIndex++], referencePoint - strokeOffset);
+}
+
/**
* Fills a vertexBuffer with non-alpha vertices similar to getStrokeVerticesFromPerimeter, except:
*
@@ -235,19 +249,17 @@ void getStrokeVerticesFromUnclosedVertices(const PaintInfo& paintInfo,
const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) {
const int extra = paintInfo.capExtraDivisions();
const int allocSize = (vertices.size() + extra) * 2;
-
Vertex* buffer = vertexBuffer.alloc<Vertex>(allocSize);
+ const int lastIndex = vertices.size() - 1;
if (extra > 0) {
// tessellate both round caps
- const int last = vertices.size() - 1;
float beginTheta = atan2(
- - (vertices[0].position[0] - vertices[1].position[0]),
- vertices[0].position[1] - vertices[1].position[1]);
+ - (vertices[0].position[0] - vertices[1].position[0]),
+ vertices[0].position[1] - vertices[1].position[1]);
float endTheta = atan2(
- - (vertices[last].position[0] - vertices[last - 1].position[0]),
- vertices[last].position[1] - vertices[last - 1].position[1]);
-
+ - (vertices[lastIndex].position[0] - vertices[lastIndex - 1].position[0]),
+ vertices[lastIndex].position[1] - vertices[lastIndex - 1].position[1]);
const float dTheta = PI / (extra + 1);
const float radialScale = 2.0f / (1 + cos(dTheta));
@@ -270,56 +282,45 @@ void getStrokeVerticesFromUnclosedVertices(const PaintInfo& paintInfo,
vec2 endRadialOffset(cos(endTheta), sin(endTheta));
paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
Vertex::set(&buffer[allocSize - 1 - capOffset],
- vertices[last].position[0] + endRadialOffset.x,
- vertices[last].position[1] + endRadialOffset.y);
+ vertices[lastIndex].position[0] + endRadialOffset.x,
+ vertices[lastIndex].position[1] + endRadialOffset.y);
}
}
int currentIndex = extra;
- const Vertex* current = &(vertices[0]);
- vec2 lastNormal;
- for (unsigned int i = 0; i < vertices.size() - 1; i++) {
+ const Vertex* last = &(vertices[0]);
+ const Vertex* current = &(vertices[1]);
+ vec2 lastNormal(current->position[1] - last->position[1],
+ last->position[0] - current->position[0]);
+ lastNormal.normalize();
+
+ storeBeginEnd(paintInfo, vertices[0], lastNormal, buffer, currentIndex, true);
+
+ for (unsigned int i = 1; i < vertices.size() - 1; i++) {
const Vertex* next = &(vertices[i + 1]);
vec2 nextNormal(next->position[1] - current->position[1],
current->position[0] - next->position[0]);
nextNormal.normalize();
- vec2 totalOffset;
- if (i == 0) {
- totalOffset = nextNormal;
- } else {
- totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
- }
- paintInfo.scaleOffsetForStrokeWidth(totalOffset);
+ vec2 strokeOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+ paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
- Vertex::set(&buffer[currentIndex++],
- current->position[0] + totalOffset.x,
- current->position[1] + totalOffset.y);
-
- Vertex::set(&buffer[currentIndex++],
- current->position[0] - totalOffset.x,
- current->position[1] - totalOffset.y);
+ vec2 center(current->position[0], current->position[1]);
+ Vertex::set(&buffer[currentIndex++], center + strokeOffset);
+ Vertex::set(&buffer[currentIndex++], center - strokeOffset);
current = next;
lastNormal = nextNormal;
}
- vec2 totalOffset = lastNormal;
- paintInfo.scaleOffsetForStrokeWidth(totalOffset);
-
- Vertex::set(&buffer[currentIndex++],
- current->position[0] + totalOffset.x,
- current->position[1] + totalOffset.y);
- Vertex::set(&buffer[currentIndex++],
- current->position[0] - totalOffset.x,
- current->position[1] - totalOffset.y);
+ storeBeginEnd(paintInfo, vertices[lastIndex], lastNormal, buffer, currentIndex, false);
DEBUG_DUMP_BUFFER();
}
/**
* Populates a vertexBuffer with AlphaVertices to create an anti-aliased fill shape tessellation
- *
+ *
* 1 - create the AA perimeter of unit width, by zig-zagging at each point around the perimeter of
* the shape (using 2 * perimeter.size() vertices)
*
@@ -389,7 +390,7 @@ void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Ver
* For explanation of constants and general methodoloyg, see comments for
* getStrokeVerticesFromUnclosedVerticesAA() below.
*/
-inline void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
+inline static void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
AlphaVertex* buffer, bool isFirst, vec2 normal, int offset) {
const int extra = paintInfo.capExtraDivisions();
const int extraOffset = (extra + 1) / 2;
@@ -772,11 +773,67 @@ void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint,
}
}
+static void expandRectToCoverVertex(SkRect& rect, float x, float y) {
+ rect.fLeft = fminf(rect.fLeft, x);
+ rect.fTop = fminf(rect.fTop, y);
+ rect.fRight = fmaxf(rect.fRight, x);
+ rect.fBottom = fmaxf(rect.fBottom, y);
+}
static void expandRectToCoverVertex(SkRect& rect, const Vertex& vertex) {
- rect.fLeft = fminf(rect.fLeft, vertex.position[0]);
- rect.fTop = fminf(rect.fTop, vertex.position[1]);
- rect.fRight = fmaxf(rect.fRight, vertex.position[0]);
- rect.fBottom = fmaxf(rect.fBottom, vertex.position[1]);
+ expandRectToCoverVertex(rect, vertex.position[0], vertex.position[1]);
+}
+
+template <class TYPE>
+static void instanceVertices(VertexBuffer& srcBuffer, VertexBuffer& dstBuffer,
+ const float* points, int count, SkRect& bounds) {
+ bounds.set(points[0], points[1], points[0], points[1]);
+
+ int numPoints = count / 2;
+ int verticesPerPoint = srcBuffer.getVertexCount();
+ dstBuffer.alloc<TYPE>(numPoints * verticesPerPoint + (numPoints - 1) * 2);
+
+ for (int i = 0; i < count; i += 2) {
+ expandRectToCoverVertex(bounds, points[i + 0], points[i + 1]);
+ dstBuffer.copyInto<TYPE>(srcBuffer, points[i + 0], points[i + 1]);
+ }
+ dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
+}
+
+void PathTessellator::tessellatePoints(const float* points, int count, SkPaint* paint,
+ const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+ const PaintInfo paintInfo(paint, transform);
+
+ // determine point shape
+ SkPath path;
+ float radius = paintInfo.halfStrokeWidth;
+ if (radius == 0.0f) radius = 0.25f;
+
+ if (paintInfo.cap == SkPaint::kRound_Cap) {
+ path.addCircle(0, 0, radius);
+ } else {
+ path.addRect(-radius, -radius, radius, radius);
+ }
+
+ // calculate outline
+ Vector<Vertex> outlineVertices;
+ approximatePathOutlineVertices(path, true,
+ paintInfo.inverseScaleX * paintInfo.inverseScaleX,
+ paintInfo.inverseScaleY * paintInfo.inverseScaleY, outlineVertices);
+
+ if (!outlineVertices.size()) return;
+
+ // tessellate, then duplicate outline across points
+ int numPoints = count / 2;
+ VertexBuffer tempBuffer;
+ if (!paintInfo.isAA) {
+ getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
+ instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
+ } else {
+ getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer);
+ instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
+ }
+
+ expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
}
void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index 596d49d..85797fc 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -30,7 +30,7 @@ class VertexBuffer {
public:
VertexBuffer():
mBuffer(0),
- mSize(0),
+ mVertexCount(0),
mCleanupMethod(NULL)
{}
@@ -44,30 +44,42 @@ public:
multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines()
*/
template <class TYPE>
- TYPE* alloc(int size) {
- if (mSize) {
+ TYPE* alloc(int vertexCount) {
+ if (mVertexCount) {
TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
// already have allocated the buffer, re-allocate space within
if (mReallocBuffer != mBuffer) {
// not first re-allocation, leave space for degenerate triangles to separate strips
reallocBuffer += 2;
}
- mReallocBuffer = reallocBuffer + size;
+ mReallocBuffer = reallocBuffer + vertexCount;
return reallocBuffer;
}
- mSize = size;
- mReallocBuffer = mBuffer = (void*)new TYPE[size];
+ mVertexCount = vertexCount;
+ mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
mCleanupMethod = &(cleanup<TYPE>);
return (TYPE*)mBuffer;
}
- void* getBuffer() const { return mBuffer; }
- unsigned int getSize() const { return mSize; }
+ template <class TYPE>
+ void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
+ int verticesToCopy = srcBuffer.getVertexCount();
+
+ TYPE* dst = alloc<TYPE>(verticesToCopy);
+ TYPE* src = (TYPE*)srcBuffer.getBuffer();
+
+ for (int i = 0; i < verticesToCopy; i++) {
+ TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset);
+ }
+ }
+
+ void* getBuffer() const { return mBuffer; } // shouldn't be const, since not a const ptr?
+ unsigned int getVertexCount() const { return mVertexCount; }
template <class TYPE>
void createDegenerateSeparators(int allocSize) {
- TYPE* end = (TYPE*)mBuffer + mSize;
+ TYPE* end = (TYPE*)mBuffer + mVertexCount;
for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
memcpy(degen, degen - 1, sizeof(TYPE));
memcpy(degen + 1, degen + 2, sizeof(TYPE));
@@ -81,7 +93,7 @@ private:
}
void* mBuffer;
- unsigned int mSize;
+ unsigned int mVertexCount;
void* mReallocBuffer; // used for multi-allocation
@@ -95,6 +107,9 @@ public:
static void tessellatePath(const SkPath& path, const SkPaint* paint,
const mat4 *transform, VertexBuffer& vertexBuffer);
+ static void tessellatePoints(const float* points, int count, SkPaint* paint,
+ const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+
static void tessellateLines(const float* points, int count, SkPaint* paint,
const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index dd1aaa2..4f94afc 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -68,24 +68,22 @@ namespace uirenderer {
#define PROGRAM_BITMAP_WRAPS_SHIFT 9
#define PROGRAM_BITMAP_WRAPT_SHIFT 11
-#define PROGRAM_GRADIENT_TYPE_SHIFT 33
+#define PROGRAM_GRADIENT_TYPE_SHIFT 33 // 2 bits for gradient type
#define PROGRAM_MODULATE_SHIFT 35
-#define PROGRAM_IS_POINT_SHIFT 36
+#define PROGRAM_HAS_AA_SHIFT 36
-#define PROGRAM_HAS_AA_SHIFT 37
+#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 37
+#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 38
-#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
-#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
+#define PROGRAM_HAS_GAMMA_CORRECTION 39
-#define PROGRAM_HAS_GAMMA_CORRECTION 40
+#define PROGRAM_IS_SIMPLE_GRADIENT 40
-#define PROGRAM_IS_SIMPLE_GRADIENT 41
+#define PROGRAM_HAS_COLORS 41
-#define PROGRAM_HAS_COLORS 42
-
-#define PROGRAM_HAS_DEBUG_HIGHLIGHT 43
-#define PROGRAM_EMULATE_STENCIL 44
+#define PROGRAM_HAS_DEBUG_HIGHLIGHT 42
+#define PROGRAM_EMULATE_STENCIL 43
///////////////////////////////////////////////////////////////////////////////
// Types
@@ -157,9 +155,6 @@ struct ProgramDescription {
SkXfermode::Mode framebufferMode;
bool swapSrcDst;
- bool isPoint;
- float pointSize;
-
bool hasGammaCorrection;
float gamma;
@@ -201,9 +196,6 @@ struct ProgramDescription {
framebufferMode = SkXfermode::kClear_Mode;
swapSrcDst = false;
- isPoint = false;
- pointSize = 0.0f;
-
hasGammaCorrection = false;
gamma = 2.2f;
@@ -269,7 +261,6 @@ struct ProgramDescription {
key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
- if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 367294c..a5ce6f6 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -53,8 +53,6 @@ const char* gVS_Header_Uniforms_TextureTransform =
const char* gVS_Header_Uniforms =
"uniform mat4 projection;\n" \
"uniform mat4 transform;\n";
-const char* gVS_Header_Uniforms_IsPoint =
- "uniform mediump float pointSize;\n";
const char* gVS_Header_Uniforms_HasGradient =
"uniform mat4 screenSpace;\n";
const char* gVS_Header_Uniforms_HasBitmap =
@@ -68,8 +66,6 @@ const char* gVS_Header_Varyings_IsAAVertexShape =
"varying float alpha;\n";
const char* gVS_Header_Varyings_HasBitmap =
"varying highp vec2 outBitmapTexCoords;\n";
-const char* gVS_Header_Varyings_PointHasBitmap =
- "varying highp vec2 outPointBitmapTexCoords;\n";
const char* gVS_Header_Varyings_HasGradient[6] = {
// Linear
"varying highp vec2 linear;\n"
@@ -118,12 +114,8 @@ const char* gVS_Main_OutGradient[6] = {
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
-const char* gVS_Main_OutPointBitmapTexCoords =
- " outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
" gl_Position = projection * transform * position;\n";
-const char* gVS_Main_PointSize =
- " gl_PointSize = pointSize;\n";
const char* gVS_Main_AAVertexShape =
" alpha = vtxAlpha;\n";
const char* gVS_Footer =
@@ -141,9 +133,6 @@ const char* gFS_Header =
"precision mediump float;\n\n";
const char* gFS_Uniforms_Color =
"uniform vec4 color;\n";
-const char* gFS_Header_Uniforms_PointHasBitmap =
- "uniform vec2 textureDimension;\n"
- "uniform float pointSize;\n";
const char* gFS_Uniforms_TextureSampler =
"uniform sampler2D baseSampler;\n";
const char* gFS_Uniforms_ExternalTextureSampler =
@@ -178,10 +167,6 @@ const char* gFS_Main =
"\nvoid main(void) {\n"
" lowp vec4 fragColor;\n";
-const char* gFS_Main_PointBitmapTexCoords =
- " highp vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
- "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
-
const char* gFS_Main_Dither[2] = {
// ES 2.0
"texture2D(ditherSampler, ditherTexCoords).a * " STR(DITHER_KERNEL_SIZE_INV_SQUARE),
@@ -484,9 +469,6 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasBitmap) {
shader.append(gVS_Header_Uniforms_HasBitmap);
}
- if (description.isPoint) {
- shader.append(gVS_Header_Uniforms_IsPoint);
- }
// Varyings
if (description.hasTexture || description.hasExternalTexture) {
shader.append(gVS_Header_Varyings_HasTexture);
@@ -501,9 +483,7 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
- shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ shader.append(gVS_Header_Varyings_HasBitmap);
}
// Begin the shader
@@ -520,12 +500,7 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Main_OutColors);
}
if (description.hasBitmap) {
- shader.append(description.isPoint ?
- gVS_Main_OutPointBitmapTexCoords :
- gVS_Main_OutBitmapTexCoords);
- }
- if (description.isPoint) {
- shader.append(gVS_Main_PointSize);
+ shader.append(gVS_Main_OutBitmapTexCoords);
}
// Output transformed position
shader.append(gVS_Main_Position);
@@ -576,9 +551,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
- shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ shader.append(gVS_Header_Varyings_HasBitmap);
}
// Uniforms
@@ -599,9 +572,6 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.appendFormat(gFS_Uniforms_GradientSampler[description.isSimpleGradient],
gFS_Uniforms_Dither);
}
- if (description.hasBitmap && description.isPoint) {
- shader.append(gFS_Header_Uniforms_PointHasBitmap);
- }
if (description.hasGammaCorrection) {
shader.append(gFS_Uniforms_Gamma);
}
@@ -609,8 +579,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
// Optimization for common cases
if (!description.isAA && !blendFramebuffer && !description.hasColors &&
description.colorOp == ProgramDescription::kColorNone &&
- !description.isPoint && !description.hasDebugHighlight &&
- !description.emulateStencil) {
+ !description.hasDebugHighlight && !description.emulateStencil) {
bool fast = false;
const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -713,9 +682,6 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.appendFormat(gFS_Main_AddDitherToGradient, gFS_Main_Dither[mHasES3]);
}
if (description.hasBitmap) {
- if (description.isPoint) {
- shader.append(gFS_Main_PointBitmapTexCoords);
- }
if (!description.isBitmapNpot) {
shader.append(gFS_Main_FetchBitmap);
} else {
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 523120e..c06762f 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HWUI_VERTEX_H
#define ANDROID_HWUI_VERTEX_H
+#include "Vector.h"
+
namespace android {
namespace uirenderer {
@@ -30,6 +32,15 @@ struct Vertex {
vertex[0].position[0] = x;
vertex[0].position[1] = y;
}
+
+ static inline void set(Vertex* vertex, vec2 val) {
+ set(vertex, val.x, val.y);
+ }
+
+ static inline void copyWithOffset(Vertex* vertex, const Vertex& src, float x, float y) {
+ set(vertex, src.position[0] + x, src.position[1] + y);
+ }
+
}; // struct Vertex
/**
@@ -81,6 +92,12 @@ struct AlphaVertex : Vertex {
vertex[0].alpha = alpha;
}
+ static inline void copyWithOffset(AlphaVertex* vertex, const AlphaVertex& src,
+ float x, float y) {
+ Vertex::set(vertex, src.position[0] + x, src.position[1] + y);
+ vertex[0].alpha = src.alpha;
+ }
+
static inline void setColor(AlphaVertex* vertex, float alpha) {
vertex[0].alpha = alpha;
}