Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9be7794 authored by John Reck's avatar John Reck
Browse files

Make RenderNodeAnimator and WebView play nice

Change-Id: Ifaefcf510b2d377663fc86f60608d6ec9be8329a
parent 5d039c45
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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);
+3 −3
Original line number Diff line number Diff line
@@ -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,
@@ -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 },
+2 −2
Original line number Diff line number Diff line
@@ -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()) {
+22 −14
Original line number Diff line number Diff line
@@ -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
};
+22 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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