summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLRenderer.java22
-rw-r--r--core/java/android/view/HardwareLayer.java105
-rw-r--r--core/java/android/view/HardwareRenderer.java6
-rw-r--r--core/java/android/view/ThreadedRenderer.java12
-rw-r--r--core/java/com/android/internal/util/VirtualRefBasePtr.java10
-rw-r--r--core/jni/android_view_HardwareLayer.cpp18
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp14
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp17
-rw-r--r--libs/hwui/DeferredLayerUpdater.h14
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp26
-rw-r--r--libs/hwui/renderthread/CanvasContext.h6
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp31
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.h13
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp33
-rw-r--r--libs/hwui/renderthread/RenderProxy.h3
15 files changed, 135 insertions, 195 deletions
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index 64a4c41..f1163e2 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -178,7 +178,7 @@ public class GLRenderer extends HardwareRenderer {
private static EGLSurface sPbuffer;
private static final Object[] sPbufferLock = new Object[0];
- private List<HardwareLayer> mAttachedLayers = new ArrayList<HardwareLayer>();
+ private List<HardwareLayer> mLayerUpdates = new ArrayList<HardwareLayer>();
private static class GLRendererEglContext extends ManagedEGLContext {
final Handler mHandler = new Handler();
@@ -471,7 +471,7 @@ public class GLRenderer extends HardwareRenderer {
@Override
void pushLayerUpdate(HardwareLayer layer) {
- mGlCanvas.pushLayerUpdate(layer);
+ mLayerUpdates.add(layer);
}
@Override
@@ -494,11 +494,6 @@ public class GLRenderer extends HardwareRenderer {
return HardwareLayer.createDisplayListLayer(this, width, height);
}
- @Override
- void onLayerCreated(HardwareLayer hardwareLayer) {
- mAttachedLayers.add(hardwareLayer);
- }
-
boolean hasContext() {
return sEgl != null && mEglContext != null
&& mEglContext.equals(sEgl.eglGetCurrentContext());
@@ -509,11 +504,7 @@ public class GLRenderer extends HardwareRenderer {
if (mGlCanvas != null) {
mGlCanvas.cancelLayerUpdate(layer);
}
- if (hasContext()) {
- long backingLayer = layer.detachBackingLayer();
- nDestroyLayer(backingLayer);
- }
- mAttachedLayers.remove(layer);
+ mLayerUpdates.remove(layer);
}
@Override
@@ -1198,16 +1189,19 @@ public class GLRenderer extends HardwareRenderer {
private void flushLayerChanges() {
// Loop through and apply any pending layer changes
- for (int i = 0; i < mAttachedLayers.size(); i++) {
- HardwareLayer layer = mAttachedLayers.get(i);
+ for (int i = 0; i < mLayerUpdates.size(); i++) {
+ HardwareLayer layer = mLayerUpdates.get(i);
layer.flushChanges();
if (!layer.isValid()) {
// The layer was removed from mAttachedLayers, rewind i by 1
// Note that this shouldn't actually happen as View.getHardwareLayer()
// is already flushing for error checking reasons
i--;
+ } else if (layer.hasDisplayList()) {
+ mCanvas.pushLayerUpdate(layer);
}
}
+ mLayerUpdates.clear();
}
@Override
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 4d78733..652bcd2 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -22,6 +22,8 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import com.android.internal.util.VirtualRefBasePtr;
+
/**
* A hardware layer can be used to render graphics operations into a hardware
* friendly buffer. For instance, with an OpenGL backend a hardware layer
@@ -36,7 +38,7 @@ final class HardwareLayer {
private static final int LAYER_TYPE_DISPLAY_LIST = 2;
private HardwareRenderer mRenderer;
- private Finalizer mFinalizer;
+ private VirtualRefBasePtr mFinalizer;
private RenderNode mDisplayList;
private final int mLayerType;
@@ -47,10 +49,7 @@ final class HardwareLayer {
}
mRenderer = renderer;
mLayerType = type;
- mFinalizer = new Finalizer(deferredUpdater);
-
- // Layer is considered initialized at this point, notify the HardwareRenderer
- mRenderer.onLayerCreated(this);
+ mFinalizer = new VirtualRefBasePtr(deferredUpdater);
}
private void assertType(int type) {
@@ -59,6 +58,10 @@ final class HardwareLayer {
}
}
+ boolean hasDisplayList() {
+ return mDisplayList != null;
+ }
+
/**
* Update the paint used when drawing this layer.
*
@@ -66,7 +69,8 @@ final class HardwareLayer {
* @see View#setLayerPaint(android.graphics.Paint)
*/
public void setLayerPaint(Paint paint) {
- nSetLayerPaint(mFinalizer.mDeferredUpdater, paint.mNativePaint);
+ nSetLayerPaint(mFinalizer.get(), paint.mNativePaint);
+ mRenderer.pushLayerUpdate(this);
}
/**
@@ -75,7 +79,7 @@ final class HardwareLayer {
* @return True if the layer can be rendered into, false otherwise
*/
public boolean isValid() {
- return mFinalizer != null && mFinalizer.mDeferredUpdater != 0;
+ return mFinalizer != null && mFinalizer.get() != 0;
}
/**
@@ -91,35 +95,14 @@ final class HardwareLayer {
mDisplayList.destroyDisplayListData();
mDisplayList = null;
}
- if (mRenderer != null) {
- mRenderer.onLayerDestroyed(this);
- mRenderer = null;
- }
- doDestroyLayerUpdater();
+ mRenderer.onLayerDestroyed(this);
+ mRenderer = null;
+ mFinalizer.release();
+ mFinalizer = null;
}
public long getDeferredLayerUpdater() {
- return mFinalizer.mDeferredUpdater;
- }
-
- /**
- * Destroys the deferred layer updater but not the backing layer. The
- * backing layer is instead returned and is the caller's responsibility
- * to destroy/recycle as appropriate.
- *
- * It is safe to call this in onLayerDestroyed only
- */
- public long detachBackingLayer() {
- long backingLayer = nDetachBackingLayer(mFinalizer.mDeferredUpdater);
- doDestroyLayerUpdater();
- return backingLayer;
- }
-
- private void doDestroyLayerUpdater() {
- if (mFinalizer != null) {
- mFinalizer.destroy();
- mFinalizer = null;
- }
+ return mFinalizer.get();
}
public RenderNode startRecording() {
@@ -132,7 +115,7 @@ final class HardwareLayer {
}
public void endRecording(Rect dirtyRect) {
- nUpdateRenderLayer(mFinalizer.mDeferredUpdater, mDisplayList.getNativeDisplayList(),
+ nUpdateRenderLayer(mFinalizer.get(), mDisplayList.getNativeDisplayList(),
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
mRenderer.pushLayerUpdate(this);
}
@@ -160,7 +143,7 @@ final class HardwareLayer {
* match the desired values.
*/
public boolean prepare(int width, int height, boolean isOpaque) {
- return nPrepare(mFinalizer.mDeferredUpdater, width, height, isOpaque);
+ return nPrepare(mFinalizer.get(), width, height, isOpaque);
}
/**
@@ -169,7 +152,8 @@ final class HardwareLayer {
* @param matrix The transform to apply to the layer.
*/
public void setTransform(Matrix matrix) {
- nSetTransform(mFinalizer.mDeferredUpdater, matrix.native_instance);
+ nSetTransform(mFinalizer.get(), matrix.native_instance);
+ mRenderer.pushLayerUpdate(this);
}
/**
@@ -183,7 +167,7 @@ final class HardwareLayer {
surface.detachFromGLContext();
// SurfaceTexture owns the texture name and detachFromGLContext
// should have deleted it
- nOnTextureDestroyed(mFinalizer.mDeferredUpdater);
+ nOnTextureDestroyed(mFinalizer.get());
}
});
}
@@ -200,24 +184,26 @@ final class HardwareLayer {
return;
}
- boolean success = nFlushChanges(mFinalizer.mDeferredUpdater);
+ boolean success = nFlushChanges(mFinalizer.get());
if (!success) {
destroy();
}
}
public long getLayer() {
- return nGetLayer(mFinalizer.mDeferredUpdater);
+ return nGetLayer(mFinalizer.get());
}
public void setSurfaceTexture(SurfaceTexture surface) {
assertType(LAYER_TYPE_TEXTURE);
- nSetSurfaceTexture(mFinalizer.mDeferredUpdater, surface, false);
+ nSetSurfaceTexture(mFinalizer.get(), surface, false);
+ mRenderer.pushLayerUpdate(this);
}
public void updateSurfaceTexture() {
assertType(LAYER_TYPE_TEXTURE);
- nUpdateSurfaceTexture(mFinalizer.mDeferredUpdater);
+ nUpdateSurfaceTexture(mFinalizer.get());
+ mRenderer.pushLayerUpdate(this);
}
/**
@@ -225,8 +211,8 @@ final class HardwareLayer {
*/
SurfaceTexture createSurfaceTexture() {
assertType(LAYER_TYPE_TEXTURE);
- SurfaceTexture st = new SurfaceTexture(nGetTexName(mFinalizer.mDeferredUpdater));
- nSetSurfaceTexture(mFinalizer.mDeferredUpdater, st, true);
+ SurfaceTexture st = new SurfaceTexture(nGetTexName(mFinalizer.get()));
+ nSetSurfaceTexture(mFinalizer.get(), st, true);
return st;
}
@@ -258,15 +244,6 @@ final class HardwareLayer {
private static native long nCreateRenderLayer(int width, int height);
private static native void nOnTextureDestroyed(long layerUpdater);
- private static native long nDetachBackingLayer(long layerUpdater);
-
- /** This also destroys the underlying layer if it is still attached.
- * Note it does not recycle the underlying layer, but instead queues it
- * for deferred deletion.
- * The HardwareRenderer should use detachBackingLayer() in the
- * onLayerDestroyed() callback to do recycling if desired.
- */
- private static native void nDestroyLayerUpdater(long layerUpdater);
private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
private static native void nSetLayerPaint(long layerUpdater, long paint);
@@ -281,28 +258,4 @@ final class HardwareLayer {
private static native long nGetLayer(long layerUpdater);
private static native int nGetTexName(long layerUpdater);
-
- private static class Finalizer {
- private long mDeferredUpdater;
-
- public Finalizer(long deferredUpdater) {
- mDeferredUpdater = deferredUpdater;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- destroy();
- } finally {
- super.finalize();
- }
- }
-
- void destroy() {
- if (mDeferredUpdater != 0) {
- nDestroyLayerUpdater(mDeferredUpdater);
- mDeferredUpdater = 0;
- }
- }
- }
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 60f8ee3..d71de9f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -323,12 +323,6 @@ public abstract class HardwareRenderer {
abstract void pushLayerUpdate(HardwareLayer layer);
/**
- * Tells the HardwareRenderer that a layer was created. The renderer should
- * make sure to apply any pending layer changes at the start of a new frame
- */
- abstract void onLayerCreated(HardwareLayer hardwareLayer);
-
- /**
* Tells the HardwareRenderer that the layer is destroyed. The renderer
* should remove the layer from any update queues.
*/
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index cac23a8..11db996 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -294,12 +294,7 @@ public class ThreadedRenderer extends HardwareRenderer {
@Override
void pushLayerUpdate(HardwareLayer layer) {
- // TODO: Remove this, it's not needed outside of GLRenderer
- }
-
- @Override
- void onLayerCreated(HardwareLayer layer) {
- // TODO: Is this actually useful?
+ nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
}
@Override
@@ -309,7 +304,7 @@ public class ThreadedRenderer extends HardwareRenderer {
@Override
void onLayerDestroyed(HardwareLayer layer) {
- nDestroyLayer(mNativeProxy, layer.getDeferredLayerUpdater());
+ nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
}
@Override
@@ -398,7 +393,8 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
private static native long nCreateTextureLayer(long nativeProxy);
private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
- private static native void nDestroyLayer(long nativeProxy, long layer);
+ private static native void nPushLayerUpdate(long nativeProxy, long layer);
+ private static native void nCancelLayerUpdate(long nativeProxy, long layer);
private static native void nFlushCaches(long nativeProxy, int flushMode);
diff --git a/core/java/com/android/internal/util/VirtualRefBasePtr.java b/core/java/com/android/internal/util/VirtualRefBasePtr.java
index 0bd4d3a..52306f1 100644
--- a/core/java/com/android/internal/util/VirtualRefBasePtr.java
+++ b/core/java/com/android/internal/util/VirtualRefBasePtr.java
@@ -32,11 +32,17 @@ public final class VirtualRefBasePtr {
return mNativePtr;
}
+ public void release() {
+ if (mNativePtr != 0) {
+ nDecStrong(mNativePtr);
+ mNativePtr = 0;
+ }
+ }
+
@Override
protected void finalize() throws Throwable {
try {
- nDecStrong(mNativePtr);
- mNativePtr = 0;
+ release();
} finally {
super.finalize();
}
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index b2f17de..33a2705 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -55,9 +55,7 @@ static jlong android_view_HardwareLayer_createRenderLayer(JNIEnv* env, jobject c
Layer* layer = LayerRenderer::createRenderLayer(width, height);
if (!layer) return 0;
- OpenGLRenderer* renderer = new LayerRenderer(layer);
- renderer->initProperties();
- return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer, renderer) );
+ return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer) );
}
static void android_view_HardwareLayer_onTextureDestroyed(JNIEnv* env, jobject clazz,
@@ -66,18 +64,6 @@ static void android_view_HardwareLayer_onTextureDestroyed(JNIEnv* env, jobject c
layer->backingLayer()->clearTexture();
}
-static jlong android_view_HardwareLayer_detachBackingLayer(JNIEnv* env, jobject clazz,
- jlong layerUpdaterPtr) {
- DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
- return reinterpret_cast<jlong>( layer->detachBackingLayer() );
-}
-
-static void android_view_HardwareLayer_destroyLayerUpdater(JNIEnv* env, jobject clazz,
- jlong layerUpdaterPtr) {
- DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
- delete layer;
-}
-
static jboolean android_view_HardwareLayer_prepare(JNIEnv* env, jobject clazz,
jlong layerUpdaterPtr, jint width, jint height, jboolean isOpaque) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
@@ -157,8 +143,6 @@ static JNINativeMethod gMethods[] = {
{ "nCreateTextureLayer", "()J", (void*) android_view_HardwareLayer_createTextureLayer },
{ "nCreateRenderLayer", "(II)J", (void*) android_view_HardwareLayer_createRenderLayer },
{ "nOnTextureDestroyed", "(J)V", (void*) android_view_HardwareLayer_onTextureDestroyed },
- { "nDetachBackingLayer", "(J)J", (void*) android_view_HardwareLayer_detachBackingLayer },
- { "nDestroyLayerUpdater", "(J)V", (void*) android_view_HardwareLayer_destroyLayerUpdater },
{ "nPrepare", "(JIIZ)Z", (void*) android_view_HardwareLayer_prepare },
{ "nSetLayerPaint", "(JJ)V", (void*) android_view_HardwareLayer_setLayerPaint },
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index bd016fd..1397131 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -287,11 +287,18 @@ static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject
return proxy->copyLayerInto(layer, bitmap);
}
-static void android_view_ThreadedRenderer_destroyLayer(JNIEnv* env, jobject clazz,
+static void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong layerPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
- proxy->destroyLayer(layer);
+ proxy->pushLayerUpdate(layer);
+}
+
+static void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jlong layerPtr) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
+ proxy->cancelLayerUpdate(layer);
}
static void android_view_ThreadedRenderer_flushCaches(JNIEnv* env, jobject clazz,
@@ -347,7 +354,8 @@ static JNINativeMethod gMethods[] = {
{ "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
{ "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
- { "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer },
+ { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
+ { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
{ "nFlushCaches", "(JI)V", (void*) android_view_ThreadedRenderer_flushCaches },
{ "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
{ "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 285c8c3..97e9bf6 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -22,14 +22,19 @@
namespace android {
namespace uirenderer {
-DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer)
+static void defaultLayerDestroyer(Layer* layer) {
+ Caches::getInstance().resourceCache.decrementRefcount(layer);
+}
+
+DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer)
: mDisplayList(0)
, mSurfaceTexture(0)
, mTransform(0)
, mNeedsGLContextAttach(false)
, mUpdateTexImage(false)
, mLayer(layer)
- , mCaches(Caches::getInstance()) {
+ , mCaches(Caches::getInstance())
+ , mDestroyer(destroyer) {
mWidth = mLayer->layer.getWidth();
mHeight = mLayer->layer.getHeight();
mBlend = mLayer->isBlend();
@@ -37,14 +42,16 @@ DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* rendere
mAlpha = mLayer->getAlpha();
mMode = mLayer->getMode();
mDirtyRect.setEmpty();
+
+ if (!mDestroyer) {
+ mDestroyer = defaultLayerDestroyer;
+ }
}
DeferredLayerUpdater::~DeferredLayerUpdater() {
SkSafeUnref(mColorFilter);
setTransform(0);
- if (mLayer) {
- mCaches.resourceCache.decrementRefcount(mLayer);
- }
+ mDestroyer(mLayer);
}
void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index cc62caa..b7cfe80 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -30,13 +30,15 @@
namespace android {
namespace uirenderer {
+typedef void (*LayerDestroyer)(Layer* layer);
+
// Container to hold the properties a layer should be set to at the start
// of a render pass
-class DeferredLayerUpdater {
+class DeferredLayerUpdater : public VirtualLightRefBase {
public:
// Note that DeferredLayerUpdater assumes it is taking ownership of the layer
// and will not call incrementRef on it as a result.
- ANDROID_API DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer = 0);
+ ANDROID_API DeferredLayerUpdater(Layer* layer, LayerDestroyer = 0);
ANDROID_API ~DeferredLayerUpdater();
ANDROID_API bool setSize(uint32_t width, uint32_t height) {
@@ -83,12 +85,6 @@ public:
return mLayer;
}
- ANDROID_API Layer* detachBackingLayer() {
- Layer* layer = mLayer;
- mLayer = 0;
- return layer;
- }
-
private:
// Generic properties
uint32_t mWidth;
@@ -111,6 +107,8 @@ private:
Layer* mLayer;
Caches& mCaches;
+ LayerDestroyer mDestroyer;
+
void doUpdateTexImage();
};
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f91e90e..9ebee1d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -427,27 +427,11 @@ void CanvasContext::makeCurrent() {
mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface);
}
-void CanvasContext::prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters,
- TreeInfo& info) {
- LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot prepareDraw without a canvas!");
- makeCurrent();
-
- processLayerUpdates(layerUpdaters, info);
- if (info.out.hasAnimations) {
- // TODO: Uh... crap?
- }
- prepareTree(info);
-}
-
-void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters,
- TreeInfo& info) {
- for (size_t i = 0; i < layerUpdaters->size(); i++) {
- DeferredLayerUpdater* update = layerUpdaters->itemAt(i);
- bool success = update->apply(info);
- LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
- if (update->backingLayer()->deferredUpdateScheduled) {
- mCanvas->pushLayerUpdate(update->backingLayer());
- }
+void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info) {
+ bool success = layerUpdater->apply(info);
+ LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
+ if (layerUpdater->backingLayer()->deferredUpdateScheduled) {
+ mCanvas->pushLayerUpdate(layerUpdater->backingLayer());
}
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index a04269b..00c5bf0 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -55,7 +55,8 @@ public:
void setup(int width, int height, const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
void makeCurrent();
- void prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info);
+ void processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info);
+ void prepareTree(TreeInfo& info);
void draw(Rect* dirty);
void destroyCanvasAndSurface();
@@ -83,9 +84,6 @@ public:
private:
friend class RegisterFrameCallbackTask;
- void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info);
- void prepareTree(TreeInfo& info);
-
void setSurface(ANativeWindow* window);
void swapBuffers();
void requireSurface();
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 7ea358f..61d67ca 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
+#include "../DeferredLayerUpdater.h"
#include "../DisplayList.h"
#include "../RenderNode.h"
#include "CanvasContext.h"
@@ -47,17 +48,22 @@ void DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) {
mContext = context;
}
-void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
- LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!");
+void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) {
+ LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!");
- mLayers.push(layer);
+ for (size_t i = 0; i < mLayers.size(); i++) {
+ if (mLayers[i].get() == layer) {
+ return;
+ }
+ }
+ mLayers.push_back(layer);
}
-void DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) {
+void DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) {
for (size_t i = 0; i < mLayers.size(); i++) {
- if (mLayers[i] == layer) {
- mLayers.removeAt(i);
- break;
+ if (mLayers[i].get() == layer) {
+ mLayers.erase(mLayers.begin() + i);
+ return;
}
}
}
@@ -132,7 +138,16 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) {
mContext->makeCurrent();
Caches::getInstance().textureCache.resetMarkInUse();
initTreeInfo(info);
- mContext->prepareDraw(&mLayers, info);
+
+ for (size_t i = 0; i < mLayers.size(); i++) {
+ mContext->processLayerUpdate(mLayers[i].get(), info);
+ }
+ mLayers.clear();
+ if (info.out.hasAnimations) {
+ // TODO: Uh... crap?
+ }
+ mContext->prepareTree(info);
+
if (info.out.hasAnimations) {
// TODO: dirty calculations, for now just do a full-screen inval
mDirty.setEmpty();
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 30c8880..d4129b6 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -16,10 +16,11 @@
#ifndef DRAWFRAMETASK_H
#define DRAWFRAMETASK_H
+#include <vector>
+
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/StrongPointer.h>
-#include <utils/Vector.h>
#include "RenderTask.h"
@@ -56,8 +57,8 @@ public:
void setContext(RenderThread* thread, CanvasContext* context);
- void addLayer(DeferredLayerUpdater* layer);
- void removeLayer(DeferredLayerUpdater* layer);
+ void pushLayerUpdate(DeferredLayerUpdater* layer);
+ void removeLayerUpdate(DeferredLayerUpdater* layer);
void setDirty(int left, int top, int right, int bottom);
void setDensity(float density) { mDensity = density; }
@@ -83,13 +84,9 @@ private:
nsecs_t mFrameTimeNanos;
nsecs_t mRecordDurationNanos;
float mDensity;
+ std::vector< sp<DeferredLayerUpdater> > mLayers;
int mSyncResult;
-
- /*********************************************
- * Multi frame data
- *********************************************/
- Vector<DeferredLayerUpdater*> mLayers;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 77c0aa7..0901963 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -229,10 +229,21 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) {
postAndWait(task);
}
+CREATE_BRIDGE1(destroyLayer, Layer* layer) {
+ LayerRenderer::destroyLayer(args->layer);
+ return NULL;
+}
+
+static void enqueueDestroyLayer(Layer* layer) {
+ SETUP_TASK(destroyLayer);
+ args->layer = layer;
+ RenderThread::getInstance().queue(task);
+}
+
CREATE_BRIDGE3(createDisplayListLayer, CanvasContext* context, int width, int height) {
Layer* layer = args->context->createRenderLayer(args->width, args->height);
if (!layer) return 0;
- return new DeferredLayerUpdater(layer);
+ return new DeferredLayerUpdater(layer, enqueueDestroyLayer);
}
DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) {
@@ -242,14 +253,13 @@ DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height)
args->context = mContext;
void* retval = postAndWait(task);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
- mDrawFrameTask.addLayer(layer);
return layer;
}
CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) {
Layer* layer = args->context->createTextureLayer();
if (!layer) return 0;
- return new DeferredLayerUpdater(layer);
+ return new DeferredLayerUpdater(layer, enqueueDestroyLayer);
}
DeferredLayerUpdater* RenderProxy::createTextureLayer() {
@@ -257,15 +267,9 @@ DeferredLayerUpdater* RenderProxy::createTextureLayer() {
args->context = mContext;
void* retval = postAndWait(task);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
- mDrawFrameTask.addLayer(layer);
return layer;
}
-CREATE_BRIDGE1(destroyLayer, Layer* layer) {
- LayerRenderer::destroyLayer(args->layer);
- return NULL;
-}
-
CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
SkBitmap* bitmap) {
bool success = args->context->copyLayerInto(args->layer, args->bitmap);
@@ -280,11 +284,12 @@ bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
return (bool) postAndWait(task);
}
-void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) {
- mDrawFrameTask.removeLayer(layer);
- SETUP_TASK(destroyLayer);
- args->layer = layer->detachBackingLayer();
- post(task);
+void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
+ mDrawFrameTask.pushLayerUpdate(layer);
+}
+
+void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
+ mDrawFrameTask.removeLayerUpdate(layer);
}
CREATE_BRIDGE2(flushCaches, CanvasContext* context, Caches::FlushMode flushMode) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index c8d42ec..944ff9c 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -80,7 +80,8 @@ public:
ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
- ANDROID_API void destroyLayer(DeferredLayerUpdater* layer);
+ ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
+ ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void flushCaches(Caches::FlushMode flushMode);