Loading core/java/android/view/ThreadedRenderer.java +11 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,12 @@ public class ThreadedRenderer extends HardwareRenderer { private static final long NANOS_PER_MS = 1000000; // Keep in sync with DrawFrameTask.h SYNC_* flags // Nothing interesting to report private static final int SYNC_OK = 0x0; // Needs a ViewRoot invalidate private static final int SYNC_INVALIDATE_REQUIRED = 0x1; private int mWidth, mHeight; private long mNativeProxy; private boolean mInitialized = false; Loading Loading @@ -201,8 +207,11 @@ public class ThreadedRenderer extends HardwareRenderer { if (dirty == null) { dirty = NULL_RECT; } nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, dirty.left, dirty.top, dirty.right, dirty.bottom); if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { attachInfo.mViewRootImpl.invalidate(); } } @Override Loading Loading @@ -304,7 +313,7 @@ public class ThreadedRenderer extends HardwareRenderer { private static native void nSetup(long nativeProxy, int width, int height); private static native void nSetDisplayListData(long nativeProxy, long displayList, long newData); private static native void nSyncAndDrawFrame(long nativeProxy, long frameTimeNanos, private static native int nSyncAndDrawFrame(long nativeProxy, long frameTimeNanos, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); private static native void nRunWithGlContext(long nativeProxy, Runnable runnable); private static native void nDestroyCanvasAndSurface(long nativeProxy); Loading core/jni/android_view_ThreadedRenderer.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -191,11 +191,11 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, proxy->setup(width, height); } static void android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, jlong proxyPtr, jlong frameTimeNanos, jint dirtyLeft, jint dirtyTop, jint dirtyRight, jint dirtyBottom) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); proxy->syncAndDrawFrame(frameTimeNanos, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); return proxy->syncAndDrawFrame(frameTimeNanos, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); } static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, jobject clazz, Loading Loading @@ -272,7 +272,7 @@ static JNINativeMethod gMethods[] = { { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface }, { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup }, { "nSyncAndDrawFrame", "(JJIIII)V", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nSyncAndDrawFrame", "(JJIIII)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface }, { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext }, Loading libs/hwui/RenderNode.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -160,13 +160,13 @@ void RenderNode::evaluateAnimations(TreeInfo& info) { newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); mAnimators.erase(newEnd, mAnimators.end()); mProperties.updateMatrix(); info.hasAnimations |= mAnimators.size(); info.out.hasAnimations |= mAnimators.size(); } void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) { if (subtree) { TextureCache& cache = Caches::getInstance().textureCache; info.hasFunctors |= subtree->functorCount; info.out.hasFunctors |= subtree->functorCount; // TODO: Fix ownedBitmapResources to not require disabling prepareTextures // and thus falling out of async drawing path. if (subtree->ownedBitmapResources.size()) { Loading libs/hwui/TreeInfo.h +22 −14 Original line number Diff line number Diff line Loading @@ -34,25 +34,33 @@ protected: struct TreeInfo { // The defaults here should be safe for everyone but DrawFrameTask to use as-is. TreeInfo() : hasFunctors(false) : frameTimeMs(0) , animationHook(NULL) , prepareTextures(false) , performStagingPush(true) , frameTimeMs(0) , evaluateAnimations(false) , hasAnimations(false) , animationHook(0) {} bool hasFunctors; nsecs_t frameTimeMs; AnimationHook* animationHook; bool prepareTextures; bool performStagingPush; // Animations nsecs_t frameTimeMs; bool evaluateAnimations; struct Out { Out() : hasFunctors(false) , hasAnimations(false) , requiresUiRedraw(false) {} bool hasFunctors; // This is only updated if evaluateAnimations is true bool hasAnimations; AnimationHook* animationHook; // This is set to true if there is an animation that RenderThread cannot // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true bool requiresUiRedraw; } out; // TODO: Damage calculations }; Loading libs/hwui/renderthread/CanvasContext.cpp +22 −6 Original line number Diff line number Diff line Loading @@ -391,10 +391,20 @@ void CanvasContext::makeCurrent() { mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface); } void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, void CanvasContext::prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info) { LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot process layer updates without a canvas!"); 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); Loading @@ -406,15 +416,21 @@ void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* lay } void CanvasContext::prepareTree(TreeInfo& info) { info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); mRenderThread.removeFrameCallback(this); info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); mRootRenderNode->prepareTree(info); if (info.hasAnimations && !info.hasFunctors) { // TODO: Functors if (info.out.hasAnimations) { if (info.out.hasFunctors) { info.out.requiresUiRedraw = true; } else if (!info.out.requiresUiRedraw) { // If animationsNeedsRedraw is set don't bother posting for an RT anim // as we will just end up fighting the UI thread. mRenderThread.postFrameCallback(this); } } } void CanvasContext::draw(Rect* dirty) { LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, Loading Loading
core/java/android/view/ThreadedRenderer.java +11 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,12 @@ public class ThreadedRenderer extends HardwareRenderer { private static final long NANOS_PER_MS = 1000000; // Keep in sync with DrawFrameTask.h SYNC_* flags // Nothing interesting to report private static final int SYNC_OK = 0x0; // Needs a ViewRoot invalidate private static final int SYNC_INVALIDATE_REQUIRED = 0x1; private int mWidth, mHeight; private long mNativeProxy; private boolean mInitialized = false; Loading Loading @@ -201,8 +207,11 @@ public class ThreadedRenderer extends HardwareRenderer { if (dirty == null) { dirty = NULL_RECT; } nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, dirty.left, dirty.top, dirty.right, dirty.bottom); if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { attachInfo.mViewRootImpl.invalidate(); } } @Override Loading Loading @@ -304,7 +313,7 @@ public class ThreadedRenderer extends HardwareRenderer { private static native void nSetup(long nativeProxy, int width, int height); private static native void nSetDisplayListData(long nativeProxy, long displayList, long newData); private static native void nSyncAndDrawFrame(long nativeProxy, long frameTimeNanos, private static native int nSyncAndDrawFrame(long nativeProxy, long frameTimeNanos, int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); private static native void nRunWithGlContext(long nativeProxy, Runnable runnable); private static native void nDestroyCanvasAndSurface(long nativeProxy); Loading
core/jni/android_view_ThreadedRenderer.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -191,11 +191,11 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, proxy->setup(width, height); } static void android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz, jlong proxyPtr, jlong frameTimeNanos, jint dirtyLeft, jint dirtyTop, jint dirtyRight, jint dirtyBottom) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); proxy->syncAndDrawFrame(frameTimeNanos, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); return proxy->syncAndDrawFrame(frameTimeNanos, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); } static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, jobject clazz, Loading Loading @@ -272,7 +272,7 @@ static JNINativeMethod gMethods[] = { { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface }, { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup }, { "nSyncAndDrawFrame", "(JJIIII)V", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nSyncAndDrawFrame", "(JJIIII)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface }, { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext }, Loading
libs/hwui/RenderNode.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -160,13 +160,13 @@ void RenderNode::evaluateAnimations(TreeInfo& info) { newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); mAnimators.erase(newEnd, mAnimators.end()); mProperties.updateMatrix(); info.hasAnimations |= mAnimators.size(); info.out.hasAnimations |= mAnimators.size(); } void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) { if (subtree) { TextureCache& cache = Caches::getInstance().textureCache; info.hasFunctors |= subtree->functorCount; info.out.hasFunctors |= subtree->functorCount; // TODO: Fix ownedBitmapResources to not require disabling prepareTextures // and thus falling out of async drawing path. if (subtree->ownedBitmapResources.size()) { Loading
libs/hwui/TreeInfo.h +22 −14 Original line number Diff line number Diff line Loading @@ -34,25 +34,33 @@ protected: struct TreeInfo { // The defaults here should be safe for everyone but DrawFrameTask to use as-is. TreeInfo() : hasFunctors(false) : frameTimeMs(0) , animationHook(NULL) , prepareTextures(false) , performStagingPush(true) , frameTimeMs(0) , evaluateAnimations(false) , hasAnimations(false) , animationHook(0) {} bool hasFunctors; nsecs_t frameTimeMs; AnimationHook* animationHook; bool prepareTextures; bool performStagingPush; // Animations nsecs_t frameTimeMs; bool evaluateAnimations; struct Out { Out() : hasFunctors(false) , hasAnimations(false) , requiresUiRedraw(false) {} bool hasFunctors; // This is only updated if evaluateAnimations is true bool hasAnimations; AnimationHook* animationHook; // This is set to true if there is an animation that RenderThread cannot // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true bool requiresUiRedraw; } out; // TODO: Damage calculations }; Loading
libs/hwui/renderthread/CanvasContext.cpp +22 −6 Original line number Diff line number Diff line Loading @@ -391,10 +391,20 @@ void CanvasContext::makeCurrent() { mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface); } void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, void CanvasContext::prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info) { LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot process layer updates without a canvas!"); 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); Loading @@ -406,15 +416,21 @@ void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* lay } void CanvasContext::prepareTree(TreeInfo& info) { info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); mRenderThread.removeFrameCallback(this); info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); mRootRenderNode->prepareTree(info); if (info.hasAnimations && !info.hasFunctors) { // TODO: Functors if (info.out.hasAnimations) { if (info.out.hasFunctors) { info.out.requiresUiRedraw = true; } else if (!info.out.requiresUiRedraw) { // If animationsNeedsRedraw is set don't bother posting for an RT anim // as we will just end up fighting the UI thread. mRenderThread.postFrameCallback(this); } } } void CanvasContext::draw(Rect* dirty) { LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, Loading