xref: /aosp_15_r20/frameworks/base/libs/hwui/renderthread/RenderTask.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #ifndef RENDERTASK_H_
18*d57664e9SAndroid Build Coastguard Worker #define RENDERTASK_H_
19*d57664e9SAndroid Build Coastguard Worker 
20*d57664e9SAndroid Build Coastguard Worker #include <cutils/compiler.h>
21*d57664e9SAndroid Build Coastguard Worker #include <utils/Timers.h>
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker namespace android {
24*d57664e9SAndroid Build Coastguard Worker class Mutex;
25*d57664e9SAndroid Build Coastguard Worker class Condition;
26*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
27*d57664e9SAndroid Build Coastguard Worker namespace renderthread {
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker #define METHOD_INVOKE_PAYLOAD_SIZE (8 * sizeof(void*))
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker /*
32*d57664e9SAndroid Build Coastguard Worker  * Notes about memory management
33*d57664e9SAndroid Build Coastguard Worker  *
34*d57664e9SAndroid Build Coastguard Worker  * RenderThread will only invoke RenderTask::run(). It is the responsibility
35*d57664e9SAndroid Build Coastguard Worker  * of the RenderTask to know if it needs to suicide at the end of run() or
36*d57664e9SAndroid Build Coastguard Worker  * if some other lifecycle is being used. As such, it is not valid to reference
37*d57664e9SAndroid Build Coastguard Worker  * anything on RenderTask after the first call to run().
38*d57664e9SAndroid Build Coastguard Worker  *
39*d57664e9SAndroid Build Coastguard Worker  * For example SignalingRenderTask
40*d57664e9SAndroid Build Coastguard Worker  * is expected to be stack allocated by the calling thread, so it does not
41*d57664e9SAndroid Build Coastguard Worker  * suicide in run() but instead relies on the caller to destroy it.
42*d57664e9SAndroid Build Coastguard Worker  *
43*d57664e9SAndroid Build Coastguard Worker  * MethodInvokeRenderTask however is currently allocated with new, so it will
44*d57664e9SAndroid Build Coastguard Worker  * suicide at the end of run(). TODO: Replace this with a small pool to avoid
45*d57664e9SAndroid Build Coastguard Worker  * malloc/free churn of small objects?
46*d57664e9SAndroid Build Coastguard Worker  */
47*d57664e9SAndroid Build Coastguard Worker 
48*d57664e9SAndroid Build Coastguard Worker class RenderTask {
49*d57664e9SAndroid Build Coastguard Worker public:
RenderTask()50*d57664e9SAndroid Build Coastguard Worker     RenderTask() : mNext(nullptr), mRunAt(0) {}
~RenderTask()51*d57664e9SAndroid Build Coastguard Worker     virtual ~RenderTask() {}
52*d57664e9SAndroid Build Coastguard Worker 
53*d57664e9SAndroid Build Coastguard Worker     virtual void run() = 0;
54*d57664e9SAndroid Build Coastguard Worker 
55*d57664e9SAndroid Build Coastguard Worker     RenderTask* mNext;
56*d57664e9SAndroid Build Coastguard Worker     nsecs_t mRunAt;  // nano-seconds on the SYSTEM_TIME_MONOTONIC clock
57*d57664e9SAndroid Build Coastguard Worker };
58*d57664e9SAndroid Build Coastguard Worker 
59*d57664e9SAndroid Build Coastguard Worker class SignalingRenderTask : public RenderTask {
60*d57664e9SAndroid Build Coastguard Worker public:
61*d57664e9SAndroid Build Coastguard Worker     // Takes ownership of task, caller owns lock and signal
SignalingRenderTask(RenderTask * task,Mutex * lock,Condition * signal)62*d57664e9SAndroid Build Coastguard Worker     SignalingRenderTask(RenderTask* task, Mutex* lock, Condition* signal)
63*d57664e9SAndroid Build Coastguard Worker             : mTask(task), mLock(lock), mSignal(signal), mHasRun(false) {}
64*d57664e9SAndroid Build Coastguard Worker     virtual void run() override;
hasRun()65*d57664e9SAndroid Build Coastguard Worker     bool hasRun() const { return mHasRun; }
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker private:
68*d57664e9SAndroid Build Coastguard Worker     RenderTask* mTask;
69*d57664e9SAndroid Build Coastguard Worker     Mutex* mLock;
70*d57664e9SAndroid Build Coastguard Worker     Condition* mSignal;
71*d57664e9SAndroid Build Coastguard Worker     bool mHasRun;
72*d57664e9SAndroid Build Coastguard Worker };
73*d57664e9SAndroid Build Coastguard Worker 
74*d57664e9SAndroid Build Coastguard Worker typedef void* (*RunnableMethod)(void* data);
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker class MethodInvokeRenderTask : public RenderTask {
77*d57664e9SAndroid Build Coastguard Worker public:
MethodInvokeRenderTask(RunnableMethod method)78*d57664e9SAndroid Build Coastguard Worker     explicit MethodInvokeRenderTask(RunnableMethod method) : mMethod(method), mReturnPtr(nullptr) {}
79*d57664e9SAndroid Build Coastguard Worker 
payload()80*d57664e9SAndroid Build Coastguard Worker     void* payload() { return mData; }
setReturnPtr(void ** retptr)81*d57664e9SAndroid Build Coastguard Worker     void setReturnPtr(void** retptr) { mReturnPtr = retptr; }
82*d57664e9SAndroid Build Coastguard Worker 
run()83*d57664e9SAndroid Build Coastguard Worker     virtual void run() override {
84*d57664e9SAndroid Build Coastguard Worker         void* retval = mMethod(mData);
85*d57664e9SAndroid Build Coastguard Worker         if (mReturnPtr) {
86*d57664e9SAndroid Build Coastguard Worker             *mReturnPtr = retval;
87*d57664e9SAndroid Build Coastguard Worker         }
88*d57664e9SAndroid Build Coastguard Worker         // Commit suicide
89*d57664e9SAndroid Build Coastguard Worker         delete this;
90*d57664e9SAndroid Build Coastguard Worker     }
91*d57664e9SAndroid Build Coastguard Worker 
92*d57664e9SAndroid Build Coastguard Worker private:
93*d57664e9SAndroid Build Coastguard Worker     RunnableMethod mMethod;
94*d57664e9SAndroid Build Coastguard Worker     char mData[METHOD_INVOKE_PAYLOAD_SIZE];
95*d57664e9SAndroid Build Coastguard Worker     void** mReturnPtr;
96*d57664e9SAndroid Build Coastguard Worker };
97*d57664e9SAndroid Build Coastguard Worker 
98*d57664e9SAndroid Build Coastguard Worker } /* namespace renderthread */
99*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */
100*d57664e9SAndroid Build Coastguard Worker } /* namespace android */
101*d57664e9SAndroid Build Coastguard Worker #endif /* RENDERTASK_H_ */
102