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

Commit 98b80379 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Attempting to fix the black flicker"

parents ba6b7c4d cc2eee89
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,
@@ -828,6 +829,10 @@ public final class ThreadedRenderer {
        }
    }

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

    static void invokeFunctor(long functor, boolean waitForCompletion) {
        nInvokeFunctor(functor, waitForCompletion);
    }
@@ -1059,6 +1064,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();

@@ -1208,6 +1225,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
@@ -3089,13 +3089,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);
@@ -3125,7 +3140,6 @@ public final class ViewRootImpl implements ViewParent,
            }

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

@@ -3138,16 +3152,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) {
@@ -3196,7 +3213,7 @@ public final class ViewRootImpl implements ViewParent,
            if (animating && mScroller != null) {
                mScroller.abortAnimation();
            }
            return;
            return false;
        }

        if (fullRedrawNeeded) {
@@ -3242,6 +3259,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.
@@ -3278,6 +3296,7 @@ public final class ViewRootImpl implements ViewParent,
                    requestDrawWindow();
                }

                useAsyncReport = true;
                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, mNextRtFrameCallback);
                mNextRtFrameCallback = null;
            } else {
@@ -3299,17 +3318,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;
                }
            }
        }
@@ -3318,6 +3337,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() {
@@ -885,6 +935,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) {
@@ -1084,6 +1147,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 },
@@ -1136,6 +1201,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
@@ -42,6 +42,7 @@
#include <algorithm>

#include <cstdlib>
#include <functional>

#define TRIM_MEMORY_COMPLETE 80
#define TRIM_MEMORY_UI_HIDDEN 20
@@ -347,6 +348,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);
    }
@@ -413,6 +420,8 @@ void CanvasContext::draw() {
                                      mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo,
                                      mRenderNodes, &(profiler()));

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

    waitOnFences();

    bool requireSwap = false;
@@ -473,6 +482,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
@@ -186,6 +186,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);
@@ -263,6 +267,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