diff options
-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 7dd6cc6..5fac525 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 7587657..0230430 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 1a5df98..2273238 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 ed5eed1..86b07fb 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 4aed9b1..40cec3e 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 3563064..fde4f96 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 34f48c9..a11b6bc 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 fdb4e8c..57df976 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 62cb0e8..0822725 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 b838764..a25c95e 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 be68412..ed5d960 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 1cf3d20..f71e5d6 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 ee34d73..1cef267 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 9beb227..7f7deec 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 5f45915..da27dac 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; |