xref: /aosp_15_r20/frameworks/native/libs/renderengine/threaded/RenderEngineThreaded.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2020 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include "RenderEngineThreaded.h"
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <sched.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <chrono>
23*38e8c45fSAndroid Build Coastguard Worker #include <future>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <private/gui/SyncFeatures.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <processgroup/processgroup.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker using namespace std::chrono_literals;
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker namespace android {
33*38e8c45fSAndroid Build Coastguard Worker namespace renderengine {
34*38e8c45fSAndroid Build Coastguard Worker namespace threaded {
35*38e8c45fSAndroid Build Coastguard Worker 
create(CreateInstanceFactory factory)36*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<RenderEngineThreaded> RenderEngineThreaded::create(CreateInstanceFactory factory) {
37*38e8c45fSAndroid Build Coastguard Worker     return std::make_unique<RenderEngineThreaded>(std::move(factory));
38*38e8c45fSAndroid Build Coastguard Worker }
39*38e8c45fSAndroid Build Coastguard Worker 
RenderEngineThreaded(CreateInstanceFactory factory)40*38e8c45fSAndroid Build Coastguard Worker RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory)
41*38e8c45fSAndroid Build Coastguard Worker       : RenderEngine(Threaded::YES) {
42*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lockThread(mThreadMutex);
45*38e8c45fSAndroid Build Coastguard Worker     mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory);
46*38e8c45fSAndroid Build Coastguard Worker }
47*38e8c45fSAndroid Build Coastguard Worker 
~RenderEngineThreaded()48*38e8c45fSAndroid Build Coastguard Worker RenderEngineThreaded::~RenderEngineThreaded() {
49*38e8c45fSAndroid Build Coastguard Worker     mRunning = false;
50*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker     if (mThread.joinable()) {
53*38e8c45fSAndroid Build Coastguard Worker         mThread.join();
54*38e8c45fSAndroid Build Coastguard Worker     }
55*38e8c45fSAndroid Build Coastguard Worker }
56*38e8c45fSAndroid Build Coastguard Worker 
setSchedFifo(bool enabled)57*38e8c45fSAndroid Build Coastguard Worker status_t RenderEngineThreaded::setSchedFifo(bool enabled) {
58*38e8c45fSAndroid Build Coastguard Worker     static constexpr int kFifoPriority = 2;
59*38e8c45fSAndroid Build Coastguard Worker     static constexpr int kOtherPriority = 0;
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker     struct sched_param param = {0};
62*38e8c45fSAndroid Build Coastguard Worker     int sched_policy;
63*38e8c45fSAndroid Build Coastguard Worker     if (enabled) {
64*38e8c45fSAndroid Build Coastguard Worker         sched_policy = SCHED_FIFO;
65*38e8c45fSAndroid Build Coastguard Worker         param.sched_priority = kFifoPriority;
66*38e8c45fSAndroid Build Coastguard Worker     } else {
67*38e8c45fSAndroid Build Coastguard Worker         sched_policy = SCHED_OTHER;
68*38e8c45fSAndroid Build Coastguard Worker         param.sched_priority = kOtherPriority;
69*38e8c45fSAndroid Build Coastguard Worker     }
70*38e8c45fSAndroid Build Coastguard Worker 
71*38e8c45fSAndroid Build Coastguard Worker     if (sched_setscheduler(0, sched_policy, &param) != 0) {
72*38e8c45fSAndroid Build Coastguard Worker         return -errno;
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
75*38e8c45fSAndroid Build Coastguard Worker }
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
threadMain(CreateInstanceFactory factory)78*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_SAFETY_ANALYSIS {
79*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
80*38e8c45fSAndroid Build Coastguard Worker 
81*38e8c45fSAndroid Build Coastguard Worker     if (!SetTaskProfiles(0, {"SFRenderEnginePolicy"})) {
82*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Failed to set render-engine task profile!");
83*38e8c45fSAndroid Build Coastguard Worker     }
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker     if (setSchedFifo(true) != NO_ERROR) {
86*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Couldn't set SCHED_FIFO");
87*38e8c45fSAndroid Build Coastguard Worker     }
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker     mRenderEngine = factory();
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker     pthread_setname_np(pthread_self(), mThreadName);
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     {
94*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock lock(mInitializedMutex);
95*38e8c45fSAndroid Build Coastguard Worker         mIsInitialized = true;
96*38e8c45fSAndroid Build Coastguard Worker     }
97*38e8c45fSAndroid Build Coastguard Worker     mInitializedCondition.notify_all();
98*38e8c45fSAndroid Build Coastguard Worker 
99*38e8c45fSAndroid Build Coastguard Worker     while (mRunning) {
100*38e8c45fSAndroid Build Coastguard Worker         const auto getNextTask = [this]() -> std::optional<Work> {
101*38e8c45fSAndroid Build Coastguard Worker             std::scoped_lock lock(mThreadMutex);
102*38e8c45fSAndroid Build Coastguard Worker             if (!mFunctionCalls.empty()) {
103*38e8c45fSAndroid Build Coastguard Worker                 Work task = mFunctionCalls.front();
104*38e8c45fSAndroid Build Coastguard Worker                 mFunctionCalls.pop();
105*38e8c45fSAndroid Build Coastguard Worker                 return std::make_optional<Work>(task);
106*38e8c45fSAndroid Build Coastguard Worker             }
107*38e8c45fSAndroid Build Coastguard Worker             return std::nullopt;
108*38e8c45fSAndroid Build Coastguard Worker         };
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker         const auto task = getNextTask();
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker         if (task) {
113*38e8c45fSAndroid Build Coastguard Worker             (*task)(*mRenderEngine);
114*38e8c45fSAndroid Build Coastguard Worker         }
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mThreadMutex);
117*38e8c45fSAndroid Build Coastguard Worker         mCondition.wait(lock, [this]() REQUIRES(mThreadMutex) {
118*38e8c45fSAndroid Build Coastguard Worker             return !mRunning || !mFunctionCalls.empty();
119*38e8c45fSAndroid Build Coastguard Worker         });
120*38e8c45fSAndroid Build Coastguard Worker     }
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     // we must release the RenderEngine on the thread that created it
123*38e8c45fSAndroid Build Coastguard Worker     mRenderEngine.reset();
124*38e8c45fSAndroid Build Coastguard Worker }
125*38e8c45fSAndroid Build Coastguard Worker 
waitUntilInitialized() const126*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::waitUntilInitialized() const {
127*38e8c45fSAndroid Build Coastguard Worker     if (!mIsInitialized) {
128*38e8c45fSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mInitializedMutex);
129*38e8c45fSAndroid Build Coastguard Worker         mInitializedCondition.wait(lock, [this] { return mIsInitialized.load(); });
130*38e8c45fSAndroid Build Coastguard Worker     }
131*38e8c45fSAndroid Build Coastguard Worker }
132*38e8c45fSAndroid Build Coastguard Worker 
primeCache(PrimeCacheConfig config)133*38e8c45fSAndroid Build Coastguard Worker std::future<void> RenderEngineThreaded::primeCache(PrimeCacheConfig config) {
134*38e8c45fSAndroid Build Coastguard Worker     const auto resultPromise = std::make_shared<std::promise<void>>();
135*38e8c45fSAndroid Build Coastguard Worker     std::future<void> resultFuture = resultPromise->get_future();
136*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
137*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
138*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
139*38e8c45fSAndroid Build Coastguard Worker     {
140*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
141*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([resultPromise, config](renderengine::RenderEngine& instance) {
142*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::primeCache");
143*38e8c45fSAndroid Build Coastguard Worker             if (setSchedFifo(false) != NO_ERROR) {
144*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Couldn't set SCHED_OTHER for primeCache");
145*38e8c45fSAndroid Build Coastguard Worker             }
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker             instance.primeCache(config);
148*38e8c45fSAndroid Build Coastguard Worker             resultPromise->set_value();
149*38e8c45fSAndroid Build Coastguard Worker 
150*38e8c45fSAndroid Build Coastguard Worker             if (setSchedFifo(true) != NO_ERROR) {
151*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Couldn't set SCHED_FIFO for primeCache");
152*38e8c45fSAndroid Build Coastguard Worker             }
153*38e8c45fSAndroid Build Coastguard Worker         });
154*38e8c45fSAndroid Build Coastguard Worker     }
155*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
156*38e8c45fSAndroid Build Coastguard Worker 
157*38e8c45fSAndroid Build Coastguard Worker     return resultFuture;
158*38e8c45fSAndroid Build Coastguard Worker }
159*38e8c45fSAndroid Build Coastguard Worker 
dump(std::string & result)160*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::dump(std::string& result) {
161*38e8c45fSAndroid Build Coastguard Worker     std::promise<std::string> resultPromise;
162*38e8c45fSAndroid Build Coastguard Worker     std::future<std::string> resultFuture = resultPromise.get_future();
163*38e8c45fSAndroid Build Coastguard Worker     {
164*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
165*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([&resultPromise, &result](renderengine::RenderEngine& instance) {
166*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::dump");
167*38e8c45fSAndroid Build Coastguard Worker             std::string localResult = result;
168*38e8c45fSAndroid Build Coastguard Worker             instance.dump(localResult);
169*38e8c45fSAndroid Build Coastguard Worker             resultPromise.set_value(std::move(localResult));
170*38e8c45fSAndroid Build Coastguard Worker         });
171*38e8c45fSAndroid Build Coastguard Worker     }
172*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
173*38e8c45fSAndroid Build Coastguard Worker     // Note: This is an rvalue.
174*38e8c45fSAndroid Build Coastguard Worker     result.assign(resultFuture.get());
175*38e8c45fSAndroid Build Coastguard Worker }
176*38e8c45fSAndroid Build Coastguard Worker 
mapExternalTextureBuffer(const sp<GraphicBuffer> & buffer,bool isRenderable)177*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
178*38e8c45fSAndroid Build Coastguard Worker                                                     bool isRenderable) {
179*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
180*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
181*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
182*38e8c45fSAndroid Build Coastguard Worker     {
183*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
184*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
185*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::mapExternalTextureBuffer");
186*38e8c45fSAndroid Build Coastguard Worker             instance.mapExternalTextureBuffer(buffer, isRenderable);
187*38e8c45fSAndroid Build Coastguard Worker         });
188*38e8c45fSAndroid Build Coastguard Worker     }
189*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
190*38e8c45fSAndroid Build Coastguard Worker }
191*38e8c45fSAndroid Build Coastguard Worker 
unmapExternalTextureBuffer(sp<GraphicBuffer> && buffer)192*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
193*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
194*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
195*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
196*38e8c45fSAndroid Build Coastguard Worker     {
197*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
198*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push(
199*38e8c45fSAndroid Build Coastguard Worker                 [=, buffer = std::move(buffer)](renderengine::RenderEngine& instance) mutable {
200*38e8c45fSAndroid Build Coastguard Worker                     SFTRACE_NAME("REThreaded::unmapExternalTextureBuffer");
201*38e8c45fSAndroid Build Coastguard Worker                     instance.unmapExternalTextureBuffer(std::move(buffer));
202*38e8c45fSAndroid Build Coastguard Worker                 });
203*38e8c45fSAndroid Build Coastguard Worker     }
204*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
205*38e8c45fSAndroid Build Coastguard Worker }
206*38e8c45fSAndroid Build Coastguard Worker 
getMaxTextureSize() const207*38e8c45fSAndroid Build Coastguard Worker size_t RenderEngineThreaded::getMaxTextureSize() const {
208*38e8c45fSAndroid Build Coastguard Worker     waitUntilInitialized();
209*38e8c45fSAndroid Build Coastguard Worker     return mRenderEngine->getMaxTextureSize();
210*38e8c45fSAndroid Build Coastguard Worker }
211*38e8c45fSAndroid Build Coastguard Worker 
getMaxViewportDims() const212*38e8c45fSAndroid Build Coastguard Worker size_t RenderEngineThreaded::getMaxViewportDims() const {
213*38e8c45fSAndroid Build Coastguard Worker     waitUntilInitialized();
214*38e8c45fSAndroid Build Coastguard Worker     return mRenderEngine->getMaxViewportDims();
215*38e8c45fSAndroid Build Coastguard Worker }
216*38e8c45fSAndroid Build Coastguard Worker 
supportsProtectedContent() const217*38e8c45fSAndroid Build Coastguard Worker bool RenderEngineThreaded::supportsProtectedContent() const {
218*38e8c45fSAndroid Build Coastguard Worker     waitUntilInitialized();
219*38e8c45fSAndroid Build Coastguard Worker     return mRenderEngine->supportsProtectedContent();
220*38e8c45fSAndroid Build Coastguard Worker }
221*38e8c45fSAndroid Build Coastguard Worker 
cleanupPostRender()222*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::cleanupPostRender() {
223*38e8c45fSAndroid Build Coastguard Worker     if (canSkipPostRenderCleanup()) {
224*38e8c45fSAndroid Build Coastguard Worker         return;
225*38e8c45fSAndroid Build Coastguard Worker     }
226*38e8c45fSAndroid Build Coastguard Worker 
227*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
228*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
229*38e8c45fSAndroid Build Coastguard Worker     {
230*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
231*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
232*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::cleanupPostRender");
233*38e8c45fSAndroid Build Coastguard Worker             instance.cleanupPostRender();
234*38e8c45fSAndroid Build Coastguard Worker         });
235*38e8c45fSAndroid Build Coastguard Worker         mNeedsPostRenderCleanup = false;
236*38e8c45fSAndroid Build Coastguard Worker     }
237*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
238*38e8c45fSAndroid Build Coastguard Worker }
239*38e8c45fSAndroid Build Coastguard Worker 
canSkipPostRenderCleanup() const240*38e8c45fSAndroid Build Coastguard Worker bool RenderEngineThreaded::canSkipPostRenderCleanup() const {
241*38e8c45fSAndroid Build Coastguard Worker     return !mNeedsPostRenderCleanup;
242*38e8c45fSAndroid Build Coastguard Worker }
243*38e8c45fSAndroid Build Coastguard Worker 
drawLayersInternal(const std::shared_ptr<std::promise<FenceResult>> && resultPromise,const DisplaySettings & display,const std::vector<LayerSettings> & layers,const std::shared_ptr<ExternalTexture> & buffer,base::unique_fd && bufferFence)244*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::drawLayersInternal(
245*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
246*38e8c45fSAndroid Build Coastguard Worker         const DisplaySettings& display, const std::vector<LayerSettings>& layers,
247*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
248*38e8c45fSAndroid Build Coastguard Worker     resultPromise->set_value(Fence::NO_FENCE);
249*38e8c45fSAndroid Build Coastguard Worker     return;
250*38e8c45fSAndroid Build Coastguard Worker }
251*38e8c45fSAndroid Build Coastguard Worker 
drawGainmapInternal(const std::shared_ptr<std::promise<FenceResult>> && resultPromise,const std::shared_ptr<ExternalTexture> & sdr,base::borrowed_fd && sdrFence,const std::shared_ptr<ExternalTexture> & hdr,base::borrowed_fd && hdrFence,float hdrSdrRatio,ui::Dataspace dataspace,const std::shared_ptr<ExternalTexture> & gainmap)252*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::drawGainmapInternal(
253*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
254*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence,
255*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
256*38e8c45fSAndroid Build Coastguard Worker         float hdrSdrRatio, ui::Dataspace dataspace,
257*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& gainmap) {
258*38e8c45fSAndroid Build Coastguard Worker     resultPromise->set_value(Fence::NO_FENCE);
259*38e8c45fSAndroid Build Coastguard Worker     return;
260*38e8c45fSAndroid Build Coastguard Worker }
261*38e8c45fSAndroid Build Coastguard Worker 
drawLayers(const DisplaySettings & display,const std::vector<LayerSettings> & layers,const std::shared_ptr<ExternalTexture> & buffer,base::unique_fd && bufferFence)262*38e8c45fSAndroid Build Coastguard Worker ftl::Future<FenceResult> RenderEngineThreaded::drawLayers(
263*38e8c45fSAndroid Build Coastguard Worker         const DisplaySettings& display, const std::vector<LayerSettings>& layers,
264*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
265*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
266*38e8c45fSAndroid Build Coastguard Worker     const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
267*38e8c45fSAndroid Build Coastguard Worker     std::future<FenceResult> resultFuture = resultPromise->get_future();
268*38e8c45fSAndroid Build Coastguard Worker     int fd = bufferFence.release();
269*38e8c45fSAndroid Build Coastguard Worker     {
270*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
271*38e8c45fSAndroid Build Coastguard Worker         mNeedsPostRenderCleanup = true;
272*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push(
273*38e8c45fSAndroid Build Coastguard Worker                 [resultPromise, display, layers, buffer, fd](renderengine::RenderEngine& instance) {
274*38e8c45fSAndroid Build Coastguard Worker                     SFTRACE_NAME("REThreaded::drawLayers");
275*38e8c45fSAndroid Build Coastguard Worker                     instance.updateProtectedContext(layers, {buffer.get()});
276*38e8c45fSAndroid Build Coastguard Worker                     instance.drawLayersInternal(std::move(resultPromise), display, layers, buffer,
277*38e8c45fSAndroid Build Coastguard Worker                                                 base::unique_fd(fd));
278*38e8c45fSAndroid Build Coastguard Worker                 });
279*38e8c45fSAndroid Build Coastguard Worker     }
280*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
281*38e8c45fSAndroid Build Coastguard Worker     return resultFuture;
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker 
drawGainmap(const std::shared_ptr<ExternalTexture> & sdr,base::borrowed_fd && sdrFence,const std::shared_ptr<ExternalTexture> & hdr,base::borrowed_fd && hdrFence,float hdrSdrRatio,ui::Dataspace dataspace,const std::shared_ptr<ExternalTexture> & gainmap)284*38e8c45fSAndroid Build Coastguard Worker ftl::Future<FenceResult> RenderEngineThreaded::drawGainmap(
285*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence,
286*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
287*38e8c45fSAndroid Build Coastguard Worker         float hdrSdrRatio, ui::Dataspace dataspace,
288*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<ExternalTexture>& gainmap) {
289*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
290*38e8c45fSAndroid Build Coastguard Worker     const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
291*38e8c45fSAndroid Build Coastguard Worker     std::future<FenceResult> resultFuture = resultPromise->get_future();
292*38e8c45fSAndroid Build Coastguard Worker     {
293*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
294*38e8c45fSAndroid Build Coastguard Worker         mNeedsPostRenderCleanup = true;
295*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([resultPromise, sdr, sdrFence = std::move(sdrFence), hdr,
296*38e8c45fSAndroid Build Coastguard Worker                              hdrFence = std::move(hdrFence), hdrSdrRatio, dataspace,
297*38e8c45fSAndroid Build Coastguard Worker                              gainmap](renderengine::RenderEngine& instance) mutable {
298*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::drawGainmap");
299*38e8c45fSAndroid Build Coastguard Worker             instance.updateProtectedContext({}, {sdr.get(), hdr.get(), gainmap.get()});
300*38e8c45fSAndroid Build Coastguard Worker             instance.drawGainmapInternal(std::move(resultPromise), sdr, std::move(sdrFence), hdr,
301*38e8c45fSAndroid Build Coastguard Worker                                          std::move(hdrFence), hdrSdrRatio, dataspace, gainmap);
302*38e8c45fSAndroid Build Coastguard Worker         });
303*38e8c45fSAndroid Build Coastguard Worker     }
304*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
305*38e8c45fSAndroid Build Coastguard Worker     return resultFuture;
306*38e8c45fSAndroid Build Coastguard Worker }
307*38e8c45fSAndroid Build Coastguard Worker 
getContextPriority()308*38e8c45fSAndroid Build Coastguard Worker int RenderEngineThreaded::getContextPriority() {
309*38e8c45fSAndroid Build Coastguard Worker     std::promise<int> resultPromise;
310*38e8c45fSAndroid Build Coastguard Worker     std::future<int> resultFuture = resultPromise.get_future();
311*38e8c45fSAndroid Build Coastguard Worker     {
312*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
313*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
314*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::getContextPriority");
315*38e8c45fSAndroid Build Coastguard Worker             int priority = instance.getContextPriority();
316*38e8c45fSAndroid Build Coastguard Worker             resultPromise.set_value(priority);
317*38e8c45fSAndroid Build Coastguard Worker         });
318*38e8c45fSAndroid Build Coastguard Worker     }
319*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
320*38e8c45fSAndroid Build Coastguard Worker     return resultFuture.get();
321*38e8c45fSAndroid Build Coastguard Worker }
322*38e8c45fSAndroid Build Coastguard Worker 
supportsBackgroundBlur()323*38e8c45fSAndroid Build Coastguard Worker bool RenderEngineThreaded::supportsBackgroundBlur() {
324*38e8c45fSAndroid Build Coastguard Worker     waitUntilInitialized();
325*38e8c45fSAndroid Build Coastguard Worker     return mRenderEngine->supportsBackgroundBlur();
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker 
onActiveDisplaySizeChanged(ui::Size size)328*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::onActiveDisplaySizeChanged(ui::Size size) {
329*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
330*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
331*38e8c45fSAndroid Build Coastguard Worker     {
332*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
333*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
334*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
335*38e8c45fSAndroid Build Coastguard Worker             instance.onActiveDisplaySizeChanged(size);
336*38e8c45fSAndroid Build Coastguard Worker         });
337*38e8c45fSAndroid Build Coastguard Worker     }
338*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
339*38e8c45fSAndroid Build Coastguard Worker }
340*38e8c45fSAndroid Build Coastguard Worker 
getRenderEngineTid() const341*38e8c45fSAndroid Build Coastguard Worker std::optional<pid_t> RenderEngineThreaded::getRenderEngineTid() const {
342*38e8c45fSAndroid Build Coastguard Worker     std::promise<pid_t> tidPromise;
343*38e8c45fSAndroid Build Coastguard Worker     std::future<pid_t> tidFuture = tidPromise.get_future();
344*38e8c45fSAndroid Build Coastguard Worker     {
345*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
346*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([&tidPromise](renderengine::RenderEngine& instance) {
347*38e8c45fSAndroid Build Coastguard Worker             tidPromise.set_value(gettid());
348*38e8c45fSAndroid Build Coastguard Worker         });
349*38e8c45fSAndroid Build Coastguard Worker     }
350*38e8c45fSAndroid Build Coastguard Worker 
351*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
352*38e8c45fSAndroid Build Coastguard Worker     return std::make_optional(tidFuture.get());
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker 
setEnableTracing(bool tracingEnabled)355*38e8c45fSAndroid Build Coastguard Worker void RenderEngineThreaded::setEnableTracing(bool tracingEnabled) {
356*38e8c45fSAndroid Build Coastguard Worker     // This function is designed so it can run asynchronously, so we do not need to wait
357*38e8c45fSAndroid Build Coastguard Worker     // for the futures.
358*38e8c45fSAndroid Build Coastguard Worker     {
359*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mThreadMutex);
360*38e8c45fSAndroid Build Coastguard Worker         mFunctionCalls.push([tracingEnabled](renderengine::RenderEngine& instance) {
361*38e8c45fSAndroid Build Coastguard Worker             SFTRACE_NAME("REThreaded::setEnableTracing");
362*38e8c45fSAndroid Build Coastguard Worker             instance.setEnableTracing(tracingEnabled);
363*38e8c45fSAndroid Build Coastguard Worker         });
364*38e8c45fSAndroid Build Coastguard Worker     }
365*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_one();
366*38e8c45fSAndroid Build Coastguard Worker }
367*38e8c45fSAndroid Build Coastguard Worker } // namespace threaded
368*38e8c45fSAndroid Build Coastguard Worker } // namespace renderengine
369*38e8c45fSAndroid Build Coastguard Worker } // namespace android
370