diff options
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 39 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 8 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 24 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.h | 4 | ||||
-rw-r--r-- | libs/hwui/Texture.h | 8 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java | 14 |
6 files changed, 67 insertions, 30 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7495a06..9c37983 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -644,7 +644,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -661,7 +661,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -677,9 +677,10 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); const float width = texture->width; const float height = texture->height; @@ -711,9 +712,10 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); int alpha; SkXfermode::Mode mode; @@ -1046,7 +1048,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t // Build and use the appropriate shader useProgram(mCaches.programCache.get(description)); - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit); + bindTexture(texture, textureUnit); glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit); int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); @@ -1220,11 +1222,13 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint) { + Texture* texture, SkPaint* paint) { int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount); @@ -1263,7 +1267,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b } // Texture - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0); + bindTexture(texture); glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0); // Always premultiplied @@ -1380,11 +1384,26 @@ SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) { return mode->fMode; } -void OpenGLRenderer::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void OpenGLRenderer::bindTexture(GLuint texture, GLuint textureUnit) { glActiveTexture(gTextureUnits[textureUnit]); glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); +} + +void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit) { + glActiveTexture(gTextureUnits[textureUnit]); + bool bound = false; + if (wrapS != texture->wrapS) { + glBindTexture(GL_TEXTURE_2D, texture->id); + bound = true; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + if (!bound) glBindTexture(GL_TEXTURE_2D, texture->id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index b7615fe..07188d4 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -231,7 +231,7 @@ private: * @param paint The paint containing the alpha, blending mode, etc. */ void drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint); + Texture* texture, SkPaint* paint); /** * Draws a textured mesh with the specified texture. If the indices are omitted, @@ -360,9 +360,11 @@ private: inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode); /** - * Binds the specified texture with the specified wrap modes. + * Binds the specified texture to the specified texture unit. */ - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit = 0); + inline void bindTexture(GLuint texture, GLuint textureUnit = 0); + inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit = 0); /** * Enable or disable blending as necessary. This function sets the appropriate diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index fa85d20..e7e1187 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -63,11 +63,17 @@ void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Sna GLuint* textureUnit) { } -void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { glActiveTexture(gTextureUnitsMap[textureUnit]); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + glBindTexture(GL_TEXTURE_2D, texture->id); + if (wrapS != texture->wrapS) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { @@ -86,7 +92,7 @@ SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::Ti } void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { - const Texture* texture = mTextureCache->get(mBitmap); + Texture* texture = mTextureCache->get(mBitmap); if (!texture) return; mTexture = texture; @@ -114,7 +120,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); - const Texture* texture = mTexture; + Texture* texture = mTexture; mTexture = NULL; if (!texture) return; const AutoTexture autoCleanup(texture); @@ -126,7 +132,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, computeScreenSpaceMatrix(textureTransform, modelView); // Uniforms - bindTexture(texture->id, mWrapS, mWrapT, textureSlot); + bindTexture(texture, mWrapS, mWrapT, textureSlot); glUniform1i(program->getUniform("bitmapSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); @@ -198,7 +204,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } @@ -291,7 +297,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 011991a..4cd1b8b 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -97,7 +97,7 @@ struct SkiaShader { void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); protected: - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); + inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); Type mType; SkShader* mKey; @@ -138,7 +138,7 @@ private: } SkBitmap* mBitmap; - const Texture* mTexture; + Texture* mTexture; GLenum mWrapS; GLenum mWrapT; }; // struct SkiaBitmapShader diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 817f143..755074d 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -29,6 +29,8 @@ struct Texture { Texture() { cleanup = false; bitmapSize = 0; + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; } /** @@ -59,6 +61,12 @@ struct Texture { * Optional, size of the original bitmap. */ uint32_t bitmapSize; + + /** + * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE. + */ + GLenum wrapS; + GLenum wrapT; }; // struct Texture class AutoTexture { diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java index 2db1071..02eaa7c 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java @@ -51,27 +51,28 @@ public class ShadersActivity extends Activity { private LinearGradient mHorGradient; private LinearGradient mDiagGradient; private LinearGradient mVertGradient; + private Bitmap mTexture; ShadersView(Context c) { super(c); - Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); - mTexWidth = texture.getWidth(); - mTexHeight = texture.getHeight(); + mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); + mTexWidth = mTexture.getWidth(); + mTexHeight = mTexture.getHeight(); mDrawWidth = mTexWidth * 2.2f; mDrawHeight = mTexHeight * 1.2f; - mRepeatShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mRepeatShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); - mTranslatedShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); Matrix m1 = new Matrix(); m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f); m1.postRotate(45, 0, 0); mTranslatedShader.setLocalMatrix(m1); - mScaledShader = new BitmapShader(texture, Shader.TileMode.MIRROR, + mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); Matrix m2 = new Matrix(); m2.setScale(0.5f, 0.5f); @@ -98,6 +99,7 @@ public class ShadersActivity extends Activity { protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawRGB(255, 255, 255); + canvas.drawBitmap(mTexture, 0.0f, 0.0f, null); // Bitmap shaders canvas.save(); |