Merge "Fix save()/restore() issues in the OpenGL renderer."

This commit is contained in:
Romain Guy
2010-08-17 18:40:50 -07:00
committed by Android (Google) Code Review
8 changed files with 87 additions and 26 deletions

View File

@@ -385,7 +385,7 @@ public abstract class HardwareRenderer {
onPreDraw();
Canvas canvas = mCanvas;
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
int saveCount = canvas.save();
canvas.translate(0, -yOffset);
try {

View File

@@ -6630,9 +6630,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @see android.widget.ScrollBarDrawable
* @hide
*/
protected void onDrawHorizontalScrollBar(Canvas canvas,
Drawable scrollBar,
int l, int t, int r, int b) {
protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar,
int l, int t, int r, int b) {
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
@@ -6651,9 +6650,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @see android.widget.ScrollBarDrawable
* @hide
*/
protected void onDrawVerticalScrollBar(Canvas canvas,
Drawable scrollBar,
int l, int t, int r, int b) {
protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
int l, int t, int r, int b) {
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
@@ -10018,8 +10016,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
private final float[] mOpaque = {255.0f};
private final float[] mTransparent = {0.0f};
private final float[] mOpaque = { 255.0f };
private final float[] mTransparent = { 0.0f };
/**
* When fading should start. This time moves into the future every time

View File

@@ -1363,7 +1363,6 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
", metrics=" + cxt.getResources().getDisplayMetrics() +
", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
}
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.translate(0, -yoff);
if (mTranslator != null) {
@@ -1374,7 +1373,6 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
mView.draw(canvas);
} finally {
mAttachInfo.mIgnoreDirtyState = false;
canvas.restoreToCount(saveCount);
}
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {

View File

@@ -111,8 +111,7 @@ public class ScrollBarDrawable extends Drawable {
}
Rect r = getBounds();
if (canvas.quickReject(r.left, r.top, r.right, r.bottom,
Canvas.EdgeType.AA)) {
if (canvas.quickReject(r.left, r.top, r.right, r.bottom, Canvas.EdgeType.AA)) {
return;
}
if (drawTrack) {

View File

@@ -193,7 +193,7 @@ void OpenGLRenderer::setViewport(int width, int height) {
void OpenGLRenderer::prepare() {
mSnapshot = new Snapshot(mFirstSnapshot);
mSaveCount = 0;
mSaveCount = 1;
glDisable(GL_SCISSOR_TEST);
@@ -219,19 +219,17 @@ int OpenGLRenderer::save(int flags) {
}
void OpenGLRenderer::restore() {
if (mSaveCount == 0) return;
if (restoreSnapshot()) {
if (mSaveCount > 1 && restoreSnapshot()) {
setScissorFromClip();
}
}
void OpenGLRenderer::restoreToCount(int saveCount) {
if (saveCount <= 0 || saveCount > mSaveCount) return;
if (saveCount < 1) saveCount = 1;
bool restoreClip = false;
while (mSaveCount != saveCount - 1) {
while (mSaveCount > saveCount) {
restoreClip |= restoreSnapshot();
}
@@ -242,7 +240,7 @@ void OpenGLRenderer::restoreToCount(int saveCount) {
int OpenGLRenderer::saveSnapshot() {
mSnapshot = new Snapshot(mSnapshot);
return ++mSaveCount;
return mSaveCount++;
}
bool OpenGLRenderer::restoreSnapshot() {
@@ -263,10 +261,18 @@ bool OpenGLRenderer::restoreSnapshot() {
composeLayer(current, previous);
}
bool skip = mSnapshot->skip;
if (!skip) {
mSaveCount--;
}
mSnapshot = previous;
mSaveCount--;
return restoreClip;
if (!skip) {
return restoreClip;
} else {
bool restorePreviousClip = restoreSnapshot();
return restoreClip || restorePreviousClip;
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -324,18 +330,20 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
// Save the layer in the snapshot
snapshot->flags |= Snapshot::kFlagIsLayer;
layer->mode = mode;
layer->alpha = alpha / 255.0f;
layer->layer.set(left, top, right, bottom);
// Save the layer in the snapshot
snapshot->flags |= Snapshot::kFlagIsLayer;
snapshot->layer = layer;
snapshot->fbo = layer->fbo;
// Creates a new snapshot to draw into the FBO
saveSnapshot();
mSaveCount--;
mSnapshot->skip = true;
mSnapshot->transform.loadTranslate(-left, -top, 0.0f);
mSnapshot->setClip(0.0f, 0.0f, right - left, bottom - top);
mSnapshot->viewport.set(0.0f, 0.0f, right - left, bottom - top);
@@ -432,7 +440,6 @@ const Rect& OpenGLRenderer::getClipBounds() {
bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
Rect r(left, top, right, bottom);
mSnapshot->transform.mapRect(r);
return !mSnapshot->clipRect.intersects(r);
}

View File

@@ -42,7 +42,7 @@ namespace uirenderer {
*/
class Snapshot: public LightRefBase<Snapshot> {
public:
Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) { }
Snapshot(): skip(false), flags(0), previous(NULL), layer(NULL), fbo(0) { }
/**
* Copies the specified snapshot. Only the transform and clip rectangle
@@ -54,6 +54,7 @@ public:
height(s->height),
transform(s->transform),
clipRect(s->clipRect),
skip(false),
flags(0),
previous(s),
layer(NULL),
@@ -164,6 +165,12 @@ public:
*/
Rect clipRect;
/**
* This snapshot should be skipped. Snapshots marked as skipped are
* created by the renderer and should be hidden from the user.
*/
bool skip;
/**
* Dirty flags.
*/

View File

@@ -19,6 +19,31 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="3dip"
android:text="Add" />
<Button
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:layout_marginLeft="3dip"
android:layout_marginRight="10dip"
android:text="Remove" />
</LinearLayout>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"

View File

@@ -23,6 +23,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
@SuppressWarnings({"UnusedDeclaration"})
@@ -51,6 +52,32 @@ public class QuickRejectActivity extends Activity {
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "count=" + count);
count = canvas.save();
Log.d("OpenGLRenderer", "count after save=" + count);
count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "getSaveCount after save=" + count);
canvas.restore();
count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "count after restore=" + count);
canvas.save();
Log.d("OpenGLRenderer", "count after save=" + canvas.getSaveCount());
canvas.save();
Log.d("OpenGLRenderer", "count after save=" + canvas.getSaveCount());
canvas.save();
Log.d("OpenGLRenderer", "count after save=" + canvas.getSaveCount());
canvas.restoreToCount(count);
count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "count after restoreToCount=" + count);
count = canvas.saveLayer(0, 0, 10, 10, mBitmapPaint, Canvas.ALL_SAVE_FLAG);
Log.d("OpenGLRenderer", "count after saveLayer=" + count);
count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "getSaveCount after saveLayer=" + count);
canvas.restore();
count = canvas.getSaveCount();
Log.d("OpenGLRenderer", "count after restore=" + count);
canvas.save();
canvas.clipRect(0.0f, 0.0f, 40.0f, 40.0f);
canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mBitmapPaint);