DisplayList overhaul
Change-Id: I53418d580c98f706e971545cff81b9921c12cc5f
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index dfc74ea..3060e6e 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -19,8 +19,6 @@
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 @@
* @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 static final int STATUS_DREW = 0x4;
private DisplayList(String name) {
- mName = name;
+ mNativeDisplayList = nCreate();
+ nSetDisplayListName(mNativeDisplayList, name);
}
/**
@@ -221,19 +210,11 @@
* @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 @@
* @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 @@
* 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 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 @@
* @hide
*/
public void setCaching(boolean caching) {
- if (hasNativeDisplayList()) {
- nSetCaching(mFinalizer.mNativeDisplayList, caching);
- }
+ nSetCaching(mNativeDisplayList, caching);
}
/**
@@ -398,9 +302,7 @@
* @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 @@
* @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 @@
* containing volume.
*/
public void setProjectBackwards(boolean shouldProject) {
- if (hasNativeDisplayList()) {
- nSetProjectBackwards(mFinalizer.mNativeDisplayList, shouldProject);
- }
+ nSetProjectBackwards(mNativeDisplayList, shouldProject);
}
/**
@@ -436,9 +334,7 @@
* 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 @@
* @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 @@
* @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 @@
* 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 @@
* 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 @@
* @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 @@
* @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 @@
* @see #getAlpha()
*/
public void setAlpha(float alpha) {
- if (hasNativeDisplayList()) {
- nSetAlpha(mFinalizer.mNativeDisplayList, alpha);
- }
+ nSetAlpha(mNativeDisplayList, alpha);
}
/**
@@ -575,10 +426,7 @@
* @see #setAlpha(float)
*/
public float getAlpha() {
- if (hasNativeDisplayList()) {
- return nGetAlpha(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
+ return nGetAlpha(mNativeDisplayList);
}
/**
@@ -593,9 +441,7 @@
* @see #hasOverlappingRendering()
*/
public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
- if (hasNativeDisplayList()) {
- nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering);
- }
+ nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
}
/**
@@ -607,10 +453,7 @@
*/
public boolean hasOverlappingRendering() {
//noinspection SimplifiableIfStatement
- if (hasNativeDisplayList()) {
- return nHasOverlappingRendering(mFinalizer.mNativeDisplayList);
- }
- return true;
+ return nHasOverlappingRendering(mNativeDisplayList);
}
/**
@@ -622,9 +465,7 @@
* @see #getTranslationX()
*/
public void setTranslationX(float translationX) {
- if (hasNativeDisplayList()) {
- nSetTranslationX(mFinalizer.mNativeDisplayList, translationX);
- }
+ nSetTranslationX(mNativeDisplayList, translationX);
}
/**
@@ -633,10 +474,7 @@
* @see #setTranslationX(float)
*/
public float getTranslationX() {
- if (hasNativeDisplayList()) {
- return nGetTranslationX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetTranslationX(mNativeDisplayList);
}
/**
@@ -648,9 +486,7 @@
* @see #getTranslationY()
*/
public void setTranslationY(float translationY) {
- if (hasNativeDisplayList()) {
- nSetTranslationY(mFinalizer.mNativeDisplayList, translationY);
- }
+ nSetTranslationY(mNativeDisplayList, translationY);
}
/**
@@ -659,10 +495,7 @@
* @see #setTranslationY(float)
*/
public float getTranslationY() {
- if (hasNativeDisplayList()) {
- return nGetTranslationY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetTranslationY(mNativeDisplayList);
}
/**
@@ -672,9 +505,7 @@
* @see #getTranslationZ()
*/
public void setTranslationZ(float translationZ) {
- if (hasNativeDisplayList()) {
- nSetTranslationZ(mFinalizer.mNativeDisplayList, translationZ);
- }
+ nSetTranslationZ(mNativeDisplayList, translationZ);
}
/**
@@ -683,10 +514,7 @@
* @see #setTranslationZ(float)
*/
public float getTranslationZ() {
- if (hasNativeDisplayList()) {
- return nGetTranslationZ(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetTranslationZ(mNativeDisplayList);
}
/**
@@ -698,9 +526,7 @@
* @see #getRotation()
*/
public void setRotation(float rotation) {
- if (hasNativeDisplayList()) {
- nSetRotation(mFinalizer.mNativeDisplayList, rotation);
- }
+ nSetRotation(mNativeDisplayList, rotation);
}
/**
@@ -709,10 +535,7 @@
* @see #setRotation(float)
*/
public float getRotation() {
- if (hasNativeDisplayList()) {
- return nGetRotation(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetRotation(mNativeDisplayList);
}
/**
@@ -724,9 +547,7 @@
* @see #getRotationX()
*/
public void setRotationX(float rotationX) {
- if (hasNativeDisplayList()) {
- nSetRotationX(mFinalizer.mNativeDisplayList, rotationX);
- }
+ nSetRotationX(mNativeDisplayList, rotationX);
}
/**
@@ -735,10 +556,7 @@
* @see #setRotationX(float)
*/
public float getRotationX() {
- if (hasNativeDisplayList()) {
- return nGetRotationX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetRotationX(mNativeDisplayList);
}
/**
@@ -750,9 +568,7 @@
* @see #getRotationY()
*/
public void setRotationY(float rotationY) {
- if (hasNativeDisplayList()) {
- nSetRotationY(mFinalizer.mNativeDisplayList, rotationY);
- }
+ nSetRotationY(mNativeDisplayList, rotationY);
}
/**
@@ -761,10 +577,7 @@
* @see #setRotationY(float)
*/
public float getRotationY() {
- if (hasNativeDisplayList()) {
- return nGetRotationY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetRotationY(mNativeDisplayList);
}
/**
@@ -776,9 +589,7 @@
* @see #getScaleX()
*/
public void setScaleX(float scaleX) {
- if (hasNativeDisplayList()) {
- nSetScaleX(mFinalizer.mNativeDisplayList, scaleX);
- }
+ nSetScaleX(mNativeDisplayList, scaleX);
}
/**
@@ -787,10 +598,7 @@
* @see #setScaleX(float)
*/
public float getScaleX() {
- if (hasNativeDisplayList()) {
- return nGetScaleX(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
+ return nGetScaleX(mNativeDisplayList);
}
/**
@@ -802,9 +610,7 @@
* @see #getScaleY()
*/
public void setScaleY(float scaleY) {
- if (hasNativeDisplayList()) {
- nSetScaleY(mFinalizer.mNativeDisplayList, scaleY);
- }
+ nSetScaleY(mNativeDisplayList, scaleY);
}
/**
@@ -813,10 +619,7 @@
* @see #setScaleY(float)
*/
public float getScaleY() {
- if (hasNativeDisplayList()) {
- return nGetScaleY(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
+ return nGetScaleY(mNativeDisplayList);
}
/**
@@ -836,11 +639,9 @@
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 @@
* @see #getPivotX()
*/
public void setPivotX(float pivotX) {
- if (hasNativeDisplayList()) {
- nSetPivotX(mFinalizer.mNativeDisplayList, pivotX);
- }
+ nSetPivotX(mNativeDisplayList, pivotX);
}
/**
@@ -863,10 +662,7 @@
* @see #setPivotX(float)
*/
public float getPivotX() {
- if (hasNativeDisplayList()) {
- return nGetPivotX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetPivotX(mNativeDisplayList);
}
/**
@@ -878,9 +674,7 @@
* @see #getPivotY()
*/
public void setPivotY(float pivotY) {
- if (hasNativeDisplayList()) {
- nSetPivotY(mFinalizer.mNativeDisplayList, pivotY);
- }
+ nSetPivotY(mNativeDisplayList, pivotY);
}
/**
@@ -889,10 +683,7 @@
* @see #setPivotY(float)
*/
public float getPivotY() {
- if (hasNativeDisplayList()) {
- return nGetPivotY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetPivotY(mNativeDisplayList);
}
/**
@@ -906,9 +697,7 @@
* @see #getCameraDistance()
*/
public void setCameraDistance(float distance) {
- if (hasNativeDisplayList()) {
- nSetCameraDistance(mFinalizer.mNativeDisplayList, distance);
- }
+ nSetCameraDistance(mNativeDisplayList, distance);
}
/**
@@ -917,10 +706,7 @@
* @see #setCameraDistance(float)
*/
public float getCameraDistance() {
- if (hasNativeDisplayList()) {
- return nGetCameraDistance(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetCameraDistance(mNativeDisplayList);
}
/**
@@ -932,9 +718,7 @@
* @see #getLeft()
*/
public void setLeft(int left) {
- if (hasNativeDisplayList()) {
- nSetLeft(mFinalizer.mNativeDisplayList, left);
- }
+ nSetLeft(mNativeDisplayList, left);
}
/**
@@ -943,10 +727,7 @@
* @see #setLeft(int)
*/
public float getLeft() {
- if (hasNativeDisplayList()) {
- return nGetLeft(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetLeft(mNativeDisplayList);
}
/**
@@ -958,9 +739,7 @@
* @see #getTop()
*/
public void setTop(int top) {
- if (hasNativeDisplayList()) {
- nSetTop(mFinalizer.mNativeDisplayList, top);
- }
+ nSetTop(mNativeDisplayList, top);
}
/**
@@ -969,10 +748,7 @@
* @see #setTop(int)
*/
public float getTop() {
- if (hasNativeDisplayList()) {
- return nGetTop(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetTop(mNativeDisplayList);
}
/**
@@ -984,9 +760,7 @@
* @see #getRight()
*/
public void setRight(int right) {
- if (hasNativeDisplayList()) {
- nSetRight(mFinalizer.mNativeDisplayList, right);
- }
+ nSetRight(mNativeDisplayList, right);
}
/**
@@ -995,10 +769,7 @@
* @see #setRight(int)
*/
public float getRight() {
- if (hasNativeDisplayList()) {
- return nGetRight(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetRight(mNativeDisplayList);
}
/**
@@ -1010,9 +781,7 @@
* @see #getBottom()
*/
public void setBottom(int bottom) {
- if (hasNativeDisplayList()) {
- nSetBottom(mFinalizer.mNativeDisplayList, bottom);
- }
+ nSetBottom(mNativeDisplayList, bottom);
}
/**
@@ -1021,10 +790,7 @@
* @see #setBottom(int)
*/
public float getBottom() {
- if (hasNativeDisplayList()) {
- return nGetBottom(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
+ return nGetBottom(mNativeDisplayList);
}
/**
@@ -1041,9 +807,7 @@
* @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 @@
* @see View#offsetLeftAndRight(int)
*/
public void offsetLeftAndRight(float offset) {
- if (hasNativeDisplayList()) {
- nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset);
- }
+ nOffsetLeftAndRight(mNativeDisplayList, offset);
}
/**
@@ -1069,9 +831,7 @@
* @see View#offsetTopAndBottom(int)
*/
public void offsetTopAndBottom(float offset) {
- if (hasNativeDisplayList()) {
- nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset);
- }
+ nOffsetTopAndBottom(mNativeDisplayList, offset);
}
/**
@@ -1081,22 +841,19 @@
* @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 @@
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 @@
// 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 a08d83a..6c6fc9b 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -18,7 +18,6 @@
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 @@
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 @@
}
}
- 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 @@
// 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 b7b6883..2b29e5c 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 @@
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 4c92e950..c90e4b0 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1196,6 +1196,11 @@
}
}
+ 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 8900d23..c526dd2 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -88,7 +88,7 @@
}
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 7a943f0..bcc28e3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -562,6 +562,8 @@
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 e8f5e45..3dcfbb3 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -148,6 +148,11 @@
}
@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 @@
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 99aee29..5936902 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7984,8 +7984,6 @@
* @hide
*/
public void dispatchStartTemporaryDetach() {
- clearDisplayList();
-
onStartTemporaryDetach();
}
@@ -9386,7 +9384,7 @@
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();
}
@@ -12813,14 +12811,6 @@
InputMethodManager imm = InputMethodManager.peekInstance();
imm.focusIn(this);
}
-
- if (mDisplayList != null) {
- mDisplayList.clearDirty();
- }
-
- if (mBackgroundDisplayList != null) {
- mBackgroundDisplayList.clearDirty();
- }
}
/**
@@ -13138,21 +13128,8 @@
}
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);
}
/**
@@ -14032,7 +14009,7 @@
}
}
} finally {
- displayList.end();
+ displayList.end(getHardwareRenderer(), canvas);
displayList.setCaching(caching);
if (isLayer) {
displayList.setLeftTopRightBottom(0, 0, width, height);
@@ -14061,23 +14038,14 @@
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);
}
}
@@ -14700,7 +14668,7 @@
alpha = t.getAlpha();
}
if ((transformType & Transformation.TYPE_MATRIX) != 0) {
- displayList.setMatrix(t.getMatrix());
+ displayList.setStaticMatrix(t.getMatrix());
}
}
}
@@ -15333,7 +15301,7 @@
* @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());
}
@@ -15343,7 +15311,7 @@
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 a338e6e..3af1c4f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -56,6 +56,7 @@
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.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 @@
private long mFpsPrevTime = -1;
private int mFpsNumFrames;
- private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>();
-
/**
* see {@link #playSoundEffect(int)}
*/
@@ -620,7 +618,6 @@
}
void destroyHardwareResources() {
- invalidateDisplayLists();
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
mAttachInfo.mHardwareRenderer.destroy(false);
@@ -634,7 +631,6 @@
HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
}
} else {
- invalidateDisplayLists();
destroyHardwareLayer(mView);
}
}
@@ -1503,7 +1499,7 @@
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 @@
appScale + ", width=" + mWidth + ", height=" + mHeight);
}
- invalidateDisplayLists();
-
attachInfo.mTreeObserver.dispatchOnDraw();
if (!dirty.isEmpty() || mIsAnimating) {
@@ -2588,20 +2582,6 @@
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 @@
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 @@
}
if (mAdded && !mFirst) {
- invalidateDisplayLists();
destroyHardwareRenderer();
if (mView != null) {
@@ -5743,10 +5722,6 @@
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 ea62bbe..84c1586 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -23,6 +23,7 @@
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.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 @@
layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical,
firstLine, lastLine);
+ final HardwareRenderer renderer = mTextView.getHardwareRenderer();
if (layout instanceof DynamicLayout) {
if (mTextDisplayLists == null) {
@@ -1345,8 +1348,6 @@
if (blockDisplayList == null) {
blockDisplayList = mTextDisplayLists[blockIndex] =
DisplayList.create("Text " + blockIndex);
- } else {
- if (blockIsInvalid) blockDisplayList.clear();
}
final boolean blockDisplayListIsInvalid = !blockDisplayList.isValid();
@@ -1379,7 +1380,7 @@
// 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 @@
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 @@
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 e47e23c..c8952c1 100644
--- a/core/jni/android_view_DisplayList.cpp
+++ b/core/jni/android_view_DisplayList.cpp
@@ -41,18 +41,6 @@
// 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 @@
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 @@
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 @@
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 @@
{ "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 4e353fa..a4e6679 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -864,22 +864,15 @@
// Display lists
// ----------------------------------------------------------------------------
-static jint android_view_GLES20Canvas_getDisplayList(JNIEnv* env,
- jobject clazz, jlong rendererPtr, jlong displayListPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
- return reinterpret_cast<jint>(renderer->getDisplayList(displayList));
-}
-
-static jint android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
- jobject clazz) {
- return reinterpret_cast<jint>(new DisplayListRenderer);
-}
-
-static void android_view_GLES20Canvas_resetDisplayListRenderer(JNIEnv* env,
+static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env,
jobject clazz, jlong rendererPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->reset();
+ return reinterpret_cast<jlong>(renderer->finishRecording());
+}
+
+static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
+ jobject clazz) {
+ return reinterpret_cast<jlong>(new DisplayListRenderer);
}
static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
@@ -1094,12 +1087,11 @@
{ "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 5c5b52c..5ea8460 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 @@
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 @@
{ "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 bc5c06e..444c8be 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -103,6 +103,14 @@
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 @@
{ "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 23c33ca..112f8d3f 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -48,179 +48,10 @@
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 @@
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 @@
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 @@
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 @@
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 9487fae..aba40b6 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -107,11 +107,13 @@
};
/**
- * 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 @@
// 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 @@
*/
class DisplayList {
public:
- DisplayList(const DisplayListRenderer& recorder);
+ ANDROID_API DisplayList();
ANDROID_API ~DisplayList();
// See flags defined in DisplayList.java
@@ -147,11 +170,10 @@
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 @@
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 @@
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 @@
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 0cbf088..5abfe79 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -32,83 +32,28 @@
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();
-}
-
-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();
-
- mShaders.clear();
- mShaderMap.clear();
-
- mPaints.clear();
- mPaintMap.clear();
-
- mRegions.clear();
- mRegionMap.clear();
-
- mPaths.clear();
- mPathMap.clear();
-
- mMatrices.clear();
-
- mLayers.clear();
-
- mHasDrawOps = false;
- mFunctorCount = 0;
+ LOG_ALWAYS_FATAL_IF(mDisplayListData,
+ "Destroyed a DisplayListRenderer during a record!");
}
///////////////////////////////////////////////////////////////////////////////
// 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* DisplayListRenderer::finishRecording() {
+ mShaderMap.clear();
+ mPaintMap.clear();
+ mRegionMap.clear();
+ mPathMap.clear();
+ DisplayListData* data = mDisplayListData;
+ mDisplayListData = 0;
+ return data;
}
void DisplayListRenderer::setViewport(int width, int height) {
@@ -120,6 +65,11 @@
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 @@
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 @@
op->setQuickRejected(rejected);
}
- mHasDrawOps = true;
+ mDisplayListData->hasDrawOps = true;
addOpInternal(op);
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 7e62c5d..6c11e59 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -61,7 +61,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 fe781bd..0568851 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -373,6 +373,10 @@
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 5fac582..2c9348c 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -32,6 +32,7 @@
class DeferredLayerUpdater;
class DisplayList;
+class DisplayListData;
class OpenGLRenderer;
class Rect;
@@ -62,6 +63,7 @@
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 0c667fd..c3bf404 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -117,6 +117,20 @@
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 8ff3d63..0934b98 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -33,6 +33,7 @@
class DeferredLayerUpdater;
class DisplayList;
+class DisplayListData;
class Layer;
class Rect;
@@ -59,6 +60,7 @@
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();