1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef RENDERTHREAD_H_
18#define RENDERTHREAD_H_
19
20#include "RenderTask.h"
21
22#include "../JankTracker.h"
23#include "CacheManager.h"
24#include "TimeLord.h"
25
26#include <GrContext.h>
27#include <cutils/compiler.h>
28#include <SkBitmap.h>
29#include <ui/DisplayInfo.h>
30#include <utils/Looper.h>
31#include <utils/Thread.h>
32
33#include <memory>
34#include <set>
35
36namespace android {
37
38class Bitmap;
39class DisplayEventReceiver;
40
41namespace uirenderer {
42
43class Readback;
44class RenderState;
45class TestUtils;
46
47namespace renderthread {
48
49class CanvasContext;
50class DispatchFrameCallbacks;
51class EglManager;
52class RenderProxy;
53class VulkanManager;
54
55class TaskQueue {
56public:
57    TaskQueue();
58
59    RenderTask* next();
60    void queue(RenderTask* task);
61    void queueAtFront(RenderTask* task);
62    RenderTask* peek();
63    void remove(RenderTask* task);
64
65private:
66    RenderTask* mHead;
67    RenderTask* mTail;
68};
69
70// Mimics android.view.Choreographer.FrameCallback
71class IFrameCallback {
72public:
73    virtual void doFrame() = 0;
74
75protected:
76    ~IFrameCallback() {}
77};
78
79class ANDROID_API RenderThread : public Thread {
80    PREVENT_COPY_AND_ASSIGN(RenderThread);
81public:
82    // RenderThread takes complete ownership of tasks that are queued
83    // and will delete them after they are run
84    ANDROID_API void queue(RenderTask* task);
85    ANDROID_API void queueAndWait(RenderTask* task);
86    ANDROID_API void queueAtFront(RenderTask* task);
87    void queueAt(RenderTask* task, nsecs_t runAtNs);
88    void remove(RenderTask* task);
89
90    // Mimics android.view.Choreographer
91    void postFrameCallback(IFrameCallback* callback);
92    bool removeFrameCallback(IFrameCallback* callback);
93    // If the callback is currently registered, it will be pushed back until
94    // the next vsync. If it is not currently registered this does nothing.
95    void pushBackFrameCallback(IFrameCallback* callback);
96
97    TimeLord& timeLord() { return mTimeLord; }
98    RenderState& renderState() const { return *mRenderState; }
99    EglManager& eglManager() const { return *mEglManager; }
100    ProfileDataContainer& globalProfileData() { return mGlobalProfileData; }
101    Readback& readback();
102
103    const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
104
105    GrContext* getGrContext() const { return mGrContext.get(); }
106    void setGrContext(GrContext* cxt);
107
108    CacheManager& cacheManager() { return *mCacheManager; }
109    VulkanManager& vulkanManager() { return *mVkManager; }
110
111    sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
112    void dumpGraphicsMemory(int fd);
113
114protected:
115    virtual bool threadLoop() override;
116
117private:
118    friend class DispatchFrameCallbacks;
119    friend class RenderProxy;
120    friend class android::uirenderer::TestUtils;
121
122    RenderThread();
123    virtual ~RenderThread();
124
125    static bool hasInstance();
126    static RenderThread& getInstance();
127
128    void initThreadLocals();
129    void initializeDisplayEventReceiver();
130    static int displayEventReceiverCallback(int fd, int events, void* data);
131    void drainDisplayEventQueue();
132    void dispatchFrameCallbacks();
133    void requestVsync();
134
135    // Returns the next task to be run. If this returns NULL nextWakeup is set
136    // to the time to requery for the nextTask to run. mNextWakeup is also
137    // set to this time
138    RenderTask* nextTask(nsecs_t* nextWakeup);
139
140    sp<Looper> mLooper;
141    Mutex mLock;
142
143    nsecs_t mNextWakeup;
144    TaskQueue mQueue;
145
146    DisplayInfo mDisplayInfo;
147
148    DisplayEventReceiver* mDisplayEventReceiver;
149    bool mVsyncRequested;
150    std::set<IFrameCallback*> mFrameCallbacks;
151    // We defer the actual registration of these callbacks until
152    // both mQueue *and* mDisplayEventReceiver have been drained off all
153    // immediate events. This makes sure that we catch the next vsync, not
154    // the previous one
155    std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks;
156    bool mFrameCallbackTaskPending;
157    DispatchFrameCallbacks* mFrameCallbackTask;
158
159    TimeLord mTimeLord;
160    RenderState* mRenderState;
161    EglManager* mEglManager;
162
163    ProfileDataContainer mGlobalProfileData;
164    Readback* mReadback = nullptr;
165
166    sk_sp<GrContext> mGrContext;
167    CacheManager* mCacheManager;
168    VulkanManager* mVkManager;
169};
170
171} /* namespace renderthread */
172} /* namespace uirenderer */
173} /* namespace android */
174#endif /* RENDERTHREAD_H_ */
175