1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/*
2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2013 The Android Open Source Project
3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License.
6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at
7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software
11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and
14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License.
15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
17cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#ifndef RENDERTHREAD_H_
18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#define RENDERTHREAD_H_
19cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
20cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include "RenderTask.h"
21e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
22ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include "../JankTracker.h"
23ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include "TimeLord.h"
24e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
2598f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger#include <GrContext.h>
26cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <cutils/compiler.h>
27b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck#include <ui/DisplayInfo.h>
28cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <utils/Looper.h>
29cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#include <utils/Thread.h>
30cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
31ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include <memory>
32ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck#include <set>
3318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
34cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace android {
353b20251a355c88193c439f928a84ae69483fb488John Reck
36e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckclass DisplayEventReceiver;
37e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
38cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace uirenderer {
393b20251a355c88193c439f928a84ae69483fb488John Reck
40c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenbergerclass Readback;
413b20251a355c88193c439f928a84ae69483fb488John Reckclass RenderState;
420a24b146cd3dacf372ce98424044423a5b2fbf2aChris Craikclass TestUtils;
433b20251a355c88193c439f928a84ae69483fb488John Reck
44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Recknamespace renderthread {
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
46443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reckclass CanvasContext;
47e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckclass DispatchFrameCallbacks;
483b20251a355c88193c439f928a84ae69483fb488John Reckclass EglManager;
493b20251a355c88193c439f928a84ae69483fb488John Reckclass RenderProxy;
500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergerclass VulkanManager;
51e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckclass TaskQueue {
534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckpublic:
544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    TaskQueue();
554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* next();
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void queue(RenderTask* task);
58a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    void queueAtFront(RenderTask* task);
594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* peek();
604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void remove(RenderTask* task);
614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckprivate:
634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* mHead;
644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* mTail;
654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck};
664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
67e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// Mimics android.view.Choreographer.FrameCallback
68e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckclass IFrameCallback {
69e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckpublic:
7018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    virtual void doFrame() = 0;
71e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
72e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckprotected:
73e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    ~IFrameCallback() {}
74e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck};
75e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
766b50780363d3bb8db600c770183fa07677509ae8John Reckclass ANDROID_API RenderThread : public Thread {
77df1742ed47da1e9b61afeae16fa448d5302a8aa0John Reck    PREVENT_COPY_AND_ASSIGN(RenderThread);
78cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic:
79cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    // RenderThread takes complete ownership of tasks that are queued
80cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    // and will delete them after they are run
81cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    ANDROID_API void queue(RenderTask* task);
820a24b146cd3dacf372ce98424044423a5b2fbf2aChris Craik    ANDROID_API void queueAndWait(RenderTask* task);
83a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    ANDROID_API void queueAtFront(RenderTask* task);
84a733f89c05567c97359169832f41389b939baaadJohn Reck    void queueAt(RenderTask* task, nsecs_t runAtNs);
854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    void remove(RenderTask* task);
86cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
87e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    // Mimics android.view.Choreographer
88e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void postFrameCallback(IFrameCallback* callback);
8901a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    bool removeFrameCallback(IFrameCallback* callback);
90a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // If the callback is currently registered, it will be pushed back until
91a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // the next vsync. If it is not currently registered this does nothing.
92a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    void pushBackFrameCallback(IFrameCallback* callback);
93e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
9418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    TimeLord& timeLord() { return mTimeLord; }
95daf7229047c44947b9b02ee187fe5b13f30ebd4bDerek Sollenberger    RenderState& renderState() const { return *mRenderState; }
96daf7229047c44947b9b02ee187fe5b13f30ebd4bDerek Sollenberger    EglManager& eglManager() const { return *mEglManager; }
97ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    JankTracker& jankTracker() { return *mJankTracker; }
98c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger    Readback& readback();
9918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
100b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
101b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck
10298f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger    GrContext* getGrContext() const { return mGrContext.get(); }
10398f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger    void setGrContext(GrContext* cxt) { mGrContext.reset(cxt); }
10498f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger
1050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    VulkanManager& vulkanManager() { return *mVkManager; }
1060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger
107cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckprotected:
108d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    virtual bool threadLoop() override;
109cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
110cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckprivate:
111e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    friend class DispatchFrameCallbacks;
1123b20251a355c88193c439f928a84ae69483fb488John Reck    friend class RenderProxy;
1130a24b146cd3dacf372ce98424044423a5b2fbf2aChris Craik    friend class android::uirenderer::TestUtils;
114cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
115cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    RenderThread();
116cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    virtual ~RenderThread();
117cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1186b50780363d3bb8db600c770183fa07677509ae8John Reck    static bool hasInstance();
1196b50780363d3bb8db600c770183fa07677509ae8John Reck    static RenderThread& getInstance();
1206b50780363d3bb8db600c770183fa07677509ae8John Reck
1213b20251a355c88193c439f928a84ae69483fb488John Reck    void initThreadLocals();
122e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void initializeDisplayEventReceiver();
123e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    static int displayEventReceiverCallback(int fd, int events, void* data);
124a733f89c05567c97359169832f41389b939baaadJohn Reck    void drainDisplayEventQueue();
125e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void dispatchFrameCallbacks();
126a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    void requestVsync();
127e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
1284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    // Returns the next task to be run. If this returns NULL nextWakeup is set
1294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    // to the time to requery for the nextTask to run. mNextWakeup is also
1304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    // set to this time
1314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    RenderTask* nextTask(nsecs_t* nextWakeup);
132cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
133cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    sp<Looper> mLooper;
134cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    Mutex mLock;
135cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    nsecs_t mNextWakeup;
1374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    TaskQueue mQueue;
138e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
139b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    DisplayInfo mDisplayInfo;
140b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck
141e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    DisplayEventReceiver* mDisplayEventReceiver;
142e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool mVsyncRequested;
143e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    std::set<IFrameCallback*> mFrameCallbacks;
144a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // We defer the actual registration of these callbacks until
145a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // both mQueue *and* mDisplayEventReceiver have been drained off all
146a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // immediate events. This makes sure that we catch the next vsync, not
147a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // the previous one
148a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks;
149e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool mFrameCallbackTaskPending;
150e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    DispatchFrameCallbacks* mFrameCallbackTask;
15118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
15218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    TimeLord mTimeLord;
1533b20251a355c88193c439f928a84ae69483fb488John Reck    RenderState* mRenderState;
1543b20251a355c88193c439f928a84ae69483fb488John Reck    EglManager* mEglManager;
155ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
156ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    JankTracker* mJankTracker = nullptr;
157c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger    Readback* mReadback = nullptr;
15898f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger
15998f75d53dbe243b1661c616643698e025d4978f6Derek Sollenberger    sk_sp<GrContext> mGrContext;
1600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    VulkanManager* mVkManager;
161cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck};
162cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
163cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace renderthread */
164cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace uirenderer */
165cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} /* namespace android */
166cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck#endif /* RENDERTHREAD_H_ */
167