summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2012-06-06 19:03:58 -0700
committerChet Haase <chet@google.com>2012-06-07 06:25:04 -0700
commit44b2fe3fc114ee5f7273c6b0fee2cc999bf244a2 (patch)
tree8d54bda8c5b7021be5d923beb641a9efb22dcf30
parent43fa4c5261a732decae3bbfaea2a00f8bb9b709c (diff)
downloadframeworks_base-44b2fe3fc114ee5f7273c6b0fee2cc999bf244a2.zip
frameworks_base-44b2fe3fc114ee5f7273c6b0fee2cc999bf244a2.tar.gz
frameworks_base-44b2fe3fc114ee5f7273c6b0fee2cc999bf244a2.tar.bz2
Track canvas clearing for swap buffers logic.
A previous fix made it necessary for a frame to render something to GL in order to cause a call to eglSwapBuffers(). Besides the calls being tracked as part of issuing a DisplayList, there is also a potential call to clear the canvas (via glClear()) on non-opaque surfaces. This call is also good to track, since a surface that gets cleared without any other drawing operations is worth flipping to the screen (to erase old contents on that surface). This fix tracks the status of the pre-draw operations to find out whether glClear() was called and then sets the drawing status appropriately. Issue #6606422 QuickContact dismissal is janky again (Tracking) Change-Id: I5fcaccfdc9293dd46b83f2fc279730a5d2740ebf
-rw-r--r--core/java/android/view/GLES20Canvas.java11
-rw-r--r--core/java/android/view/HardwareCanvas.java9
-rw-r--r--core/java/android/view/HardwareRenderer.java14
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp12
-rw-r--r--libs/hwui/DisplayListRenderer.cpp3
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--libs/hwui/LayerRenderer.cpp6
-rw-r--r--libs/hwui/LayerRenderer.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp9
-rw-r--r--libs/hwui/OpenGLRenderer.h4
10 files changed, 39 insertions, 33 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 1631fb3..055aee3 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -215,16 +215,17 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nSetViewport(int renderer, int width, int height);
@Override
- public void onPreDraw(Rect dirty) {
+ public int onPreDraw(Rect dirty) {
if (dirty != null) {
- nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque);
+ return nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
+ mOpaque);
} else {
- nPrepare(mRenderer, mOpaque);
+ return nPrepare(mRenderer, mOpaque);
}
}
- private static native void nPrepare(int renderer, boolean opaque);
- private static native void nPrepareDirty(int renderer, int left, int top, int right, int bottom,
+ private static native int nPrepare(int renderer, boolean opaque);
+ private static native int nPrepareDirty(int renderer, int left, int top, int right, int bottom,
boolean opaque);
@Override
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index ee2dd59..777552a 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -41,8 +41,10 @@ public abstract class HardwareCanvas extends Canvas {
* Invoked before any drawing operation is performed in this canvas.
*
* @param dirty The dirty rectangle to update, can be null.
+ * @return {@link DisplayList#STATUS_DREW} if anything was drawn (such as a call to clear
+ * the canvas).
*/
- public abstract void onPreDraw(Rect dirty);
+ public abstract int onPreDraw(Rect dirty);
/**
* Invoked after all drawing operation have been performed.
@@ -58,8 +60,9 @@ public abstract class HardwareCanvas extends Canvas {
* @param flags Optional flags about drawing, see {@link DisplayList} for
* the possible flags.
*
- * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
- * {@link DisplayList#STATUS_INVOKE}
+ * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW}, or
+ * {@link DisplayList#STATUS_INVOKE}, or'd with {@link DisplayList#STATUS_DREW}
+ * if anything was drawn.
*/
public abstract int drawDisplayList(DisplayList displayList, Rect dirty, int flags);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 7e86ea3..0ae6b56 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1042,8 +1042,8 @@ public abstract class HardwareRenderer {
return mGl != null && mCanvas != null;
}
- void onPreDraw(Rect dirty) {
-
+ int onPreDraw(Rect dirty) {
+ return DisplayList.STATUS_DONE;
}
void onPostDraw() {
@@ -1102,9 +1102,7 @@ public abstract class HardwareRenderer {
}
}
- onPreDraw(dirty);
-
- int status = DisplayList.STATUS_DONE;
+ int status = onPreDraw(dirty);
int saveCount = canvas.save();
callbacks.onHardwarePreDraw(canvas);
@@ -1138,7 +1136,7 @@ public abstract class HardwareRenderer {
drawDisplayListStartTime = System.nanoTime();
}
- status = canvas.drawDisplayList(displayList, mRedrawClip,
+ status |= canvas.drawDisplayList(displayList, mRedrawClip,
DisplayList.FLAG_CLIP_CHILDREN);
if (mProfileEnabled) {
@@ -1372,8 +1370,8 @@ public abstract class HardwareRenderer {
}
@Override
- void onPreDraw(Rect dirty) {
- mGlCanvas.onPreDraw(dirty);
+ int onPreDraw(Rect dirty) {
+ return mGlCanvas.onPreDraw(dirty);
}
@Override
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 82f8984..a51b77e 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -133,15 +133,15 @@ static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
renderer->setViewport(width, height);
}
-static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
+static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jboolean opaque) {
- renderer->prepare(opaque);
+ return renderer->prepare(opaque);
}
-static void android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
+static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom,
jboolean opaque) {
- renderer->prepareDirty(left, top, right, bottom, opaque);
+ return renderer->prepareDirty(left, top, right, bottom, opaque);
}
static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
@@ -868,8 +868,8 @@ static JNINativeMethod gMethods[] = {
{ "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
{ "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
- { "nPrepare", "(IZ)V", (void*) android_view_GLES20Canvas_prepare },
- { "nPrepareDirty", "(IIIIIZ)V", (void*) android_view_GLES20Canvas_prepareDirty },
+ { "nPrepare", "(IZ)I", (void*) android_view_GLES20Canvas_prepare },
+ { "nPrepareDirty", "(IIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty },
{ "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish },
{ "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize },
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 88d2209..d376e3a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -1368,13 +1368,14 @@ void DisplayListRenderer::setViewport(int width, int height) {
mHeight = height;
}
-void DisplayListRenderer::prepareDirty(float left, float top,
+int DisplayListRenderer::prepareDirty(float left, float top,
float right, float bottom, bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSaveCount = 1;
mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
mRestoreSaveCount = -1;
+ return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
}
void DisplayListRenderer::finish() {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 4fa1baa..6b4c6b2 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -547,7 +547,7 @@ public:
virtual bool isDeferred();
virtual void setViewport(int width, int height);
- virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 2a4e72b..65f8c7c 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -37,7 +37,7 @@ LayerRenderer::LayerRenderer(Layer* layer): mLayer(layer) {
LayerRenderer::~LayerRenderer() {
}
-void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
+int LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->getFbo());
@@ -57,9 +57,9 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto
mLayer->region.subtractSelf(r);
}
- OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
+ return OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
#else
- OpenGLRenderer::prepareDirty(0.0f, 0.0f, width, height, opaque);
+ return OpenGLRenderer::prepareDirty(0.0f, 0.0f, width, height, opaque);
#endif
}
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index c461ea7..8f3a0a3 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -47,7 +47,7 @@ public:
ANDROID_API LayerRenderer(Layer* layer);
virtual ~LayerRenderer();
- virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
virtual bool hasLayer();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2dc9726..0d857bf 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -164,11 +164,11 @@ void OpenGLRenderer::setViewport(int width, int height) {
glEnableVertexAttribArray(Program::kBindingPosition);
}
-void OpenGLRenderer::prepare(bool opaque) {
- prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
+int OpenGLRenderer::prepare(bool opaque) {
+ return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
}
-void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
+int OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
mCaches.clearGarbage();
mSnapshot = new Snapshot(mFirstSnapshot,
@@ -184,9 +184,12 @@ void OpenGLRenderer::prepareDirty(float left, float top, float right, float bott
if (!opaque) {
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
glClear(GL_COLOR_BUFFER_BIT);
+ return DrawGlInfo::kStatusDrew;
} else {
mCaches.resetScissor();
}
+
+ return DrawGlInfo::kStatusDone;
}
void OpenGLRenderer::syncState() {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 7703e80..b342f50 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -67,8 +67,8 @@ public:
virtual void setViewport(int width, int height);
- ANDROID_API void prepare(bool opaque);
- virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ ANDROID_API int prepare(bool opaque);
+ virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
// These two calls must not be recorded in display lists