diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 152 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 15 | ||||
| -rw-r--r-- | libs/hwui/Program.cpp | 9 | ||||
| -rw-r--r-- | libs/hwui/Program.h | 2 |
4 files changed, 73 insertions, 105 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index dd0cca22738c..e1d7f6ba19ed 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -979,8 +979,8 @@ void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float ri } } -void OpenGLRenderer::setupDrawModelViewIdentity() { - mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform); +void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) { + mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform, offset); } void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom, @@ -1389,13 +1389,46 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int } } -void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline, - float strokeWidth) { +void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { + if (mSnapshot->isIgnored()) return; + + const bool isAA = paint->isAntiAlias(); + float strokeWidth = paint->getStrokeWidth() * 0.5f; + // A stroke width of 0 has a special meaning in Skia: + // it draws a line 1 px wide regardless of current transform + bool isHairLine = paint->getStrokeWidth() == 0.0f; + int alpha; + SkXfermode::Mode mode; + int generatedVerticesCount = 0; int verticesCount = count; if (count > 4) { // Polyline: account for extra vertices needed for continous tri-strip verticesCount += (count -4); } + + getAlphaAndMode(paint, &alpha, &mode); + setupDraw(); + if (isAA) { + setupDrawAALine(); + } + setupDrawColor(paint->getColor(), alpha); + setupDrawColorFilter(); + setupDrawShader(); + if (isAA) { + setupDrawBlending(true, mode); + } else { + setupDrawBlending(mode); + } + setupDrawProgram(); + setupDrawModelViewIdentity(true); + setupDrawColorUniforms(); + setupDrawColorFilterUniforms(); + setupDrawShaderIdentityUniforms(); + + if (isHairLine) { + // Set a real stroke width to be used in quad construction + strokeWidth = .5; + } if (isAA) { // Expand boundary to enable AA calculations on the quad border strokeWidth += .5f; @@ -1407,25 +1440,22 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool if (!isAA) { setupDrawVertices(vertices); } else { - AlphaVertex* alphaCoords = aaVertices + gVertexAlphaOffset; + void* alphaCoords = ((GLbyte*) aaVertices) + gVertexAlphaOffset; // innerProportion is the ratio of the inner (non-AA) port of the line to the total // AA stroke width (the base stroke width expanded by a half pixel on either side). // This value is used in the fragment shader to determine how to fill fragments. float innerProportion = fmax(strokeWidth - 1.0f, 0) / (strokeWidth + .5f); - setupDrawAALine((void*) aaVertices, (void*) alphaCoords, innerProportion); + setupDrawAALine((void*) aaVertices, alphaCoords, innerProportion); } - int generatedVerticesCount = 0; AlphaVertex *prevAAVertex = NULL; Vertex *prevVertex = NULL; float inverseScaleX = 1.0f; float inverseScaleY = 1.0f; - if (isHairline) { + if (isHairLine) { // The quad that we use for AA hairlines needs to account for scaling because the line // should always be one pixel wide regardless of scale. - inverseScaleX = 1.0f; - inverseScaleY = 1.0f; if (!mSnapshot->transform->isPureTranslate()) { Matrix4 *mat = mSnapshot->transform; float m00 = mat->data[Matrix4::kScaleX]; @@ -1446,22 +1476,19 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool vec2 a(points[i], points[i + 1]); vec2 b(points[i + 2], points[i + 3]); - // Bias to snap to the same pixels as Skia - a += 0.375; - b += 0.375; - // Find the normal to the line vec2 n = (b - a).copyNormalized() * strokeWidth; - if (isHairline) { - float wideningFactor; - if (fabs(n.x) >= fabs(n.y)) { - wideningFactor = fabs(1.0f / n.x); - } else { - wideningFactor = fabs(1.0f / n.y); + if (isHairLine) { + n *= inverseScaleX; + if (isAA) { + float wideningFactor; + if (fabs(n.x) >= fabs(n.y)) { + wideningFactor = fabs(1.0f / n.x); + } else { + wideningFactor = fabs(1.0f / n.y); + } + n *= wideningFactor; } - n.x *= inverseScaleX; - n.y *= inverseScaleY; - n *= wideningFactor; } float x = n.x; n.x = -n.y; @@ -1525,69 +1552,6 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool } } -void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { - if (mSnapshot->isIgnored()) return; - - const bool isAA = paint->isAntiAlias(); - const float strokeWidth = paint->getStrokeWidth() * 0.5f; - // A stroke width of 0 has a special meaning in Skia: - // it draws a line 1 px wide regardless of current transform - bool isHairLine = paint->getStrokeWidth() == 0.0f; - - int alpha; - SkXfermode::Mode mode; - getAlphaAndMode(paint, &alpha, &mode); - int generatedVerticesCount = 0; - - setupDraw(); - if (isAA) { - setupDrawAALine(); - } - setupDrawColor(paint->getColor(), alpha); - setupDrawColorFilter(); - setupDrawShader(); - if (isAA) { - setupDrawBlending(true, mode); - } else { - setupDrawBlending(mode); - } - setupDrawProgram(); - setupDrawModelViewIdentity(); - setupDrawColorUniforms(); - setupDrawColorFilterUniforms(); - setupDrawShaderIdentityUniforms(); - - if (!isHairLine) { - drawLinesAsQuads(points, count, isAA, isHairLine, strokeWidth); - } else { - if (isAA) { - drawLinesAsQuads(points, count, isAA, isHairLine, .5f); - } else { - int verticesCount = count >> 1; - Vertex lines[verticesCount]; - Vertex* vertices = &lines[0]; - setupDrawVertices(vertices); - for (int i = 0; i < count; i += 4) { - - const float left = fmin(points[i], points[i + 2]); - const float right = fmax(points[i], points[i + 2]); - const float top = fmin(points[i + 1], points[i + 3]); - const float bottom = fmax(points[i + 1], points[i + 3]); - - Vertex::set(vertices++, points[i], points[i + 1]); - Vertex::set(vertices++, points[i + 2], points[i + 3]); - generatedVerticesCount += 2; - dirtyLayer(left, top, - right == left ? left + 1 : right, bottom == top ? top + 1 : bottom, - *mSnapshot->transform); - } - - glLineWidth(1.0f); - glDrawArrays(GL_LINES, 0, generatedVerticesCount); - } - } -} - void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { if (mSnapshot->isIgnored()) return; @@ -1596,8 +1560,13 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { // 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); @@ -1609,13 +1578,13 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { TextureVertex* vertex = &pointsData[0]; setupDraw(); - setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth()); + setupDrawPoint(strokeWidth); setupDrawColor(paint->getColor(), alpha); setupDrawColorFilter(); setupDrawShader(); setupDrawBlending(mode); setupDrawProgram(); - setupDrawModelViewIdentity(); + setupDrawModelViewIdentity(true); setupDrawColorUniforms(); setupDrawColorFilterUniforms(); setupDrawPointUniforms(); @@ -1625,6 +1594,11 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { 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; + dirtyLayer(left, top, right, bottom, *mSnapshot->transform); } glDrawArrays(GL_POINTS, 0, generatedVerticesCount); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 0276095c98e7..918e1fb4178d 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -283,19 +283,6 @@ private: void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint); /** - * Draws a line as a quad. Called by drawLines() for all cases except hairline without AA. - * - * @param points The vertices of the lines. Every four entries specifies the x/y points - * of a single line segment. - * @param count The number of entries in the points array. - * @param isAA Whether the line is anti-aliased - * @param isHairline Whether the line has strokeWidth==0, which results in the line being - * one pixel wide on the display regardless of scale. - */ - void drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline, - float strokeWidth); - - /** * Draws a textured rectangle with the specified texture. The specified coordinates * are transformed by the current snapshot's transform matrix. * @@ -453,7 +440,7 @@ private: bool swapSrcDst = false); void setupDrawProgram(); void setupDrawDirtyRegionsDisabled(); - void setupDrawModelViewIdentity(); + void setupDrawModelViewIdentity(bool offset = false); void setupDrawModelView(float left, float top, float right, float bottom, bool ignoreTransform = false, bool ignoreModelView = false); void setupDrawModelViewTranslate(float left, float top, float right, float bottom, diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index 2187f24e2c83..972dd87a5d71 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -124,8 +124,15 @@ GLuint Program::buildShader(const char* source, GLenum type) { } void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix, - const mat4& transformMatrix) { + const mat4& transformMatrix, bool offset) { mat4 t(projectionMatrix); + if (offset) { + // offset screenspace xy by an amount that compensates for typical precision issues + // in GPU hardware that tends to paint hor/vert lines in pixels shifted up and to the left. + // This offset value is based on an assumption that some hardware may use as little + // as 12.4 precision, so we offset by slightly more than 1/16. + t.translate(.375, .375, 0); + } t.multiply(transformMatrix); t.multiply(modelViewMatrix); diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index afc6f3d4a368..764cb0583b24 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -81,7 +81,7 @@ public: * transform matrices. */ void set(const mat4& projectionMatrix, const mat4& modelViewMatrix, - const mat4& transformMatrix); + const mat4& transformMatrix, bool offset = false); /** * Sets the color associated with this shader. |