Merge "Cleanup implementation of hardware layers." into honeycomb
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 @@
/**
* 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 @@
}
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 @@
// 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 @@
// 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 @@
* 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 @@
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 @@
@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 @@
}
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 @@
/**
* 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 d586043..0186f21 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2397,8 +2397,7 @@
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 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;
+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);
- jint layerId = LayerRenderer::createLayer(width, height,
- &layerWidth, &layerHeight, &textureId);
-
- 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 @@
{ "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 @@
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();
+ mLayerGarbage.clear();
}
-void Caches::deleteFboDeferred(GLuint fbo) {
+void Caches::deleteLayerDeferred(Layer* layer) {
Mutex::Autolock _l(mGarbageLock);
- mFboGarbage.push(fbo);
-}
-
-void Caches::deleteTextureDeferred(GLuint texture) {
- 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 @@
GLuint mRegionMeshIndices;
mutable Mutex mGarbageLock;
- Vector<GLuint> mFboGarbage;
- Vector<GLuint> mTextureGarbage;
+ Vector<Layer*> mLayerGarbage;
public:
/**
@@ -110,14 +109,9 @@
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 @@
}
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 @@
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 @@
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 @@
///////////////////////////////////////////////////////////////////////////////
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 @@
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 @@
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;
+ }
+
+ layer->width = width;
+ layer->height = height;
}
-
- *layerWidth = width;
- *layerHeight = 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 (fbo) glDeleteFramebuffers(1, &fbo);
- if (texture) glDeleteTextures(1, &texture);
+ if (layer->fbo) glDeleteFramebuffers(1, &layer->fbo);
+ if (layer->texture) glDeleteTextures(1, &layer->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 @@
class LayerRenderer: public OpenGLRenderer {
public:
- LayerRenderer(GLuint fbo): mFbo(fbo) {
+ LayerRenderer(Layer* layer): mLayer(layer) {
}
~LayerRenderer() {
@@ -48,15 +49,13 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*/
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 @@
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;