diff options
22 files changed, 341 insertions, 865 deletions
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index dfc74ea333c8..3060e6e44a25 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -19,8 +19,6 @@ package android.view; import android.graphics.Matrix; import android.graphics.Path; -import java.util.ArrayList; - /** * <p>A display list records a series of graphics related operations and can replay * them later. Display lists are usually built by recording operations on a @@ -124,18 +122,8 @@ import java.util.ArrayList; * @hide */ public class DisplayList { - private boolean mDirty; - private ArrayList<DisplayList> mChildDisplayLists; - - private GLES20RecordingCanvas mCanvas; private boolean mValid; - - // Used for debugging - private final String mName; - - // The native display list will be destroyed when this object dies. - // DO NOT overwrite this reference once it is set. - private DisplayListFinalizer mFinalizer; + private final long mNativeDisplayList; /** * Flag used when calling @@ -188,7 +176,8 @@ public class DisplayList { public static final int STATUS_DREW = 0x4; private DisplayList(String name) { - mName = name; + mNativeDisplayList = nCreate(); + nSetDisplayListName(mNativeDisplayList, name); } /** @@ -221,19 +210,11 @@ public class DisplayList { * @see #isValid() */ public HardwareCanvas start(int width, int height) { - if (mCanvas != null) { - throw new IllegalStateException("Recording has already started"); - } - - mValid = false; - mCanvas = GLES20RecordingCanvas.obtain(this); - mCanvas.start(); - - mCanvas.setViewport(width, height); + HardwareCanvas canvas = GLES20RecordingCanvas.obtain(); + canvas.setViewport(width, height); // The dirty rect should always be null for a display list - mCanvas.onPreDraw(null); - - return mCanvas; + canvas.onPreDraw(null); + return canvas; } /** @@ -244,47 +225,27 @@ public class DisplayList { * @see #start(int, int) * @see #isValid() */ - public void end() { - if (mCanvas != null) { - mCanvas.onPostDraw(); - if (mFinalizer != null) { - mCanvas.end(mFinalizer.mNativeDisplayList); - } else { - mFinalizer = new DisplayListFinalizer(mCanvas.end(0)); - nSetDisplayListName(mFinalizer.mNativeDisplayList, mName); - } - mCanvas.recycle(); - mCanvas = null; - mValid = true; + public void end(HardwareRenderer renderer, HardwareCanvas endCanvas) { + if (!(endCanvas instanceof GLES20RecordingCanvas)) { + throw new IllegalArgumentException("Passed an invalid canvas to end!"); } + + GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas; + canvas.onPostDraw(); + long displayListData = canvas.finishRecording(); + renderer.swapDisplayListData(mNativeDisplayList, displayListData); + canvas.recycle(); + mValid = true; } /** - * Clears resources held onto by this display list. After calling this method - * {@link #isValid()} will return false. - * - * @see #isValid() - * @see #reset() - */ - public void clear() { - clearDirty(); - - if (mCanvas != null) { - mCanvas.recycle(); - mCanvas = null; - } + * After calling this method {@link #isValid()} will return false. + * TODO: Have Editor stop using this + * + * @see #isValid() + */ + public void markInvalid() { mValid = false; - - clearReferences(); - } - - void clearReferences() { - if (mChildDisplayLists != null) mChildDisplayLists.clear(); - } - - ArrayList<DisplayList> getChildDisplayLists() { - if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>(); - return mChildDisplayLists; } /** @@ -292,53 +253,14 @@ public class DisplayList { * during destruction of hardware resources, to ensure that we do not hold onto * obsolete resources after related resources are gone. * - * @see #clear() - * * @hide */ - public void reset() { - if (hasNativeDisplayList()) { - nReset(mFinalizer.mNativeDisplayList); + public void destroyDisplayListData(HardwareRenderer renderer) { + if (renderer == null) { + throw new IllegalArgumentException("Cannot destroyDisplayListData with a null renderer"); } - clear(); - } - - /** - * Sets the dirty flag. When a display list is dirty, {@link #clear()} should - * be invoked whenever possible. - * - * @see #isDirty() - * @see #clear() - * - * @hide - */ - public void markDirty() { - mDirty = true; - } - - /** - * Removes the dirty flag. This method can be used to cancel a cleanup - * previously scheduled by setting the dirty flag. - * - * @see #isDirty() - * @see #clear() - * - * @hide - */ - protected void clearDirty() { - mDirty = false; - } - - /** - * Indicates whether the display list is dirty. - * - * @see #markDirty() - * @see #clear() - * - * @hide - */ - public boolean isDirty() { - return mDirty; + renderer.swapDisplayListData(mNativeDisplayList, 0); + mValid = false; } /** @@ -349,27 +271,11 @@ public class DisplayList { */ public boolean isValid() { return mValid; } - /** - * Return the amount of memory used by this display list. - * - * @return The size of this display list in bytes - * - * @hide - */ - public int getSize() { - if (mFinalizer == null) return 0; - return nGetDisplayListSize(mFinalizer.mNativeDisplayList); - } - - boolean hasNativeDisplayList() { - return mValid && mFinalizer != null; - } - long getNativeDisplayList() { - if (!mValid || mFinalizer == null) { + if (!mValid) { throw new IllegalStateException("The display list is not valid."); } - return mFinalizer.mNativeDisplayList; + return mNativeDisplayList; } /////////////////////////////////////////////////////////////////////////// @@ -386,9 +292,7 @@ public class DisplayList { * @hide */ public void setCaching(boolean caching) { - if (hasNativeDisplayList()) { - nSetCaching(mFinalizer.mNativeDisplayList, caching); - } + nSetCaching(mNativeDisplayList, caching); } /** @@ -398,9 +302,7 @@ public class DisplayList { * @param clipToBounds true if the display list should clip to its bounds */ public void setClipToBounds(boolean clipToBounds) { - if (hasNativeDisplayList()) { - nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds); - } + nSetClipToBounds(mNativeDisplayList, clipToBounds); } /** @@ -410,9 +312,7 @@ public class DisplayList { * @param isolatedZVolume true if the display list should collect and Z order descendents. */ public void setIsolatedZVolume(boolean isolatedZVolume) { - if (hasNativeDisplayList()) { - nSetIsolatedZVolume(mFinalizer.mNativeDisplayList, isolatedZVolume); - } + nSetIsolatedZVolume(mNativeDisplayList, isolatedZVolume); } /** @@ -425,9 +325,7 @@ public class DisplayList { * containing volume. */ public void setProjectBackwards(boolean shouldProject) { - if (hasNativeDisplayList()) { - nSetProjectBackwards(mFinalizer.mNativeDisplayList, shouldProject); - } + nSetProjectBackwards(mNativeDisplayList, shouldProject); } /** @@ -436,9 +334,7 @@ public class DisplayList { * ProjectBackwards=true directly on top of it. Default value is false. */ public void setProjectionReceiver(boolean shouldRecieve) { - if (hasNativeDisplayList()) { - nSetProjectionReceiver(mFinalizer.mNativeDisplayList, shouldRecieve); - } + nSetProjectionReceiver(mNativeDisplayList, shouldRecieve); } /** @@ -450,10 +346,8 @@ public class DisplayList { * @param outline Convex, CW Path to store in the DisplayList. May be null. */ public void setOutline(Path outline) { - if (hasNativeDisplayList()) { - long nativePath = (outline == null) ? 0 : outline.mNativePath; - nSetOutline(mFinalizer.mNativeDisplayList, nativePath); - } + long nativePath = (outline == null) ? 0 : outline.mNativePath; + nSetOutline(mNativeDisplayList, nativePath); } /** @@ -462,9 +356,7 @@ public class DisplayList { * @param clipToOutline true if clipping to the outline. */ public void setClipToOutline(boolean clipToOutline) { - if (hasNativeDisplayList()) { - nSetClipToOutline(mFinalizer.mNativeDisplayList, clipToOutline); - } + nSetClipToOutline(mNativeDisplayList, clipToOutline); } /** @@ -474,9 +366,7 @@ public class DisplayList { * and non-empty, otherwise it will be the bounds rect. */ public void setCastsShadow(boolean castsShadow) { - if (hasNativeDisplayList()) { - nSetCastsShadow(mFinalizer.mNativeDisplayList, castsShadow); - } + nSetCastsShadow(mNativeDisplayList, castsShadow); } /** @@ -485,9 +375,7 @@ public class DisplayList { * If set to true, camera distance will be ignored. Defaults to false. */ public void setUsesGlobalCamera(boolean usesGlobalCamera) { - if (hasNativeDisplayList()) { - nSetUsesGlobalCamera(mFinalizer.mNativeDisplayList, usesGlobalCamera); - } + nSetUsesGlobalCamera(mNativeDisplayList, usesGlobalCamera); } /** @@ -499,41 +387,8 @@ public class DisplayList { * @see #getMatrix(android.graphics.Matrix) * @see #getMatrix() */ - public void setMatrix(Matrix matrix) { - if (hasNativeDisplayList()) { - nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance); - } - } - - /** - * Returns the static matrix set on this display list. - * - * @return A new {@link Matrix} instance populated with this display list's static - * matrix - * - * @see #getMatrix(android.graphics.Matrix) - * @see #setMatrix(android.graphics.Matrix) - */ - public Matrix getMatrix() { - return getMatrix(new Matrix()); - } - - /** - * Copies this display list's static matrix into the specified matrix. - * - * @param matrix The {@link Matrix} instance in which to copy this display - * list's static matrix. Cannot be null - * - * @return The <code>matrix</code> parameter, for convenience - * - * @see #getMatrix() - * @see #setMatrix(android.graphics.Matrix) - */ - public Matrix getMatrix(Matrix matrix) { - if (hasNativeDisplayList()) { - nGetMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance); - } - return matrix; + public void setStaticMatrix(Matrix matrix) { + nSetStaticMatrix(mNativeDisplayList, matrix.native_instance); } /** @@ -547,10 +402,8 @@ public class DisplayList { * @hide */ public void setAnimationMatrix(Matrix matrix) { - if (hasNativeDisplayList()) { - nSetAnimationMatrix(mFinalizer.mNativeDisplayList, - (matrix != null) ? matrix.native_instance : 0); - } + nSetAnimationMatrix(mNativeDisplayList, + (matrix != null) ? matrix.native_instance : 0); } /** @@ -562,9 +415,7 @@ public class DisplayList { * @see #getAlpha() */ public void setAlpha(float alpha) { - if (hasNativeDisplayList()) { - nSetAlpha(mFinalizer.mNativeDisplayList, alpha); - } + nSetAlpha(mNativeDisplayList, alpha); } /** @@ -575,10 +426,7 @@ public class DisplayList { * @see #setAlpha(float) */ public float getAlpha() { - if (hasNativeDisplayList()) { - return nGetAlpha(mFinalizer.mNativeDisplayList); - } - return 1.0f; + return nGetAlpha(mNativeDisplayList); } /** @@ -593,9 +441,7 @@ public class DisplayList { * @see #hasOverlappingRendering() */ public void setHasOverlappingRendering(boolean hasOverlappingRendering) { - if (hasNativeDisplayList()) { - nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering); - } + nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering); } /** @@ -607,10 +453,7 @@ public class DisplayList { */ public boolean hasOverlappingRendering() { //noinspection SimplifiableIfStatement - if (hasNativeDisplayList()) { - return nHasOverlappingRendering(mFinalizer.mNativeDisplayList); - } - return true; + return nHasOverlappingRendering(mNativeDisplayList); } /** @@ -622,9 +465,7 @@ public class DisplayList { * @see #getTranslationX() */ public void setTranslationX(float translationX) { - if (hasNativeDisplayList()) { - nSetTranslationX(mFinalizer.mNativeDisplayList, translationX); - } + nSetTranslationX(mNativeDisplayList, translationX); } /** @@ -633,10 +474,7 @@ public class DisplayList { * @see #setTranslationX(float) */ public float getTranslationX() { - if (hasNativeDisplayList()) { - return nGetTranslationX(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetTranslationX(mNativeDisplayList); } /** @@ -648,9 +486,7 @@ public class DisplayList { * @see #getTranslationY() */ public void setTranslationY(float translationY) { - if (hasNativeDisplayList()) { - nSetTranslationY(mFinalizer.mNativeDisplayList, translationY); - } + nSetTranslationY(mNativeDisplayList, translationY); } /** @@ -659,10 +495,7 @@ public class DisplayList { * @see #setTranslationY(float) */ public float getTranslationY() { - if (hasNativeDisplayList()) { - return nGetTranslationY(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetTranslationY(mNativeDisplayList); } /** @@ -672,9 +505,7 @@ public class DisplayList { * @see #getTranslationZ() */ public void setTranslationZ(float translationZ) { - if (hasNativeDisplayList()) { - nSetTranslationZ(mFinalizer.mNativeDisplayList, translationZ); - } + nSetTranslationZ(mNativeDisplayList, translationZ); } /** @@ -683,10 +514,7 @@ public class DisplayList { * @see #setTranslationZ(float) */ public float getTranslationZ() { - if (hasNativeDisplayList()) { - return nGetTranslationZ(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetTranslationZ(mNativeDisplayList); } /** @@ -698,9 +526,7 @@ public class DisplayList { * @see #getRotation() */ public void setRotation(float rotation) { - if (hasNativeDisplayList()) { - nSetRotation(mFinalizer.mNativeDisplayList, rotation); - } + nSetRotation(mNativeDisplayList, rotation); } /** @@ -709,10 +535,7 @@ public class DisplayList { * @see #setRotation(float) */ public float getRotation() { - if (hasNativeDisplayList()) { - return nGetRotation(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetRotation(mNativeDisplayList); } /** @@ -724,9 +547,7 @@ public class DisplayList { * @see #getRotationX() */ public void setRotationX(float rotationX) { - if (hasNativeDisplayList()) { - nSetRotationX(mFinalizer.mNativeDisplayList, rotationX); - } + nSetRotationX(mNativeDisplayList, rotationX); } /** @@ -735,10 +556,7 @@ public class DisplayList { * @see #setRotationX(float) */ public float getRotationX() { - if (hasNativeDisplayList()) { - return nGetRotationX(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetRotationX(mNativeDisplayList); } /** @@ -750,9 +568,7 @@ public class DisplayList { * @see #getRotationY() */ public void setRotationY(float rotationY) { - if (hasNativeDisplayList()) { - nSetRotationY(mFinalizer.mNativeDisplayList, rotationY); - } + nSetRotationY(mNativeDisplayList, rotationY); } /** @@ -761,10 +577,7 @@ public class DisplayList { * @see #setRotationY(float) */ public float getRotationY() { - if (hasNativeDisplayList()) { - return nGetRotationY(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetRotationY(mNativeDisplayList); } /** @@ -776,9 +589,7 @@ public class DisplayList { * @see #getScaleX() */ public void setScaleX(float scaleX) { - if (hasNativeDisplayList()) { - nSetScaleX(mFinalizer.mNativeDisplayList, scaleX); - } + nSetScaleX(mNativeDisplayList, scaleX); } /** @@ -787,10 +598,7 @@ public class DisplayList { * @see #setScaleX(float) */ public float getScaleX() { - if (hasNativeDisplayList()) { - return nGetScaleX(mFinalizer.mNativeDisplayList); - } - return 1.0f; + return nGetScaleX(mNativeDisplayList); } /** @@ -802,9 +610,7 @@ public class DisplayList { * @see #getScaleY() */ public void setScaleY(float scaleY) { - if (hasNativeDisplayList()) { - nSetScaleY(mFinalizer.mNativeDisplayList, scaleY); - } + nSetScaleY(mNativeDisplayList, scaleY); } /** @@ -813,10 +619,7 @@ public class DisplayList { * @see #setScaleY(float) */ public float getScaleY() { - if (hasNativeDisplayList()) { - return nGetScaleY(mFinalizer.mNativeDisplayList); - } - return 1.0f; + return nGetScaleY(mNativeDisplayList); } /** @@ -836,11 +639,9 @@ public class DisplayList { public void setTransformationInfo(float alpha, float translationX, float translationY, float translationZ, float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { - if (hasNativeDisplayList()) { - nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, - translationX, translationY, translationZ, - rotation, rotationX, rotationY, scaleX, scaleY); - } + nSetTransformationInfo(mNativeDisplayList, alpha, + translationX, translationY, translationZ, + rotation, rotationX, rotationY, scaleX, scaleY); } /** @@ -852,9 +653,7 @@ public class DisplayList { * @see #getPivotX() */ public void setPivotX(float pivotX) { - if (hasNativeDisplayList()) { - nSetPivotX(mFinalizer.mNativeDisplayList, pivotX); - } + nSetPivotX(mNativeDisplayList, pivotX); } /** @@ -863,10 +662,7 @@ public class DisplayList { * @see #setPivotX(float) */ public float getPivotX() { - if (hasNativeDisplayList()) { - return nGetPivotX(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetPivotX(mNativeDisplayList); } /** @@ -878,9 +674,7 @@ public class DisplayList { * @see #getPivotY() */ public void setPivotY(float pivotY) { - if (hasNativeDisplayList()) { - nSetPivotY(mFinalizer.mNativeDisplayList, pivotY); - } + nSetPivotY(mNativeDisplayList, pivotY); } /** @@ -889,10 +683,7 @@ public class DisplayList { * @see #setPivotY(float) */ public float getPivotY() { - if (hasNativeDisplayList()) { - return nGetPivotY(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetPivotY(mNativeDisplayList); } /** @@ -906,9 +697,7 @@ public class DisplayList { * @see #getCameraDistance() */ public void setCameraDistance(float distance) { - if (hasNativeDisplayList()) { - nSetCameraDistance(mFinalizer.mNativeDisplayList, distance); - } + nSetCameraDistance(mNativeDisplayList, distance); } /** @@ -917,10 +706,7 @@ public class DisplayList { * @see #setCameraDistance(float) */ public float getCameraDistance() { - if (hasNativeDisplayList()) { - return nGetCameraDistance(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetCameraDistance(mNativeDisplayList); } /** @@ -932,9 +718,7 @@ public class DisplayList { * @see #getLeft() */ public void setLeft(int left) { - if (hasNativeDisplayList()) { - nSetLeft(mFinalizer.mNativeDisplayList, left); - } + nSetLeft(mNativeDisplayList, left); } /** @@ -943,10 +727,7 @@ public class DisplayList { * @see #setLeft(int) */ public float getLeft() { - if (hasNativeDisplayList()) { - return nGetLeft(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetLeft(mNativeDisplayList); } /** @@ -958,9 +739,7 @@ public class DisplayList { * @see #getTop() */ public void setTop(int top) { - if (hasNativeDisplayList()) { - nSetTop(mFinalizer.mNativeDisplayList, top); - } + nSetTop(mNativeDisplayList, top); } /** @@ -969,10 +748,7 @@ public class DisplayList { * @see #setTop(int) */ public float getTop() { - if (hasNativeDisplayList()) { - return nGetTop(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetTop(mNativeDisplayList); } /** @@ -984,9 +760,7 @@ public class DisplayList { * @see #getRight() */ public void setRight(int right) { - if (hasNativeDisplayList()) { - nSetRight(mFinalizer.mNativeDisplayList, right); - } + nSetRight(mNativeDisplayList, right); } /** @@ -995,10 +769,7 @@ public class DisplayList { * @see #setRight(int) */ public float getRight() { - if (hasNativeDisplayList()) { - return nGetRight(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetRight(mNativeDisplayList); } /** @@ -1010,9 +781,7 @@ public class DisplayList { * @see #getBottom() */ public void setBottom(int bottom) { - if (hasNativeDisplayList()) { - nSetBottom(mFinalizer.mNativeDisplayList, bottom); - } + nSetBottom(mNativeDisplayList, bottom); } /** @@ -1021,10 +790,7 @@ public class DisplayList { * @see #setBottom(int) */ public float getBottom() { - if (hasNativeDisplayList()) { - return nGetBottom(mFinalizer.mNativeDisplayList); - } - return 0.0f; + return nGetBottom(mNativeDisplayList); } /** @@ -1041,9 +807,7 @@ public class DisplayList { * @see View#setBottom(int) */ public void setLeftTopRightBottom(int left, int top, int right, int bottom) { - if (hasNativeDisplayList()) { - nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom); - } + nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom); } /** @@ -1055,9 +819,7 @@ public class DisplayList { * @see View#offsetLeftAndRight(int) */ public void offsetLeftAndRight(float offset) { - if (hasNativeDisplayList()) { - nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset); - } + nOffsetLeftAndRight(mNativeDisplayList, offset); } /** @@ -1069,9 +831,7 @@ public class DisplayList { * @see View#offsetTopAndBottom(int) */ public void offsetTopAndBottom(float offset) { - if (hasNativeDisplayList()) { - nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset); - } + nOffsetTopAndBottom(mNativeDisplayList, offset); } /** @@ -1081,22 +841,19 @@ public class DisplayList { * @hide */ public void output() { - if (hasNativeDisplayList()) { - nOutput(mFinalizer.mNativeDisplayList); - } + nOutput(mNativeDisplayList); } /////////////////////////////////////////////////////////////////////////// // Native methods /////////////////////////////////////////////////////////////////////////// + private static native long nCreate(); private static native void nDestroyDisplayList(long displayList); - private static native int nGetDisplayListSize(long displayList); private static native void nSetDisplayListName(long displayList, String name); // Properties - private static native void nReset(long displayList); private static native void nOffsetTopAndBottom(long displayList, float offset); private static native void nOffsetLeftAndRight(long displayList, float offset); private static native void nSetLeftTopRightBottom(long displayList, int left, int top, @@ -1135,7 +892,6 @@ public class DisplayList { private static native void nSetAnimationMatrix(long displayList, long animationMatrix); private static native boolean nHasOverlappingRendering(long displayList); - private static native void nGetMatrix(long displayList, long matrix); private static native float nGetAlpha(long displayList); private static native float nGetLeft(long displayList); private static native float nGetTop(long displayList); @@ -1158,20 +914,12 @@ public class DisplayList { // Finalization /////////////////////////////////////////////////////////////////////////// - private static class DisplayListFinalizer { - final long mNativeDisplayList; - - public DisplayListFinalizer(long nativeDisplayList) { - mNativeDisplayList = nativeDisplayList; - } - - @Override - protected void finalize() throws Throwable { - try { - nDestroyDisplayList(mNativeDisplayList); - } finally { - super.finalize(); - } + @Override + protected void finalize() throws Throwable { + try { + nDestroyDisplayList(mNativeDisplayList); + } finally { + super.finalize(); } } } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index a08d83ab5518..6c6fc9b792c1 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -18,7 +18,6 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.ColorFilter; import android.graphics.DrawFilter; import android.graphics.Matrix; import android.graphics.NinePatch; @@ -47,7 +46,7 @@ class GLES20Canvas extends HardwareCanvas { private static final int MODIFIER_SHADER = 2; private final boolean mOpaque; - private long mRenderer; + protected long mRenderer; // The native renderer will be destroyed when this object dies. // DO NOT overwrite this reference once it is set. @@ -107,10 +106,6 @@ class GLES20Canvas extends HardwareCanvas { } } - protected void resetDisplayListRenderer() { - nResetDisplayListRenderer(mRenderer); - } - private static native long nCreateRenderer(); private static native long nCreateDisplayListRenderer(); private static native void nResetDisplayListRenderer(long renderer); @@ -361,11 +356,7 @@ class GLES20Canvas extends HardwareCanvas { // Display list /////////////////////////////////////////////////////////////////////////// - long getDisplayList(long displayList) { - return nGetDisplayList(mRenderer, displayList); - } - - private static native long nGetDisplayList(long renderer, long displayList); + protected static native long nFinishRecording(long renderer); @Override public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) { diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java index b7b68833afa7..2b29e5ce9a7f 100644 --- a/core/java/android/view/GLES20RecordingCanvas.java +++ b/core/java/android/view/GLES20RecordingCanvas.java @@ -16,7 +16,6 @@ package android.view; -import android.graphics.Rect; import android.util.Pools.SynchronizedPool; /** @@ -33,39 +32,23 @@ class GLES20RecordingCanvas extends GLES20Canvas { private static final SynchronizedPool<GLES20RecordingCanvas> sPool = new SynchronizedPool<GLES20RecordingCanvas>(POOL_LIMIT); - private DisplayList mDisplayList; - private GLES20RecordingCanvas() { super(true, true); } - static GLES20RecordingCanvas obtain(DisplayList displayList) { + static GLES20RecordingCanvas obtain() { GLES20RecordingCanvas canvas = sPool.acquire(); if (canvas == null) { canvas = new GLES20RecordingCanvas(); } - canvas.mDisplayList = displayList; return canvas; } void recycle() { - mDisplayList = null; - resetDisplayListRenderer(); sPool.release(this); } - void start() { - mDisplayList.clearReferences(); - } - - long end(long nativeDisplayList) { - return getDisplayList(nativeDisplayList); - } - - @Override - public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) { - int status = super.drawDisplayList(displayList, dirty, flags); - mDisplayList.getChildDisplayLists().add(displayList); - return status; + long finishRecording() { + return nFinishRecording(mRenderer); } } diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java index 4c92e950441c..c90e4b08677b 100644 --- a/core/java/android/view/GLRenderer.java +++ b/core/java/android/view/GLRenderer.java @@ -1196,6 +1196,11 @@ public class GLRenderer extends HardwareRenderer { } } + void swapDisplayListData(long displayList, long newData) { + nSwapDisplayListData(displayList, newData); + } + private static native void nSwapDisplayListData(long displayList, long newData); + private DisplayList buildDisplayList(View view, HardwareCanvas canvas) { if (mDrawDelta <= 0) { return view.mDisplayList; diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 8900d23a53cf..c526dd29815b 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -88,7 +88,7 @@ final class HardwareLayer { } if (mDisplayList != null) { - mDisplayList.reset(); + mDisplayList.destroyDisplayListData(mRenderer); mDisplayList = null; } if (mRenderer != null) { diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 7a943f0a136c..bcc28e303f61 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -562,6 +562,8 @@ public abstract class HardwareRenderer { mRequested = requested; } + abstract void swapDisplayListData(long displayList, long newData); + /** * Describes a series of frames that should be drawn on screen as a graph. * Each frame is composed of 1 or more elements. diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index e8f5e45fb393..3dcfbb357779 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -148,6 +148,11 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override + void swapDisplayListData(long displayList, long newData) { + nSwapDisplayListData(mNativeProxy, displayList, newData); + } + + @Override void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) { attachInfo.mIgnoreDirtyState = true; attachInfo.mDrawingTime = SystemClock.uptimeMillis(); @@ -252,6 +257,8 @@ public class ThreadedRenderer extends HardwareRenderer { private static native boolean nInitialize(long nativeProxy, Surface window); private static native void nUpdateSurface(long nativeProxy, Surface window); private static native void nSetup(long nativeProxy, int width, int height); + private static native void nSwapDisplayListData(long nativeProxy, long displayList, + long newData); private static native void nDrawDisplayList(long nativeProxy, long displayList, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); private static native void nRunWithGlContext(long nativeProxy, Runnable runnable); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 39dc3f4370d2..31b8b04a03c3 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7983,8 +7983,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void dispatchStartTemporaryDetach() { - clearDisplayList(); - onStartTemporaryDetach(); } @@ -9385,7 +9383,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((changed & VISIBILITY_MASK) != 0) { // If the view is invisible, cleanup its display list to free up resources - if (newVisibility != VISIBLE) { + if (newVisibility != VISIBLE && mAttachInfo != null) { cleanupDraw(); } @@ -12812,14 +12810,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, InputMethodManager imm = InputMethodManager.peekInstance(); imm.focusIn(this); } - - if (mDisplayList != null) { - mDisplayList.clearDirty(); - } - - if (mBackgroundDisplayList != null) { - mBackgroundDisplayList.clearDirty(); - } } /** @@ -13137,21 +13127,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private void cleanupDraw() { - if (mAttachInfo != null) { - // Ensure the display lists are reset when the view root dies. - if (mDisplayList != null) { - mDisplayList.markDirty(); - mAttachInfo.mViewRootImpl.enqueueDisplayList(mDisplayList); - } - if (mBackgroundDisplayList != null) { - mBackgroundDisplayList.markDirty(); - mAttachInfo.mViewRootImpl.enqueueDisplayList(mBackgroundDisplayList); - } - mAttachInfo.mViewRootImpl.cancelInvalidate(this); - } else { - // Should never happen. - resetDisplayList(); - } + resetDisplayList(); + mAttachInfo.mViewRootImpl.cancelInvalidate(this); } /** @@ -14027,7 +14004,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } finally { - displayList.end(); + displayList.end(getHardwareRenderer(), canvas); displayList.setCaching(caching); if (isLayer) { displayList.setLeftTopRightBottom(0, 0, width, height); @@ -14056,23 +14033,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return mDisplayList; } - private void clearDisplayList() { - if (mDisplayList != null) { - mDisplayList.clear(); - } - - if (mBackgroundDisplayList != null) { - mBackgroundDisplayList.clear(); - } - } - private void resetDisplayList() { - if (mDisplayList != null) { - mDisplayList.reset(); + HardwareRenderer renderer = getHardwareRenderer(); + if (mDisplayList != null && mDisplayList.isValid()) { + mDisplayList.destroyDisplayListData(renderer); } - if (mBackgroundDisplayList != null) { - mBackgroundDisplayList.reset(); + if (mBackgroundDisplayList != null && mBackgroundDisplayList.isValid()) { + mBackgroundDisplayList.destroyDisplayListData(renderer); } } @@ -14695,7 +14663,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, alpha = t.getAlpha(); } if ((transformType & Transformation.TYPE_MATRIX) != 0) { - displayList.setMatrix(t.getMatrix()); + displayList.setStaticMatrix(t.getMatrix()); } } } @@ -15328,7 +15296,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param displayList Existing display list, or {@code null} * @return A valid display list for the specified drawable */ - private static DisplayList getDrawableDisplayList(Drawable drawable, DisplayList displayList) { + private DisplayList getDrawableDisplayList(Drawable drawable, DisplayList displayList) { if (displayList == null) { displayList = DisplayList.create(drawable.getClass().getName()); } @@ -15338,7 +15306,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final int height = bounds.height(); final HardwareCanvas canvas = displayList.start(width, height); drawable.draw(canvas); - displayList.end(); + displayList.end(getHardwareRenderer(), canvas); // Set up drawable properties that are view-independent. displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a338e6eb5580..3af1c4fcfdf7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -56,6 +56,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.util.TypedValue; +import android.view.Surface.OutOfResourcesException; import android.view.View.AttachInfo; import android.view.View.MeasureSpec; import android.view.accessibility.AccessibilityEvent; @@ -69,7 +70,6 @@ import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.view.Surface.OutOfResourcesException; import android.widget.Scroller; import com.android.internal.R; @@ -294,8 +294,6 @@ public final class ViewRootImpl implements ViewParent, private long mFpsPrevTime = -1; private int mFpsNumFrames; - private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>(); - /** * see {@link #playSoundEffect(int)} */ @@ -620,7 +618,6 @@ public final class ViewRootImpl implements ViewParent, } void destroyHardwareResources() { - invalidateDisplayLists(); if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView); mAttachInfo.mHardwareRenderer.destroy(false); @@ -634,7 +631,6 @@ public final class ViewRootImpl implements ViewParent, HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE); } } else { - invalidateDisplayLists(); destroyHardwareLayer(mView); } } @@ -1503,7 +1499,7 @@ public final class ViewRootImpl implements ViewParent, com.android.internal.R.integer.config_mediumAnimTime); layerCanvas.restoreToCount(restoreCount); - layerDisplayList.end(); + layerDisplayList.end(mAttachInfo.mHardwareRenderer, layerCanvas); layerDisplayList.setCaching(true); layerDisplayList.setLeftTopRightBottom(0, 0, mWidth, mHeight); mTempRect.set(0, 0, mWidth, mHeight); @@ -2369,8 +2365,6 @@ public final class ViewRootImpl implements ViewParent, appScale + ", width=" + mWidth + ", height=" + mHeight); } - invalidateDisplayLists(); - attachInfo.mTreeObserver.dispatchOnDraw(); if (!dirty.isEmpty() || mIsAnimating) { @@ -2588,20 +2582,6 @@ public final class ViewRootImpl implements ViewParent, return null; } - void invalidateDisplayLists() { - final ArrayList<DisplayList> displayLists = mDisplayLists; - final int count = displayLists.size(); - - for (int i = 0; i < count; i++) { - final DisplayList displayList = displayLists.get(i); - if (displayList.isDirty()) { - displayList.reset(); - } - } - - displayLists.clear(); - } - /** * @hide */ @@ -5229,7 +5209,7 @@ public final class ViewRootImpl implements ViewParent, DisplayList displayList = view.mDisplayList; info[0]++; if (displayList != null) { - info[1] += displayList.getSize(); + info[1] += 0; /* TODO: Memory used by display lists */ } if (view instanceof ViewGroup) { @@ -5277,7 +5257,6 @@ public final class ViewRootImpl implements ViewParent, } if (mAdded && !mFirst) { - invalidateDisplayLists(); destroyHardwareRenderer(); if (mView != null) { @@ -5743,10 +5722,6 @@ public final class ViewRootImpl implements ViewParent, mInvalidateOnAnimationRunnable.addViewRect(info); } - public void enqueueDisplayList(DisplayList displayList) { - mDisplayLists.add(displayList); - } - public void cancelInvalidate(View view) { mHandler.removeMessages(MSG_INVALIDATE, view); // fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index ea62bbe6e85d..84c158649c28 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.InputFilter; import android.text.SpannableString; + import com.android.internal.util.ArrayUtils; import com.android.internal.widget.EditableInputConnection; @@ -77,6 +78,7 @@ import android.view.DisplayList; import android.view.DragEvent; import android.view.Gravity; import android.view.HardwareCanvas; +import android.view.HardwareRenderer; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -1314,6 +1316,7 @@ public class Editor { layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical, firstLine, lastLine); + final HardwareRenderer renderer = mTextView.getHardwareRenderer(); if (layout instanceof DynamicLayout) { if (mTextDisplayLists == null) { @@ -1345,8 +1348,6 @@ public class Editor { if (blockDisplayList == null) { blockDisplayList = mTextDisplayLists[blockIndex] = DisplayList.create("Text " + blockIndex); - } else { - if (blockIsInvalid) blockDisplayList.clear(); } final boolean blockDisplayListIsInvalid = !blockDisplayList.isValid(); @@ -1379,7 +1380,7 @@ public class Editor { // No need to untranslate, previous context is popped after // drawDisplayList } finally { - blockDisplayList.end(); + blockDisplayList.end(renderer, hardwareCanvas); // Same as drawDisplayList below, handled by our TextView's parent blockDisplayList.setClipToBounds(false); } @@ -1459,7 +1460,7 @@ public class Editor { while (i < numberOfBlocks) { final int blockIndex = blockIndices[i]; if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) { - mTextDisplayLists[blockIndex].clear(); + mTextDisplayLists[blockIndex].markInvalid(); } if (blockEndLines[i] >= lastLine) break; i++; @@ -1470,7 +1471,7 @@ public class Editor { void invalidateTextDisplayList() { if (mTextDisplayLists != null) { for (int i = 0; i < mTextDisplayLists.length; i++) { - if (mTextDisplayLists[i] != null) mTextDisplayLists[i].clear(); + if (mTextDisplayLists[i] != null) mTextDisplayLists[i].markInvalid(); } } } diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp index e47e23c6224a..c8952c1cc50b 100644 --- a/core/jni/android_view_DisplayList.cpp +++ b/core/jni/android_view_DisplayList.cpp @@ -41,18 +41,6 @@ using namespace uirenderer; // DisplayList view properties // ---------------------------------------------------------------------------- -static void android_view_DisplayList_reset(JNIEnv* env, - jobject clazz, jlong displayListPtr) { - DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - displayList->reset(); -} - -static jint android_view_DisplayList_getDisplayListSize(JNIEnv* env, - jobject clazz, jlong displayListPtr) { - DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - return displayList->getSize(); -} - static void android_view_DisplayList_setDisplayListName(JNIEnv* env, jobject clazz, jlong displayListPtr, jstring name) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); @@ -69,6 +57,11 @@ static void android_view_DisplayList_output(JNIEnv* env, displayList->output(); } +static jlong android_view_DisplayList_create(JNIEnv* env, jobject clazz) { + DisplayList* displayList = new DisplayList(); + return reinterpret_cast<jlong>(displayList); +} + static void android_view_DisplayList_destroyDisplayList(JNIEnv* env, jobject clazz, jlong displayListPtr) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); @@ -285,18 +278,6 @@ static void android_view_DisplayList_offsetTopAndBottom(JNIEnv* env, displayList->offsetTopBottom(offset); } -static void android_view_DisplayList_getMatrix(JNIEnv* env, - jobject clazz, jlong displayListPtr, jlong matrixPtr) { - DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); - SkMatrix* source = displayList->getStaticMatrix(); - if (source) { - matrix->setConcat(SkMatrix::I(), *source); - } else { - matrix->setIdentity(); - } -} - static jboolean android_view_DisplayList_hasOverlappingRendering(JNIEnv* env, jobject clazz, jlong displayListPtr) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); @@ -403,13 +384,12 @@ const char* const kClassPathName = "android/view/DisplayList"; static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER + { "nCreate", "()J", (void*) android_view_DisplayList_create }, { "nDestroyDisplayList", "(J)V", (void*) android_view_DisplayList_destroyDisplayList }, - { "nGetDisplayListSize", "(J)I", (void*) android_view_DisplayList_getDisplayListSize }, { "nSetDisplayListName", "(JLjava/lang/String;)V", (void*) android_view_DisplayList_setDisplayListName }, { "nOutput", "(J)V", (void*) android_view_DisplayList_output }, - { "nReset", "(J)V", (void*) android_view_DisplayList_reset }, { "nSetCaching", "(JZ)V", (void*) android_view_DisplayList_setCaching }, { "nSetStaticMatrix", "(JJ)V", (void*) android_view_DisplayList_setStaticMatrix }, { "nSetAnimationMatrix", "(JJ)V", (void*) android_view_DisplayList_setAnimationMatrix }, @@ -445,7 +425,6 @@ static JNINativeMethod gMethods[] = { { "nOffsetLeftAndRight", "(JF)V", (void*) android_view_DisplayList_offsetLeftAndRight }, { "nOffsetTopAndBottom", "(JF)V", (void*) android_view_DisplayList_offsetTopAndBottom }, - { "nGetMatrix", "(JJ)V", (void*) android_view_DisplayList_getMatrix }, { "nHasOverlappingRendering", "(J)Z", (void*) android_view_DisplayList_hasOverlappingRendering }, { "nGetAlpha", "(J)F", (void*) android_view_DisplayList_getAlpha }, { "nGetLeft", "(J)F", (void*) android_view_DisplayList_getLeft }, diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 4e353fafc158..a4e667983de2 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -864,22 +864,15 @@ static void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz, // Display lists // ---------------------------------------------------------------------------- -static jint android_view_GLES20Canvas_getDisplayList(JNIEnv* env, - jobject clazz, jlong rendererPtr, jlong displayListPtr) { +static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env, + jobject clazz, jlong rendererPtr) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); - DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - return reinterpret_cast<jint>(renderer->getDisplayList(displayList)); + return reinterpret_cast<jlong>(renderer->finishRecording()); } -static jint android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, +static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) { - return reinterpret_cast<jint>(new DisplayListRenderer); -} - -static void android_view_GLES20Canvas_resetDisplayListRenderer(JNIEnv* env, - jobject clazz, jlong rendererPtr) { - DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); - renderer->reset(); + return reinterpret_cast<jlong>(new DisplayListRenderer); } static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env, @@ -1094,12 +1087,11 @@ static JNINativeMethod gMethods[] = { { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds }, - { "nGetDisplayList", "(JJ)J", (void*) android_view_GLES20Canvas_getDisplayList }, + { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording }, { "nDrawDisplayList", "(JJLandroid/graphics/Rect;I)I", (void*) android_view_GLES20Canvas_drawDisplayList }, { "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer }, - { "nResetDisplayListRenderer", "(J)V", (void*) android_view_GLES20Canvas_resetDisplayListRenderer }, { "nInterrupt", "(J)V", (void*) android_view_GLES20Canvas_interrupt }, { "nResume", "(J)V", (void*) android_view_GLES20Canvas_resume }, diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp index 5c5b52c7bb0d..5ea8460b840d 100644 --- a/core/jni/android_view_GLRenderer.cpp +++ b/core/jni/android_view_GLRenderer.cpp @@ -27,6 +27,7 @@ #include <utils/Timers.h> #include <Caches.h> +#include <DisplayList.h> #include <Extensions.h> #include <LayerRenderer.h> @@ -139,6 +140,14 @@ static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz, LayerRenderer::destroyLayer(layer); } +static void android_view_GLRenderer_swapDisplayListData(JNIEnv* env, jobject clazz, + jlong displayListPtr, jlong newDataPtr) { + using namespace android::uirenderer; + DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); + DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr); + displayList->setData(newData); +} + #endif // USE_OPENGL_RENDERER // ---------------------------------------------------------------------------- @@ -169,6 +178,7 @@ static JNINativeMethod gMethods[] = { { "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime }, { "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer }, + { "nSwapDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_swapDisplayListData }, #endif { "setupShadersDiskCache", "(Ljava/lang/String;)V", diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index bc5c06e8bcb8..444c8bec8f6f 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -103,6 +103,14 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, proxy->setup(width, height); } +static void android_view_ThreadedRenderer_swapDisplayListData(JNIEnv* env, jobject clazz, + jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); + DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); + DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr); + proxy->swapDisplayListData(displayList, newData); +} + static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz, jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop, jint dirtyRight, jint dirtyBottom) { @@ -183,10 +191,11 @@ static JNINativeMethod gMethods[] = { { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize }, { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup }, - { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList}, - { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas}, - { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor}, - { "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor}, + { "nSwapDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_swapDisplayListData }, + { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList }, + { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas }, + { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor }, + { "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor }, { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext }, { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer }, { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer }, diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 23c33ca92547..112f8d3f5deb 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -48,179 +48,10 @@ void DisplayList::outputLogBuffer(int fd) { fflush(file); } -DisplayList::DisplayList(const DisplayListRenderer& recorder) : - mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL), - mStaticMatrix(NULL), mAnimationMatrix(NULL) { +DisplayList::DisplayList() : + mDisplayListData(0), mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL), + mTransformMatrix3D(NULL), mStaticMatrix(NULL), mAnimationMatrix(NULL) { - initFromDisplayListRenderer(recorder); -} - -DisplayList::~DisplayList() { - mDestroyed = true; - clearResources(); -} - -void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { - if (displayList) { - DISPLAY_LIST_LOGD("Deferring display list destruction"); - Caches::getInstance().deleteDisplayListDeferred(displayList); - } -} - -void DisplayList::clearResources() { - mDisplayListData = NULL; - - delete mTransformMatrix; - delete mTransformCamera; - delete mTransformMatrix3D; - delete mStaticMatrix; - delete mAnimationMatrix; - - mTransformMatrix = NULL; - mTransformCamera = NULL; - mTransformMatrix3D = NULL; - mStaticMatrix = NULL; - mAnimationMatrix = NULL; - - Caches& caches = Caches::getInstance(); - caches.unregisterFunctors(mFunctorCount); - caches.resourceCache.lock(); - - for (size_t i = 0; i < mBitmapResources.size(); i++) { - caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); - } - - for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { - const SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); - caches.resourceCache.decrementRefcountLocked(bitmap); - caches.resourceCache.destructorLocked(bitmap); - } - - for (size_t i = 0; i < mPatchResources.size(); i++) { - caches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i)); - } - - for (size_t i = 0; i < mShaders.size(); i++) { - caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); - caches.resourceCache.destructorLocked(mShaders.itemAt(i)); - } - - for (size_t i = 0; i < mSourcePaths.size(); i++) { - caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); - } - - for (size_t i = 0; i < mLayers.size(); i++) { - caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i)); - } - - caches.resourceCache.unlock(); - - for (size_t i = 0; i < mPaints.size(); i++) { - delete mPaints.itemAt(i); - } - - for (size_t i = 0; i < mRegions.size(); i++) { - delete mRegions.itemAt(i); - } - - for (size_t i = 0; i < mPaths.size(); i++) { - delete mPaths.itemAt(i); - } - - for (size_t i = 0; i < mMatrices.size(); i++) { - delete mMatrices.itemAt(i); - } - - mBitmapResources.clear(); - mOwnedBitmapResources.clear(); - mPatchResources.clear(); - mShaders.clear(); - mSourcePaths.clear(); - mPaints.clear(); - mRegions.clear(); - mPaths.clear(); - mMatrices.clear(); - mLayers.clear(); -} - -void DisplayList::reset() { - clearResources(); - init(); -} - -void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { - if (reusing) { - // re-using display list - clear out previous allocations - clearResources(); - } - - init(); - - mDisplayListData = recorder.getDisplayListData(); - mSize = mDisplayListData->allocator.usedSize(); - - if (mSize == 0) { - return; - } - - mFunctorCount = recorder.getFunctorCount(); - - Caches& caches = Caches::getInstance(); - caches.registerFunctors(mFunctorCount); - caches.resourceCache.lock(); - - const Vector<const SkBitmap*>& bitmapResources = recorder.getBitmapResources(); - for (size_t i = 0; i < bitmapResources.size(); i++) { - const SkBitmap* resource = bitmapResources.itemAt(i); - mBitmapResources.add(resource); - caches.resourceCache.incrementRefcountLocked(resource); - } - - const Vector<const SkBitmap*>& ownedBitmapResources = recorder.getOwnedBitmapResources(); - for (size_t i = 0; i < ownedBitmapResources.size(); i++) { - const SkBitmap* resource = ownedBitmapResources.itemAt(i); - mOwnedBitmapResources.add(resource); - caches.resourceCache.incrementRefcountLocked(resource); - } - - const Vector<const Res_png_9patch*>& patchResources = recorder.getPatchResources(); - for (size_t i = 0; i < patchResources.size(); i++) { - const Res_png_9patch* resource = patchResources.itemAt(i); - mPatchResources.add(resource); - caches.resourceCache.incrementRefcountLocked(resource); - } - - const Vector<SkiaShader*>& shaders = recorder.getShaders(); - for (size_t i = 0; i < shaders.size(); i++) { - SkiaShader* resource = shaders.itemAt(i); - mShaders.add(resource); - caches.resourceCache.incrementRefcountLocked(resource); - } - - const SortedVector<const SkPath*>& sourcePaths = recorder.getSourcePaths(); - for (size_t i = 0; i < sourcePaths.size(); i++) { - mSourcePaths.add(sourcePaths.itemAt(i)); - caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i)); - } - - const Vector<Layer*>& layers = recorder.getLayers(); - for (size_t i = 0; i < layers.size(); i++) { - mLayers.add(layers.itemAt(i)); - caches.resourceCache.incrementRefcountLocked(layers.itemAt(i)); - } - - caches.resourceCache.unlock(); - - mPaints.appendVector(recorder.getPaints()); - mRegions.appendVector(recorder.getRegions()); - mPaths.appendVector(recorder.getPaths()); - mMatrices.appendVector(recorder.getMatrices()); -} - -void DisplayList::init() { - mSize = 0; - mIsRenderable = true; - mFunctorCount = 0; mLeft = 0; mTop = 0; mRight = 0; @@ -256,8 +87,28 @@ void DisplayList::init() { mCaching = false; } -size_t DisplayList::getSize() { - return mSize; +DisplayList::~DisplayList() { + LOG_ALWAYS_FATAL_IF(mDestroyed, "Double destroyed DisplayList %p", this); + + mDestroyed = true; + delete mDisplayListData; + delete mTransformMatrix; + delete mTransformCamera; + delete mTransformMatrix3D; + delete mStaticMatrix; + delete mAnimationMatrix; +} + +void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { + if (displayList) { + DISPLAY_LIST_LOGD("Deferring display list destruction"); + Caches::getInstance().deleteDisplayListDeferred(displayList); + } +} + +void DisplayList::setData(DisplayListData* data) { + delete mDisplayListData; + mDisplayListData = data; } /** @@ -518,7 +369,7 @@ void DisplayList::computeOrderingImpl( const mat4* transformFromProjectionSurface) { m3dNodes.clear(); mProjectedNodes.clear(); - if (mDisplayListData == NULL || mSize == 0) return; + if (mDisplayListData == NULL || mDisplayListData->isEmpty()) return; // TODO: should avoid this calculation in most cases // TODO: just calculate single matrix, down to all leaf composited elements @@ -716,10 +567,10 @@ void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, template <class T> void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) { if (CC_UNLIKELY(mDestroyed)) { // temporary debug logging - ALOGW("Error: %s is drawing after destruction, size %d", getName(), mSize); + ALOGW("Error: %s is drawing after destruction, size %d", getName()); CRASH(); } - if (mSize == 0 || mAlpha <= 0) { + if (mDisplayListData->isEmpty() || mAlpha <= 0) { DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string()); return; } @@ -777,5 +628,67 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) renderer.setOverrideLayerAlpha(1.0f); } +void DisplayListData::cleanupResources() { + Caches& caches = Caches::getInstance(); + caches.unregisterFunctors(functorCount); + caches.resourceCache.lock(); + + for (size_t i = 0; i < bitmapResources.size(); i++) { + caches.resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i)); + } + + for (size_t i = 0; i < ownedBitmapResources.size(); i++) { + const SkBitmap* bitmap = ownedBitmapResources.itemAt(i); + caches.resourceCache.decrementRefcountLocked(bitmap); + caches.resourceCache.destructorLocked(bitmap); + } + + for (size_t i = 0; i < patchResources.size(); i++) { + caches.resourceCache.decrementRefcountLocked(patchResources.itemAt(i)); + } + + for (size_t i = 0; i < shaders.size(); i++) { + caches.resourceCache.decrementRefcountLocked(shaders.itemAt(i)); + caches.resourceCache.destructorLocked(shaders.itemAt(i)); + } + + for (size_t i = 0; i < sourcePaths.size(); i++) { + caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i)); + } + + for (size_t i = 0; i < layers.size(); i++) { + caches.resourceCache.decrementRefcountLocked(layers.itemAt(i)); + } + + caches.resourceCache.unlock(); + + for (size_t i = 0; i < paints.size(); i++) { + delete paints.itemAt(i); + } + + for (size_t i = 0; i < regions.size(); i++) { + delete regions.itemAt(i); + } + + for (size_t i = 0; i < paths.size(); i++) { + delete paths.itemAt(i); + } + + for (size_t i = 0; i < matrices.size(); i++) { + delete matrices.itemAt(i); + } + + bitmapResources.clear(); + ownedBitmapResources.clear(); + patchResources.clear(); + shaders.clear(); + sourcePaths.clear(); + paints.clear(); + regions.clear(); + paths.clear(); + matrices.clear(); + layers.clear(); +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 9487fae00940..aba40b662533 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -107,11 +107,13 @@ public: }; /** - * Refcounted structure that holds the list of commands used in display list stream. + * Data structure that holds the list of commands used in display list stream */ -class DisplayListData : public LightRefBase<DisplayListData> { +class DisplayListData { public: - DisplayListData() : projectionReceiveIndex(-1) {} + DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {} + virtual ~DisplayListData() { cleanupResources(); } + // allocator into which all ops were allocated LinearAllocator allocator; @@ -123,6 +125,27 @@ public: // index of DisplayListOp restore, after which projected descendents should be drawn int projectionReceiveIndex; + + Vector<const SkBitmap*> bitmapResources; + Vector<const SkBitmap*> ownedBitmapResources; + Vector<const Res_png_9patch*> patchResources; + + Vector<const SkPaint*> paints; + Vector<const SkPath*> paths; + SortedVector<const SkPath*> sourcePaths; + Vector<const SkRegion*> regions; + Vector<const SkMatrix*> matrices; + Vector<SkiaShader*> shaders; + Vector<Layer*> layers; + uint32_t functorCount; + bool hasDrawOps; + + bool isEmpty() { + return !displayListOps.size(); + } + +private: + void cleanupResources(); }; /** @@ -139,7 +162,7 @@ public: */ class DisplayList { public: - DisplayList(const DisplayListRenderer& recorder); + ANDROID_API DisplayList(); ANDROID_API ~DisplayList(); // See flags defined in DisplayList.java @@ -147,11 +170,10 @@ public: kReplayFlag_ClipChildren = 0x1 }; - ANDROID_API size_t getSize(); ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); ANDROID_API static void outputLogBuffer(int fd); - void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); + ANDROID_API void setData(DisplayListData* newData); void computeOrdering(); void defer(DeferStateStruct& deferStruct, const int level); @@ -159,14 +181,8 @@ public: ANDROID_API void output(uint32_t level = 1); - ANDROID_API void reset(); - - void setRenderable(bool renderable) { - mIsRenderable = renderable; - } - bool isRenderable() const { - return mIsRenderable; + return mDisplayListData && mDisplayListData->hasDrawOps; } void setName(const char* name) { @@ -571,10 +587,6 @@ private: template <class T> inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); - void init(); - - void clearResources(); - void updateMatrix(); class TextContainer { @@ -591,24 +603,7 @@ private: const char* mText; }; - Vector<const SkBitmap*> mBitmapResources; - Vector<const SkBitmap*> mOwnedBitmapResources; - Vector<const Res_png_9patch*> mPatchResources; - - Vector<const SkPaint*> mPaints; - Vector<const SkPath*> mPaths; - SortedVector<const SkPath*> mSourcePaths; - Vector<const SkRegion*> mRegions; - Vector<const SkMatrix*> mMatrices; - Vector<SkiaShader*> mShaders; - Vector<Layer*> mLayers; - - sp<DisplayListData> mDisplayListData; - - size_t mSize; - - bool mIsRenderable; - uint32_t mFunctorCount; + DisplayListData* mDisplayListData; String8 mName; bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 0cbf08878964..5abfe79e08d8 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -32,83 +32,28 @@ namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer(): - mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData), + mCaches(Caches::getInstance()), mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), - mHasDrawOps(false), mFunctorCount(0) { + mRestoreSaveCount(-1), mDisplayListData(0) { } DisplayListRenderer::~DisplayListRenderer() { - reset(); + LOG_ALWAYS_FATAL_IF(mDisplayListData, + "Destroyed a DisplayListRenderer during a record!"); } -void DisplayListRenderer::reset() { - mDisplayListData = new DisplayListData(); - mCaches.resourceCache.lock(); - - for (size_t i = 0; i < mBitmapResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); - } - - for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i)); - } - - for (size_t i = 0; i < mPatchResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i)); - } - - for (size_t i = 0; i < mShaders.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); - } - - for (size_t i = 0; i < mSourcePaths.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); - } - - for (size_t i = 0; i < mLayers.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i)); - } - - mCaches.resourceCache.unlock(); - - mBitmapResources.clear(); - mOwnedBitmapResources.clear(); - mPatchResources.clear(); - mSourcePaths.clear(); +/////////////////////////////////////////////////////////////////////////////// +// Operations +/////////////////////////////////////////////////////////////////////////////// - mShaders.clear(); +DisplayListData* DisplayListRenderer::finishRecording() { mShaderMap.clear(); - - mPaints.clear(); mPaintMap.clear(); - - mRegions.clear(); mRegionMap.clear(); - - mPaths.clear(); mPathMap.clear(); - - mMatrices.clear(); - - mLayers.clear(); - - mHasDrawOps = false; - mFunctorCount = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Operations -/////////////////////////////////////////////////////////////////////////////// - -DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { - if (!displayList) { - displayList = new DisplayList(*this); - } else { - displayList->initFromDisplayListRenderer(*this, true); - } - // TODO: should just avoid setting the DisplayList's DisplayListData - displayList->setRenderable(mHasDrawOps); - return displayList; + DisplayListData* data = mDisplayListData; + mDisplayListData = 0; + return data; } void DisplayListRenderer::setViewport(int width, int height) { @@ -120,6 +65,11 @@ void DisplayListRenderer::setViewport(int width, int height) { status_t DisplayListRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { + + LOG_ALWAYS_FATAL_IF(mDisplayListData, + "prepareDirty called a second time during a recording!"); + mDisplayListData = new DisplayListData(); + initializeSaveStack(0, 0, getWidth(), getHeight()); mDirtyClip = opaque; @@ -142,7 +92,7 @@ void DisplayListRenderer::resume() { status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay addDrawOp(new (alloc()) DrawFunctorOp(functor)); - mFunctorCount++; + mDisplayListData->functorCount++; return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } @@ -501,7 +451,7 @@ void DisplayListRenderer::addDrawOp(DrawOp* op) { op->setQuickRejected(rejected); } - mHasDrawOps = true; + mDisplayListData->hasDrawOps = true; addOpInternal(op); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 7e62c5d39ecf..6c11e5976ae3 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -61,7 +61,7 @@ public: ANDROID_API DisplayListRenderer(); virtual ~DisplayListRenderer(); - ANDROID_API DisplayList* getDisplayList(DisplayList* displayList); + ANDROID_API DisplayListData* finishRecording(); virtual bool isRecording() const { return true; } @@ -162,59 +162,6 @@ public: // TODO: rename for consistency virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); -// ---------------------------------------------------------------------------- -// DisplayList / resource management -// ---------------------------------------------------------------------------- - ANDROID_API void reset(); - - sp<DisplayListData> getDisplayListData() const { - return mDisplayListData; - } - - const Vector<const SkBitmap*>& getBitmapResources() const { - return mBitmapResources; - } - - const Vector<const SkBitmap*>& getOwnedBitmapResources() const { - return mOwnedBitmapResources; - } - - const Vector<const Res_png_9patch*>& getPatchResources() const { - return mPatchResources; - } - - const Vector<SkiaShader*>& getShaders() const { - return mShaders; - } - - const Vector<const SkPaint*>& getPaints() const { - return mPaints; - } - - const Vector<const SkPath*>& getPaths() const { - return mPaths; - } - - const SortedVector<const SkPath*>& getSourcePaths() const { - return mSourcePaths; - } - - const Vector<const SkRegion*>& getRegions() const { - return mRegions; - } - - const Vector<Layer*>& getLayers() const { - return mLayers; - } - - const Vector<const SkMatrix*>& getMatrices() const { - return mMatrices; - } - - uint32_t getFunctorCount() const { - return mFunctorCount; - } - private: void insertRestoreToCount(); void insertTranslate(); @@ -252,11 +199,11 @@ private: pathCopy = newPathCopy; // replaceValueFor() performs an add if the entry doesn't exist mPathMap.replaceValueFor(path, pathCopy); - mPaths.add(pathCopy); + mDisplayListData->paths.add(pathCopy); } - if (mSourcePaths.indexOf(path) < 0) { + if (mDisplayListData->sourcePaths.indexOf(path) < 0) { mCaches.resourceCache.incrementRefcount(path); - mSourcePaths.add(path); + mDisplayListData->sourcePaths.add(path); } return pathCopy; } @@ -271,7 +218,7 @@ private: paintCopy = new SkPaint(*paint); // replaceValueFor() performs an add if the entry doesn't exist mPaintMap.replaceValueFor(paint, paintCopy); - mPaints.add(paintCopy); + mDisplayListData->paints.add(paintCopy); } return paintCopy; @@ -288,7 +235,7 @@ private: regionCopy = new SkRegion(*region); // replaceValueFor() performs an add if the entry doesn't exist mRegionMap.replaceValueFor(region, regionCopy); - mRegions.add(regionCopy); + mDisplayListData->regions.add(regionCopy); } return regionCopy; @@ -299,14 +246,14 @@ private: // Copying the matrix is cheap and prevents against the user changing // the original matrix before the operation that uses it const SkMatrix* copy = new SkMatrix(*matrix); - mMatrices.add(copy); + mDisplayListData->matrices.add(copy); return copy; } return matrix; } inline Layer* refLayer(Layer* layer) { - mLayers.add(layer); + mDisplayListData->layers.add(layer); mCaches.resourceCache.incrementRefcount(layer); return layer; } @@ -316,13 +263,13 @@ private: // correctly, such as creating the bitmap from scratch, drawing with it, changing its // contents, and drawing again. The only fix would be to always copy it the first time, // which doesn't seem worth the extra cycles for this unlikely case. - mBitmapResources.add(bitmap); + mDisplayListData->bitmapResources.add(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); return bitmap; } inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) { - mOwnedBitmapResources.add(bitmap); + mDisplayListData->ownedBitmapResources.add(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); return bitmap; } @@ -336,52 +283,31 @@ private: shaderCopy = shader->copy(); // replaceValueFor() performs an add if the entry doesn't exist mShaderMap.replaceValueFor(shader, shaderCopy); - mShaders.add(shaderCopy); + mDisplayListData->shaders.add(shaderCopy); mCaches.resourceCache.incrementRefcount(shaderCopy); } return shaderCopy; } inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { - mPatchResources.add(patch); + mDisplayListData->patchResources.add(patch); mCaches.resourceCache.incrementRefcount(patch); return patch; } - // TODO: move these to DisplayListData - Vector<const SkBitmap*> mBitmapResources; - Vector<const SkBitmap*> mOwnedBitmapResources; - Vector<const Res_png_9patch*> mPatchResources; - - Vector<const SkPaint*> mPaints; DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap; - - Vector<const SkPath*> mPaths; DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; - - SortedVector<const SkPath*> mSourcePaths; - - Vector<const SkRegion*> mRegions; DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; - - Vector<SkiaShader*> mShaders; DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; - Vector<const SkMatrix*> mMatrices; - - Vector<Layer*> mLayers; - int mRestoreSaveCount; Caches& mCaches; - sp<DisplayListData> mDisplayListData; + DisplayListData* mDisplayListData; float mTranslateX; float mTranslateY; bool mHasTranslate; - bool mHasDrawOps; - - uint32_t mFunctorCount; friend class DisplayList; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index fe781bd771f9..056885129bfa 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -373,6 +373,10 @@ void CanvasContext::setup(int width, int height) { mCanvas->setViewport(width, height); } +void CanvasContext::swapDisplayListData(DisplayList* displayList, DisplayListData* newData) { + displayList->setData(newData); +} + void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) { mGlobalContext->makeCurrent(mEglSurface); for (size_t i = 0; i < layerUpdaters->size(); i++) { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 5fac5821f99d..2c9348cd55b5 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -32,6 +32,7 @@ namespace uirenderer { class DeferredLayerUpdater; class DisplayList; +class DisplayListData; class OpenGLRenderer; class Rect; @@ -62,6 +63,7 @@ public: bool initialize(EGLNativeWindowType window); void updateSurface(EGLNativeWindowType window); void setup(int width, int height); + void swapDisplayListData(DisplayList* displayList, DisplayListData* newData); void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters); void drawDisplayList(DisplayList* displayList, Rect* dirty); void destroyCanvas(); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 0c667fd0046f..c3bf404115f1 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -117,6 +117,20 @@ void RenderProxy::setup(int width, int height) { post(task); } +CREATE_BRIDGE3(swapDisplayListData, CanvasContext* context, DisplayList* displayList, + DisplayListData* newData) { + args->context->swapDisplayListData(args->displayList, args->newData); + return NULL; +} + +void RenderProxy::swapDisplayListData(DisplayList* displayList, DisplayListData* newData) { + SETUP_TASK(swapDisplayListData); + args->context = mContext; + args->displayList = displayList; + args->newData = newData; + post(task); +} + CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList, Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) { Rect* dirty = &args->dirty; diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 8ff3d638feca..0934b981db91 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -33,6 +33,7 @@ namespace uirenderer { class DeferredLayerUpdater; class DisplayList; +class DisplayListData; class Layer; class Rect; @@ -59,6 +60,7 @@ public: ANDROID_API bool initialize(EGLNativeWindowType window); ANDROID_API void updateSurface(EGLNativeWindowType window); ANDROID_API void setup(int width, int height); + ANDROID_API void swapDisplayListData(DisplayList* displayList, DisplayListData* newData); ANDROID_API void drawDisplayList(DisplayList* displayList, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); ANDROID_API void destroyCanvas(); |