Merge "Implement support for drawBitmapMesh's colors array"

This commit is contained in:
Romain Guy
2013-02-14 18:49:34 +00:00
committed by Android (Google) Code Review
9 changed files with 136 additions and 27 deletions

View File

@ -901,9 +901,9 @@ class GLES20Canvas extends HardwareCanvas {
final int count = (meshWidth + 1) * (meshHeight + 1); final int count = (meshWidth + 1) * (meshHeight + 1);
checkRange(verts.length, vertOffset, count * 2); checkRange(verts.length, vertOffset, count * 2);
// TODO: Colors are ignored for now if (colors != null) {
colors = null; checkRange(colors.length, colorOffset, count);
colorOffset = 0; }
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
try { try {

View File

@ -365,11 +365,12 @@ void Caches::bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei str
} }
} }
void Caches::bindTexCoordsVertexPointer(bool force, GLvoid* vertices) { void Caches::bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride) {
if (force || vertices != mCurrentTexCoordsPointer) { if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
GLuint slot = currentProgram->texCoords; GLuint slot = currentProgram->texCoords;
glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertices); glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
mCurrentTexCoordsPointer = vertices; mCurrentTexCoordsPointer = vertices;
mCurrentTexCoordsStride = stride;
} }
} }
@ -390,7 +391,7 @@ void Caches::enableTexCoordsVertexArray() {
} }
} }
void Caches::disbaleTexCoordsVertexArray() { void Caches::disableTexCoordsVertexArray() {
if (mTexCoordsArrayEnabled) { if (mTexCoordsArrayEnabled) {
glDisableVertexAttribArray(Program::kBindingTexCoords); glDisableVertexAttribArray(Program::kBindingTexCoords);
mTexCoordsArrayEnabled = false; mTexCoordsArrayEnabled = false;

View File

@ -183,7 +183,7 @@ public:
* Binds an attrib to the specified float vertex pointer. * Binds an attrib to the specified float vertex pointer.
* Assumes a stride of gMeshStride and a size of 2. * Assumes a stride of gMeshStride and a size of 2.
*/ */
void bindTexCoordsVertexPointer(bool force, GLvoid* vertices); void bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride = gMeshStride);
/** /**
* Resets the vertex pointers. * Resets the vertex pointers.
@ -192,7 +192,7 @@ public:
void resetTexCoordsVertexPointer(); void resetTexCoordsVertexPointer();
void enableTexCoordsVertexArray(); void enableTexCoordsVertexArray();
void disbaleTexCoordsVertexArray(); void disableTexCoordsVertexArray();
/** /**
* Activate the specified texture unit. The texture unit must * Activate the specified texture unit. The texture unit must
@ -299,6 +299,7 @@ private:
void* mCurrentPositionPointer; void* mCurrentPositionPointer;
GLsizei mCurrentPositionStride; GLsizei mCurrentPositionStride;
void* mCurrentTexCoordsPointer; void* mCurrentTexCoordsPointer;
GLsizei mCurrentTexCoordsStride;
bool mTexCoordsArrayEnabled; bool mTexCoordsArrayEnabled;

View File

@ -317,7 +317,7 @@ void OpenGLRenderer::interrupt() {
mCaches.unbindMeshBuffer(); mCaches.unbindMeshBuffer();
mCaches.unbindIndicesBuffer(); mCaches.unbindIndicesBuffer();
mCaches.resetVertexPointers(); mCaches.resetVertexPointers();
mCaches.disbaleTexCoordsVertexArray(); mCaches.disableTexCoordsVertexArray();
debugOverdraw(false, false); debugOverdraw(false, false);
} }
@ -1469,12 +1469,18 @@ void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
mDescription.hasAlpha8Texture = isAlpha8; mDescription.hasAlpha8Texture = isAlpha8;
} }
void OpenGLRenderer::setupDrawWithTextureAndColor(bool isAlpha8) {
mDescription.hasTexture = true;
mDescription.hasColors = true;
mDescription.hasAlpha8Texture = isAlpha8;
}
void OpenGLRenderer::setupDrawWithExternalTexture() { void OpenGLRenderer::setupDrawWithExternalTexture() {
mDescription.hasExternalTexture = true; mDescription.hasExternalTexture = true;
} }
void OpenGLRenderer::setupDrawNoTexture() { void OpenGLRenderer::setupDrawNoTexture() {
mCaches.disbaleTexCoordsVertexArray(); mCaches.disableTexCoordsVertexArray();
} }
void OpenGLRenderer::setupDrawAA() { void OpenGLRenderer::setupDrawAA() {
@ -1682,6 +1688,23 @@ void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint v
mCaches.unbindIndicesBuffer(); mCaches.unbindIndicesBuffer();
} }
void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors) {
bool force = mCaches.unbindMeshBuffer();
GLsizei stride = sizeof(ColorTextureVertex);
mCaches.bindPositionVertexPointer(force, vertices, stride);
if (mCaches.currentProgram->texCoords >= 0) {
mCaches.bindTexCoordsVertexPointer(force, texCoords, stride);
}
int slot = mCaches.currentProgram->getAttrib("colors");
if (slot >= 0) {
glEnableVertexAttribArray(slot);
glVertexAttribPointer(slot, 4, GL_FLOAT, GL_FALSE, stride, colors);
}
mCaches.unbindIndicesBuffer();
}
void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords) { void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords) {
bool force = mCaches.unbindMeshBuffer(); bool force = mCaches.unbindMeshBuffer();
mCaches.bindPositionVertexPointer(force, vertices); mCaches.bindPositionVertexPointer(force, vertices);
@ -1833,9 +1856,16 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
const uint32_t count = meshWidth * meshHeight * 6; const uint32_t count = meshWidth * meshHeight * 6;
// TODO: Support the colors array ColorTextureVertex mesh[count];
TextureVertex mesh[count]; ColorTextureVertex* vertex = mesh;
TextureVertex* vertex = mesh;
bool cleanupColors = false;
if (!colors) {
uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1);
colors = new int[colorsCount];
memset(colors, 0xff, colorsCount * sizeof(int));
cleanupColors = true;
}
for (int32_t y = 0; y < meshHeight; y++) { for (int32_t y = 0; y < meshHeight; y++) {
for (int32_t x = 0; x < meshWidth; x++) { for (int32_t x = 0; x < meshWidth; x++) {
@ -1855,13 +1885,13 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
int dx = i + (meshWidth + 1) * 2 + 2; int dx = i + (meshWidth + 1) * 2 + 2;
int dy = dx + 1; int dy = dx + 1;
TextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2); ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
TextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1); ColorTextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2, colors[ax / 2]);
TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1); ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
TextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2); ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1); ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2); ColorTextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1, colors[cx / 2]);
left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx]))); left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx])));
top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy]))); top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy])));
@ -1871,12 +1901,16 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
} }
if (quickReject(left, top, right, bottom)) { if (quickReject(left, top, right, bottom)) {
if (cleanupColors) delete[] colors;
return DrawGlInfo::kStatusDone; return DrawGlInfo::kStatusDone;
} }
mCaches.activeTexture(0); mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap); Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return DrawGlInfo::kStatusDone; if (!texture) {
if (cleanupColors) delete[] colors;
return DrawGlInfo::kStatusDone;
}
const AutoTexture autoCleanup(texture); const AutoTexture autoCleanup(texture);
texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setWrap(GL_CLAMP_TO_EDGE, true);
@ -1886,13 +1920,35 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
SkXfermode::Mode mode; SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode); getAlphaAndMode(paint, &alpha, &mode);
float a = alpha / 255.0f;
if (hasLayer()) { if (hasLayer()) {
dirtyLayer(left, top, right, bottom, *mSnapshot->transform); dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
} }
drawTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f, setupDraw();
mode, texture->blend, &mesh[0].position[0], &mesh[0].texture[0], setupDrawWithTextureAndColor();
GL_TRIANGLES, count, false, false, 0, false, false); setupDrawColor(a, a, a, a);
setupDrawColorFilter();
setupDrawBlending(true, mode, false);
setupDrawProgram();
setupDrawDirtyRegionsDisabled();
setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, false);
setupDrawTexture(texture->id);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0], &mesh[0].color[0]);
glDrawArrays(GL_TRIANGLES, 0, count);
finishDrawTexture();
int slot = mCaches.currentProgram->getAttrib("colors");
if (slot >= 0) {
glDisableVertexAttribArray(slot);
}
if (cleanupColors) delete[] colors;
return DrawGlInfo::kStatusDrew; return DrawGlInfo::kStatusDrew;
} }

View File

@ -777,6 +777,7 @@ private:
* Various methods to setup OpenGL rendering. * Various methods to setup OpenGL rendering.
*/ */
void setupDrawWithTexture(bool isAlpha8 = false); void setupDrawWithTexture(bool isAlpha8 = false);
void setupDrawWithTextureAndColor(bool isAlpha8 = false);
void setupDrawWithExternalTexture(); void setupDrawWithExternalTexture();
void setupDrawNoTexture(); void setupDrawNoTexture();
void setupDrawAA(); void setupDrawAA();
@ -811,6 +812,7 @@ private:
void setupDrawTextureTransformUniforms(mat4& transform); void setupDrawTextureTransformUniforms(mat4& transform);
void setupDrawTextGammaUniforms(); void setupDrawTextGammaUniforms();
void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors);
void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords); void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords);
void setupDrawVertices(GLvoid* vertices); void setupDrawVertices(GLvoid* vertices);
void finishDrawTexture(); void finishDrawTexture();

View File

@ -81,6 +81,8 @@ namespace uirenderer {
#define PROGRAM_IS_SIMPLE_GRADIENT 41 #define PROGRAM_IS_SIMPLE_GRADIENT 41
#define PROGRAM_HAS_COLORS 42
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Types // Types
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -120,6 +122,9 @@ struct ProgramDescription {
bool hasExternalTexture; bool hasExternalTexture;
bool hasTextureTransform; bool hasTextureTransform;
// Color attribute
bool hasColors;
// Modulate, this should only be set when setColor() return true // Modulate, this should only be set when setColor() return true
bool modulate; bool modulate;
@ -164,6 +169,8 @@ struct ProgramDescription {
hasExternalTexture = false; hasExternalTexture = false;
hasTextureTransform = false; hasTextureTransform = false;
hasColors = false;
isAA = false; isAA = false;
modulate = false; modulate = false;
@ -259,6 +266,7 @@ struct ProgramDescription {
if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION; if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT; if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS;
return key; return key;
} }

View File

@ -40,6 +40,8 @@ const char* gVS_Header_Attributes =
"attribute vec4 position;\n"; "attribute vec4 position;\n";
const char* gVS_Header_Attributes_TexCoords = const char* gVS_Header_Attributes_TexCoords =
"attribute vec2 texCoords;\n"; "attribute vec2 texCoords;\n";
const char* gVS_Header_Attributes_Colors =
"attribute vec4 colors;\n";
const char* gVS_Header_Attributes_AAVertexShapeParameters = const char* gVS_Header_Attributes_AAVertexShapeParameters =
"attribute float vtxAlpha;\n"; "attribute float vtxAlpha;\n";
const char* gVS_Header_Uniforms_TextureTransform = const char* gVS_Header_Uniforms_TextureTransform =
@ -65,6 +67,8 @@ const char* gVS_Header_Uniforms_HasBitmap =
"uniform mediump vec2 textureDimension;\n"; "uniform mediump vec2 textureDimension;\n";
const char* gVS_Header_Varyings_HasTexture = const char* gVS_Header_Varyings_HasTexture =
"varying vec2 outTexCoords;\n"; "varying vec2 outTexCoords;\n";
const char* gVS_Header_Varyings_HasColors =
"varying vec4 outColors;\n";
const char* gVS_Header_Varyings_IsAAVertexShape = const char* gVS_Header_Varyings_IsAAVertexShape =
"varying float alpha;\n"; "varying float alpha;\n";
const char* gVS_Header_Varyings_HasBitmap = const char* gVS_Header_Varyings_HasBitmap =
@ -94,6 +98,8 @@ const char* gVS_Main =
"\nvoid main(void) {\n"; "\nvoid main(void) {\n";
const char* gVS_Main_OutTexCoords = const char* gVS_Main_OutTexCoords =
" outTexCoords = texCoords;\n"; " outTexCoords = texCoords;\n";
const char* gVS_Main_OutColors =
" outColors = colors;\n";
const char* gVS_Main_OutTransformedTexCoords = const char* gVS_Main_OutTransformedTexCoords =
" outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n"; " outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n";
const char* gVS_Main_OutGradient[6] = { const char* gVS_Main_OutGradient[6] = {
@ -325,6 +331,8 @@ const char* gFS_Main_BitmapShader_Modulate[6] = {
}; };
const char* gFS_Main_FragColor = const char* gFS_Main_FragColor =
" gl_FragColor = fragColor;\n"; " gl_FragColor = fragColor;\n";
const char* gFS_Main_FragColor_HasColors =
" gl_FragColor *= outColors;\n";
const char* gFS_Main_FragColor_Blend = const char* gFS_Main_FragColor_Blend =
" gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n"; " gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n";
const char* gFS_Main_FragColor_Blend_Swap = const char* gFS_Main_FragColor_Blend_Swap =
@ -459,6 +467,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.isAA) { if (description.isAA) {
shader.append(gVS_Header_Attributes_AAVertexShapeParameters); shader.append(gVS_Header_Attributes_AAVertexShapeParameters);
} }
if (description.hasColors) {
shader.append(gVS_Header_Attributes_Colors);
}
// Uniforms // Uniforms
shader.append(gVS_Header_Uniforms); shader.append(gVS_Header_Uniforms);
if (description.hasTextureTransform) { if (description.hasTextureTransform) {
@ -480,6 +491,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.isAA) { if (description.isAA) {
shader.append(gVS_Header_Varyings_IsAAVertexShape); shader.append(gVS_Header_Varyings_IsAAVertexShape);
} }
if (description.hasColors) {
shader.append(gVS_Header_Varyings_HasColors);
}
if (description.hasGradient) { if (description.hasGradient) {
shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]); shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
} }
@ -499,6 +513,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.isAA) { if (description.isAA) {
shader.append(gVS_Main_AAVertexShape); shader.append(gVS_Main_AAVertexShape);
} }
if (description.hasColors) {
shader.append(gVS_Main_OutColors);
}
if (description.hasBitmap) { if (description.hasBitmap) {
shader.append(description.isPoint ? shader.append(description.isPoint ?
gVS_Main_OutPointBitmapTexCoords : gVS_Main_OutPointBitmapTexCoords :
@ -549,6 +566,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.isAA) { if (description.isAA) {
shader.append(gVS_Header_Varyings_IsAAVertexShape); shader.append(gVS_Header_Varyings_IsAAVertexShape);
} }
if (description.hasColors) {
shader.append(gVS_Header_Varyings_HasColors);
}
if (description.hasGradient) { if (description.hasGradient) {
shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]); shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
} }
@ -583,7 +603,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
} }
// Optimization for common cases // Optimization for common cases
if (!description.isAA && !blendFramebuffer && if (!description.isAA && !blendFramebuffer && !description.hasColors &&
description.colorOp == ProgramDescription::kColorNone && !description.isPoint) { description.colorOp == ProgramDescription::kColorNone && !description.isPoint) {
bool fast = false; bool fast = false;
@ -729,6 +749,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(!description.swapSrcDst ? shader.append(!description.swapSrcDst ?
gFS_Main_FragColor_Blend : gFS_Main_FragColor_Blend_Swap); gFS_Main_FragColor_Blend : gFS_Main_FragColor_Blend_Swap);
} }
if (description.hasColors) {
shader.append(gFS_Main_FragColor_HasColors);
}
} }
// End the shader // End the shader
shader.append(gFS_Footer); shader.append(gFS_Footer);

View File

@ -33,7 +33,7 @@ struct Vertex {
}; // struct Vertex }; // struct Vertex
/** /**
* Simple structure to describe a vertex with a position and a texture. * Simple structure to describe a vertex with a position and texture UV.
*/ */
struct TextureVertex { struct TextureVertex {
float position[2]; float position[2];
@ -52,6 +52,24 @@ struct TextureVertex {
} }
}; // struct TextureVertex }; // struct TextureVertex
/**
* Simple structure to describe a vertex with a position, texture UV and ARGB color.
*/
struct ColorTextureVertex : TextureVertex {
float color[4];
static inline void set(ColorTextureVertex* vertex, float x, float y,
float u, float v, int color) {
TextureVertex::set(vertex, x, y, u, v);
const float a = ((color >> 24) & 0xff) / 255.0f;
vertex[0].color[0] = a * ((color >> 16) & 0xff) / 255.0f;
vertex[0].color[1] = a * ((color >> 8) & 0xff) / 255.0f;
vertex[0].color[2] = a * ((color ) & 0xff) / 255.0f;
vertex[0].color[3] = a;
}
}; // struct ColorTextureVertex
/** /**
* Simple structure to describe a vertex with a position and an alpha value. * Simple structure to describe a vertex with a position and an alpha value.
*/ */

View File

@ -54,7 +54,7 @@ public class BitmapMeshActivity extends Activity {
0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2, 0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2,
0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4, 0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4,
}; };
mColors = new int[] { mColors = new int[] {
0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff0000, 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff0000,
0xff0000ff, 0xffff0000, 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00, 0xff00ff00,