Merge "Fix save()/restore() issues in the OpenGL renderer."
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user