Merge "Use optimized display lists for all hwaccelerated rendering" into honeycomb
This commit is contained in:
@@ -34,15 +34,16 @@ import java.util.List;
|
||||
* custom animations, use the {@link LayoutTransition#setAnimator(int, Animator)
|
||||
* setAnimator()} method.
|
||||
*
|
||||
* <p>One of the core concepts of these transition animations is that there are two core
|
||||
* <p>One of the core concepts of these transition animations is that there are two types of
|
||||
* changes that cause the transition and four different animations that run because of
|
||||
* those changes. The changes that trigger the transition are items being added to a container
|
||||
* (referred to as an "appearing" transition) or removed from a container (also known as
|
||||
* "disappearing"). The animations that run due to those events are one that animates
|
||||
* "disappearing"). Setting the visibility of views (between GONE and VISIBLE) will trigger
|
||||
* the same add/remove logic. The animations that run due to those events are one that animates
|
||||
* items being added, one that animates items being removed, and two that animate the other
|
||||
* items in the container that change due to the add/remove occurrence. Users of
|
||||
* the transition may want different animations for the changing items depending on whether
|
||||
* they are changing due to anappearing or disappearing event, so there is one animation for
|
||||
* they are changing due to an appearing or disappearing event, so there is one animation for
|
||||
* each of these variations of the changing event. Most of the API of this class is concerned
|
||||
* with setting up the basic properties of the animations used in these four situations,
|
||||
* or with setting up custom animations for any or all of the four.</p>
|
||||
@@ -62,6 +63,18 @@ import java.util.List;
|
||||
* values when the transition begins. Custom animations will be similarly populated with
|
||||
* the target and values being animated, assuming they use ObjectAnimator objects with
|
||||
* property names that are known on the target object.</p>
|
||||
*
|
||||
* <p>This class, and the associated XML flag for containers, animateLayoutChanges="true",
|
||||
* provides a simple utility meant for automating changes in straightforward situations.
|
||||
* Using LayoutTransition at multiple levels of a nested view hierarchy may not work due to the
|
||||
* interrelationship of the various levels of layout. Also, a container that is being scrolled
|
||||
* at the same time as items are being added or removed is probably not a good candidate for
|
||||
* this utility, because the before/after locations calculated by LayoutTransition
|
||||
* may not match the actual locations when the animations finish due to the container
|
||||
* being scrolled as the animations are running. You can work around that
|
||||
* particular issue by disabling the 'changing' animations by setting the CHANGE_APPEARING
|
||||
* and CHANGE_DISAPPEARING animations to null, and setting the startDelay of the
|
||||
* other animations appropriately.</p>
|
||||
*/
|
||||
public class LayoutTransition {
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@ package android.view;
|
||||
* them later. Display lists are usually built by recording operations on a
|
||||
* {@link android.graphics.Canvas}. Replaying the operations from a display list
|
||||
* avoids executing views drawing code on every frame, and is thus much more
|
||||
* efficient.
|
||||
* efficient.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
abstract class DisplayList {
|
||||
public abstract class DisplayList {
|
||||
/**
|
||||
* Starts recording the display list. All operations performed on the
|
||||
* returned canvas are recorded and stored in this display list.
|
||||
|
||||
@@ -219,6 +219,13 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
private native void nAcquireContext(int renderer);
|
||||
|
||||
@Override
|
||||
public boolean callDrawGLFunction(int drawGLFunction) {
|
||||
return nCallDrawGLFunction(mRenderer, drawGLFunction);
|
||||
}
|
||||
|
||||
private native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
|
||||
|
||||
@Override
|
||||
public void releaseContext() {
|
||||
if (mContextLocked) {
|
||||
@@ -246,11 +253,11 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
private static native void nDestroyDisplayList(int displayList);
|
||||
|
||||
@Override
|
||||
public void drawDisplayList(DisplayList displayList) {
|
||||
nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
|
||||
public boolean drawDisplayList(DisplayList displayList) {
|
||||
return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
|
||||
}
|
||||
|
||||
private native void nDrawDisplayList(int renderer, int displayList);
|
||||
private native boolean nDrawDisplayList(int renderer, int displayList);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Hardware layer
|
||||
@@ -306,7 +313,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
@Override
|
||||
public boolean clipRect(int left, int top, int right, int bottom) {
|
||||
return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
|
||||
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);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* An implementation of display list for OpenGL ES 2.0.
|
||||
*/
|
||||
@@ -27,12 +29,24 @@ class GLES20DisplayList extends DisplayList {
|
||||
private boolean mValid = false;
|
||||
|
||||
int mNativeDisplayList;
|
||||
WeakReference<View> hostView;
|
||||
|
||||
// The native display list will be destroyed when this object dies.
|
||||
// DO NOT overwrite this reference once it is set.
|
||||
@SuppressWarnings("unused")
|
||||
private DisplayListFinalizer mFinalizer;
|
||||
|
||||
public GLES20DisplayList(View view) {
|
||||
hostView = new WeakReference<View>(view);
|
||||
}
|
||||
|
||||
public void invalidateView() {
|
||||
View v = hostView.get();
|
||||
if (v != null) {
|
||||
v.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
HardwareCanvas start() {
|
||||
if (mStarted) {
|
||||
|
||||
@@ -21,9 +21,11 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
/**
|
||||
* Hardware accelerated canvas.
|
||||
* Hardware accelerated canvas.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
abstract class HardwareCanvas extends Canvas {
|
||||
public abstract class HardwareCanvas extends Canvas {
|
||||
@Override
|
||||
public boolean isHardwareAccelerated() {
|
||||
return true;
|
||||
@@ -49,7 +51,7 @@ abstract class HardwareCanvas extends Canvas {
|
||||
*
|
||||
* @param displayList The display list to replay.
|
||||
*/
|
||||
abstract void drawDisplayList(DisplayList displayList);
|
||||
abstract boolean drawDisplayList(DisplayList displayList);
|
||||
|
||||
/**
|
||||
* Draws the specified layer onto this canvas.
|
||||
@@ -59,5 +61,18 @@ abstract class HardwareCanvas extends Canvas {
|
||||
* @param y The top coordinate of the layer
|
||||
* @param paint The paint used to draw the layer
|
||||
*/
|
||||
abstract void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint);
|
||||
abstract void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint);
|
||||
|
||||
/**
|
||||
* Calls the function specified with the drawGLFunction function pointer. This is
|
||||
* functionality used by webkit for calling into their renderer from our display lists.
|
||||
* This function may return true if an invalidation is needed after the call.
|
||||
*
|
||||
* @param drawGLFunction A native function pointer
|
||||
* @return true if an invalidate is needed after the call, false otherwise
|
||||
*/
|
||||
public boolean callDrawGLFunction(int drawGLFunction) {
|
||||
// Noop - this is done in the display list recorder subclass
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public abstract class HardwareRenderer {
|
||||
*
|
||||
* @return A new display list.
|
||||
*/
|
||||
abstract DisplayList createDisplayList();
|
||||
abstract DisplayList createDisplayList(View v);
|
||||
|
||||
/**
|
||||
* Creates a new hardware layer.
|
||||
@@ -506,19 +506,32 @@ public abstract class HardwareRenderer {
|
||||
if (checkCurrent()) {
|
||||
onPreDraw();
|
||||
|
||||
Canvas canvas = mCanvas;
|
||||
HardwareCanvas canvas = mCanvas;
|
||||
attachInfo.mHardwareCanvas = canvas;
|
||||
int saveCount = canvas.save();
|
||||
callbacks.onHardwarePreDraw(canvas);
|
||||
|
||||
|
||||
try {
|
||||
view.draw(canvas);
|
||||
view.mRecreateDisplayList =
|
||||
(view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED;
|
||||
view.mPrivateFlags &= ~View.INVALIDATED;
|
||||
DisplayList displayList = view.getDisplayList();
|
||||
if (displayList != null) {
|
||||
if (canvas.drawDisplayList(displayList)) {
|
||||
view.invalidate();
|
||||
}
|
||||
} else {
|
||||
// Shouldn't reach here
|
||||
view.draw(canvas);
|
||||
}
|
||||
} finally {
|
||||
callbacks.onHardwarePostDraw(canvas);
|
||||
canvas.restoreToCount(saveCount);
|
||||
view.mRecreateDisplayList = false;
|
||||
}
|
||||
|
||||
|
||||
onPostDraw();
|
||||
|
||||
|
||||
if (ViewDebug.DEBUG_PROFILE_DRAWING) {
|
||||
EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
|
||||
}
|
||||
@@ -704,8 +717,8 @@ public abstract class HardwareRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
DisplayList createDisplayList() {
|
||||
return new GLES20DisplayList();
|
||||
DisplayList createDisplayList(View v) {
|
||||
return new GLES20DisplayList(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1508,6 +1508,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
@ViewDebug.ExportedProperty(category = "measurement")
|
||||
/*package*/ int mMeasuredHeight;
|
||||
|
||||
/**
|
||||
* Flag to indicate that this view was marked INVALIDATED, or had its display list
|
||||
* invalidated, prior to the current drawing iteration. If true, the view must re-draw
|
||||
* its display list. This flag, used only when hw accelerated, allows us to clear the
|
||||
* flag while retaining this information until it's needed (at getDisplayList() time and
|
||||
* in drawChild(), when we decide to draw a view's children's display lists into our own).
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
boolean mRecreateDisplayList = false;
|
||||
|
||||
/**
|
||||
* The view's identifier.
|
||||
* {@hide}
|
||||
@@ -1671,6 +1682,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
/** {@hide} */
|
||||
static final int ACTIVATED = 0x40000000;
|
||||
|
||||
/**
|
||||
* Indicates that this view was specifically invalidated, not just dirtied because some
|
||||
* child view was invalidated. The flag is used to determine when we need to recreate
|
||||
* a view's display list (as opposed to just returning a reference to its existing
|
||||
* display list).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
static final int INVALIDATED = 0x80000000;
|
||||
|
||||
/**
|
||||
* Always allow a user to over-scroll this view, provided it is a
|
||||
* view that can scroll.
|
||||
@@ -5295,6 +5316,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
if ((changed & VISIBILITY_MASK) != 0) {
|
||||
if (mParent instanceof ViewGroup) {
|
||||
((ViewGroup)mParent).onChildVisibilityChanged(this, (flags & VISIBILITY_MASK));
|
||||
((View) mParent).invalidate();
|
||||
}
|
||||
dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
|
||||
}
|
||||
@@ -5306,6 +5328,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
if ((changed & DRAWING_CACHE_ENABLED) != 0) {
|
||||
destroyDrawingCache();
|
||||
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
|
||||
if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
|
||||
@@ -5666,6 +5689,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5699,6 +5723,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5732,6 +5757,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5767,6 +5793,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5802,6 +5829,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5843,6 +5871,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5883,6 +5912,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5922,6 +5952,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mPrivateFlags &= ~ALPHA_SET;
|
||||
invalidate(false);
|
||||
}
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6241,6 +6272,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6274,6 +6306,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMatrixDirty = true;
|
||||
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
|
||||
invalidate(false);
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6490,6 +6523,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
int oldY = mScrollY;
|
||||
mScrollX = x;
|
||||
mScrollY = y;
|
||||
invalidateParentIfAccelerated();
|
||||
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
|
||||
if (!awakenScrollBars()) {
|
||||
invalidate();
|
||||
@@ -6690,8 +6724,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
}
|
||||
|
||||
if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
|
||||
(mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
|
||||
(mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID ||
|
||||
(mPrivateFlags & INVALIDATED) != INVALIDATED) {
|
||||
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
||||
mPrivateFlags |= INVALIDATED;
|
||||
final ViewParent p = mParent;
|
||||
final AttachInfo ai = mAttachInfo;
|
||||
if (p != null && ai != null && ai.mHardwareAccelerated) {
|
||||
@@ -6728,8 +6764,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
}
|
||||
|
||||
if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
|
||||
(mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
|
||||
(mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID ||
|
||||
(mPrivateFlags & INVALIDATED) != INVALIDATED) {
|
||||
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
||||
mPrivateFlags |= INVALIDATED;
|
||||
final ViewParent p = mParent;
|
||||
final AttachInfo ai = mAttachInfo;
|
||||
if (p != null && ai != null && ai.mHardwareAccelerated) {
|
||||
@@ -6776,10 +6814,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
boolean opaque = isOpaque();
|
||||
if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
|
||||
(invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) ||
|
||||
opaque != mLastIsOpaque) {
|
||||
opaque != mLastIsOpaque || (mPrivateFlags & INVALIDATED) != INVALIDATED) {
|
||||
mLastIsOpaque = opaque;
|
||||
mPrivateFlags &= ~DRAWN;
|
||||
if (invalidateCache) {
|
||||
mPrivateFlags |= INVALIDATED;
|
||||
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
||||
}
|
||||
final AttachInfo ai = mAttachInfo;
|
||||
@@ -6801,6 +6840,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to indicate that the parent of this view should be invalidated. This functionality
|
||||
* is used to force the parent to rebuild its display list (when hardware-accelerated),
|
||||
* which is necessary when various parent-managed properties of the view change, such as
|
||||
* alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
protected void invalidateParentIfAccelerated() {
|
||||
if (isHardwareAccelerated() && mParent instanceof View) {
|
||||
((View) mParent).invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this View is opaque. An opaque View guarantees that it will
|
||||
* draw all the pixels overlapping its bounds using a fully opaque color.
|
||||
@@ -7630,6 +7683,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mHardwareLayer = null;
|
||||
}
|
||||
|
||||
if (mDisplayList != null) {
|
||||
mDisplayList.invalidate();
|
||||
}
|
||||
|
||||
if (mAttachInfo != null) {
|
||||
mAttachInfo.mHandler.removeMessages(AttachInfo.INVALIDATE_MSG, this);
|
||||
mAttachInfo.mHandler.removeMessages(AttachInfo.INVALIDATE_RECT_MSG, this);
|
||||
@@ -7953,7 +8010,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
|
||||
+ "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
|
||||
}
|
||||
|
||||
|
||||
if (layerType == mLayerType) {
|
||||
if (layerType != LAYER_TYPE_NONE && paint != mLayerPaint) {
|
||||
mLayerPaint = paint == null ? new Paint() : paint;
|
||||
@@ -8041,7 +8098,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mHardwareLayer.resize(width, height);
|
||||
}
|
||||
|
||||
final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas);
|
||||
final HardwareCanvas canvas = mHardwareLayer.start(mAttachInfo.mHardwareCanvas);
|
||||
try {
|
||||
canvas.setViewport(width, height);
|
||||
canvas.onPreDraw();
|
||||
@@ -8064,7 +8121,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
canvas.restoreToCount(restoreCount);
|
||||
} finally {
|
||||
canvas.onPostDraw();
|
||||
mHardwareLayer.end(currentCanvas);
|
||||
mHardwareLayer.end(mAttachInfo.mHardwareCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8081,9 +8138,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
*
|
||||
* <p>Enabling the drawing cache is similar to
|
||||
* {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
|
||||
* acceleration is turned off. When hardware acceleration is turned on enabling the
|
||||
* drawing cache has either no effect or the cache used at drawing time is not a bitmap.
|
||||
* This API can however be used to manually generate a bitmap copy of this view.</p>
|
||||
* acceleration is turned off. When hardware acceleration is turned on, enabling the
|
||||
* drawing cache has no effect on rendering because the system uses a different mechanism
|
||||
* for acceleration which ignores the flag. If you want to use a Bitmap for the view, even
|
||||
* when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)}
|
||||
* for information on how to enable software and hardware layers.</p>
|
||||
*
|
||||
* <p>This API can be used to manually generate
|
||||
* a bitmap copy of this view, by setting the flag to <code>true</code> and calling
|
||||
* {@link #getDrawingCache()}.</p>
|
||||
*
|
||||
* @param enabled true to enable the drawing cache, false otherwise
|
||||
*
|
||||
@@ -8109,26 +8172,77 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging utility which recursively outputs the dirty state of a view and its
|
||||
* descendants.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
|
||||
Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.DIRTY_MASK) +
|
||||
") DRAWN(" + (mPrivateFlags & DRAWN) + ")" + " CACHE_VALID(" +
|
||||
(mPrivateFlags & View.DRAWING_CACHE_VALID) +
|
||||
") INVALIDATED(" + (mPrivateFlags & INVALIDATED) + ")");
|
||||
if (clear) {
|
||||
mPrivateFlags &= clearMask;
|
||||
}
|
||||
if (this instanceof ViewGroup) {
|
||||
ViewGroup parent = (ViewGroup) this;
|
||||
final int count = parent.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = (View) parent.getChildAt(i);
|
||||
child.outputDirtyFlags(indent + " ", clear, clearMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used by ViewGroup to cause its children to restore or recreate their
|
||||
* display lists. It is called by getDisplayList() when the parent ViewGroup does not need
|
||||
* to recreate its own display list, which would happen if it went through the normal
|
||||
* draw/dispatchDraw mechanisms.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
protected void dispatchGetDisplayList() {}
|
||||
|
||||
/**
|
||||
* <p>Returns a display list that can be used to draw this view again
|
||||
* without executing its draw method.</p>
|
||||
*
|
||||
* @return A DisplayList ready to replay, or null if caching is not enabled.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
DisplayList getDisplayList() {
|
||||
if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
|
||||
return null;
|
||||
}
|
||||
public DisplayList getDisplayList() {
|
||||
if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED &&
|
||||
((mPrivateFlags & DRAWING_CACHE_VALID) == 0 ||
|
||||
mDisplayList == null || !mDisplayList.isValid())) {
|
||||
if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 ||
|
||||
mDisplayList == null || !mDisplayList.isValid() ||
|
||||
mRecreateDisplayList)) {
|
||||
// Don't need to recreate the display list, just need to tell our
|
||||
// children to restore/recreate theirs
|
||||
if (mDisplayList != null && mDisplayList.isValid() &&
|
||||
!mRecreateDisplayList) {
|
||||
mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
|
||||
mPrivateFlags &= ~DIRTY_MASK;
|
||||
dispatchGetDisplayList();
|
||||
|
||||
return mDisplayList;
|
||||
}
|
||||
|
||||
// If we got here, we're recreating it. Mark it as such to ensure that
|
||||
// we copy in child display lists into ours in drawChild()
|
||||
mRecreateDisplayList = true;
|
||||
|
||||
if (mDisplayList == null) {
|
||||
mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList();
|
||||
mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(this);
|
||||
// If we're creating a new display list, make sure our parent gets invalidated
|
||||
// since they will need to recreate their display list to account for this
|
||||
// new child display list.
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
|
||||
final HardwareCanvas canvas = mDisplayList.start();
|
||||
@@ -8141,6 +8255,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
|
||||
final int restoreCount = canvas.save();
|
||||
|
||||
computeScroll();
|
||||
canvas.translate(-mScrollX, -mScrollY);
|
||||
mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
|
||||
|
||||
// Fast path for layouts with no backgrounds
|
||||
@@ -8229,9 +8345,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mUnscaledDrawingCache.recycle();
|
||||
mUnscaledDrawingCache = null;
|
||||
}
|
||||
if (mDisplayList != null) {
|
||||
mDisplayList.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10480,6 +10593,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
|
||||
setAnimation(animation);
|
||||
invalidate();
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10490,6 +10604,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mCurrentAnimation.detach();
|
||||
}
|
||||
mCurrentAnimation = null;
|
||||
invalidateParentIfAccelerated();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -11495,6 +11610,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
|
||||
final Callbacks mRootCallbacks;
|
||||
|
||||
Canvas mHardwareCanvas;
|
||||
|
||||
/**
|
||||
* The top view of the hierarchy.
|
||||
*/
|
||||
|
||||
@@ -998,22 +998,27 @@ public class ViewDebug {
|
||||
new ViewOperation<Object>() {
|
||||
public Object[] pre() {
|
||||
final DisplayMetrics metrics =
|
||||
view.getResources().getDisplayMetrics();
|
||||
final Bitmap bitmap =
|
||||
(view != null && view.getResources() != null) ?
|
||||
view.getResources().getDisplayMetrics() : null;
|
||||
final Bitmap bitmap = metrics != null ?
|
||||
Bitmap.createBitmap(metrics.widthPixels,
|
||||
metrics.heightPixels, Bitmap.Config.RGB_565);
|
||||
final Canvas canvas = new Canvas(bitmap);
|
||||
metrics.heightPixels, Bitmap.Config.RGB_565) : null;
|
||||
final Canvas canvas = bitmap != null ? new Canvas(bitmap) : null;
|
||||
return new Object[] {
|
||||
bitmap, canvas
|
||||
};
|
||||
}
|
||||
|
||||
public void run(Object... data) {
|
||||
view.draw((Canvas) data[1]);
|
||||
if (data[1] != null) {
|
||||
view.draw((Canvas) data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public void post(Object... data) {
|
||||
((Bitmap) data[0]).recycle();
|
||||
if (data[0] != null) {
|
||||
((Bitmap) data[0]).recycle();
|
||||
}
|
||||
}
|
||||
}) : 0;
|
||||
out.write(String.valueOf(durationMeasure));
|
||||
|
||||
@@ -2205,6 +2205,27 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to cause children of this ViewGroup to restore or recreate their
|
||||
* display lists. It is called by getDisplayList() when the parent ViewGroup does not need
|
||||
* to recreate its own display list, which would happen if it went through the normal
|
||||
* draw/dispatchDraw mechanisms.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
protected void dispatchGetDisplayList() {
|
||||
final int count = mChildrenCount;
|
||||
final View[] children = mChildren;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = children[i];
|
||||
child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED;
|
||||
child.mPrivateFlags &= ~INVALIDATED;
|
||||
child.getDisplayList();
|
||||
child.mRecreateDisplayList = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw one child of this View Group. This method is responsible for getting
|
||||
* the canvas in the right state. This includes clipping, translating so
|
||||
@@ -2247,7 +2268,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
caching = true;
|
||||
if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
|
||||
} else {
|
||||
caching = layerType != LAYER_TYPE_NONE;
|
||||
caching = (layerType != LAYER_TYPE_NONE) || canvas.isHardwareAccelerated();
|
||||
}
|
||||
|
||||
if (a != null) {
|
||||
@@ -2329,6 +2350,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
return more;
|
||||
}
|
||||
|
||||
if (canvas.isHardwareAccelerated()) {
|
||||
// Clear INVALIDATED flag to allow invalidation to occur during rendering, but
|
||||
// retain the flag's value temporarily in the mRecreateDisplayList flag
|
||||
child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED;
|
||||
child.mPrivateFlags &= ~INVALIDATED;
|
||||
}
|
||||
|
||||
child.computeScroll();
|
||||
|
||||
final int sx = child.mScrollX;
|
||||
@@ -2347,7 +2375,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
if (layerType == LAYER_TYPE_SOFTWARE) {
|
||||
child.buildDrawingCache(true);
|
||||
cache = child.getDrawingCache(true);
|
||||
} else {
|
||||
} else if (layerType == LAYER_TYPE_NONE) {
|
||||
displayList = child.getDisplayList();
|
||||
}
|
||||
}
|
||||
@@ -2357,7 +2385,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
final boolean hasNoCache = cache == null || hasDisplayList;
|
||||
|
||||
final int restoreTo = canvas.save();
|
||||
if (hasNoCache) {
|
||||
if (cache == null && !hasDisplayList) {
|
||||
canvas.translate(cl - sx, ct - sy);
|
||||
} else {
|
||||
canvas.translate(cl, ct);
|
||||
@@ -2375,7 +2403,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
int transX = 0;
|
||||
int transY = 0;
|
||||
|
||||
if (hasNoCache) {
|
||||
if (cache == null && !hasDisplayList) {
|
||||
transX = -sx;
|
||||
transY = -sy;
|
||||
}
|
||||
@@ -2435,10 +2463,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
}
|
||||
|
||||
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
|
||||
if (hasNoCache) {
|
||||
if (cache == null && !hasDisplayList) {
|
||||
canvas.clipRect(sx, sy, sx + (cr - cl), sy + (cb - ct));
|
||||
} else {
|
||||
if (!scalingRequired) {
|
||||
if (!scalingRequired || cache == null) {
|
||||
canvas.clipRect(0, 0, cr - cl, cb - ct);
|
||||
} else {
|
||||
canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
|
||||
@@ -2473,7 +2501,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
}
|
||||
} else {
|
||||
child.mPrivateFlags &= ~DIRTY_MASK;
|
||||
((HardwareCanvas) canvas).drawDisplayList(displayList);
|
||||
// Skip drawing the display list into ours if we were just refreshing
|
||||
// it's content; we already have a reference to it in our display list
|
||||
if (mRecreateDisplayList || mLayerType != LAYER_TYPE_NONE) {
|
||||
((HardwareCanvas) canvas).drawDisplayList(displayList);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cache != null) {
|
||||
@@ -2503,6 +2535,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
finishAnimatingView(child, a);
|
||||
}
|
||||
|
||||
if (more && canvas.isHardwareAccelerated()) {
|
||||
// invalidation is the trigger to recreate display lists, so if we're using
|
||||
// display lists to render, force an invalidate to allow the animation to
|
||||
// continue drawing another frame
|
||||
invalidate();
|
||||
}
|
||||
|
||||
child.mRecreateDisplayList = false;
|
||||
|
||||
return more;
|
||||
}
|
||||
|
||||
@@ -2743,7 +2784,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
// addViewInner() will call child.requestLayout() when setting the new LayoutParams
|
||||
// therefore, we call requestLayout() on ourselves before, so that the child's request
|
||||
// will be blocked at our level
|
||||
child.mPrivateFlags &= ~DIRTY_MASK;
|
||||
requestLayout();
|
||||
invalidate();
|
||||
addViewInner(child, index, params, false);
|
||||
@@ -3425,10 +3465,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION;
|
||||
|
||||
if (dirty == null) {
|
||||
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 ((view.mPrivateFlags & DIRTY_MASK) != 0) {
|
||||
// already marked dirty - we're done
|
||||
break;
|
||||
|
||||
@@ -597,7 +597,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
dirty.inset(-1, -1);
|
||||
}
|
||||
}
|
||||
if (!mDirty.isEmpty()) {
|
||||
if (!mDirty.isEmpty() && !mDirty.contains(dirty)) {
|
||||
mAttachInfo.mIgnoreDirtyState = true;
|
||||
}
|
||||
mDirty.union(dirty);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.webkit;
|
||||
|
||||
import android.view.HardwareCanvas;
|
||||
import com.android.internal.R;
|
||||
|
||||
import android.annotation.Widget;
|
||||
@@ -353,7 +354,7 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
private ZoomManager mZoomManager;
|
||||
|
||||
private Rect mGLRectViewport;
|
||||
private Rect mGLRectViewport = new Rect();
|
||||
|
||||
/**
|
||||
* Transportation object for returning WebView across thread boundaries.
|
||||
@@ -4079,20 +4080,8 @@ public class WebView extends AbsoluteLayout
|
||||
}
|
||||
|
||||
if (canvas.isHardwareAccelerated()) {
|
||||
try {
|
||||
if (canvas.acquireContext()) {
|
||||
Rect rect = new Rect(mGLRectViewport.left,
|
||||
mGLRectViewport.top,
|
||||
mGLRectViewport.right,
|
||||
mGLRectViewport.bottom
|
||||
- getVisibleTitleHeight());
|
||||
if (nativeDrawGL(rect, getScale(), extras)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
canvas.releaseContext();
|
||||
}
|
||||
int functor = nativeGetDrawGLFunction(mGLRectViewport, getScale(), extras);
|
||||
((HardwareCanvas) canvas).callDrawGLFunction(functor);
|
||||
} else {
|
||||
DrawFilter df = null;
|
||||
if (mZoomManager.isZoomAnimating() || UIAnimationsRunning) {
|
||||
@@ -5163,7 +5152,6 @@ public class WebView extends AbsoluteLayout
|
||||
if (mNativeClass != 0) {
|
||||
nativeRecordButtons(false, false, true);
|
||||
}
|
||||
setFocusControllerActive(false);
|
||||
}
|
||||
mGotKeyDown = false;
|
||||
}
|
||||
@@ -5173,18 +5161,16 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
void setGLRectViewport() {
|
||||
// Use the getGlobalVisibleRect() to get the intersection among the parents
|
||||
Rect webViewRect = new Rect();
|
||||
boolean visible = getGlobalVisibleRect(webViewRect);
|
||||
getGlobalVisibleRect(mGLRectViewport);
|
||||
|
||||
// Then need to invert the Y axis, just for GL
|
||||
View rootView = getRootView();
|
||||
int rootViewHeight = rootView.getHeight();
|
||||
int savedWebViewBottom = webViewRect.bottom;
|
||||
webViewRect.bottom = rootViewHeight - webViewRect.top;
|
||||
webViewRect.top = rootViewHeight - savedWebViewBottom;
|
||||
int savedWebViewBottom = mGLRectViewport.bottom;
|
||||
mGLRectViewport.bottom = rootViewHeight - mGLRectViewport.top - getVisibleTitleHeight();
|
||||
mGLRectViewport.top = rootViewHeight - savedWebViewBottom;
|
||||
|
||||
// Store the viewport
|
||||
mGLRectViewport = webViewRect;
|
||||
nativeUpdateDrawGLFunction(mGLRectViewport);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8239,6 +8225,8 @@ public class WebView extends AbsoluteLayout
|
||||
boolean splitIfNeeded);
|
||||
private native void nativeDumpDisplayTree(String urlOrNull);
|
||||
private native boolean nativeEvaluateLayersAnimations();
|
||||
private native int nativeGetDrawGLFunction(Rect rect, float scale, int extras);
|
||||
private native void nativeUpdateDrawGLFunction(Rect rect);
|
||||
private native boolean nativeDrawGL(Rect rect, float scale, int extras);
|
||||
private native void nativeExtendSelection(int x, int y);
|
||||
private native int nativeFindAll(String findLower, String findUpper,
|
||||
|
||||
@@ -2357,6 +2357,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
if (mScrollY != 0) {
|
||||
mScrollY = 0;
|
||||
invalidateParentIfAccelerated();
|
||||
finishGlows();
|
||||
invalidate();
|
||||
}
|
||||
@@ -2733,6 +2734,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
if (mScrollY != 0) {
|
||||
mScrollY = 0;
|
||||
invalidateParentIfAccelerated();
|
||||
finishGlows();
|
||||
invalidate();
|
||||
}
|
||||
@@ -2951,6 +2953,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
// Coming back to 'real' list scrolling
|
||||
incrementalDeltaY = -newScroll;
|
||||
mScrollY = 0;
|
||||
invalidateParentIfAccelerated();
|
||||
|
||||
// No need to do all this work if we're not going to move anyway
|
||||
if (incrementalDeltaY != 0) {
|
||||
@@ -3244,6 +3247,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
protected void onOverScrolled(int scrollX, int scrollY,
|
||||
boolean clampedX, boolean clampedY) {
|
||||
mScrollY = scrollY;
|
||||
invalidateParentIfAccelerated();
|
||||
|
||||
if (clampedY) {
|
||||
// Velocity is broken by hitting the limit; don't start a fling off of this.
|
||||
|
||||
@@ -647,6 +647,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
if (!mScroller.isFinished()) {
|
||||
mScrollX = scrollX;
|
||||
mScrollY = scrollY;
|
||||
invalidateParentIfAccelerated();
|
||||
if (clampedX) {
|
||||
mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
|
||||
}
|
||||
|
||||
@@ -644,6 +644,7 @@ public class ScrollView extends FrameLayout {
|
||||
if (!mScroller.isFinished()) {
|
||||
mScrollX = scrollX;
|
||||
mScrollY = scrollY;
|
||||
invalidateParentIfAccelerated();
|
||||
if (clampedY) {
|
||||
mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
|
||||
}
|
||||
|
||||
@@ -6272,6 +6272,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
if (mScroller.computeScrollOffset()) {
|
||||
mScrollX = mScroller.getCurrX();
|
||||
mScrollY = mScroller.getCurrY();
|
||||
invalidateParentIfAccelerated();
|
||||
postInvalidate(); // So we draw again
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas
|
||||
renderer->acquireContext();
|
||||
}
|
||||
|
||||
static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject canvas,
|
||||
OpenGLRenderer* renderer, Functor *functor) {
|
||||
return renderer->callDrawGLFunction(functor);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas,
|
||||
OpenGLRenderer* renderer) {
|
||||
renderer->releaseContext();
|
||||
@@ -482,9 +487,9 @@ static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env,
|
||||
delete displayList;
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
|
||||
static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
|
||||
jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) {
|
||||
renderer->drawDisplayList(displayList);
|
||||
return renderer->drawDisplayList(displayList);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -577,6 +582,8 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nPrepare", "(IZ)V", (void*) android_view_GLES20Canvas_prepare },
|
||||
{ "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 },
|
||||
|
||||
{ "nSave", "(II)I", (void*) android_view_GLES20Canvas_save },
|
||||
@@ -639,7 +646,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nGetDisplayList", "(I)I", (void*) android_view_GLES20Canvas_getDisplayList },
|
||||
{ "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
|
||||
{ "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer },
|
||||
{ "nDrawDisplayList", "(II)V", (void*) android_view_GLES20Canvas_drawDisplayList },
|
||||
{ "nDrawDisplayList", "(II)Z", (void*) android_view_GLES20Canvas_drawDisplayList },
|
||||
|
||||
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
|
||||
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
|
||||
|
||||
33
include/utils/Functor.h
Normal file
33
include/utils/Functor.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_FUNCTOR_H
|
||||
#define ANDROID_FUNCTOR_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Functor {
|
||||
public:
|
||||
Functor() {}
|
||||
virtual ~Functor() {}
|
||||
virtual status_t operator ()() { return true; }
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_FUNCTOR_H
|
||||
@@ -117,7 +117,8 @@ const char* DisplayList::OP_NAMES[] = {
|
||||
"ResetColorFilter",
|
||||
"SetupColorFilter",
|
||||
"ResetShadow",
|
||||
"SetupShadow"
|
||||
"SetupShadow",
|
||||
"DrawGLFunction"
|
||||
};
|
||||
|
||||
DisplayList::DisplayList(const DisplayListRenderer& recorder) {
|
||||
@@ -212,7 +213,8 @@ void DisplayList::init() {
|
||||
mPathHeap = NULL;
|
||||
}
|
||||
|
||||
void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
bool needsInvalidate = false;
|
||||
TextContainer text;
|
||||
mReader.rewind();
|
||||
|
||||
@@ -229,87 +231,165 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
int saveCount = renderer.getSaveCount() - 1;
|
||||
while (!mReader.eof()) {
|
||||
int op = mReader.readInt();
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
|
||||
switch (op) {
|
||||
case DrawGLFunction: {
|
||||
Functor *functor = (Functor *) getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
|
||||
needsInvalidate |= renderer.callDrawGLFunction(functor);
|
||||
}
|
||||
break;
|
||||
case AcquireContext: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.acquireContext();
|
||||
}
|
||||
break;
|
||||
case ReleaseContext: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.releaseContext();
|
||||
}
|
||||
break;
|
||||
case Save: {
|
||||
renderer.save(getInt());
|
||||
int rendererNum = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
|
||||
renderer.save(rendererNum);
|
||||
}
|
||||
break;
|
||||
case Restore: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.restore();
|
||||
}
|
||||
break;
|
||||
case RestoreToCount: {
|
||||
renderer.restoreToCount(saveCount + getInt());
|
||||
int restoreCount = saveCount + getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
|
||||
renderer.restoreToCount(restoreCount);
|
||||
}
|
||||
break;
|
||||
case SaveLayer: {
|
||||
renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getPaint(), getInt());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
int flags = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
|
||||
OP_NAMES[op], f1, f2, f3, f4, paint, flags);
|
||||
renderer.saveLayer(f1, f2, f3, f4, paint, flags);
|
||||
}
|
||||
break;
|
||||
case SaveLayerAlpha: {
|
||||
renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getInt(), getInt());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
int alpha = getInt();
|
||||
int flags = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
|
||||
OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
|
||||
renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
|
||||
}
|
||||
break;
|
||||
case Translate: {
|
||||
renderer.translate(getFloat(), getFloat());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
|
||||
renderer.translate(f1, f2);
|
||||
}
|
||||
break;
|
||||
case Rotate: {
|
||||
renderer.rotate(getFloat());
|
||||
float rotation = getFloat();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
|
||||
renderer.rotate(rotation);
|
||||
}
|
||||
break;
|
||||
case Scale: {
|
||||
renderer.scale(getFloat(), getFloat());
|
||||
float sx = getFloat();
|
||||
float sy = getFloat();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
|
||||
renderer.scale(sx, sy);
|
||||
}
|
||||
break;
|
||||
case Skew: {
|
||||
renderer.skew(getFloat(), getFloat());
|
||||
float sx = getFloat();
|
||||
float sy = getFloat();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
|
||||
renderer.skew(sx, sy);
|
||||
}
|
||||
break;
|
||||
case SetMatrix: {
|
||||
renderer.setMatrix(getMatrix());
|
||||
SkMatrix* matrix = getMatrix();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
|
||||
renderer.setMatrix(matrix);
|
||||
}
|
||||
break;
|
||||
case ConcatMatrix: {
|
||||
renderer.concatMatrix(getMatrix());
|
||||
SkMatrix* matrix = getMatrix();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
|
||||
renderer.concatMatrix(matrix);
|
||||
}
|
||||
break;
|
||||
case ClipRect: {
|
||||
renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
(SkRegion::Op) getInt());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
int regionOp = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
|
||||
f1, f2, f3, f4, regionOp);
|
||||
renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
|
||||
}
|
||||
break;
|
||||
case DrawDisplayList: {
|
||||
renderer.drawDisplayList(getDisplayList(), level + 1);
|
||||
DisplayList* displayList = getDisplayList();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
|
||||
displayList, level + 1);
|
||||
needsInvalidate |= renderer.drawDisplayList(displayList, level + 1);
|
||||
}
|
||||
break;
|
||||
case DrawLayer: {
|
||||
renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint());
|
||||
Layer* layer = (Layer*) getInt();
|
||||
float x = getFloat();
|
||||
float y = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
|
||||
layer, x, y, paint);
|
||||
renderer.drawLayer(layer, x, y, paint);
|
||||
}
|
||||
break;
|
||||
case DrawBitmap: {
|
||||
renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
|
||||
SkBitmap* bitmap = getBitmap();
|
||||
float x = getFloat();
|
||||
float y = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
|
||||
bitmap, x, y, paint);
|
||||
renderer.drawBitmap(bitmap, x, y, paint);
|
||||
}
|
||||
break;
|
||||
case DrawBitmapMatrix: {
|
||||
renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
|
||||
SkBitmap* bitmap = getBitmap();
|
||||
SkMatrix* matrix = getMatrix();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
|
||||
bitmap, matrix, paint);
|
||||
renderer.drawBitmap(bitmap, matrix, paint);
|
||||
}
|
||||
break;
|
||||
case DrawBitmapRect: {
|
||||
renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
SkBitmap* bitmap = getBitmap();
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
float f5 = getFloat();
|
||||
float f6 = getFloat();
|
||||
float f7 = getFloat();
|
||||
float f8 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
|
||||
(char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
|
||||
renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
|
||||
}
|
||||
break;
|
||||
case DrawBitmapMesh: {
|
||||
@@ -323,6 +403,7 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
bool hasColors = getInt();
|
||||
int* colors = hasColors ? getInts(colorsCount) : NULL;
|
||||
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
|
||||
}
|
||||
break;
|
||||
@@ -340,80 +421,148 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
yDivs = getInts(yDivsCount);
|
||||
colors = getUInts(numColors);
|
||||
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
|
||||
numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
}
|
||||
break;
|
||||
case DrawColor: {
|
||||
renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
|
||||
int color = getInt();
|
||||
int xferMode = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
|
||||
renderer.drawColor(color, (SkXfermode::Mode) xferMode);
|
||||
}
|
||||
break;
|
||||
case DrawRect: {
|
||||
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
|
||||
f1, f2, f3, f4, paint);
|
||||
renderer.drawRect(f1, f2, f3, f4, paint);
|
||||
}
|
||||
break;
|
||||
case DrawRoundRect: {
|
||||
renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getFloat(), getFloat(), getPaint());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
float f5 = getFloat();
|
||||
float f6 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
|
||||
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
|
||||
renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
|
||||
}
|
||||
break;
|
||||
case DrawCircle: {
|
||||
renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
|
||||
(char*) indent, OP_NAMES[op], f1, f2, f3, paint);
|
||||
renderer.drawCircle(f1, f2, f3, paint);
|
||||
}
|
||||
break;
|
||||
case DrawOval: {
|
||||
renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
|
||||
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
|
||||
renderer.drawOval(f1, f2, f3, f4, paint);
|
||||
}
|
||||
break;
|
||||
case DrawArc: {
|
||||
renderer.drawArc(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getFloat(), getFloat(), getInt() == 1, getPaint());
|
||||
float f1 = getFloat();
|
||||
float f2 = getFloat();
|
||||
float f3 = getFloat();
|
||||
float f4 = getFloat();
|
||||
float f5 = getFloat();
|
||||
float f6 = getFloat();
|
||||
int i1 = getInt();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
|
||||
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
|
||||
renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
|
||||
}
|
||||
break;
|
||||
case DrawPath: {
|
||||
renderer.drawPath(getPath(), getPaint());
|
||||
SkPath* path = getPath();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
|
||||
renderer.drawPath(path, paint);
|
||||
}
|
||||
break;
|
||||
case DrawLines: {
|
||||
int count = 0;
|
||||
float* points = getFloats(count);
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.drawLines(points, count, getPaint());
|
||||
}
|
||||
break;
|
||||
case DrawText: {
|
||||
getText(&text);
|
||||
renderer.drawText(text.text(), text.length(), getInt(),
|
||||
getFloat(), getFloat(), getPaint());
|
||||
int count = getInt();
|
||||
float x = getFloat();
|
||||
float y = getFloat();
|
||||
SkPaint* paint = getPaint();
|
||||
DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
|
||||
text.text(), text.length(), count, x, y, paint);
|
||||
renderer.drawText(text.text(), text.length(), count, x, y, paint);
|
||||
}
|
||||
break;
|
||||
case ResetShader: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.resetShader();
|
||||
}
|
||||
break;
|
||||
case SetupShader: {
|
||||
renderer.setupShader(getShader());
|
||||
SkiaShader* shader = getShader();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
|
||||
renderer.setupShader(shader);
|
||||
}
|
||||
break;
|
||||
case ResetColorFilter: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.resetColorFilter();
|
||||
}
|
||||
break;
|
||||
case SetupColorFilter: {
|
||||
renderer.setupColorFilter(getColorFilter());
|
||||
SkiaColorFilter *colorFilter = getColorFilter();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
|
||||
renderer.setupColorFilter(colorFilter);
|
||||
}
|
||||
break;
|
||||
case ResetShadow: {
|
||||
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
|
||||
renderer.resetShadow();
|
||||
}
|
||||
break;
|
||||
case SetupShadow: {
|
||||
renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
|
||||
float radius = getFloat();
|
||||
float dx = getFloat();
|
||||
float dy = getFloat();
|
||||
int color = getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
|
||||
radius, dx, dy, color);
|
||||
renderer.setupShadow(radius, dx, dy, color);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
|
||||
(char*) indent, OP_NAMES[op]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2);
|
||||
DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
|
||||
return needsInvalidate;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -493,12 +642,26 @@ void DisplayListRenderer::finish() {
|
||||
OpenGLRenderer::finish();
|
||||
}
|
||||
|
||||
void DisplayListRenderer::interrupt() {
|
||||
|
||||
}
|
||||
void DisplayListRenderer::resume() {
|
||||
|
||||
}
|
||||
void DisplayListRenderer::acquireContext() {
|
||||
// TODO: probably noop instead of calling super
|
||||
addOp(DisplayList::AcquireContext);
|
||||
OpenGLRenderer::acquireContext();
|
||||
}
|
||||
|
||||
bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
|
||||
addOp(DisplayList::DrawGLFunction);
|
||||
addInt((int) functor);
|
||||
return false; // No invalidate needed at record-time
|
||||
}
|
||||
|
||||
void DisplayListRenderer::releaseContext() {
|
||||
// TODO: probably noop instead of calling super
|
||||
addOp(DisplayList::ReleaseContext);
|
||||
OpenGLRenderer::releaseContext();
|
||||
}
|
||||
@@ -581,9 +744,10 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
|
||||
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
|
||||
}
|
||||
|
||||
void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
addOp(DisplayList::DrawDisplayList);
|
||||
addDisplayList(displayList);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <SkTSearch.h>
|
||||
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "Functor.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@@ -124,13 +125,14 @@ public:
|
||||
SetupColorFilter,
|
||||
ResetShadow,
|
||||
SetupShadow,
|
||||
DrawGLFunction,
|
||||
};
|
||||
|
||||
static const char* OP_NAMES[];
|
||||
|
||||
void initFromDisplayListRenderer(const DisplayListRenderer& recorder);
|
||||
|
||||
void replay(OpenGLRenderer& renderer, uint32_t level = 0);
|
||||
bool replay(OpenGLRenderer& renderer, uint32_t level = 0);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@@ -242,9 +244,13 @@ public:
|
||||
void prepare(bool opaque);
|
||||
void finish();
|
||||
|
||||
bool callDrawGLFunction(Functor *functor);
|
||||
void acquireContext();
|
||||
void releaseContext();
|
||||
|
||||
void interrupt();
|
||||
void resume();
|
||||
|
||||
int save(int flags);
|
||||
void restore();
|
||||
void restoreToCount(int saveCount);
|
||||
@@ -264,7 +270,7 @@ public:
|
||||
|
||||
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
|
||||
void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
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);
|
||||
|
||||
@@ -48,10 +48,10 @@ int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bot
|
||||
return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
bool OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawDisplayList");
|
||||
OpenGLRenderer::drawDisplayList(displayList);
|
||||
return OpenGLRenderer::drawDisplayList(displayList);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
int saveLayer(float left, float top, float right, float bottom,
|
||||
SkPaint* p, int flags);
|
||||
|
||||
void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
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);
|
||||
|
||||
@@ -213,6 +213,13 @@ void OpenGLRenderer::releaseContext() {
|
||||
resume();
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
|
||||
interrupt();
|
||||
status_t result = (*functor)();
|
||||
resume();
|
||||
return (result == 0) ? false : true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// State management
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1031,12 +1038,13 @@ void OpenGLRenderer::finishDrawTexture() {
|
||||
// Drawing
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
|
||||
// will be performed by the display list itself
|
||||
if (displayList) {
|
||||
displayList->replay(*this, level);
|
||||
return displayList->replay(*this, level);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <SkShader.h>
|
||||
#include <SkXfermode.h>
|
||||
|
||||
#include <utils/Functor.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
@@ -65,9 +66,10 @@ public:
|
||||
virtual void finish();
|
||||
|
||||
// These two calls must not be recorded in display lists
|
||||
void interrupt();
|
||||
void resume();
|
||||
virtual void interrupt();
|
||||
virtual void resume();
|
||||
|
||||
virtual bool callDrawGLFunction(Functor *functor);
|
||||
virtual void acquireContext();
|
||||
virtual void releaseContext();
|
||||
|
||||
@@ -95,7 +97,7 @@ public:
|
||||
bool quickReject(float left, float top, float right, float bottom);
|
||||
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
|
||||
virtual void drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
virtual bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user