diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 52 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 42 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.h | 13 |
6 files changed, 120 insertions, 6 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index f2f983f..bf1182c 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -53,6 +53,7 @@ const char* DisplayList::OP_NAMES[] = { "DrawArc", "DrawPath", "DrawLines", + "DrawPoints", "DrawText", "ResetShader", "SetupShader", @@ -441,6 +442,13 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) renderer.drawLines(points, count, getPaint()); } break; + case DrawPoints: { + int count = 0; + float* points = getFloats(count); + DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); + renderer.drawPoints(points, count, getPaint()); + } + break; case DrawText: { getText(&text); int count = getInt(); @@ -787,6 +795,12 @@ void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { addPaint(paint); } +void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { + addOp(DisplayList::DrawPoints); + addFloats(points, count); + addPaint(paint); +} + void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { addOp(DisplayList::DrawText); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 8773cb5..da57e4a 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -89,6 +89,7 @@ public: DrawArc, DrawPath, DrawLines, + DrawPoints, DrawText, ResetShader, SetupShader, @@ -264,6 +265,7 @@ public: float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); void drawPath(SkPath* path, SkPaint* paint); void drawLines(float* points, int count, SkPaint* paint); + void drawPoints(float* points, int count, SkPaint* paint); void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); void resetShader(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index a711289..6c454a4 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -879,6 +879,11 @@ void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { mDescription.hasAlpha8Texture = isAlpha8; } +void OpenGLRenderer::setupDrawPoint(float pointSize) { + mDescription.isPoint = true; + mDescription.pointSize = pointSize; +} + void OpenGLRenderer::setupDrawColor(int color) { setupDrawColor(color, (color >> 24) & 0xFF); } @@ -987,6 +992,11 @@ 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 || (mShader && mSetShaderColor)) { mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA); @@ -1446,6 +1456,48 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { } } +void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { + if (mSnapshot->isIgnored()) return; + + // 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 meaningin Skia: + // it draws an unscaled 1px point + const bool isHairLine = paint->getStrokeWidth() == 0.0f; + + int alpha; + SkXfermode::Mode mode; + getAlphaAndMode(paint, &alpha, &mode); + + int verticesCount = count >> 1; + int generatedVerticesCount = 0; + + TextureVertex pointsData[verticesCount]; + TextureVertex* vertex = &pointsData[0]; + + setupDraw(); + setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth()); + setupDrawColor(paint->getColor(), alpha); + setupDrawColorFilter(); + setupDrawShader(); + setupDrawBlending(mode); + setupDrawProgram(); + setupDrawModelViewIdentity(); + 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++; + } + + glDrawArrays(GL_POINTS, 0, generatedVerticesCount); +} + void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region if (mSnapshot->isIgnored()) return; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 402563c..4b93b80 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -119,6 +119,7 @@ public: float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); virtual void drawPath(SkPath* path, SkPaint* paint); virtual void drawLines(float* points, int count, SkPaint* paint); + virtual void drawPoints(float* points, int count, SkPaint* paint); virtual void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint); @@ -424,6 +425,7 @@ private: * Various methods to setup OpenGL rendering. */ void setupDrawWithTexture(bool isAlpha8 = false); + void setupDrawPoint(float pointSize); void setupDrawColor(int color); void setupDrawColor(int color, int alpha); void setupDrawColor(float r, float g, float b, float a); @@ -442,6 +444,7 @@ 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/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 0b6c7b5..2562306 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -41,6 +41,8 @@ const char* gVS_Header_Attributes_TexCoords = "attribute vec2 texCoords;\n"; const char* gVS_Header_Uniforms = "uniform mat4 transform;\n"; +const char* gVS_Header_Uniforms_IsPoint = + "uniform float pointSize;\n"; const char* gVS_Header_Uniforms_HasGradient[3] = { // Linear "uniform mat4 screenSpace;\n", @@ -56,6 +58,8 @@ const char* gVS_Header_Varyings_HasTexture = "varying vec2 outTexCoords;\n"; const char* gVS_Header_Varyings_HasBitmap = "varying vec2 outBitmapTexCoords;\n"; +const char* gVS_Header_Varyings_PointHasBitmap = + "varying vec2 outPointBitmapTexCoords;\n"; const char* gVS_Header_Varyings_HasGradient[3] = { // Linear "varying vec2 linear;\n", @@ -78,8 +82,12 @@ const char* gVS_Main_OutGradient[3] = { }; 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 = transform * position;\n"; +const char* gVS_Main_PointSize = + " gl_PointSize = pointSize;\n"; const char* gVS_Footer = "}\n\n"; @@ -93,6 +101,9 @@ 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 sampler;\n"; const char* gFS_Uniforms_GradientSampler[3] = { @@ -121,6 +132,10 @@ const char* gFS_Main = "\nvoid main(void) {\n" " lowp vec4 fragColor;\n"; +const char* gFS_Main_PointBitmapTexCoords = + " vec2 outBitmapTexCoords = outPointBitmapTexCoords + " + "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n"; + // Fast cases const char* gFS_Fast_SingleColor = "\nvoid main(void) {\n" @@ -347,6 +362,9 @@ 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) { shader.append(gVS_Header_Varyings_HasTexture); @@ -355,7 +373,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]); } if (description.hasBitmap) { - shader.append(gVS_Header_Varyings_HasBitmap); + shader.append(description.isPoint ? + gVS_Header_Varyings_PointHasBitmap : + gVS_Header_Varyings_HasBitmap); } // Begin the shader @@ -367,7 +387,12 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description shader.append(gVS_Main_OutGradient[description.gradientType]); } if (description.hasBitmap) { - shader.append(gVS_Main_OutBitmapTexCoords); + shader.append(description.isPoint ? + gVS_Main_OutPointBitmapTexCoords : + gVS_Main_OutBitmapTexCoords); + } + if (description.isPoint) { + shader.append(gVS_Main_PointSize); } // Output transformed position shader.append(gVS_Main_Position); @@ -399,7 +424,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]); } if (description.hasBitmap) { - shader.append(gVS_Header_Varyings_HasBitmap); + shader.append(description.isPoint ? + gVS_Header_Varyings_PointHasBitmap : + gVS_Header_Varyings_HasBitmap); } // Uniforms @@ -417,9 +444,13 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (description.hasGradient) { shader.append(gFS_Uniforms_GradientSampler[description.gradientType]); } + if (description.hasBitmap && description.isPoint) { + shader.append(gFS_Header_Uniforms_PointHasBitmap); + } // Optimization for common cases - if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone) { + if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone && + !description.isPoint) { bool fast = false; const bool noShader = !description.hasGradient && !description.hasBitmap; @@ -507,6 +538,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti shader.append(gFS_Main_FetchGradient[description.gradientType]); } 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/ProgramCache.h b/libs/hwui/ProgramCache.h index ead5b92..737d91b 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -71,7 +71,9 @@ namespace uirenderer { #define PROGRAM_BITMAP_WRAPT_SHIFT 11 #define PROGRAM_GRADIENT_TYPE_SHIFT 33 -#define PROGRAM_MODULATE 35 +#define PROGRAM_MODULATE_SHIFT 35 + +#define PROGRAM_IS_POINT_SHIFT 36 /////////////////////////////////////////////////////////////////////////////// // Types @@ -135,6 +137,9 @@ struct ProgramDescription { SkXfermode::Mode framebufferMode; bool swapSrcDst; + bool isPoint; + float pointSize; + /** * Resets this description. All fields are reset back to the default * values they hold after building a new instance. @@ -162,6 +167,9 @@ struct ProgramDescription { framebufferMode = SkXfermode::kClear_Mode; swapSrcDst = false; + + isPoint = false; + pointSize = 0.0f; } /** @@ -223,7 +231,8 @@ 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; + if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT; + if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT; return key; } |