Add support for paths.
Rendering is implementing by rasterizing the paths into A8 textures.
This cna be extremely inefficient if the path changes often.
Change-Id: I609343f304ae38e0d319359403ee73b9b5b3c93a
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d694039..a72045b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -37,7 +37,8 @@
///////////////////////////////////////////////////////////////////////////////
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
-#define DEFAULT_LAYER_CACHE_SIZE 10.0f
+#define DEFAULT_LAYER_CACHE_SIZE 6.0f
+#define DEFAULT_PATH_CACHE_SIZE 6.0f
#define DEFAULT_PATCH_CACHE_SIZE 100
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
@@ -105,6 +106,7 @@
mTextureCache(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)),
mGradientCache(MB(DEFAULT_GRADIENT_CACHE_SIZE)),
+ mPathCache(MB(DEFAULT_PATH_CACHE_SIZE)),
mPatchCache(DEFAULT_PATCH_CACHE_SIZE) {
LOGD("Create OpenGLRenderer");
@@ -125,11 +127,18 @@
if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) {
LOGD(" Setting gradient cache size to %sMB", property);
- mLayerCache.setMaxSize(MB(atof(property)));
+ mGradientCache.setMaxSize(MB(atof(property)));
} else {
LOGD(" Using default gradient cache size of %.2fMB", DEFAULT_GRADIENT_CACHE_SIZE);
}
+ if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) {
+ LOGD(" Setting path cache size to %sMB", property);
+ mPathCache.setMaxSize(MB(atof(property)));
+ } else {
+ LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE);
+ }
+
mCurrentProgram = NULL;
mShader = NULL;
mColorFilter = NULL;
@@ -597,6 +606,73 @@
glDisableVertexAttribArray(texCoordsSlot);
}
+void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
+ GLuint textureUnit = 0;
+ glActiveTexture(gTextureUnits[textureUnit]);
+
+ PathTexture* texture = mPathCache.get(path, paint);
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ uint32_t color = paint->getColor();
+ const GLfloat a = alpha / 255.0f;
+ const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f;
+ const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f;
+ const GLfloat b = a * ((color ) & 0xFF) / 255.0f;
+
+ // Describe the required shaders
+ ProgramDescription description;
+ description.hasTexture = true;
+ description.hasAlpha8Texture = true;
+ if (mShader) {
+ mShader->describe(description, mExtensions);
+ }
+ if (mColorFilter) {
+ mColorFilter->describe(description, mExtensions);
+ }
+
+ // Build and use the appropriate shader
+ useProgram(mProgramCache.get(description));
+
+ // Setup the blending mode
+ chooseBlending(true, mode);
+ bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
+ glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);
+
+ int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
+ glEnableVertexAttribArray(texCoordsSlot);
+
+ // Setup attributes
+ glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mMeshVertices[0].position[0]);
+ glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mMeshVertices[0].texture[0]);
+
+ // Setup uniforms
+ mModelView.loadTranslate(texture->left - texture->offset,
+ texture->top - texture->offset, 0.0f);
+ mModelView.scale(texture->width, texture->height, 1.0f);
+ mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+
+ glUniform4f(mCurrentProgram->color, r, g, b, a);
+
+ textureUnit++;
+ // Setup attributes and uniforms required by the shaders
+ if (mShader) {
+ mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
+ }
+ if (mColorFilter) {
+ mColorFilter->setupProgram(mCurrentProgram);
+ }
+
+ // Draw the mesh
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ glDisableVertexAttribArray(texCoordsSlot);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Shaders
///////////////////////////////////////////////////////////////////////////////