Enable partial invalidates when rendering with OpenGL.
Change-Id: Ie8be06c4776b815e8737753eb8003b4fd8936130
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index dce1a6c..dac3135 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -192,21 +192,36 @@
nSetViewport(mRenderer, width, height);
}
- private native void nSetViewport(int renderer, int width, int height);
+ private static native void nSetViewport(int renderer, int width, int height);
- @Override
- void onPreDraw() {
- nPrepare(mRenderer, mOpaque);
+ /**
+ * @hide
+ */
+ public static boolean preserveBackBuffer() {
+ return nPreserveBackBuffer();
}
- private native void nPrepare(int renderer, boolean opaque);
+ private static native boolean nPreserveBackBuffer();
+
+ @Override
+ void onPreDraw(Rect dirty) {
+ if (dirty != null) {
+ nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque);
+ } else {
+ 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,
+ boolean opaque);
@Override
void onPostDraw() {
nFinish(mRenderer);
}
- private native void nFinish(int renderer);
+ private static native void nFinish(int renderer);
@Override
public boolean acquireContext() {
@@ -217,14 +232,14 @@
return mContextLocked;
}
- private native void nAcquireContext(int renderer);
+ private static native void nAcquireContext(int renderer);
@Override
public boolean callDrawGLFunction(int drawGLFunction) {
return nCallDrawGLFunction(mRenderer, drawGLFunction);
}
- private native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
+ private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
@Override
public void releaseContext() {
@@ -234,7 +249,7 @@
}
}
- private native void nReleaseContext(int renderer);
+ private static native void nReleaseContext(int renderer);
///////////////////////////////////////////////////////////////////////////
// Display list
@@ -244,7 +259,7 @@
return nGetDisplayList(mRenderer);
}
- private native int nGetDisplayList(int renderer);
+ private static native int nGetDisplayList(int renderer);
static void destroyDisplayList(int displayList) {
nDestroyDisplayList(displayList);
@@ -257,7 +272,7 @@
return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
}
- private native boolean nDrawDisplayList(int renderer, int displayList);
+ private static native boolean nDrawDisplayList(int renderer, int displayList);
///////////////////////////////////////////////////////////////////////////
// Hardware layer
@@ -271,7 +286,7 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
+ private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
void interrupt() {
nInterrupt(mRenderer);
@@ -281,8 +296,8 @@
nResume(mRenderer);
}
- private native void nInterrupt(int renderer);
- private native void nResume(int renderer);
+ private static native void nInterrupt(int renderer);
+ private static native void nResume(int renderer);
///////////////////////////////////////////////////////////////////////////
// Clipping
@@ -303,7 +318,7 @@
return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
}
- private native boolean nClipRect(int renderer, float left, float top,
+ private static native boolean nClipRect(int renderer, float left, float top,
float right, float bottom, int op);
@Override
@@ -316,7 +331,8 @@
return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
}
- private native boolean nClipRect(int renderer, int left, int top, int right, int bottom, int op);
+ private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom,
+ int op);
@Override
public boolean clipRect(Rect rect) {
@@ -355,14 +371,14 @@
return nGetClipBounds(mRenderer, bounds);
}
- private native boolean nGetClipBounds(int renderer, Rect bounds);
+ private static native boolean nGetClipBounds(int renderer, Rect bounds);
@Override
public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt);
}
- private native boolean nQuickReject(int renderer, float left, float top,
+ private static native boolean nQuickReject(int renderer, float left, float top,
float right, float bottom, int edge);
@Override
@@ -384,56 +400,56 @@
if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
}
- private native void nTranslate(int renderer, float dx, float dy);
+ private static native void nTranslate(int renderer, float dx, float dy);
@Override
public void skew(float sx, float sy) {
nSkew(mRenderer, sx, sy);
}
- private native void nSkew(int renderer, float sx, float sy);
+ private static native void nSkew(int renderer, float sx, float sy);
@Override
public void rotate(float degrees) {
nRotate(mRenderer, degrees);
}
- private native void nRotate(int renderer, float degrees);
+ private static native void nRotate(int renderer, float degrees);
@Override
public void scale(float sx, float sy) {
nScale(mRenderer, sx, sy);
}
- private native void nScale(int renderer, float sx, float sy);
+ private static native void nScale(int renderer, float sx, float sy);
@Override
public void setMatrix(Matrix matrix) {
nSetMatrix(mRenderer, matrix.native_instance);
}
- private native void nSetMatrix(int renderer, int matrix);
+ private static native void nSetMatrix(int renderer, int matrix);
@Override
public int getNativeMatrix() {
return nGetMatrix(mRenderer);
}
- private native int nGetMatrix(int renderer);
+ private static native int nGetMatrix(int renderer);
@Override
public void getMatrix(Matrix matrix) {
nGetMatrix(mRenderer, matrix.native_instance);
}
- private native void nGetMatrix(int renderer, int matrix);
+ private static native void nGetMatrix(int renderer, int matrix);
@Override
public void concat(Matrix matrix) {
nConcatMatrix(mRenderer, matrix.native_instance);
}
- private native void nConcatMatrix(int renderer, int matrix);
+ private static native void nConcatMatrix(int renderer, int matrix);
///////////////////////////////////////////////////////////////////////////
// State management
@@ -449,7 +465,7 @@
return nSave(mRenderer, saveFlags);
}
- private native int nSave(int renderer, int flags);
+ private static native int nSave(int renderer, int flags);
@Override
public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
@@ -469,8 +485,8 @@
return save(saveFlags);
}
- private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
- int paint, int saveFlags);
+ private static native int nSaveLayer(int renderer, float left, float top,
+ float right, float bottom, int paint, int saveFlags);
@Override
public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
@@ -487,7 +503,7 @@
return save(saveFlags);
}
- private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
+ private static native int nSaveLayerAlpha(int renderer, float left, float top, float right,
float bottom, int alpha, int saveFlags);
@Override
@@ -495,21 +511,21 @@
nRestore(mRenderer);
}
- private native void nRestore(int renderer);
+ private static native void nRestore(int renderer);
@Override
public void restoreToCount(int saveCount) {
nRestoreToCount(mRenderer, saveCount);
}
- private native void nRestoreToCount(int renderer, int saveCount);
+ private static native void nRestoreToCount(int renderer, int saveCount);
@Override
public int getSaveCount() {
return nGetSaveCount(mRenderer);
}
- private native int nGetSaveCount(int renderer);
+ private static native int nGetSaveCount(int renderer);
///////////////////////////////////////////////////////////////////////////
// Filtering
@@ -538,8 +554,9 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawArc(int renderer, float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, boolean useCenter, int paint);
+ private static native void nDrawArc(int renderer, float left, float top,
+ float right, float bottom, float startAngle, float sweepAngle,
+ boolean useCenter, int paint);
@Override
public void drawARGB(int a, int r, int g, int b) {
@@ -556,7 +573,7 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
+ private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
float left, float top, float right, float bottom, int paint);
@Override
@@ -568,7 +585,7 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawBitmap(
+ private static native void nDrawBitmap(
int renderer, int bitmap, byte[] buffer, float left, float top, int paint);
@Override
@@ -581,7 +598,8 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawBitmap(int renderer, int bitmap, byte[] buff, int matrix, int paint);
+ private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
+ int matrix, int paint);
@Override
public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
@@ -616,7 +634,7 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+ private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float left, float top, float right, float bottom, int paint);
@@ -665,7 +683,7 @@
if (hasColorFilter) nResetModifiers(mRenderer);
}
- private native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
+ private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
int meshWidth, int meshHeight, float[] verts, int vertOffset,
int[] colors, int colorOffset, int paint);
@@ -676,7 +694,8 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
+ private static native void nDrawCircle(int renderer, float cx, float cy,
+ float radius, int paint);
@Override
public void drawColor(int color) {
@@ -688,7 +707,7 @@
nDrawColor(mRenderer, color, mode.nativeInt);
}
- private native void nDrawColor(int renderer, int color, int mode);
+ private static native void nDrawColor(int renderer, int color, int mode);
@Override
public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
@@ -709,7 +728,8 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawLines(int renderer, float[] points, int offset, int count, int paint);
+ private static native void nDrawLines(int renderer, float[] points,
+ int offset, int count, int paint);
@Override
public void drawLines(float[] pts, Paint paint) {
@@ -723,8 +743,8 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawOval(int renderer, float left, float top, float right, float bottom,
- int paint);
+ private static native void nDrawOval(int renderer, float left, float top,
+ float right, float bottom, int paint);
@Override
public void drawPaint(Paint paint) {
@@ -746,8 +766,8 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawPath(int renderer, int path, int paint);
- private native void nDrawRects(int renderer, int region, int paint);
+ private static native void nDrawPath(int renderer, int path, int paint);
+ private static native void nDrawRects(int renderer, int region, int paint);
@Override
public void drawPicture(Picture picture) {
@@ -798,8 +818,8 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawRect(int renderer, float left, float top, float right, float bottom,
- int paint);
+ private static native void nDrawRect(int renderer, float left, float top,
+ float right, float bottom, int paint);
@Override
public void drawRect(Rect r, Paint paint) {
@@ -824,7 +844,7 @@
if (hasModifier) nResetModifiers(mRenderer);
}
- private native void nDrawRoundRect(int renderer, float left, float top,
+ private static native void nDrawRoundRect(int renderer, float left, float top,
float right, float bottom, float rx, float y, int paint);
@Override
@@ -841,8 +861,8 @@
}
}
- private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y,
- int bidiFlags, int paint);
+ private static native void nDrawText(int renderer, char[] text, int index, int count,
+ float x, float y, int bidiFlags, int paint);
@Override
public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
@@ -858,7 +878,8 @@
} else {
char[] buf = TemporaryBuffer.obtain(end - start);
TextUtils.getChars(text, start, end, buf, 0);
- nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint);
+ nDrawText(mRenderer, buf, 0, end - start, x, y,
+ paint.mBidiFlags, paint.mNativePaint);
TemporaryBuffer.recycle(buf);
}
} finally {
@@ -880,8 +901,8 @@
}
}
- private native void nDrawText(int renderer, String text, int start, int end, float x, float y,
- int bidiFlags, int paint);
+ private static native void nDrawText(int renderer, String text, int start, int end,
+ float x, float y, int bidiFlags, int paint);
@Override
public void drawText(String text, float x, float y, Paint paint) {
@@ -924,7 +945,7 @@
}
}
- private native void nDrawTextRun(int renderer, char[] text, int index, int count,
+ private static native void nDrawTextRun(int renderer, char[] text, int index, int count,
int contextIndex, int contextCount, float x, float y, int dir, int nativePaint);
@Override
@@ -958,7 +979,7 @@
}
}
- private native void nDrawTextRun(int renderer, String text, int start, int end,
+ private static native void nDrawTextRun(int renderer, String text, int start, int end,
int contextStart, int contextEnd, float x, float y, int flags, int nativePaint);
@Override
@@ -1001,9 +1022,10 @@
return false;
}
- private native void nSetupShader(int renderer, int shader);
- private native void nSetupColorFilter(int renderer, int colorFilter);
- private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color);
+ private static native void nSetupShader(int renderer, int shader);
+ private static native void nSetupColorFilter(int renderer, int colorFilter);
+ private static native void nSetupShadow(int renderer, float radius,
+ float dx, float dy, int color);
- private native void nResetModifiers(int renderer);
+ private static native void nResetModifiers(int renderer);
}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index a4d36b7..e6fecc8 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Rect;
/**
* Hardware accelerated canvas.
@@ -38,8 +39,10 @@
/**
* Invoked before any drawing operation is performed in this canvas.
+ *
+ * @param dirty The dirty rectangle to update, can be null.
*/
- abstract void onPreDraw();
+ abstract void onPreDraw(Rect dirty);
/**
* Invoked after all drawing operation have been performed.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index c82184a..271fa1a 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -18,6 +18,8 @@
package android.view;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.os.SystemClock;
import android.util.EventLog;
import android.util.Log;
@@ -39,6 +41,16 @@
static final String LOG_TAG = "HardwareRenderer";
/**
+ * Turn on to only refresh the parts of the screen that need updating.
+ */
+ public static final boolean RENDER_DIRTY_REGIONS = true;
+
+ /**
+ * Turn on to draw dirty regions every other frame.
+ */
+ private static final boolean DEBUG_DIRTY_REGION = false;
+
+ /**
* A process can set this flag to false to prevent the use of hardware
* rendering.
*
@@ -108,11 +120,14 @@
/**
* Draws the specified view.
- *
+ *
* @param view The view to draw.
* @param attachInfo AttachInfo tied to the specified view.
+ * @param callbacks Callbacks invoked when drawing happens.
+ * @param dirty The dirty rectangle to update, can be null.
*/
- abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
+ abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ Rect dirty);
/**
* Creates a new display list that can be used to record batches of
@@ -214,6 +229,8 @@
@SuppressWarnings({"deprecation"})
static abstract class GlRenderer extends HardwareRenderer {
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ private static final int EGL_SURFACE_TYPE = 0x3033;
+ private static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
static EGLContext sEglContext;
static EGL10 sEgl;
@@ -226,6 +243,9 @@
GL mGl;
HardwareCanvas mCanvas;
+ int mFrameCount;
+ Paint mDebugPaint;
+
final int mGlVersion;
final boolean mTranslucent;
@@ -412,7 +432,7 @@
if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
int error = sEgl.eglGetError();
if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
- Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+ Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
return null;
}
throw new RuntimeException("createWindowSurface failed "
@@ -427,6 +447,12 @@
throw new RuntimeException("eglMakeCurrent failed "
+ getEGLErrorString(sEgl.eglGetError()));
}
+
+ if (RENDER_DIRTY_REGIONS) {
+ if (!GLES20Canvas.preserveBackBuffer()) {
+ Log.w(LOG_TAG, "Backbuffer cannot be preserved");
+ }
+ }
return sEglContext.getGL();
}
@@ -471,12 +497,12 @@
void setup(int width, int height) {
mCanvas.setViewport(width, height);
}
-
+
boolean canDraw() {
return mGl != null && mCanvas != null;
}
- void onPreDraw() {
+ void onPreDraw(Rect dirty) {
}
void onPostDraw() {
@@ -492,8 +518,14 @@
}
@Override
- void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
+ void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ Rect dirty) {
if (canDraw()) {
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+ dirty = null;
+ }
+
attachInfo.mDrawingTime = SystemClock.uptimeMillis();
attachInfo.mIgnoreDirtyState = true;
view.mPrivateFlags |= View.DRAWN;
@@ -504,10 +536,11 @@
}
if (checkCurrent()) {
- onPreDraw();
+ onPreDraw(dirty);
HardwareCanvas canvas = mCanvas;
attachInfo.mHardwareCanvas = canvas;
+
int saveCount = canvas.save();
callbacks.onHardwarePreDraw(canvas);
@@ -515,6 +548,7 @@
view.mRecreateDisplayList =
(view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED;
view.mPrivateFlags &= ~View.INVALIDATED;
+
DisplayList displayList = view.getDisplayList();
if (displayList != null) {
if (canvas.drawDisplayList(displayList)) {
@@ -524,6 +558,16 @@
// Shouldn't reach here
view.draw(canvas);
}
+
+ if (DEBUG_DIRTY_REGION) {
+ if (mDebugPaint == null) {
+ mDebugPaint = new Paint();
+ mDebugPaint.setColor(0x7fff0000);
+ }
+ if (dirty != null && (mFrameCount++ & 1) == 0) {
+ canvas.drawRect(dirty, mDebugPaint);
+ }
+ }
} finally {
callbacks.onHardwarePostDraw(canvas);
canvas.restoreToCount(saveCount);
@@ -636,6 +680,8 @@
EGL10.EGL_ALPHA_SIZE, alphaSize,
EGL10.EGL_DEPTH_SIZE, depthSize,
EGL10.EGL_STENCIL_SIZE, stencilSize,
+ EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT |
+ (RENDER_DIRTY_REGIONS ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
EGL10.EGL_NONE });
mValue = new int[1];
mRedSize = redSize;
@@ -656,7 +702,16 @@
int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
- if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize) {
+ boolean backBuffer;
+ if (RENDER_DIRTY_REGIONS) {
+ int surfaceType = findConfigAttrib(egl, display, config,
+ EGL_SURFACE_TYPE, 0);
+ backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0;
+ } else {
+ backBuffer = true;
+ }
+ if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize
+ && backBuffer) {
return config;
}
}
@@ -696,8 +751,8 @@
}
@Override
- void onPreDraw() {
- mGlCanvas.onPreDraw();
+ void onPreDraw(Rect dirty) {
+ mGlCanvas.onPreDraw(dirty);
}
@Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8af2549..b073513 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6730,11 +6730,14 @@
mPrivateFlags |= INVALIDATED;
final ViewParent p = mParent;
final AttachInfo ai = mAttachInfo;
- if (p != null && ai != null && ai.mHardwareAccelerated) {
- // fast-track for GL-enabled applications; just invalidate the whole hierarchy
- // with a null dirty rect, which tells the ViewRoot to redraw everything
- p.invalidateChild(this, null);
- return;
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+ if (p != null && ai != null && ai.mHardwareAccelerated) {
+ // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+ // with a null dirty rect, which tells the ViewRoot to redraw everything
+ p.invalidateChild(this, null);
+ return;
+ }
}
if (p != null && ai != null) {
final int scrollX = mScrollX;
@@ -6770,11 +6773,14 @@
mPrivateFlags |= INVALIDATED;
final ViewParent p = mParent;
final AttachInfo ai = mAttachInfo;
- if (p != null && ai != null && ai.mHardwareAccelerated) {
- // fast-track for GL-enabled applications; just invalidate the whole hierarchy
- // with a null dirty rect, which tells the ViewRoot to redraw everything
- p.invalidateChild(this, null);
- return;
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+ if (p != null && ai != null && ai.mHardwareAccelerated) {
+ // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+ // with a null dirty rect, which tells the ViewRoot to redraw everything
+ p.invalidateChild(this, null);
+ return;
+ }
}
if (p != null && ai != null && l < r && t < b) {
final int scrollX = mScrollX;
@@ -6823,11 +6829,14 @@
}
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
- if (p != null && ai != null && ai.mHardwareAccelerated) {
- // fast-track for GL-enabled applications; just invalidate the whole hierarchy
- // with a null dirty rect, which tells the ViewRoot to redraw everything
- p.invalidateChild(this, null);
- return;
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+ if (p != null && ai != null && ai.mHardwareAccelerated) {
+ // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+ // with a null dirty rect, which tells the ViewRoot to redraw everything
+ p.invalidateChild(this, null);
+ return;
+ }
}
if (p != null && ai != null) {
@@ -8101,7 +8110,8 @@
final HardwareCanvas canvas = mHardwareLayer.start(mAttachInfo.mHardwareCanvas);
try {
canvas.setViewport(width, height);
- canvas.onPreDraw();
+ // TODO: We should pass the dirty rect
+ canvas.onPreDraw(null);
computeScroll();
canvas.translate(-mScrollX, -mScrollY);
@@ -8190,7 +8200,7 @@
ViewGroup parent = (ViewGroup) this;
final int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
- final View child = (View) parent.getChildAt(i);
+ final View child = parent.getChildAt(i);
child.outputDirtyFlags(indent + " ", clear, clearMask);
}
}
@@ -8251,7 +8261,8 @@
int height = mBottom - mTop;
canvas.setViewport(width, height);
- canvas.onPreDraw();
+ // The dirty rect should always be null for a display list
+ canvas.onPreDraw(null);
final int restoreCount = canvas.save();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c73cbe6..3703a64 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3527,10 +3527,20 @@
(int) (boundingRect.bottom + 0.5f));
}
+ if (child.mLayerType != LAYER_TYPE_NONE) {
+ mPrivateFlags |= INVALIDATED;
+ mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ }
do {
View view = null;
if (parent instanceof View) {
view = (View) parent;
+ if (view.mLayerType != LAYER_TYPE_NONE &&
+ view.getParent() instanceof View) {
+ final View grandParent = (View) view.getParent();
+ grandParent.mPrivateFlags |= INVALIDATED;
+ grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ }
}
if (drawAnimation) {
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ba671c0..19d7811 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -160,7 +160,9 @@
int mWidth;
int mHeight;
- Rect mDirty; // will be a graphics.Region soon
+ Rect mDirty;
+ final Rect mCurrentDirty = new Rect();
+ final Rect mPreviousDirty = new Rect();
boolean mIsAnimating;
CompatibilityInfo.Translator mTranslator;
@@ -1055,6 +1057,7 @@
disposeResizeBitmap();
} else if (surfaceGenerationId != mSurface.getGenerationId() &&
mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
+ fullRedrawNeeded = true;
mAttachInfo.mHardwareRenderer.updateSurface(mHolder);
}
} catch (RemoteException e) {
@@ -1488,10 +1491,15 @@
if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
if (!dirty.isEmpty() || mIsAnimating) {
mIsAnimating = false;
- dirty.setEmpty();
mHardwareYOffset = yoff;
mResizeAlpha = resizeAlpha;
- mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
+
+ mCurrentDirty.set(dirty);
+ mCurrentDirty.union(mPreviousDirty);
+ mPreviousDirty.set(dirty);
+ dirty.setEmpty();
+
+ mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this, mCurrentDirty);
}
if (animating) {
@@ -1986,6 +1994,7 @@
if (mAttachInfo.mHardwareRenderer != null &&
mSurface != null && mSurface.isValid()) {
+ mFullRedrawNeeded = true;
mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
mAttachInfo, mHolder);
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e4a89d7..9de270d 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "OpenGLRenderer"
+#include <EGL/egl.h>
+
#include "jni.h"
#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
@@ -75,6 +77,23 @@
} gRectClassInfo;
// ----------------------------------------------------------------------------
+// Misc
+// ----------------------------------------------------------------------------
+
+static jboolean android_view_GLES20Canvas_preserveBackBuffer(JNIEnv* env, jobject clazz) {
+ EGLDisplay display = eglGetCurrentDisplay();
+ EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
+
+ eglGetError();
+ eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+ EGLint error = eglGetError();
+ RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
+
+ return error == EGL_SUCCESS;
+}
+
+// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
@@ -97,32 +116,38 @@
// Setup
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jint width, jint height) {
renderer->setViewport(width, height);
}
-static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jboolean opaque) {
renderer->prepare(opaque);
}
-static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas,
+static void 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);
+}
+
+static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->finish();
}
-static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->acquireContext();
}
-static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, Functor *functor) {
return renderer->callDrawGLFunction(functor);
}
-static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->releaseContext();
}
@@ -131,22 +156,22 @@
// State
// ----------------------------------------------------------------------------
-static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
+static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer,
jint flags) {
return renderer->save(flags);
}
-static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
return renderer->getSaveCount();
}
-static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->restore();
}
-static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jint saveCount) {
renderer->restoreToCount(saveCount);
}
@@ -155,13 +180,13 @@
// Layers
// ----------------------------------------------------------------------------
-static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
SkPaint* paint, jint saveFlags) {
return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
}
-static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
jint alpha, jint saveFlags) {
return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
@@ -171,25 +196,25 @@
// Clipping
// ----------------------------------------------------------------------------
-static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
SkCanvas::EdgeType edge) {
return renderer->quickReject(left, top, right, bottom);
}
-static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
SkRegion::Op op) {
return renderer->clipRect(left, top, right, bottom, op);
}
-static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom,
SkRegion::Op op) {
return renderer->clipRect(float(left), float(top), float(right), float(bottom), op);
}
-static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jobject rect) {
const android::uirenderer::Rect& bounds(renderer->getClipBounds());
@@ -203,42 +228,42 @@
// Transforms
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
renderer->translate(dx, dy);
}
-static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat degrees) {
renderer->rotate(degrees);
}
-static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
renderer->scale(sx, sy);
}
-static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
renderer->skew(sx, sy);
}
-static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkMatrix* matrix) {
renderer->setMatrix(matrix);
}
static const float* android_view_GLES20Canvas_getNativeMatrix(JNIEnv* env,
- jobject canvas, OpenGLRenderer* renderer) {
+ jobject clazz, OpenGLRenderer* renderer) {
return renderer->getMatrix();
}
-static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkMatrix* matrix) {
renderer->getMatrix(matrix);
}
-static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkMatrix* matrix) {
renderer->concatMatrix(matrix);
}
@@ -247,7 +272,7 @@
// Drawing
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, float left,
float top, SkPaint* paint) {
// This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -256,7 +281,7 @@
renderer->drawBitmap(bitmap, left, top, paint);
}
-static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
@@ -267,7 +292,7 @@
dstLeft, dstTop, dstRight, dstBottom, paint);
}
-static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix,
SkPaint* paint) {
// This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -276,7 +301,7 @@
renderer->drawBitmap(bitmap, matrix, paint);
}
-static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset,
jintArray colors, jint colorOffset, SkPaint* paint) {
@@ -292,7 +317,7 @@
if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
}
-static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks,
float left, float top, float right, float bottom, SkPaint* paint) {
// This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -309,41 +334,41 @@
env->ReleaseByteArrayElements(chunks, storage, 0);
}
-static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
renderer->drawColor(color, mode);
}
-static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
SkPaint* paint) {
renderer->drawRect(left, top, right, bottom, paint);
}
-static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
jfloat rx, jfloat ry, SkPaint* paint) {
renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
}
-static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
renderer->drawCircle(x, y, radius, paint);
}
-static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
SkPaint* paint) {
renderer->drawOval(left, top, right, bottom, paint);
}
-static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
jfloat startAngle, jfloat sweepAngle, jboolean useCenter, SkPaint* paint) {
renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
}
-static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
SkRegion::Iterator it(*region);
while (!it.done()) {
@@ -353,12 +378,12 @@
}
}
-static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkPath* path, SkPaint* paint) {
renderer->drawPath(path, paint);
}
-static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) {
jfloat* storage = env->GetFloatArrayElements(points, NULL);
@@ -371,24 +396,24 @@
// Shaders and color filters
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->resetShader();
renderer->resetColorFilter();
renderer->resetShadow();
}
-static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkiaShader* shader) {
renderer->setupShader(shader);
}
-static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkiaColorFilter* filter) {
renderer->setupColorFilter(filter);
}
-static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) {
renderer->setupShadow(radius, dx, dy, color);
}
@@ -425,7 +450,7 @@
}
}
-static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
jfloat x, jfloat y, jint flags, SkPaint* paint) {
jchar* textArray = env->GetCharArrayElements(text, NULL);
@@ -433,7 +458,7 @@
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
}
-static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jstring text, jint start, jint end,
jfloat x, jfloat y, jint flags, SkPaint* paint) {
const jchar* textArray = env->GetStringChars(text, NULL);
@@ -441,7 +466,7 @@
env->ReleaseStringChars(text, textArray);
}
-static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
SkPaint* paint) {
@@ -451,7 +476,7 @@
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
}
-static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jstring text, jint start, jint end,
jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
SkPaint* paint) {
@@ -468,7 +493,7 @@
// ----------------------------------------------------------------------------
static DisplayList* android_view_GLES20Canvas_getDisplayList(JNIEnv* env,
- jobject canvas, DisplayListRenderer* renderer) {
+ jobject clazz, DisplayListRenderer* renderer) {
return renderer->getDisplayList();
}
@@ -488,7 +513,7 @@
}
static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
- jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) {
+ jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList) {
return renderer->drawDisplayList(displayList);
}
@@ -496,12 +521,12 @@
// Layers
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->interrupt();
}
-static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->resume();
}
@@ -547,7 +572,7 @@
LayerRenderer::destroyLayerDeferred(layer);
}
-static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
renderer->drawLayer(layer, x, y, paint);
}
@@ -576,16 +601,20 @@
{ "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable },
#ifdef USE_OPENGL_RENDERER
+ { "nPreserveBackBuffer", "()Z", (void*) android_view_GLES20Canvas_preserveBackBuffer },
+
{ "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 },
{ "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish },
{ "nAcquireContext", "(I)V", (void*) android_view_GLES20Canvas_acquireContext },
- { "nCallDrawGLFunction", "(II)Z",
- (void*) android_view_GLES20Canvas_callDrawGLFunction },
{ "nReleaseContext", "(I)V", (void*) android_view_GLES20Canvas_releaseContext },
+ { "nCallDrawGLFunction", "(II)Z",
+ (void*) android_view_GLES20Canvas_callDrawGLFunction },
+
{ "nSave", "(II)I", (void*) android_view_GLES20Canvas_save },
{ "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore },
{ "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount },
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index a768efe..d70fba8 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -629,7 +629,8 @@
mHeight = height;
}
-void DisplayListRenderer::prepare(bool opaque) {
+void DisplayListRenderer::prepareDirty(float left, float top,
+ float right, float bottom, bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSaveCount = 1;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6c8e8f5..bab5149 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,7 +28,7 @@
#include <SkTSearch.h>
#include "OpenGLRenderer.h"
-#include "Functor.h"
+#include "utils/Functor.h"
namespace android {
namespace uirenderer {
@@ -241,7 +241,7 @@
DisplayList* getDisplayList();
void setViewport(int width, int height);
- void prepare(bool opaque);
+ void prepareDirty(float left, float top, float right, float bottom, bool opaque);
void finish();
bool callDrawGLFunction(Functor *functor);
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 1c89577..36709dc 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -26,7 +26,7 @@
// Rendering
///////////////////////////////////////////////////////////////////////////////
-void LayerRenderer::prepare(bool opaque) {
+void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
#if RENDER_LAYERS_AS_REGIONS
@@ -35,7 +35,7 @@
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
- OpenGLRenderer::prepare(opaque);
+ OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque);
}
void LayerRenderer::finish() {
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 1e39847..d2f565e 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -46,7 +46,7 @@
~LayerRenderer() {
}
- void prepare(bool opaque);
+ void prepareDirty(float left, float top, float right, float bottom, bool opaque);
void finish();
bool hasLayer();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 98f8fc5..d343a6f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -136,6 +136,10 @@
}
void OpenGLRenderer::prepare(bool opaque) {
+ prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
+}
+
+void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
mCaches.clearGarbage();
mSnapshot = new Snapshot(mFirstSnapshot,
@@ -146,15 +150,14 @@
glDisable(GL_DITHER);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
+ mSnapshot->setClip(left, top, right, bottom);
+
if (!opaque) {
- glDisable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(0, 0, mWidth, mHeight);
- mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
}
void OpenGLRenderer::finish() {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index bd29609..77de1d2 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -62,7 +62,8 @@
virtual void setViewport(int width, int height);
- virtual void prepare(bool opaque);
+ void prepare(bool opaque);
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
// These two calls must not be recorded in display lists
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 61f8e1a..2895b69 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
package="com.android.test.hwui">
<uses-permission android:name="android.permission.INTERNET" />
- <uses-sdk android:minSdkVersion="Honeycomb" />
+ <uses-sdk android:minSdkVersion="11" />
<application
android:label="HwUi"
diff --git a/tests/HwAccelerationTest/default.properties b/tests/HwAccelerationTest/default.properties
index 5a8ea50..da2dcdd 100644
--- a/tests/HwAccelerationTest/default.properties
+++ b/tests/HwAccelerationTest/default.properties
@@ -8,4 +8,4 @@
# project structure.
# Project target.
-target=android-Froyo
+target=android-Honeycomb