diff options
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 58 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 5 | ||||
| -rw-r--r-- | libs/hwui/TextureCache.cpp | 30 | ||||
| -rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 6 | ||||
| -rw-r--r-- | tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java | 13 |
5 files changed, 81 insertions, 31 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index d8023859..3010f29 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -54,10 +54,10 @@ static const GLsizei gDrawColorVertexCount = 4; // This array is never used directly but used as a memcpy source in the // OpenGLRenderer constructor static const TextureVertex gDrawTextureVertices[] = { - FV(0.0f, 0.0f, 0.0f, 1.0f), - FV(1.0f, 0.0f, 1.0f, 1.0f), - FV(0.0f, 1.0f, 0.0f, 0.0f), - FV(1.0f, 1.0f, 1.0f, 0.0f) + FV(0.0f, 0.0f, 0.0f, 0.0f), + FV(1.0f, 0.0f, 1.0f, 0.0f), + FV(0.0f, 1.0f, 0.0f, 1.0f), + FV(1.0f, 1.0f, 1.0f, 1.0f) }; static const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); static const GLsizei gDrawTextureVertexCount = 4; @@ -208,7 +208,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { resetDrawTextureTexCoords(u1, v1, u2, v1); drawTextureRect(layer.left, layer.top, layer.right, layer.bottom, - current->texture, current->alpha, current->mode, true); + current->texture, current->alpha, current->mode, true, true); resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f); @@ -378,8 +378,33 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) // Drawing /////////////////////////////////////////////////////////////////////////////// -void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top, const SkPaint* paint) { - LOGD("Drawing bitmap!"); +void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) { + Texture* texture = mTextureCache.get(bitmap); + + SkXfermode::Mode mode; + int alpha; + + if (paint) { + const bool isMode = SkXfermode::IsMode(paint->getXfermode(), &mode); + if (!isMode) { + // Assume SRC_OVER + mode = SkXfermode::kSrcOver_Mode; + } + + // Skia draws using the color's alpha channel if < 255 + // Otherwise, it uses the paint's alpha + int color = paint->getColor(); + alpha = (color >> 24) & 0xFF; + if (alpha == 255) { + alpha = paint->getAlpha(); + } + } else { + mode = SkXfermode::kSrcOver_Mode; + alpha = 255; + } + + drawTextureRect(left, top, left + texture->width, top + texture->height, texture->id, + alpha / 255.0f, mode, texture->blend, true); } void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { @@ -443,23 +468,26 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, - GLuint texture, float alpha, SkXfermode::Mode mode, bool isPremultiplied) { + GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied) { mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); - GLenum sourceMode = gBlends[mode].src; - if (!isPremultiplied && sourceMode == GL_ONE) { - sourceMode = GL_SRC_ALPHA; - } + if (blend || alpha < 1.0f || mode != SkXfermode::kSrcOver_Mode) { + GLenum sourceMode = gBlends[mode].src; + if (!isPremultiplied && sourceMode == GL_ONE) { + sourceMode = GL_SRC_ALPHA; + } - // TODO: Try to disable blending when the texture is opaque and alpha == 1.0f - glEnable(GL_BLEND); - glBlendFunc(sourceMode, gBlends[mode].dst); + glEnable(GL_BLEND); + glBlendFunc(sourceMode, gBlends[mode].dst); + } glBindTexture(GL_TEXTURE_2D, texture); + // TODO handle tiling and filtering here + glActiveTexture(GL_TEXTURE0); glUniform1i(mDrawTextureShader->sampler, 0); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index e5cc98c..965188f 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -102,7 +102,7 @@ public: bool quickReject(float left, float top, float right, float bottom); bool clipRect(float left, float top, float right, float bottom); - void drawBitmap(const SkBitmap* bitmap, float left, float top, const SkPaint* paint); + void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint); void drawColor(int color, SkXfermode::Mode mode); void drawRect(float left, float top, float right, float bottom, const SkPaint* paint); @@ -183,10 +183,11 @@ private: * @param texture The texture name to map onto the rectangle * @param alpha An additional translucency parameter, between 0.0f and 1.0f * @param mode The blending mode + * @param blend True if the texture contains an alpha channel * @param isPremultiplied Indicates whether the texture has premultiplied alpha */ void drawTextureRect(float left, float top, float right, float bottom, GLuint texture, - float alpha, SkXfermode::Mode mode, bool isPremultiplied = false); + float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = false); /** * Resets the texture coordinates stored in mDrawTextureVertices. Setting the values diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index c3b1463..4e16507 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -41,7 +41,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) { Texture* texture = mCache.get(bitmap); if (!texture) { texture = new Texture; - generateTexture(bitmap, texture); + generateTexture(bitmap, texture, false); mCache.put(bitmap, texture); } else if (bitmap->getGenerationID() != texture->generation) { generateTexture(bitmap, texture, true); @@ -58,7 +58,14 @@ void TextureCache::clear() { } void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) { + SkAutoLockPixels alp(*bitmap); + if (!bitmap->readyToDraw()) { + LOGE("Cannot generate texture from bitmap"); + return; + } + if (!regenerate) { + texture->generation = bitmap->getGenerationID(); texture->width = bitmap->width(); texture->height = bitmap->height(); @@ -66,25 +73,28 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege } glBindTexture(GL_TEXTURE_2D, texture->id); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); switch (bitmap->getConfig()) { case SkBitmap::kRGB_565_Config: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, texture->width, texture->height, - 0, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels()); + texture->blend = false; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmap->rowBytesAsPixels(), texture->height, 0, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels()); break; case SkBitmap::kARGB_8888_Config: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels()); + texture->blend = true; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels()); break; default: break; } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index f9b2823..7a00c67 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -33,7 +33,7 @@ <activity android:name="LayersActivity" android:label="_Layers" - android:theme="@android:style/Theme.Translucent"> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> @@ -43,7 +43,7 @@ <activity android:name="XfermodeActivity" android:label="_Xfermodes" - android:theme="@android:style/Theme.Translucent"> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> @@ -53,7 +53,7 @@ <activity android:name="BitmapsActivity" android:label="_Bitmaps" - android:theme="@android:style/Theme.Translucent"> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java index 85e7bf0..dfc8a71 100644 --- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java +++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/BitmapsActivity.java @@ -26,13 +26,24 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.os.Bundle; import android.view.View; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; @SuppressWarnings({"UnusedDeclaration"}) public class BitmapsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(new BitmapsView(this)); + final BitmapsView view = new BitmapsView(this); + setContentView(view); + + ScaleAnimation a = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, + ScaleAnimation.RELATIVE_TO_SELF, 0.5f, + ScaleAnimation.RELATIVE_TO_SELF,0.5f); + a.setDuration(2000); + a.setRepeatCount(Animation.INFINITE); + a.setRepeatMode(Animation.REVERSE); + view.startAnimation(a); } static class BitmapsView extends View { |
