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

Commit 8b3480c6 authored by John Reck's avatar John Reck Committed by android-build-merger
Browse files

Merge "Attempting to fix the black flicker" into pi-dev

am: b5595125

Change-Id: I95ee7346a8d2f10c07185d3c386a7ee778f6bd98
parents fe1c990a b5595125
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -329,6 +329,7 @@ public final class ThreadedRenderer {
    // in response, so it really just exists to differentiate from LOST_SURFACE
    // but possibly both can just be deleted.
    private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
    private static final int SYNC_FRAME_DROPPED = 1 << 3;

    private static final String[] VISUALIZERS = {
        PROFILE_PROPERTY_VISUALIZE_BARS,
@@ -832,6 +833,10 @@ public final class ThreadedRenderer {
        }
    }

    void setFrameCompleteCallback(FrameCompleteCallback callback) {
        nSetFrameCompleteCallback(mNativeProxy, callback);
    }

    static void invokeFunctor(long functor, boolean waitForCompletion) {
        nInvokeFunctor(functor, waitForCompletion);
    }
@@ -1067,6 +1072,18 @@ public final class ThreadedRenderer {
        void onFrameDraw(long frame);
    }

    /**
     * Interface used to be notified when a frame has finished rendering
     */
    public interface FrameCompleteCallback {
        /**
         * Invoked after a frame draw
         *
         * @param frameNr The id of the frame that was drawn.
         */
        void onFrameComplete(long frameNr);
    }

    private static class ProcessInitializer {
        static ProcessInitializer sInstance = new ProcessInitializer();

@@ -1218,6 +1235,8 @@ public final class ThreadedRenderer {
    private static native void nSetContentDrawBounds(long nativeProxy, int left,
             int top, int right, int bottom);
    private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
    private static native void nSetFrameCompleteCallback(long nativeProxy,
            FrameCompleteCallback callback);

    private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
    private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
+30 −10
Original line number Diff line number Diff line
@@ -3096,13 +3096,28 @@ public final class ViewRootImpl implements ViewParent,
            return;
        }

        final boolean fullRedrawNeeded = mFullRedrawNeeded;
        final boolean fullRedrawNeeded = mFullRedrawNeeded || mReportNextDraw;
        mFullRedrawNeeded = false;

        mIsDrawing = true;
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");

        boolean usingAsyncReport = false;
        if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null
                && mAttachInfo.mThreadedRenderer.isEnabled()) {
            usingAsyncReport = true;
            mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> {
                // TODO: Use the frame number
                pendingDrawFinished();
            });
        }

        try {
            draw(fullRedrawNeeded);
            boolean canUseAsync = draw(fullRedrawNeeded);
            if (usingAsyncReport && !canUseAsync) {
                mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null);
                usingAsyncReport = false;
            }
        } finally {
            mIsDrawing = false;
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
@@ -3132,7 +3147,6 @@ public final class ViewRootImpl implements ViewParent,
            }

            if (mAttachInfo.mThreadedRenderer != null) {
                mAttachInfo.mThreadedRenderer.fence();
                mAttachInfo.mThreadedRenderer.setStopped(mStopped);
            }

@@ -3145,16 +3159,19 @@ public final class ViewRootImpl implements ViewParent,
                SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();

                sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
            } else {
            } else if (!usingAsyncReport) {
                if (mAttachInfo.mThreadedRenderer != null) {
                    mAttachInfo.mThreadedRenderer.fence();
                }
                pendingDrawFinished();
            }
        }
    }

    private void draw(boolean fullRedrawNeeded) {
    private boolean draw(boolean fullRedrawNeeded) {
        Surface surface = mSurface;
        if (!surface.isValid()) {
            return;
            return false;
        }

        if (DEBUG_FPS) {
@@ -3203,7 +3220,7 @@ public final class ViewRootImpl implements ViewParent,
            if (animating && mScroller != null) {
                mScroller.abortAnimation();
            }
            return;
            return false;
        }

        if (fullRedrawNeeded) {
@@ -3250,6 +3267,7 @@ public final class ViewRootImpl implements ViewParent,
        mAttachInfo.mDrawingTime =
                mChoreographer.getFrameTimeNanos() / TimeUtils.NANOS_PER_MS;

        boolean useAsyncReport = false;
        if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
            if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
                // If accessibility focus moved, always invalidate the root.
@@ -3286,6 +3304,7 @@ public final class ViewRootImpl implements ViewParent,
                    requestDrawWindow();
                }

                useAsyncReport = true;
                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, mNextRtFrameCallback);
                mNextRtFrameCallback = null;
            } else {
@@ -3307,17 +3326,17 @@ public final class ViewRootImpl implements ViewParent,
                                mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
                    } catch (OutOfResourcesException e) {
                        handleOutOfResourcesException(e);
                        return;
                        return false;
                    }

                    mFullRedrawNeeded = true;
                    scheduleTraversals();
                    return;
                    return false;
                }

                if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
                        scalingRequired, dirty, surfaceInsets)) {
                    return;
                    return false;
                }
            }
        }
@@ -3326,6 +3345,7 @@ public final class ViewRootImpl implements ViewParent,
            mFullRedrawNeeded = true;
            scheduleTraversals();
        }
        return useAsyncReport;
    }

    /**
+70 −0
Original line number Diff line number Diff line
@@ -15,9 +15,11 @@
 */

#define LOG_TAG "ThreadedRenderer"
#define ATRACE_TAG ATRACE_TAG_VIEW

#include <algorithm>
#include <atomic>
#include <inttypes.h>

#include "jni.h"
#include <nativehelper/JNIHelp.h>
@@ -37,6 +39,7 @@
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
#include <utils/TraceUtils.h>
#include <android_runtime/android_view_Surface.h>
#include <system/window.h>

@@ -72,6 +75,10 @@ struct {
    jmethodID onFrameDraw;
} gFrameDrawingCallback;

struct {
    jmethodID onFrameComplete;
} gFrameCompleteCallback;

static JNIEnv* getenv(JavaVM* vm) {
    JNIEnv* env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -153,6 +160,49 @@ private:
    std::string mMessage;
};

class FrameCompleteWrapper : public MessageHandler {
public:
    FrameCompleteWrapper(JNIEnv* env, jobject jobject) {
        mLooper = Looper::getForThread();
        LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create runnable on a Looper thread!");
        env->GetJavaVM(&mVm);
        mObject = env->NewGlobalRef(jobject);
        LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref");
    }

    virtual ~FrameCompleteWrapper() {
        releaseObject();
    }

    void postFrameComplete(int64_t frameNr) {
        if (mObject) {
            mFrameNr = frameNr;
            mLooper->sendMessage(this, 0);
        }
    }

    virtual void handleMessage(const Message&) {
        if (mObject) {
            ATRACE_FORMAT("frameComplete %" PRId64, mFrameNr);
            getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, mFrameNr);
            releaseObject();
        }
    }

private:
    JavaVM* mVm;
    jobject mObject;
    sp<Looper> mLooper;
    int64_t mFrameNr = -1;

    void releaseObject() {
        if (mObject) {
            getenv(mVm)->DeleteGlobalRef(mObject);
            mObject = nullptr;
        }
    }
};

class RootRenderNode : public RenderNode, ErrorHandler {
public:
    explicit RootRenderNode(JNIEnv* env) : RenderNode() {
@@ -891,6 +941,19 @@ static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
    }
}

static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env,
        jobject clazz, jlong proxyPtr, jobject callback) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    if (!callback) {
        proxy->setFrameCompleteCallback(nullptr);
    } else {
        sp<FrameCompleteWrapper> wrapper = new FrameCompleteWrapper{env, callback};
        proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) {
            wrapper->postFrameComplete(frameNr);
        });
    }
}

static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
        jobject clazz, jobject jsurface, jint left, jint top,
        jint right, jint bottom, jobject jbitmap) {
@@ -1091,6 +1154,8 @@ static const JNINativeMethod gMethods[] = {
    { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
    { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V",
            (void*)android_view_ThreadedRenderer_setFrameCallback},
    { "nSetFrameCompleteCallback", "(JLandroid/view/ThreadedRenderer$FrameCompleteCallback;)V",
            (void*)android_view_ThreadedRenderer_setFrameCompleteCallback },
    { "nAddFrameMetricsObserver",
            "(JLandroid/view/FrameMetricsObserver;)J",
            (void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
@@ -1143,6 +1208,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
    gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
            "onFrameDraw", "(J)V");

    jclass frameCompleteClass = FindClassOrDie(env,
            "android/view/ThreadedRenderer$FrameCompleteCallback");
    gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass,
            "onFrameComplete", "(J)V");

    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}

+16 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include <algorithm>

#include <cstdlib>
#include <functional>

#define TRIM_MEMORY_COMPLETE 80
#define TRIM_MEMORY_UI_HIDDEN 20
@@ -383,6 +384,12 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
        info.out.canDrawThisFrame = true;
    }

    // TODO: Do we need to abort out if the backdrop is added but not ready? Should that even
    // be an allowable combination?
    if (mRenderNodes.size() > 2 && !mRenderNodes[1]->isRenderable()) {
        info.out.canDrawThisFrame = false;
    }

    if (!info.out.canDrawThisFrame) {
        mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
    }
@@ -449,6 +456,8 @@ void CanvasContext::draw() {
                                      mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo,
                                      mRenderNodes, &(profiler()));

    int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1;

    waitOnFences();

    bool requireSwap = false;
@@ -509,6 +518,13 @@ void CanvasContext::draw() {
    }
#endif

    if (didSwap) {
        for (auto& func : mFrameCompleteCallbacks) {
            std::invoke(func, frameCompleteNr);
        }
        mFrameCompleteCallbacks.clear();
    }

    mJankTracker.finishFrame(*mCurrentFrameInfo);
    if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
        mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data());
+6 −0
Original line number Diff line number Diff line
@@ -190,6 +190,10 @@ public:

    IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }

    void addFrameCompleteListener(std::function<void(int64_t)>&& func) {
        mFrameCompleteCallbacks.push_back(std::move(func));
    }

private:
    CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
                  IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -267,6 +271,8 @@ private:
    std::vector<sp<FuncTask>> mFrameFences;
    sp<TaskProcessor<bool>> mFrameWorkProcessor;
    std::unique_ptr<IRenderPipeline> mRenderPipeline;

    std::vector<std::function<void(int64_t)>> mFrameCompleteCallbacks;
};

} /* namespace renderthread */
Loading