RenderThread.h revision 6b50780363d3bb8db600c770183fa07677509ae8
111417b1cfde8f1749905f2d735623af9214148afJeff Brown/*
211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Copyright (C) 2013 The Android Open Source Project
311417b1cfde8f1749905f2d735623af9214148afJeff Brown *
411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
511417b1cfde8f1749905f2d735623af9214148afJeff Brown * you may not use this file except in compliance with the License.
611417b1cfde8f1749905f2d735623af9214148afJeff Brown * You may obtain a copy of the License at
711417b1cfde8f1749905f2d735623af9214148afJeff Brown *
811417b1cfde8f1749905f2d735623af9214148afJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
911417b1cfde8f1749905f2d735623af9214148afJeff Brown *
1011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Unless required by applicable law or agreed to in writing, software
1111417b1cfde8f1749905f2d735623af9214148afJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1211417b1cfde8f1749905f2d735623af9214148afJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311417b1cfde8f1749905f2d735623af9214148afJeff Brown * See the License for the specific language governing permissions and
1411417b1cfde8f1749905f2d735623af9214148afJeff Brown * limitations under the License.
1511417b1cfde8f1749905f2d735623af9214148afJeff Brown */
1611417b1cfde8f1749905f2d735623af9214148afJeff Brown
1711417b1cfde8f1749905f2d735623af9214148afJeff Brown#ifndef RENDERTHREAD_H_
1811417b1cfde8f1749905f2d735623af9214148afJeff Brown#define RENDERTHREAD_H_
1911417b1cfde8f1749905f2d735623af9214148afJeff Brown
2011417b1cfde8f1749905f2d735623af9214148afJeff Brown#include "RenderTask.h"
2111417b1cfde8f1749905f2d735623af9214148afJeff Brown
227599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown#include "../JankTracker.h"
2311417b1cfde8f1749905f2d735623af9214148afJeff Brown#include "TimeLord.h"
2411417b1cfde8f1749905f2d735623af9214148afJeff Brown
2511417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <cutils/compiler.h>
2611417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <ui/DisplayInfo.h>
2711417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <utils/Looper.h>
2811417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <utils/Thread.h>
2911417b1cfde8f1749905f2d735623af9214148afJeff Brown
3011417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <condition_variable>
3111417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <memory>
3211417b1cfde8f1749905f2d735623af9214148afJeff Brown#include <mutex>
339c83739aefcb1748551645a656bece0d864cef76Sungsoo Lim#include <set>
3411417b1cfde8f1749905f2d735623af9214148afJeff Brown
35e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikasnamespace android {
36e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas
3711417b1cfde8f1749905f2d735623af9214148afJeff Brownclass DisplayEventReceiver;
38e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas
39d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brownnamespace uirenderer {
4011417b1cfde8f1749905f2d735623af9214148afJeff Brown
4111417b1cfde8f1749905f2d735623af9214148afJeff Brownclass RenderState;
4211417b1cfde8f1749905f2d735623af9214148afJeff Brownclass TestUtils;
4311417b1cfde8f1749905f2d735623af9214148afJeff Brown
4411417b1cfde8f1749905f2d735623af9214148afJeff Brownnamespace renderthread {
4511417b1cfde8f1749905f2d735623af9214148afJeff Brown
4611417b1cfde8f1749905f2d735623af9214148afJeff Brownclass CanvasContext;
4711417b1cfde8f1749905f2d735623af9214148afJeff Brownclass DispatchFrameCallbacks;
4811417b1cfde8f1749905f2d735623af9214148afJeff Brownclass EglManager;
4911417b1cfde8f1749905f2d735623af9214148afJeff Brownclass RenderProxy;
5011417b1cfde8f1749905f2d735623af9214148afJeff Brown
5111417b1cfde8f1749905f2d735623af9214148afJeff Brownclass TaskQueue {
52e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikaspublic:
5311417b1cfde8f1749905f2d735623af9214148afJeff Brown    TaskQueue();
5411417b1cfde8f1749905f2d735623af9214148afJeff Brown
5511417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderTask* next();
5611417b1cfde8f1749905f2d735623af9214148afJeff Brown    void queue(RenderTask* task);
5711417b1cfde8f1749905f2d735623af9214148afJeff Brown    void queueAtFront(RenderTask* task);
5811417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderTask* peek();
5911417b1cfde8f1749905f2d735623af9214148afJeff Brown    void remove(RenderTask* task);
6011417b1cfde8f1749905f2d735623af9214148afJeff Brown
6111417b1cfde8f1749905f2d735623af9214148afJeff Brownprivate:
6211417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderTask* mHead;
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderTask* mTail;
6411417b1cfde8f1749905f2d735623af9214148afJeff Brown};
6511417b1cfde8f1749905f2d735623af9214148afJeff Brown
6611417b1cfde8f1749905f2d735623af9214148afJeff Brown// Mimics android.view.Choreographer.FrameCallback
6711417b1cfde8f1749905f2d735623af9214148afJeff Brownclass IFrameCallback {
6811417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic:
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown    virtual void doFrame() = 0;
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown
7111417b1cfde8f1749905f2d735623af9214148afJeff Brownprotected:
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown    ~IFrameCallback() {}
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown};
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown
7511417b1cfde8f1749905f2d735623af9214148afJeff Brownclass ANDROID_API RenderThread : public Thread {
7611417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic:
7711417b1cfde8f1749905f2d735623af9214148afJeff Brown    // RenderThread takes complete ownership of tasks that are queued
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown    // and will delete them after they are run
7911417b1cfde8f1749905f2d735623af9214148afJeff Brown    ANDROID_API void queue(RenderTask* task);
8011417b1cfde8f1749905f2d735623af9214148afJeff Brown    ANDROID_API void queueAndWait(RenderTask* task);
8111417b1cfde8f1749905f2d735623af9214148afJeff Brown    ANDROID_API void queueAtFront(RenderTask* task);
8211417b1cfde8f1749905f2d735623af9214148afJeff Brown    void queueAt(RenderTask* task, nsecs_t runAtNs);
8311417b1cfde8f1749905f2d735623af9214148afJeff Brown    void remove(RenderTask* task);
8411417b1cfde8f1749905f2d735623af9214148afJeff Brown
8511417b1cfde8f1749905f2d735623af9214148afJeff Brown    // Mimics android.view.Choreographer
8611417b1cfde8f1749905f2d735623af9214148afJeff Brown    void postFrameCallback(IFrameCallback* callback);
8711417b1cfde8f1749905f2d735623af9214148afJeff Brown    bool removeFrameCallback(IFrameCallback* callback);
8811417b1cfde8f1749905f2d735623af9214148afJeff Brown    // If the callback is currently registered, it will be pushed back until
8911417b1cfde8f1749905f2d735623af9214148afJeff Brown    // the next vsync. If it is not currently registered this does nothing.
9011417b1cfde8f1749905f2d735623af9214148afJeff Brown    void pushBackFrameCallback(IFrameCallback* callback);
91d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown    TimeLord& timeLord() { return mTimeLord; }
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderState& renderState() { return *mRenderState; }
943d4c9459ed77f732dd3ba602713af6ebf9280c8cJeff Brown    EglManager& eglManager() { return *mEglManager; }
9511417b1cfde8f1749905f2d735623af9214148afJeff Brown    JankTracker& jankTracker() { return *mJankTracker; }
9611417b1cfde8f1749905f2d735623af9214148afJeff Brown
9711417b1cfde8f1749905f2d735623af9214148afJeff Brown    const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
9811417b1cfde8f1749905f2d735623af9214148afJeff Brown
9911417b1cfde8f1749905f2d735623af9214148afJeff Brownprotected:
10011417b1cfde8f1749905f2d735623af9214148afJeff Brown    virtual bool threadLoop() override;
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown
10211417b1cfde8f1749905f2d735623af9214148afJeff Brownprivate:
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown    friend class DispatchFrameCallbacks;
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown    friend class RenderProxy;
10511417b1cfde8f1749905f2d735623af9214148afJeff Brown    friend class android::uirenderer::TestUtils;
10611417b1cfde8f1749905f2d735623af9214148afJeff Brown
10711417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderThread();
10811417b1cfde8f1749905f2d735623af9214148afJeff Brown    virtual ~RenderThread();
10911417b1cfde8f1749905f2d735623af9214148afJeff Brown
11011417b1cfde8f1749905f2d735623af9214148afJeff Brown    static bool hasInstance();
11111417b1cfde8f1749905f2d735623af9214148afJeff Brown    static RenderThread& getInstance();
11211417b1cfde8f1749905f2d735623af9214148afJeff Brown
11311417b1cfde8f1749905f2d735623af9214148afJeff Brown    void initThreadLocals();
114d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown    void initializeDisplayEventReceiver();
11511417b1cfde8f1749905f2d735623af9214148afJeff Brown    static int displayEventReceiverCallback(int fd, int events, void* data);
11611417b1cfde8f1749905f2d735623af9214148afJeff Brown    void drainDisplayEventQueue();
11711417b1cfde8f1749905f2d735623af9214148afJeff Brown    void dispatchFrameCallbacks();
11811417b1cfde8f1749905f2d735623af9214148afJeff Brown    void requestVsync();
11911417b1cfde8f1749905f2d735623af9214148afJeff Brown
12011417b1cfde8f1749905f2d735623af9214148afJeff Brown    // Returns the next task to be run. If this returns NULL nextWakeup is set
12111417b1cfde8f1749905f2d735623af9214148afJeff Brown    // to the time to requery for the nextTask to run. mNextWakeup is also
12211417b1cfde8f1749905f2d735623af9214148afJeff Brown    // set to this time
12311417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderTask* nextTask(nsecs_t* nextWakeup);
12411417b1cfde8f1749905f2d735623af9214148afJeff Brown
12511417b1cfde8f1749905f2d735623af9214148afJeff Brown    sp<Looper> mLooper;
12611417b1cfde8f1749905f2d735623af9214148afJeff Brown    Mutex mLock;
12711417b1cfde8f1749905f2d735623af9214148afJeff Brown
12811417b1cfde8f1749905f2d735623af9214148afJeff Brown    nsecs_t mNextWakeup;
12911417b1cfde8f1749905f2d735623af9214148afJeff Brown    TaskQueue mQueue;
13011417b1cfde8f1749905f2d735623af9214148afJeff Brown    Mutex mSyncMutex;
13111417b1cfde8f1749905f2d735623af9214148afJeff Brown    Condition mSyncCondition;
13211417b1cfde8f1749905f2d735623af9214148afJeff Brown
13311417b1cfde8f1749905f2d735623af9214148afJeff Brown    DisplayInfo mDisplayInfo;
13411417b1cfde8f1749905f2d735623af9214148afJeff Brown
13511417b1cfde8f1749905f2d735623af9214148afJeff Brown    DisplayEventReceiver* mDisplayEventReceiver;
13611417b1cfde8f1749905f2d735623af9214148afJeff Brown    bool mVsyncRequested;
13711417b1cfde8f1749905f2d735623af9214148afJeff Brown    std::set<IFrameCallback*> mFrameCallbacks;
13811417b1cfde8f1749905f2d735623af9214148afJeff Brown    // We defer the actual registration of these callbacks until
13911417b1cfde8f1749905f2d735623af9214148afJeff Brown    // both mQueue *and* mDisplayEventReceiver have been drained off all
14011417b1cfde8f1749905f2d735623af9214148afJeff Brown    // immediate events. This makes sure that we catch the next vsync, not
14111417b1cfde8f1749905f2d735623af9214148afJeff Brown    // the previous one
14211417b1cfde8f1749905f2d735623af9214148afJeff Brown    std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks;
14311417b1cfde8f1749905f2d735623af9214148afJeff Brown    bool mFrameCallbackTaskPending;
14411417b1cfde8f1749905f2d735623af9214148afJeff Brown    DispatchFrameCallbacks* mFrameCallbackTask;
14511417b1cfde8f1749905f2d735623af9214148afJeff Brown
14611417b1cfde8f1749905f2d735623af9214148afJeff Brown    TimeLord mTimeLord;
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown    RenderState* mRenderState;
14811417b1cfde8f1749905f2d735623af9214148afJeff Brown    EglManager* mEglManager;
14911417b1cfde8f1749905f2d735623af9214148afJeff Brown
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown    JankTracker* mJankTracker = nullptr;
15111417b1cfde8f1749905f2d735623af9214148afJeff Brown};
15211417b1cfde8f1749905f2d735623af9214148afJeff Brown
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown} /* namespace renderthread */
15411417b1cfde8f1749905f2d735623af9214148afJeff Brown} /* namespace uirenderer */
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown} /* namespace android */
15611417b1cfde8f1749905f2d735623af9214148afJeff Brown#endif /* RENDERTHREAD_H_ */
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown