1 /*
2  * Copyright (C) 2014 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 #ifndef DRAWFRAMETASK_H
17 #define DRAWFRAMETASK_H
18 
19 #include <optional>
20 #include <vector>
21 
22 #include <performance_hint_private.h>
23 #include <utils/Condition.h>
24 #include <utils/Mutex.h>
25 #include <utils/StrongPointer.h>
26 
27 #include "RenderTask.h"
28 
29 #include "../FrameInfo.h"
30 #include "../Rect.h"
31 #include "../TreeInfo.h"
32 
33 namespace android {
34 namespace uirenderer {
35 
36 class DeferredLayerUpdater;
37 class RenderNode;
38 
39 namespace renderthread {
40 
41 class CanvasContext;
42 class RenderThread;
43 
44 namespace SyncResult {
45 enum {
46     OK = 0,
47     UIRedrawRequired = 1 << 0,
48     LostSurfaceRewardIfFound = 1 << 1,
49     ContextIsStopped = 1 << 2,
50     FrameDropped = 1 << 3,
51 };
52 }
53 
54 /*
55  * This is a special Super Task. It is re-used multiple times by RenderProxy,
56  * and contains state (such as layer updaters & new DisplayLists) that is
57  * tracked across many frames not just a single frame.
58  * It is the sync-state task, and will kick off the post-sync draw
59  */
60 class DrawFrameTask {
61 public:
62     DrawFrameTask();
63     virtual ~DrawFrameTask();
64 
65     void setContext(RenderThread* thread, CanvasContext* context, RenderNode* targetNode,
66                     int32_t uiThreadId, int32_t renderThreadId);
setContentDrawBounds(int left,int top,int right,int bottom)67     void setContentDrawBounds(int left, int top, int right, int bottom) {
68         mContentDrawBounds.set(left, top, right, bottom);
69     }
70 
71     void pushLayerUpdate(DeferredLayerUpdater* layer);
72     void removeLayerUpdate(DeferredLayerUpdater* layer);
73 
74     int drawFrame();
75 
frameInfo()76     int64_t* frameInfo() { return mFrameInfo; }
77 
78     void run();
79 
setFrameCallback(std::function<void (int64_t)> && callback)80     void setFrameCallback(std::function<void(int64_t)>&& callback) {
81         mFrameCallback = std::move(callback);
82     }
83 
setFrameCommitCallback(std::function<void (bool)> && callback)84     void setFrameCommitCallback(std::function<void(bool)>&& callback) {
85         mFrameCommitCallback = std::move(callback);
86     }
87 
setFrameCompleteCallback(std::function<void ()> && callback)88     void setFrameCompleteCallback(std::function<void()>&& callback) {
89         mFrameCompleteCallback = std::move(callback);
90     }
91 
92 private:
93     class HintSessionWrapper {
94     public:
95         HintSessionWrapper(int32_t uiThreadId, int32_t renderThreadId);
96         ~HintSessionWrapper();
97 
98         void updateTargetWorkDuration(long targetDurationNanos);
99         void reportActualWorkDuration(long actualDurationNanos);
100 
101     private:
102         APerformanceHintSession* mHintSession = nullptr;
103     };
104 
105     void postAndWait();
106     bool syncFrameState(TreeInfo& info);
107     void unblockUiThread();
108 
109     Mutex mLock;
110     Condition mSignal;
111 
112     RenderThread* mRenderThread;
113     CanvasContext* mContext;
114     RenderNode* mTargetNode = nullptr;
115     int32_t mUiThreadId = -1;
116     int32_t mRenderThreadId = -1;
117     Rect mContentDrawBounds;
118 
119     /*********************************************
120      *  Single frame data
121      *********************************************/
122     std::vector<sp<DeferredLayerUpdater> > mLayers;
123 
124     int mSyncResult;
125     int64_t mSyncQueued;
126 
127     int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
128 
129     std::function<void(int64_t)> mFrameCallback;
130     std::function<void(bool)> mFrameCommitCallback;
131     std::function<void()> mFrameCompleteCallback;
132 
133     nsecs_t mLastDequeueBufferDuration = 0;
134     nsecs_t mLastTargetWorkDuration = 0;
135     std::optional<HintSessionWrapper> mHintSessionWrapper;
136 };
137 
138 } /* namespace renderthread */
139 } /* namespace uirenderer */
140 } /* namespace android */
141 
142 #endif /* DRAWFRAMETASK_H */
143