diff options
author | 2011-01-13 12:13:20 -0800 | |
---|---|---|
committer | 2011-01-13 12:13:20 -0800 | |
commit | ada830f639591b99c3e40de22b07296c7932a33f (patch) | |
tree | 308f469469e96ce7f99d2ec5135e7d44eb858a35 | |
parent | 4f6aff386045000c2c03b903c7109cb42092b7ea (diff) |
Cleanup implementation of hardware layers.
The new implementation relies on OpenGLRenderer's existing layer
code instead of duplicating it. The new code is much cleaner, with
simpler and better APIs and allows tracking of drawn regions inside
layers. Region tracking is not yet enabled but this will be done
in a future CL.
Change-Id: Ie826121a2227de8252c77b992a61218defea5143
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 24 | ||||
-rw-r--r-- | core/java/android/view/GLES20Layer.java | 56 | ||||
-rw-r--r-- | core/java/android/view/HardwareCanvas.java | 9 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 3 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 69 | ||||
-rw-r--r-- | libs/hwui/Caches.cpp | 27 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 12 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 12 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 103 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.h | 15 | ||||
-rw-r--r-- | libs/hwui/OpenGLDebugRenderer.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/OpenGLDebugRenderer.h | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 20 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 28 |
15 files changed, 178 insertions, 210 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 7dd6cc6db758..5fac52510765 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -83,9 +83,9 @@ class GLES20Canvas extends HardwareCanvas { /** * Creates a canvas to render into an FBO. */ - GLES20Canvas(int fbo, boolean translucent) { + GLES20Canvas(int layer, boolean translucent) { mOpaque = !translucent; - mRenderer = nCreateLayerRenderer(fbo); + mRenderer = nCreateLayerRenderer(layer); setupFinalizer(); } @@ -114,7 +114,7 @@ class GLES20Canvas extends HardwareCanvas { } private static native int nCreateRenderer(); - private static native int nCreateLayerRenderer(int fbo); + private static native int nCreateLayerRenderer(int layer); private static native int nGetDisplayListRenderer(int renderer); private static native void nDestroyRenderer(int renderer); @@ -156,11 +156,10 @@ class GLES20Canvas extends HardwareCanvas { // Hardware layers /////////////////////////////////////////////////////////////////////////// - static native int nCreateLayer(int width, int height, int[] layerInfo); - static native void nResizeLayer(int layerId, int layerTextureId, int width, int height, - int[] layerInfo); - static native void nDestroyLayer(int layerId, int layerTextureId); - static native void nDestroyLayerDeferred(int layerId, int layerTextureId); + static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo); + static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo); + static native void nDestroyLayer(int layerId); + static native void nDestroyLayerDeferred(int layerId); /////////////////////////////////////////////////////////////////////////// // Canvas management @@ -257,18 +256,15 @@ class GLES20Canvas extends HardwareCanvas { // Hardware layer /////////////////////////////////////////////////////////////////////////// - void drawHardwareLayer(float left, float top, float right, float bottom, - HardwareLayer layer, Paint paint) { + void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) { final GLES20Layer glLayer = (GLES20Layer) layer; boolean hasColorFilter = paint != null && setupColorFilter(paint); final int nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawLayer(mRenderer, left, top, right, bottom, glLayer.mLayerTextureId, - glLayer.getU(), glLayer.getV(), nativePaint); + nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint); if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawLayer(int renderer, float left, float top, float right, float bottom, - int layerTexture, float u, float v, int paint); + private native void nDrawLayer(int renderer, int layer, float x, float y, int paint); void interrupt() { nInterrupt(mRenderer); diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java index 7587657aa218..02304304c78d 100644 --- a/core/java/android/view/GLES20Layer.java +++ b/core/java/android/view/GLES20Layer.java @@ -22,52 +22,45 @@ import android.graphics.Canvas; * An OpenGL ES 2.0 implementation of {@link HardwareLayer}. */ class GLES20Layer extends HardwareLayer { - private int mLayerId; - int mLayerTextureId; + private int mLayer; private int mLayerWidth; private int mLayerHeight; private final GLES20Canvas mCanvas; - private float mU; - private float mV; - @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private final Finalizer mFinalizer; GLES20Layer(int width, int height, boolean isOpaque) { super(width, height, isOpaque); - int[] layerInfo = new int[3]; - mLayerId = GLES20Canvas.nCreateLayer(width, height, layerInfo); - if (mLayerId != 0) { + int[] layerInfo = new int[2]; + mLayer = GLES20Canvas.nCreateLayer(width, height, isOpaque, layerInfo); + if (mLayer != 0) { mLayerWidth = layerInfo[0]; mLayerHeight = layerInfo[1]; - mLayerTextureId = layerInfo[2]; - mCanvas = new GLES20Canvas(mLayerId, !isOpaque); - mFinalizer = new Finalizer(mLayerId, mLayerTextureId); - - mU = mWidth / (float) mLayerWidth; - mV = mHeight/ (float) mLayerHeight; + mCanvas = new GLES20Canvas(mLayer, !isOpaque); + mFinalizer = new Finalizer(mLayer); } else { mCanvas = null; mFinalizer = null; } } - float getU() { - return mU; - } - - float getV() { - return mV; + /** + * Returns the native layer object used to render this layer. + * + * @return A pointer to the native layer object, or 0 if the object is NULL + */ + public int getLayer() { + return mLayer; } @Override boolean isValid() { - return mLayerId != 0 && mLayerWidth > 0 && mLayerHeight > 0; + return mLayer != 0 && mLayerWidth > 0 && mLayerHeight > 0; } @Override @@ -77,15 +70,12 @@ class GLES20Layer extends HardwareLayer { mWidth = width; mHeight = height; - int[] layerInfo = new int[3]; + int[] layerInfo = new int[2]; - GLES20Canvas.nResizeLayer(mLayerId, mLayerTextureId, width, height, layerInfo); + GLES20Canvas.nResizeLayer(mLayer, width, height, layerInfo); mLayerWidth = layerInfo[0]; mLayerHeight = layerInfo[1]; - - mU = mWidth / (float) mLayerWidth; - mV = mHeight/ (float) mLayerHeight; } } @@ -112,23 +102,21 @@ class GLES20Layer extends HardwareLayer { @Override void destroy() { mFinalizer.destroy(); - mLayerId = mLayerTextureId = 0; + mLayer = 0; } private static class Finalizer { private int mLayerId; - private int mLayerTextureId; - public Finalizer(int layerId, int layerTextureId) { + public Finalizer(int layerId) { mLayerId = layerId; - mLayerTextureId = layerTextureId; } @Override protected void finalize() throws Throwable { try { - if (mLayerId != 0 || mLayerTextureId != 0) { - GLES20Canvas.nDestroyLayerDeferred(mLayerId, mLayerTextureId); + if (mLayerId != 0) { + GLES20Canvas.nDestroyLayerDeferred(mLayerId); } } finally { super.finalize(); @@ -136,8 +124,8 @@ class GLES20Layer extends HardwareLayer { } void destroy() { - GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId); - mLayerId = mLayerTextureId = 0; + GLES20Canvas.nDestroyLayer(mLayerId); + mLayerId = 0; } } } diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java index 1a5df98cc69f..2273238e66e9 100644 --- a/core/java/android/view/HardwareCanvas.java +++ b/core/java/android/view/HardwareCanvas.java @@ -54,13 +54,10 @@ abstract class HardwareCanvas extends Canvas { /** * Draws the specified layer onto this canvas. * - * @param left The left coordinate of the layer - * @param top The top coordinate of the layer - * @param right The right coordinate of the layer - * @param bottom The bottom coordinate of the layer * @param layer The layer to composite on this canvas + * @param x The left coordinate of the layer + * @param y The top coordinate of the layer * @param paint The paint used to draw the layer */ - abstract void drawHardwareLayer(float left, float top, float right, float bottom, - HardwareLayer layer, Paint paint); + abstract void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index ed5eed159f0d..86b07fb0da8f 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2391,8 +2391,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (!layerSaved && layerType == LAYER_TYPE_HARDWARE) { final HardwareLayer layer = child.getHardwareLayer(canvas); if (layer != null && layer.isValid()) { - ((HardwareCanvas) canvas).drawHardwareLayer(0, 0, cr - cl, cb - ct, - layer, child.mLayerPaint); + ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint); layerRendered = true; } else { canvas.saveLayer(sx, sy, sx + cr - cl, sy + cb - ct, child.mLayerPaint, diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 4aed9b1b8ac5..40cec3e38b23 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -458,59 +458,49 @@ static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject canvas, } static OpenGLRenderer* android_view_GLES20Canvas_createLayerRenderer(JNIEnv* env, - jobject clazz, jint fbo) { - return new LayerRenderer(fbo); + jobject clazz, Layer* layer) { + if (layer) { + return new LayerRenderer(layer); + } + return NULL; } -static jint android_view_GLES20Canvas_createLayer(JNIEnv* env, - jobject clazz, jint width, jint height, jintArray layerInfo) { - uint32_t layerWidth = 0; - uint32_t layerHeight = 0; - GLuint textureId = 0; - - jint layerId = LayerRenderer::createLayer(width, height, - &layerWidth, &layerHeight, &textureId); +static Layer* android_view_GLES20Canvas_createLayer(JNIEnv* env, jobject clazz, + jint width, jint height, jboolean isOpaque, jintArray layerInfo) { + Layer* layer = LayerRenderer::createLayer(width, height, isOpaque); - if (layerId) { + if (layer) { jint* storage = env->GetIntArrayElements(layerInfo, NULL); - storage[0] = layerWidth; - storage[1] = layerHeight; - storage[2] = textureId; + storage[0] = layer->width; + storage[1] = layer->height; env->ReleaseIntArrayElements(layerInfo, storage, 0); } - return layerId; + return layer; } -static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env, - jobject clazz, jint layerId, jint layerTextureId, jint width, jint height, - jintArray layerInfo) { - uint32_t layerWidth = 0; - uint32_t layerHeight = 0; - - LayerRenderer::resizeLayer(layerId, layerTextureId, width, height, &layerWidth, &layerHeight); +static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env, jobject clazz, + Layer* layer, jint width, jint height, jintArray layerInfo) { + LayerRenderer::resizeLayer(layer, width, height); jint* storage = env->GetIntArrayElements(layerInfo, NULL); - storage[0] = layerWidth; - storage[1] = layerHeight; + storage[0] = layer->width; + storage[1] = layer->height; env->ReleaseIntArrayElements(layerInfo, storage, 0); } -static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env, - jobject clazz, jint layerId, jint layerTextureId) { - LayerRenderer::destroyLayer(layerId, layerTextureId); +static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env, jobject clazz, Layer* layer) { + LayerRenderer::destroyLayer(layer); } static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env, - jobject clazz, jint layerId, jint layerTextureId) { - LayerRenderer::destroyLayerDeferred(layerId, layerTextureId); + jobject clazz, Layer* layer) { + LayerRenderer::destroyLayerDeferred(layer); } -static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, - jobject canvas, OpenGLRenderer* renderer, - jfloat left, jfloat top, jfloat right, jfloat bottom, - jint layerTexture, jfloat u, jfloat v, SkPaint* paint) { - renderer->drawLayer(layerTexture, left, top, right, bottom, u, v, paint); +static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) { + renderer->drawLayer(layer, x, y, paint); } #endif // USE_OPENGL_RENDERER @@ -602,12 +592,11 @@ static JNINativeMethod gMethods[] = { { "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume }, { "nCreateLayerRenderer", "(I)I", (void*) android_view_GLES20Canvas_createLayerRenderer }, - { "nCreateLayer", "(II[I)I", (void*) android_view_GLES20Canvas_createLayer }, - { "nResizeLayer", "(IIII[I)V", (void*) android_view_GLES20Canvas_resizeLayer }, - { "nDestroyLayer", "(II)V", (void*) android_view_GLES20Canvas_destroyLayer }, - { "nDestroyLayerDeferred", "(II)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred }, - { "nDrawLayer", "(IFFFFIFFI)V", - (void*) android_view_GLES20Canvas_drawLayer }, + { "nCreateLayer", "(IIZ[I)I", (void*) android_view_GLES20Canvas_createLayer }, + { "nResizeLayer", "(III[I)V" , (void*) android_view_GLES20Canvas_resizeLayer }, + { "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer }, + { "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred }, + { "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer }, #endif }; diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 35630649ee33..fde4f966c7b1 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -109,29 +109,22 @@ void Caches::clearGarbage() { Mutex::Autolock _l(mGarbageLock); - size_t count = mFboGarbage.size(); + size_t count = mLayerGarbage.size(); for (size_t i = 0; i < count; i++) { - GLuint fbo = mFboGarbage.itemAt(i); - if (fbo) glDeleteFramebuffers(1, &fbo); - } - mFboGarbage.clear(); + Layer* layer = mLayerGarbage.itemAt(i); + if (layer) { + if (layer->fbo) glDeleteFramebuffers(1, &layer->fbo); + if (layer->texture) glDeleteTextures(1, &layer->texture); - count = mTextureGarbage.size(); - for (size_t i = 0; i < count; i++) { - GLuint texture = mTextureGarbage.itemAt(i); - if (texture) glDeleteTextures(1, &texture); + delete layer; + } } - mTextureGarbage.clear(); -} - -void Caches::deleteFboDeferred(GLuint fbo) { - Mutex::Autolock _l(mGarbageLock); - mFboGarbage.push(fbo); + mLayerGarbage.clear(); } -void Caches::deleteTextureDeferred(GLuint texture) { +void Caches::deleteLayerDeferred(Layer* layer) { Mutex::Autolock _l(mGarbageLock); - mTextureGarbage.push(texture); + mLayerGarbage.push(layer); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 34f48c950869..a11b6bc1ec08 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -91,8 +91,7 @@ class Caches: public Singleton<Caches> { GLuint mRegionMeshIndices; mutable Mutex mGarbageLock; - Vector<GLuint> mFboGarbage; - Vector<GLuint> mTextureGarbage; + Vector<Layer*> mLayerGarbage; public: /** @@ -110,14 +109,9 @@ public: void clearGarbage(); /** - * Can be used to delete an FBO from a non EGL thread. + * Can be used to delete a layer from a non EGL thread. */ - void deleteFboDeferred(GLuint fbo); - - /** - * Can be used to delete a texture from a non EGL thread. - */ - void deleteTextureDeferred(GLuint texture); + void deleteLayerDeferred(Layer* layer); /** * Binds the VBO used to render simple textured quads. diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index fdb4e8ce8532..57df976ebf9a 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -242,8 +242,7 @@ void DisplayList::replay(OpenGLRenderer& renderer) { } break; case DrawLayer: { - renderer.drawLayer(getInt(), getFloat(), getFloat(), getFloat(), getFloat(), - getFloat(), getFloat(), getPaint()); + renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint()); } break; case DrawBitmap: { @@ -488,13 +487,10 @@ void DisplayListRenderer::drawDisplayList(DisplayList* displayList) { addDisplayList(displayList); } -void DisplayListRenderer::drawLayer(int texture, float left, float top, float right, float bottom, - float u, float v, SkPaint* paint) { +void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { addOp(DisplayList::DrawLayer); - addInt(texture); - addBounds(left, top, right, bottom); - addFloat(u); - addFloat(v); + addInt((int) layer); + addPoint(x, y); addPaint(paint); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 62cb0e8bc874..082272511b76 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -246,8 +246,7 @@ public: bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); void drawDisplayList(DisplayList* displayList); - void drawLayer(int texture, float left, float top, float right, float bottom, - float u, float v, SkPaint* paint); + void drawLayer(Layer* layer, float x, float y, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index b838764a54de..a25c95ed6614 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -27,10 +27,10 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// void LayerRenderer::prepare(bool opaque) { - LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mFbo); + LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo); glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo); - glBindFramebuffer(GL_FRAMEBUFFER, mFbo); + glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); OpenGLRenderer::prepare(opaque); } @@ -39,33 +39,33 @@ void LayerRenderer::finish() { OpenGLRenderer::finish(); glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo); - LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mFbo); + LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo); } /////////////////////////////////////////////////////////////////////////////// // Static functions /////////////////////////////////////////////////////////////////////////////// -GLuint LayerRenderer::createLayer(uint32_t width, uint32_t height, - uint32_t* layerWidth, uint32_t* layerHeight, GLuint* texture) { +Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) { LAYER_RENDERER_LOGD("Creating new layer %dx%d", width, height); + Layer* layer = new Layer(width, height); + GLuint previousFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); - GLuint fbo = 0; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glGenFramebuffers(1, &layer->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo); if (glGetError() != GL_NO_ERROR) { glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - glDeleteBuffers(1, &fbo); + glDeleteBuffers(1, &layer->fbo); return 0; } glActiveTexture(GL_TEXTURE0); - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); + glGenTextures(1, &layer->texture); + glBindTexture(GL_TEXTURE_2D, layer->texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); @@ -80,66 +80,81 @@ GLuint LayerRenderer::createLayer(uint32_t width, uint32_t height, if (glGetError() != GL_NO_ERROR) { glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - glDeleteBuffers(1, &fbo); - glDeleteTextures(1, texture); + glDeleteBuffers(1, &layer->fbo); + glDeleteTextures(1, &layer->texture); + delete layer; return 0; } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - *texture, 0); + layer->texture, 0); if (glGetError() != GL_NO_ERROR) { glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - glDeleteBuffers(1, &fbo); - glDeleteTextures(1, texture); + glDeleteBuffers(1, &layer->fbo); + glDeleteTextures(1, &layer->texture); + delete layer; return 0; } glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - *layerWidth = width; - *layerHeight = height; + layer->layer.set(0.0f, 0.0f, width, height); + layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f); + layer->alpha = 255; + layer->mode = SkXfermode::kSrcOver_Mode; + layer->blend = !isOpaque; + layer->empty = false; + layer->colorFilter = NULL; - return fbo; + return layer; } -void LayerRenderer::resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height, - uint32_t* layerWidth, uint32_t* layerHeight) { - LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", fbo, width, height); +bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) { + if (layer) { + LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->fbo, width, height); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, layer->texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); - if (glGetError() != GL_NO_ERROR) { - glDeleteBuffers(1, &fbo); - glDeleteTextures(1, &texture); + if (glGetError() != GL_NO_ERROR) { + glDeleteBuffers(1, &layer->fbo); + glDeleteTextures(1, &layer->texture); - *layerWidth = 0; - *layerHeight = 0; + layer->width = 0; + layer->height = 0; + layer->fbo = 0; + layer->texture = 0; - return; - } + return false; + } - *layerWidth = width; - *layerHeight = height; + layer->width = width; + layer->height = height; + } + return true; } -void LayerRenderer::destroyLayer(GLuint fbo, GLuint texture) { - LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", fbo); +void LayerRenderer::destroyLayer(Layer* layer) { + if (layer) { + LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", layer->fbo); + + if (layer->fbo) glDeleteFramebuffers(1, &layer->fbo); + if (layer->texture) glDeleteTextures(1, &layer->texture); - if (fbo) glDeleteFramebuffers(1, &fbo); - if (texture) glDeleteTextures(1, &texture); + delete layer; + } } -void LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) { - LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", fbo); +void LayerRenderer::destroyLayerDeferred(Layer* layer) { + if (layer) { + LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->fbo); - Caches& caches = Caches::getInstance(); - if (fbo) caches.deleteFboDeferred(fbo); - if (texture) caches.deleteTextureDeferred(texture); + Caches::getInstance().deleteLayerDeferred(layer); + } } }; // namespace uirenderer diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index be684122f80a..ed5d9609c001 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -18,6 +18,7 @@ #define ANDROID_HWUI_LAYER_RENDERER_H #include "OpenGLRenderer.h" +#include "Layer.h" namespace android { namespace uirenderer { @@ -39,7 +40,7 @@ namespace uirenderer { class LayerRenderer: public OpenGLRenderer { public: - LayerRenderer(GLuint fbo): mFbo(fbo) { + LayerRenderer(Layer* layer): mLayer(layer) { } ~LayerRenderer() { @@ -48,15 +49,13 @@ public: void prepare(bool opaque); void finish(); - static GLuint createLayer(uint32_t width, uint32_t height, - uint32_t* layerWidth, uint32_t* layerHeight, GLuint* texture); - static void resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height, - uint32_t* layerWidth, uint32_t* layerHeight); - static void destroyLayer(GLuint fbo, GLuint texture); - static void destroyLayerDeferred(GLuint fbo, GLuint texture); + static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false); + static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height); + static void destroyLayer(Layer* layer); + static void destroyLayerDeferred(Layer* layer); private: - GLuint mFbo; + Layer* mLayer; GLuint mPreviousFbo; }; // class LayerRenderer diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp index 1cf3d20c8be1..f71e5d6dfa24 100644 --- a/libs/hwui/OpenGLDebugRenderer.cpp +++ b/libs/hwui/OpenGLDebugRenderer.cpp @@ -54,6 +54,12 @@ void OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList) { OpenGLRenderer::drawDisplayList(displayList); } +void OpenGLDebugRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { + mPrimitivesCount++; + StopWatch w("drawLayer"); + OpenGLRenderer::drawLayer(layer, x, y, paint); +} + void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { mPrimitivesCount++; diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h index ee34d736d700..1cef267fcbdb 100644 --- a/libs/hwui/OpenGLDebugRenderer.h +++ b/libs/hwui/OpenGLDebugRenderer.h @@ -41,6 +41,7 @@ public: SkPaint* p, int flags); void drawDisplayList(DisplayList* displayList); + void drawLayer(Layer* layer, float x, float y, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 9beb227c9b0c..7f7deec90a1b 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -622,10 +622,12 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { setupDraw(); setupDrawWithTexture(); setupDrawColor(alpha, alpha, alpha, alpha); + setupDrawColorFilter(); setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false); setupDrawProgram(); setupDrawDirtyRegionsDisabled(); setupDrawPureColorUniforms(); + setupDrawColorFilterUniforms(); setupDrawTexture(layer->texture); setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom); setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]); @@ -1485,28 +1487,22 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { finishDrawTexture(); } -void OpenGLRenderer::drawLayer(int texture, float left, float top, float right, float bottom, - float u, float v, SkPaint* paint) { - if (quickReject(left, top, right, bottom)) { +void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { + if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) { return; } glActiveTexture(gTextureUnits[0]); - if (!texture) return; - - mCaches.unbindMeshBuffer(); - resetDrawTextureTexCoords(0.0f, v, u, 0.0f); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); - // TODO: Should get the blend info from the caller - drawTextureMesh(left, top, right, bottom, texture, alpha / 255.0f, mode, true, - &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], - GL_TRIANGLE_STRIP, gMeshCount); + layer->alpha = alpha; + layer->mode = mode; - resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); + const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); + composeLayerRect(layer, r); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 5f45915ca940..da27dac0d132 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -95,8 +95,7 @@ public: virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); virtual void drawDisplayList(DisplayList* displayList); - virtual void drawLayer(int texture, float left, float top, float right, float bottom, - float u, float v, SkPaint* paint); + virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint); virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, @@ -133,6 +132,19 @@ protected: */ virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous); + /** + * Mark the layer as dirty at the specified coordinates. The coordinates + * are transformed with the supplied matrix. + */ + virtual void dirtyLayer(const float left, const float top, + const float right, const float bottom, const mat4 transform); + + /** + * Mark the layer as dirty at the specified coordinates. + */ + virtual void dirtyLayer(const float left, const float top, + const float right, const float bottom); + private: /** * Saves the current state of the renderer as a new snapshot. @@ -402,18 +414,6 @@ private: mDirtyClip = true; } - /** - * Mark the layer as dirty at the specified coordinates. The coordinates - * are transformed with the supplied matrix. - */ - void dirtyLayer(const float left, const float top, const float right, const float bottom, - const mat4 transform); - - /** - * Mark the layer as dirty at the specified coordinates. - */ - void dirtyLayer(const float left, const float top, const float right, const float bottom); - // Dimensions of the drawing surface int mWidth, mHeight; |