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, ¶m) != 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