| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2020 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 |  | 
 | 17 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
 | 18 |  | 
 | 19 | #include "RenderEngineThreaded.h" | 
 | 20 |  | 
 | 21 | #include <sched.h> | 
 | 22 | #include <chrono> | 
 | 23 | #include <future> | 
 | 24 |  | 
 | 25 | #include <android-base/stringprintf.h> | 
| Ana Krulec | 15f7cf3 | 2020-05-12 11:57:42 -0700 | [diff] [blame] | 26 | #include <private/gui/SyncFeatures.h> | 
| Wei Wang | 976a645 | 2021-06-11 15:26:00 -0700 | [diff] [blame] | 27 | #include <processgroup/processgroup.h> | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 28 | #include <utils/Trace.h> | 
 | 29 |  | 
 | 30 | #include "gl/GLESRenderEngine.h" | 
 | 31 |  | 
 | 32 | using namespace std::chrono_literals; | 
 | 33 |  | 
 | 34 | namespace android { | 
 | 35 | namespace renderengine { | 
 | 36 | namespace threaded { | 
 | 37 |  | 
| Alec Mouri | 0d99510 | 2021-02-24 16:53:38 -0800 | [diff] [blame] | 38 | std::unique_ptr<RenderEngineThreaded> RenderEngineThreaded::create(CreateInstanceFactory factory, | 
 | 39 |                                                                    RenderEngineType type) { | 
 | 40 |     return std::make_unique<RenderEngineThreaded>(std::move(factory), type); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 41 | } | 
 | 42 |  | 
| Alec Mouri | 0d99510 | 2021-02-24 16:53:38 -0800 | [diff] [blame] | 43 | RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory, RenderEngineType type) | 
 | 44 |       : RenderEngine(type) { | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 45 |     ATRACE_CALL(); | 
 | 46 |  | 
 | 47 |     std::lock_guard lockThread(mThreadMutex); | 
| Ana Krulec | 15f7cf3 | 2020-05-12 11:57:42 -0700 | [diff] [blame] | 48 |     mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 49 | } | 
 | 50 |  | 
 | 51 | RenderEngineThreaded::~RenderEngineThreaded() { | 
| Alec Mouri | 39d9cb7 | 2021-06-10 10:26:15 -0700 | [diff] [blame] | 52 |     mRunning = false; | 
 | 53 |     mCondition.notify_one(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 54 |  | 
 | 55 |     if (mThread.joinable()) { | 
 | 56 |         mThread.join(); | 
 | 57 |     } | 
 | 58 | } | 
 | 59 |  | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 60 | status_t RenderEngineThreaded::setSchedFifo(bool enabled) { | 
 | 61 |     static constexpr int kFifoPriority = 2; | 
 | 62 |     static constexpr int kOtherPriority = 0; | 
 | 63 |  | 
 | 64 |     struct sched_param param = {0}; | 
 | 65 |     int sched_policy; | 
 | 66 |     if (enabled) { | 
 | 67 |         sched_policy = SCHED_FIFO; | 
 | 68 |         param.sched_priority = kFifoPriority; | 
 | 69 |     } else { | 
 | 70 |         sched_policy = SCHED_OTHER; | 
 | 71 |         param.sched_priority = kOtherPriority; | 
 | 72 |     } | 
 | 73 |  | 
 | 74 |     if (sched_setscheduler(0, sched_policy, ¶m) != 0) { | 
 | 75 |         return -errno; | 
 | 76 |     } | 
 | 77 |     return NO_ERROR; | 
 | 78 | } | 
 | 79 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 80 | // NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations. | 
| Ana Krulec | 15f7cf3 | 2020-05-12 11:57:42 -0700 | [diff] [blame] | 81 | void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_SAFETY_ANALYSIS { | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 82 |     ATRACE_CALL(); | 
 | 83 |  | 
| Wei Wang | 976a645 | 2021-06-11 15:26:00 -0700 | [diff] [blame] | 84 |     if (!SetTaskProfiles(0, {"SFRenderEnginePolicy"})) { | 
 | 85 |         ALOGW("Failed to set render-engine task profile!"); | 
 | 86 |     } | 
 | 87 |  | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 88 |     if (setSchedFifo(true) != NO_ERROR) { | 
 | 89 |         ALOGW("Couldn't set SCHED_FIFO"); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 90 |     } | 
 | 91 |  | 
| Ana Krulec | 15f7cf3 | 2020-05-12 11:57:42 -0700 | [diff] [blame] | 92 |     mRenderEngine = factory(); | 
| Derek Sollenberger | 1ec2fb5 | 2021-06-16 15:11:27 -0400 | [diff] [blame] | 93 |     mIsProtected = mRenderEngine->isProtected(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 94 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 95 |     pthread_setname_np(pthread_self(), mThreadName); | 
 | 96 |  | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 97 |     { | 
| Alec Mouri | 39d9cb7 | 2021-06-10 10:26:15 -0700 | [diff] [blame] | 98 |         std::scoped_lock lock(mInitializedMutex); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 99 |         mIsInitialized = true; | 
 | 100 |     } | 
 | 101 |     mInitializedCondition.notify_all(); | 
 | 102 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 103 |     while (mRunning) { | 
| Alec Mouri | 39d9cb7 | 2021-06-10 10:26:15 -0700 | [diff] [blame] | 104 |         const auto getNextTask = [this]() -> std::optional<Work> { | 
 | 105 |             std::scoped_lock lock(mThreadMutex); | 
 | 106 |             if (!mFunctionCalls.empty()) { | 
 | 107 |                 Work task = mFunctionCalls.front(); | 
 | 108 |                 mFunctionCalls.pop(); | 
 | 109 |                 return std::make_optional<Work>(task); | 
 | 110 |             } | 
 | 111 |             return std::nullopt; | 
 | 112 |         }; | 
 | 113 |  | 
 | 114 |         const auto task = getNextTask(); | 
 | 115 |  | 
 | 116 |         if (task) { | 
 | 117 |             (*task)(*mRenderEngine); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 118 |         } | 
| Alec Mouri | 39d9cb7 | 2021-06-10 10:26:15 -0700 | [diff] [blame] | 119 |  | 
 | 120 |         std::unique_lock<std::mutex> lock(mThreadMutex); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 121 |         mCondition.wait(lock, [this]() REQUIRES(mThreadMutex) { | 
 | 122 |             return !mRunning || !mFunctionCalls.empty(); | 
 | 123 |         }); | 
 | 124 |     } | 
| Derek Sollenberger | 40dcb02 | 2021-04-14 10:28:27 -0400 | [diff] [blame] | 125 |  | 
 | 126 |     // we must release the RenderEngine on the thread that created it | 
 | 127 |     mRenderEngine.reset(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 128 | } | 
 | 129 |  | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 130 | void RenderEngineThreaded::waitUntilInitialized() const { | 
 | 131 |     std::unique_lock<std::mutex> lock(mInitializedMutex); | 
 | 132 |     mInitializedCondition.wait(lock, [=] { return mIsInitialized; }); | 
 | 133 | } | 
 | 134 |  | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 135 | std::future<void> RenderEngineThreaded::primeCache() { | 
 | 136 |     const auto resultPromise = std::make_shared<std::promise<void>>(); | 
 | 137 |     std::future<void> resultFuture = resultPromise->get_future(); | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 138 |     ATRACE_CALL(); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 139 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 140 |     // for the futures. | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 141 |     { | 
 | 142 |         std::lock_guard lock(mThreadMutex); | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 143 |         mFunctionCalls.push([resultPromise](renderengine::RenderEngine& instance) { | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 144 |             ATRACE_NAME("REThreaded::primeCache"); | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 145 |             if (setSchedFifo(false) != NO_ERROR) { | 
 | 146 |                 ALOGW("Couldn't set SCHED_OTHER for primeCache"); | 
 | 147 |             } | 
 | 148 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 149 |             instance.primeCache(); | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 150 |             resultPromise->set_value(); | 
 | 151 |  | 
 | 152 |             if (setSchedFifo(true) != NO_ERROR) { | 
 | 153 |                 ALOGW("Couldn't set SCHED_FIFO for primeCache"); | 
 | 154 |             } | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 155 |         }); | 
 | 156 |     } | 
 | 157 |     mCondition.notify_one(); | 
| Ady Abraham | fe2a6db | 2021-06-09 15:41:37 -0700 | [diff] [blame] | 158 |  | 
 | 159 |     return resultFuture; | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 160 | } | 
 | 161 |  | 
 | 162 | void RenderEngineThreaded::dump(std::string& result) { | 
 | 163 |     std::promise<std::string> resultPromise; | 
 | 164 |     std::future<std::string> resultFuture = resultPromise.get_future(); | 
 | 165 |     { | 
 | 166 |         std::lock_guard lock(mThreadMutex); | 
 | 167 |         mFunctionCalls.push([&resultPromise, &result](renderengine::RenderEngine& instance) { | 
 | 168 |             ATRACE_NAME("REThreaded::dump"); | 
 | 169 |             std::string localResult = result; | 
 | 170 |             instance.dump(localResult); | 
 | 171 |             resultPromise.set_value(std::move(localResult)); | 
 | 172 |         }); | 
 | 173 |     } | 
 | 174 |     mCondition.notify_one(); | 
 | 175 |     // Note: This is an rvalue. | 
 | 176 |     result.assign(resultFuture.get()); | 
 | 177 | } | 
 | 178 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 179 | void RenderEngineThreaded::genTextures(size_t count, uint32_t* names) { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 180 |     ATRACE_CALL(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 181 |     std::promise<void> resultPromise; | 
 | 182 |     std::future<void> resultFuture = resultPromise.get_future(); | 
 | 183 |     { | 
 | 184 |         std::lock_guard lock(mThreadMutex); | 
 | 185 |         mFunctionCalls.push([&resultPromise, count, names](renderengine::RenderEngine& instance) { | 
 | 186 |             ATRACE_NAME("REThreaded::genTextures"); | 
 | 187 |             instance.genTextures(count, names); | 
 | 188 |             resultPromise.set_value(); | 
 | 189 |         }); | 
 | 190 |     } | 
 | 191 |     mCondition.notify_one(); | 
 | 192 |     resultFuture.wait(); | 
 | 193 | } | 
 | 194 |  | 
 | 195 | void RenderEngineThreaded::deleteTextures(size_t count, uint32_t const* names) { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 196 |     ATRACE_CALL(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 197 |     std::promise<void> resultPromise; | 
 | 198 |     std::future<void> resultFuture = resultPromise.get_future(); | 
 | 199 |     { | 
 | 200 |         std::lock_guard lock(mThreadMutex); | 
 | 201 |         mFunctionCalls.push([&resultPromise, count, &names](renderengine::RenderEngine& instance) { | 
 | 202 |             ATRACE_NAME("REThreaded::deleteTextures"); | 
 | 203 |             instance.deleteTextures(count, names); | 
 | 204 |             resultPromise.set_value(); | 
 | 205 |         }); | 
 | 206 |     } | 
 | 207 |     mCondition.notify_one(); | 
 | 208 |     resultFuture.wait(); | 
 | 209 | } | 
 | 210 |  | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 211 | void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, | 
 | 212 |                                                     bool isRenderable) { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 213 |     ATRACE_CALL(); | 
| Ana Krulec | dfec8f5 | 2021-01-13 12:51:47 -0800 | [diff] [blame] | 214 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 215 |     // for the futures. | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 216 |     { | 
 | 217 |         std::lock_guard lock(mThreadMutex); | 
| Ana Krulec | dfec8f5 | 2021-01-13 12:51:47 -0800 | [diff] [blame] | 218 |         mFunctionCalls.push([=](renderengine::RenderEngine& instance) { | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 219 |             ATRACE_NAME("REThreaded::mapExternalTextureBuffer"); | 
 | 220 |             instance.mapExternalTextureBuffer(buffer, isRenderable); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 221 |         }); | 
 | 222 |     } | 
 | 223 |     mCondition.notify_one(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 224 | } | 
 | 225 |  | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 226 | void RenderEngineThreaded::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 227 |     ATRACE_CALL(); | 
| Ana Krulec | dfec8f5 | 2021-01-13 12:51:47 -0800 | [diff] [blame] | 228 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 229 |     // for the futures. | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 230 |     { | 
 | 231 |         std::lock_guard lock(mThreadMutex); | 
| Ana Krulec | dfec8f5 | 2021-01-13 12:51:47 -0800 | [diff] [blame] | 232 |         mFunctionCalls.push([=](renderengine::RenderEngine& instance) { | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 233 |             ATRACE_NAME("REThreaded::unmapExternalTextureBuffer"); | 
 | 234 |             instance.unmapExternalTextureBuffer(buffer); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 235 |         }); | 
 | 236 |     } | 
 | 237 |     mCondition.notify_one(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 238 | } | 
 | 239 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 240 | size_t RenderEngineThreaded::getMaxTextureSize() const { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 241 |     waitUntilInitialized(); | 
 | 242 |     return mRenderEngine->getMaxTextureSize(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 243 | } | 
 | 244 |  | 
 | 245 | size_t RenderEngineThreaded::getMaxViewportDims() const { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 246 |     waitUntilInitialized(); | 
 | 247 |     return mRenderEngine->getMaxViewportDims(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 248 | } | 
 | 249 |  | 
 | 250 | bool RenderEngineThreaded::isProtected() const { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 251 |     waitUntilInitialized(); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 252 |     std::lock_guard lock(mThreadMutex); | 
| Derek Sollenberger | 1ec2fb5 | 2021-06-16 15:11:27 -0400 | [diff] [blame] | 253 |     return mIsProtected; | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 254 | } | 
 | 255 |  | 
 | 256 | bool RenderEngineThreaded::supportsProtectedContent() const { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 257 |     waitUntilInitialized(); | 
 | 258 |     return mRenderEngine->supportsProtectedContent(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 259 | } | 
 | 260 |  | 
| Derek Sollenberger | 1ec2fb5 | 2021-06-16 15:11:27 -0400 | [diff] [blame] | 261 | void RenderEngineThreaded::useProtectedContext(bool useProtectedContext) { | 
 | 262 |     if (isProtected() == useProtectedContext || | 
 | 263 |         (useProtectedContext && !supportsProtectedContent())) { | 
 | 264 |         return; | 
 | 265 |     } | 
 | 266 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 267 |     { | 
 | 268 |         std::lock_guard lock(mThreadMutex); | 
| Derek Sollenberger | 1ec2fb5 | 2021-06-16 15:11:27 -0400 | [diff] [blame] | 269 |         mFunctionCalls.push([useProtectedContext, this](renderengine::RenderEngine& instance) { | 
 | 270 |             ATRACE_NAME("REThreaded::useProtectedContext"); | 
 | 271 |             instance.useProtectedContext(useProtectedContext); | 
 | 272 |             if (instance.isProtected() != useProtectedContext) { | 
 | 273 |                 ALOGE("Failed to switch RenderEngine context."); | 
 | 274 |                 // reset the cached mIsProtected value to a good state, but this does not | 
 | 275 |                 // prevent other callers of this method and isProtected from reading the | 
 | 276 |                 // invalid cached value. | 
 | 277 |                 mIsProtected = instance.isProtected(); | 
 | 278 |             } | 
 | 279 |         }); | 
 | 280 |         mIsProtected = useProtectedContext; | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 281 |     } | 
 | 282 |     mCondition.notify_one(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 283 | } | 
 | 284 |  | 
| Derek Sollenberger | d3f6065 | 2021-06-11 15:34:36 -0400 | [diff] [blame] | 285 | void RenderEngineThreaded::cleanupPostRender() { | 
 | 286 |     if (canSkipPostRenderCleanup()) { | 
 | 287 |         return; | 
 | 288 |     } | 
 | 289 |  | 
 | 290 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 291 |     // for the futures. | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 292 |     { | 
 | 293 |         std::lock_guard lock(mThreadMutex); | 
| Derek Sollenberger | d3f6065 | 2021-06-11 15:34:36 -0400 | [diff] [blame] | 294 |         mFunctionCalls.push([=](renderengine::RenderEngine& instance) { | 
 | 295 |             ATRACE_NAME("REThreaded::unmapExternalTextureBuffer"); | 
 | 296 |             instance.cleanupPostRender(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 297 |         }); | 
 | 298 |     } | 
 | 299 |     mCondition.notify_one(); | 
| Derek Sollenberger | d3f6065 | 2021-06-11 15:34:36 -0400 | [diff] [blame] | 300 | } | 
 | 301 |  | 
 | 302 | bool RenderEngineThreaded::canSkipPostRenderCleanup() const { | 
 | 303 |     waitUntilInitialized(); | 
 | 304 |     return mRenderEngine->canSkipPostRenderCleanup(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 305 | } | 
 | 306 |  | 
 | 307 | status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display, | 
 | 308 |                                           const std::vector<const LayerSettings*>& layers, | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 309 |                                           const std::shared_ptr<ExternalTexture>& buffer, | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 310 |                                           const bool useFramebufferCache, | 
 | 311 |                                           base::unique_fd&& bufferFence, | 
 | 312 |                                           base::unique_fd* drawFence) { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 313 |     ATRACE_CALL(); | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 314 |     std::promise<status_t> resultPromise; | 
 | 315 |     std::future<status_t> resultFuture = resultPromise.get_future(); | 
 | 316 |     { | 
 | 317 |         std::lock_guard lock(mThreadMutex); | 
 | 318 |         mFunctionCalls.push([&resultPromise, &display, &layers, &buffer, useFramebufferCache, | 
 | 319 |                              &bufferFence, &drawFence](renderengine::RenderEngine& instance) { | 
 | 320 |             ATRACE_NAME("REThreaded::drawLayers"); | 
 | 321 |             status_t status = instance.drawLayers(display, layers, buffer, useFramebufferCache, | 
 | 322 |                                                   std::move(bufferFence), drawFence); | 
 | 323 |             resultPromise.set_value(status); | 
 | 324 |         }); | 
 | 325 |     } | 
 | 326 |     mCondition.notify_one(); | 
 | 327 |     return resultFuture.get(); | 
 | 328 | } | 
 | 329 |  | 
| Marin Shalamanov | 23c31af | 2020-09-09 15:01:47 +0200 | [diff] [blame] | 330 | void RenderEngineThreaded::cleanFramebufferCache() { | 
| Ady Abraham | b57e8c2 | 2021-05-07 15:17:29 -0700 | [diff] [blame] | 331 |     ATRACE_CALL(); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 332 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 333 |     // for the futures. | 
| Marin Shalamanov | 23c31af | 2020-09-09 15:01:47 +0200 | [diff] [blame] | 334 |     { | 
 | 335 |         std::lock_guard lock(mThreadMutex); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 336 |         mFunctionCalls.push([](renderengine::RenderEngine& instance) { | 
| Marin Shalamanov | 23c31af | 2020-09-09 15:01:47 +0200 | [diff] [blame] | 337 |             ATRACE_NAME("REThreaded::cleanFramebufferCache"); | 
 | 338 |             instance.cleanFramebufferCache(); | 
| Marin Shalamanov | 23c31af | 2020-09-09 15:01:47 +0200 | [diff] [blame] | 339 |         }); | 
 | 340 |     } | 
 | 341 |     mCondition.notify_one(); | 
| Marin Shalamanov | 23c31af | 2020-09-09 15:01:47 +0200 | [diff] [blame] | 342 | } | 
 | 343 |  | 
| Alec Mouri | d6f0946 | 2020-12-07 11:18:17 -0800 | [diff] [blame] | 344 | int RenderEngineThreaded::getContextPriority() { | 
 | 345 |     std::promise<int> resultPromise; | 
 | 346 |     std::future<int> resultFuture = resultPromise.get_future(); | 
 | 347 |     { | 
 | 348 |         std::lock_guard lock(mThreadMutex); | 
 | 349 |         mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) { | 
 | 350 |             ATRACE_NAME("REThreaded::getContextPriority"); | 
 | 351 |             int priority = instance.getContextPriority(); | 
 | 352 |             resultPromise.set_value(priority); | 
 | 353 |         }); | 
 | 354 |     } | 
 | 355 |     mCondition.notify_one(); | 
 | 356 |     return resultFuture.get(); | 
 | 357 | } | 
 | 358 |  | 
| Derek Sollenberger | b399837 | 2021-02-16 15:16:56 -0500 | [diff] [blame] | 359 | bool RenderEngineThreaded::supportsBackgroundBlur() { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 360 |     waitUntilInitialized(); | 
 | 361 |     return mRenderEngine->supportsBackgroundBlur(); | 
| Derek Sollenberger | b399837 | 2021-02-16 15:16:56 -0500 | [diff] [blame] | 362 | } | 
 | 363 |  | 
| Derek Sollenberger | c4a05e1 | 2021-03-24 16:45:20 -0400 | [diff] [blame] | 364 | void RenderEngineThreaded::onPrimaryDisplaySizeChanged(ui::Size size) { | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 365 |     // This function is designed so it can run asynchronously, so we do not need to wait | 
 | 366 |     // for the futures. | 
| Derek Sollenberger | c4a05e1 | 2021-03-24 16:45:20 -0400 | [diff] [blame] | 367 |     { | 
 | 368 |         std::lock_guard lock(mThreadMutex); | 
| Derek Sollenberger | 4bea01e | 2021-04-09 13:59:37 -0400 | [diff] [blame] | 369 |         mFunctionCalls.push([size](renderengine::RenderEngine& instance) { | 
| Derek Sollenberger | c4a05e1 | 2021-03-24 16:45:20 -0400 | [diff] [blame] | 370 |             ATRACE_NAME("REThreaded::onPrimaryDisplaySizeChanged"); | 
 | 371 |             instance.onPrimaryDisplaySizeChanged(size); | 
| Derek Sollenberger | c4a05e1 | 2021-03-24 16:45:20 -0400 | [diff] [blame] | 372 |         }); | 
 | 373 |     } | 
 | 374 |     mCondition.notify_one(); | 
| Derek Sollenberger | c4a05e1 | 2021-03-24 16:45:20 -0400 | [diff] [blame] | 375 | } | 
 | 376 |  | 
| Ana Krulec | 9bc9dc6 | 2020-02-26 12:16:40 -0800 | [diff] [blame] | 377 | } // namespace threaded | 
 | 378 | } // namespace renderengine | 
| Alec Mouri | 368e158 | 2020-08-13 10:14:29 -0700 | [diff] [blame] | 379 | } // namespace android |