blob: d9b650c1ff3762e19b15ce8e40c17a892c8927ac [file] [log] [blame]
John Reck4f02bf42014-01-03 18:09:17 -08001/*
2 * Copyright (C) 2013 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
John Reck4f02bf42014-01-03 18:09:17 -080017#include "RenderProxy.h"
18
rnleece9762b2021-05-21 15:40:53 -070019#include <gui/TraceUtils.h>
John Reckba6adf62015-02-19 14:36:50 -080020#include "DeferredLayerUpdater.h"
21#include "DisplayList.h"
John Recka8963062017-06-14 10:47:50 -070022#include "Properties.h"
John Reck10dd0582016-03-31 16:36:16 -070023#include "Readback.h"
John Reckba6adf62015-02-19 14:36:50 -080024#include "Rect.h"
John Reck5cca8f22018-12-10 17:06:22 -080025#include "WebViewFunctorManager.h"
John Reckba6adf62015-02-19 14:36:50 -080026#include "renderthread/CanvasContext.h"
27#include "renderthread/RenderTask.h"
28#include "renderthread/RenderThread.h"
29#include "utils/Macros.h"
John Reck43871902016-08-01 14:39:24 -070030#include "utils/TimeUtils.h"
John Reck4f02bf42014-01-03 18:09:17 -080031
Bo Liu6a3fc602021-07-17 16:42:13 -040032#include <pthread.h>
33
John Reck4f02bf42014-01-03 18:09:17 -080034namespace android {
35namespace uirenderer {
36namespace renderthread {
37
John Reck1bcacfd2017-11-03 10:12:19 -070038RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
39 IContextFactory* contextFactory)
40 : mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
Matt Buckley7c1786b2023-01-30 23:36:56 +000041 pid_t uiThreadId = pthread_gettid_np(pthread_self());
42 pid_t renderThreadId = getRenderThreadTid();
43 mContext = mRenderThread.queue().runSync([=, this]() -> CanvasContext* {
44 CanvasContext* context =
45 CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
46 if (context != nullptr) {
47 mRenderThread.queue().post(
48 [=] { mDrawFrameTask.createHintSession(uiThreadId, renderThreadId); });
49 }
50 return context;
John Reckf8441e62017-10-23 13:10:41 -070051 });
Matt Buckley7c1786b2023-01-30 23:36:56 +000052 mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode, uiThreadId, renderThreadId);
John Reck4f02bf42014-01-03 18:09:17 -080053}
54
55RenderProxy::~RenderProxy() {
56 destroyContext();
57}
58
John Reck4f02bf42014-01-03 18:09:17 -080059void RenderProxy::destroyContext() {
60 if (mContext) {
Bo Liu6a3fc602021-07-17 16:42:13 -040061 mDrawFrameTask.setContext(nullptr, nullptr, nullptr, -1, -1);
John Reck668f0e32014-03-26 15:10:40 -070062 // This is also a fence as we need to be certain that there are no
63 // outstanding mDrawFrame tasks posted before it is destroyed
John Reck1bcacfd2017-11-03 10:12:19 -070064 mRenderThread.queue().runSync([this]() { delete mContext; });
John Reckf8441e62017-10-23 13:10:41 -070065 mContext = nullptr;
John Reck4f02bf42014-01-03 18:09:17 -080066 }
67}
68
John Reck1125d1f2014-10-23 11:02:19 -070069void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
John Reck1bcacfd2017-11-03 10:12:19 -070070 mRenderThread.queue().post([this, swapBehavior]() { mContext->setSwapBehavior(swapBehavior); });
John Recke4280ba2014-05-05 16:39:37 -070071}
72
73bool RenderProxy::loadSystemProperties() {
John Reckf8441e62017-10-23 13:10:41 -070074 return mRenderThread.queue().runSync([this]() -> bool {
John Reckd9d7f122018-05-03 14:40:56 -070075 bool needsRedraw = Properties::load();
John Reckf8441e62017-10-23 13:10:41 -070076 if (mContext->profiler().consumeProperties()) {
77 needsRedraw = true;
78 }
79 return needsRedraw;
80 });
John Reckb36016c2015-03-11 08:50:53 -070081}
82
83void RenderProxy::setName(const char* name) {
John Reckf8441e62017-10-23 13:10:41 -070084 // block since name/value pointers owned by caller
85 // TODO: Support move arguments
John Reck1bcacfd2017-11-03 10:12:19 -070086 mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
John Reck4f02bf42014-01-03 18:09:17 -080087}
88
Alec Mouri43fe6fc2019-12-23 07:46:19 -080089void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
John Recke95c62d2020-08-18 12:37:43 -070090 if (window) { ANativeWindow_acquire(window); }
Alec Mouri43fe6fc2019-12-23 07:46:19 -080091 mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {
92 mContext->setSurface(win, enableTimeout);
John Recke95c62d2020-08-18 12:37:43 -070093 if (win) { ANativeWindow_release(win); }
John Reckcd18c222019-11-21 14:40:53 -080094 });
John Reck4f02bf42014-01-03 18:09:17 -080095}
96
Huihong Luo5fdf7b82021-01-15 14:27:06 -080097void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
98 auto funcs = mRenderThread.getASurfaceControlFunctions();
99 if (surfaceControl) {
100 funcs.acquireFunc(surfaceControl);
101 }
102 mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
103 mContext->setSurfaceControl(control);
104 if (control) {
105 funcs.releaseFunc(control);
106 }
107 });
108}
109
John Reck8785ceb2018-10-29 16:45:58 -0700110void RenderProxy::allocateBuffers() {
111 mRenderThread.queue().post([=]() { mContext->allocateBuffers(); });
Jorim Jaggi7823ee72018-07-17 15:24:16 +0200112}
113
John Reck8785ceb2018-10-29 16:45:58 -0700114bool RenderProxy::pause() {
John Reck1bcacfd2017-11-03 10:12:19 -0700115 return mRenderThread.queue().runSync([this]() -> bool { return mContext->pauseSurface(); });
John Reck8afcc762016-04-13 10:24:06 -0700116}
117
118void RenderProxy::setStopped(bool stopped) {
John Reck1bcacfd2017-11-03 10:12:19 -0700119 mRenderThread.queue().runSync([this, stopped]() { mContext->setStopped(stopped); });
John Reck8afcc762016-04-13 10:24:06 -0700120}
121
John Reck8785ceb2018-10-29 16:45:58 -0700122void RenderProxy::setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
John Reck1bcacfd2017-11-03 10:12:19 -0700123 mRenderThread.queue().post(
John Reck8785ceb2018-10-29 16:45:58 -0700124 [=]() { mContext->setLightAlpha(ambientShadowAlpha, spotShadowAlpha); });
Alan Viverette50210d92015-05-14 18:05:36 -0700125}
126
John Reck8785ceb2018-10-29 16:45:58 -0700127void RenderProxy::setLightGeometry(const Vector3& lightCenter, float lightRadius) {
128 mRenderThread.queue().post([=]() { mContext->setLightGeometry(lightCenter, lightRadius); });
John Reck63a06672014-05-07 13:45:54 -0700129}
130
131void RenderProxy::setOpaque(bool opaque) {
John Reck1bcacfd2017-11-03 10:12:19 -0700132 mRenderThread.queue().post([=]() { mContext->setOpaque(opaque); });
Romain Guy26a2b972017-04-17 09:39:51 -0700133}
134
John Reckb36bfdd2020-07-23 13:47:49 -0700135void RenderProxy::setColorMode(ColorMode mode) {
136 mRenderThread.queue().post([=]() { mContext->setColorMode(mode); });
Romain Guy26a2b972017-04-17 09:39:51 -0700137}
138
John Reckba6adf62015-02-19 14:36:50 -0800139int64_t* RenderProxy::frameInfo() {
140 return mDrawFrameTask.frameInfo();
141}
142
chaviwadba0b12022-03-18 17:42:15 -0500143void RenderProxy::forceDrawNextFrame() {
144 mDrawFrameTask.forceDrawNextFrame();
145}
146
John Reck2de950d2017-01-25 10:58:30 -0800147int RenderProxy::syncAndDrawFrame() {
148 return mDrawFrameTask.drawFrame();
John Reck4f02bf42014-01-03 18:09:17 -0800149}
150
John Reck2de950d2017-01-25 10:58:30 -0800151void RenderProxy::destroy() {
John Reckfae904d2014-04-14 11:01:57 -0700152 // destroyCanvasAndSurface() needs a fence as when it returns the
153 // underlying BufferQueue is going to be released from under
154 // the render thread.
John Reck1bcacfd2017-11-03 10:12:19 -0700155 mRenderThread.queue().runSync([=]() { mContext->destroy(); });
John Reck0d1f6342014-03-28 20:30:27 -0700156}
157
John Reck283bb462018-12-13 16:40:14 -0800158void RenderProxy::destroyFunctor(int functor) {
159 ATRACE_CALL();
160 RenderThread& thread = RenderThread::getInstance();
John Reck5cca8f22018-12-10 17:06:22 -0800161 thread.queue().post([=]() { WebViewFunctorManager::instance().destroyFunctor(functor); });
John Reck283bb462018-12-13 16:40:14 -0800162}
163
John Reck19b6bcf2014-02-14 20:03:38 -0800164DeferredLayerUpdater* RenderProxy::createTextureLayer() {
John Reckf8441e62017-10-23 13:10:41 -0700165 return mRenderThread.queue().runSync([this]() -> auto {
166 return mContext->createTextureLayer();
167 });
John Reck3e824952014-08-20 10:08:39 -0700168}
169
John Reck2de950d2017-01-25 10:58:30 -0800170void RenderProxy::buildLayer(RenderNode* node) {
John Reck1bcacfd2017-11-03 10:12:19 -0700171 mRenderThread.queue().runSync([&]() { mContext->buildLayer(node); });
John Reck19b6bcf2014-02-14 20:03:38 -0800172}
173
John Reck3731dc22015-04-13 15:20:29 -0700174bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
John Reckfbeac3c2019-03-29 11:24:56 -0700175 ATRACE_NAME("TextureView#getBitmap");
Stan Iliev1a025a72018-09-05 16:35:11 -0400176 auto& thread = RenderThread::getInstance();
John Reck5cca8f22018-12-10 17:06:22 -0800177 return thread.queue().runSync([&]() -> bool {
178 return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success;
179 });
John Reck19b6bcf2014-02-14 20:03:38 -0800180}
181
John Reckd72e0a32014-05-29 18:56:11 -0700182void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
183 mDrawFrameTask.pushLayerUpdate(layer);
184}
185
186void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
187 mDrawFrameTask.removeLayerUpdate(layer);
John Reck19b6bcf2014-02-14 20:03:38 -0800188}
189
John Reck918ad522014-06-27 14:45:25 -0700190void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
John Reck1bcacfd2017-11-03 10:12:19 -0700191 return mRenderThread.queue().runSync([&]() { layer->detachSurfaceTexture(); });
John Recke1628b72014-05-23 15:11:19 -0700192}
193
John Reck2de950d2017-01-25 10:58:30 -0800194void RenderProxy::destroyHardwareResources() {
John Reck1bcacfd2017-11-03 10:12:19 -0700195 return mRenderThread.queue().runSync([&]() { mContext->destroyHardwareResources(); });
John Reckf47a5942014-06-30 16:20:04 -0700196}
197
198void RenderProxy::trimMemory(int level) {
John Reckcd3a22c2014-08-06 13:33:59 -0700199 // Avoid creating a RenderThread to do a trimMemory.
200 if (RenderThread::hasInstance()) {
201 RenderThread& thread = RenderThread::getInstance();
John Reck1bcacfd2017-11-03 10:12:19 -0700202 thread.queue().post([&thread, level]() { CanvasContext::trimMemory(thread, level); });
John Reckcd3a22c2014-08-06 13:33:59 -0700203 }
John Reckf47a5942014-06-30 16:20:04 -0700204}
205
John Reck39207682021-05-12 19:10:47 -0400206void RenderProxy::purgeCaches() {
207 if (RenderThread::hasInstance()) {
208 RenderThread& thread = RenderThread::getInstance();
209 thread.queue().post([&thread]() {
210 if (thread.getGrContext()) {
211 thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
212 }
213 });
214 }
215}
216
Chris Craik2507c342015-05-04 14:36:49 -0700217void RenderProxy::overrideProperty(const char* name, const char* value) {
John Reckf8441e62017-10-23 13:10:41 -0700218 // expensive, but block here since name/value pointers owned by caller
John Reck1bcacfd2017-11-03 10:12:19 -0700219 RenderThread::getInstance().queue().runSync(
220 [&]() { Properties::overrideProperty(name, value); });
Chris Craik2507c342015-05-04 14:36:49 -0700221}
222
John Reck28ad7b52014-04-07 16:59:25 -0700223void RenderProxy::fence() {
John Reck1bcacfd2017-11-03 10:12:19 -0700224 mRenderThread.queue().runSync([]() {});
John Reck28ad7b52014-04-07 16:59:25 -0700225}
226
John Recke4c1e6c2018-05-24 16:27:35 -0700227int RenderProxy::maxTextureSize() {
John Reck5cca8f22018-12-10 17:06:22 -0800228 static int maxTextureSize = RenderThread::getInstance().queue().runSync(
229 []() { return DeviceInfo::get()->maxTextureSize(); });
John Recke4c1e6c2018-05-24 16:27:35 -0700230 return maxTextureSize;
John Reckf47a5942014-06-30 16:20:04 -0700231}
232
233void RenderProxy::stopDrawing() {
John Reck1bcacfd2017-11-03 10:12:19 -0700234 mRenderThread.queue().runSync([this]() { mContext->stopDrawing(); });
John Recka5dda642014-05-22 15:43:54 -0700235}
236
237void RenderProxy::notifyFramePending() {
John Reck1bcacfd2017-11-03 10:12:19 -0700238 mRenderThread.queue().post([this]() { mContext->notifyFramePending(); });
John Reckfe5e7b72014-05-23 17:42:28 -0700239}
240
John Reckba6adf62015-02-19 14:36:50 -0800241void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
John Reckf8441e62017-10-23 13:10:41 -0700242 mRenderThread.queue().runSync([&]() {
Jorim Jaggi71db8892021-02-03 23:19:29 +0100243 std::lock_guard lock(mRenderThread.getJankDataMutex());
John Reckf8441e62017-10-23 13:10:41 -0700244 mContext->profiler().dumpData(fd);
245 if (dumpFlags & DumpFlags::FrameStats) {
246 mContext->dumpFrames(fd);
247 }
248 if (dumpFlags & DumpFlags::JankStats) {
249 mRenderThread.globalProfileData()->dump(fd);
250 }
251 if (dumpFlags & DumpFlags::Reset) {
252 mContext->resetFrameStats();
253 }
254 });
John Reck7f2e5e32015-05-05 11:00:53 -0700255}
256
257void RenderProxy::resetProfileInfo() {
Jorim Jaggi33adb572021-02-22 14:27:53 +0100258 mRenderThread.queue().runSync([=]() {
259 std::lock_guard lock(mRenderThread.getJankDataMutex());
260 mContext->resetFrameStats();
261 });
John Reck7f2e5e32015-05-05 11:00:53 -0700262}
263
John Reckf8441e62017-10-23 13:10:41 -0700264uint32_t RenderProxy::frameTimePercentile(int percentile) {
265 return mRenderThread.queue().runSync([&]() -> auto {
Jorim Jaggi71db8892021-02-03 23:19:29 +0100266 std::lock_guard lock(mRenderThread.globalProfileData().getDataMutex());
John Reckf8441e62017-10-23 13:10:41 -0700267 return mRenderThread.globalProfileData()->findPercentile(percentile);
268 });
John Reck0e89e2b2014-10-31 14:49:06 -0700269}
270
John Reck712eae02021-10-01 15:24:27 -0400271void RenderProxy::dumpGraphicsMemory(int fd, bool includeProfileData, bool resetProfile) {
John Reckba7e9652019-01-23 10:33:41 -0800272 if (RenderThread::hasInstance()) {
273 auto& thread = RenderThread::getInstance();
John Reck712eae02021-10-01 15:24:27 -0400274 thread.queue().runSync([&]() {
275 thread.dumpGraphicsMemory(fd, includeProfileData);
276 if (resetProfile) {
277 thread.globalProfileData()->reset();
278 }
279 });
John Reckba7e9652019-01-23 10:33:41 -0800280 }
John Reckedc524c2015-03-18 15:24:33 -0700281}
282
John Reck39207682021-05-12 19:10:47 -0400283void RenderProxy::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
284 if (RenderThread::hasInstance()) {
285 auto& thread = RenderThread::getInstance();
286 thread.queue().runSync([&]() { thread.getMemoryUsage(cpuUsage, gpuUsage); });
287 }
288}
289
John Reckedc524c2015-03-18 15:24:33 -0700290void RenderProxy::setProcessStatsBuffer(int fd) {
John Reckdf1742e2017-01-19 15:56:21 -0800291 auto& rt = RenderThread::getInstance();
John Reck0fa0cbc2019-04-05 16:57:46 -0700292 rt.queue().post([&rt, fd = dup(fd)]() {
John Reckf8441e62017-10-23 13:10:41 -0700293 rt.globalProfileData().switchStorageToAshmem(fd);
294 close(fd);
295 });
John Reckdf1742e2017-01-19 15:56:21 -0800296}
297
298void RenderProxy::rotateProcessStatsBuffer() {
John Reckdf1742e2017-01-19 15:56:21 -0800299 auto& rt = RenderThread::getInstance();
John Reck1bcacfd2017-11-03 10:12:19 -0700300 rt.queue().post([&rt]() { rt.globalProfileData().rotateStorage(); });
John Reckedc524c2015-03-18 15:24:33 -0700301}
302
Tim Murray33eb07f2016-06-10 10:03:20 -0700303int RenderProxy::getRenderThreadTid() {
304 return mRenderThread.getTid();
305}
306
Skuhneea7a7fb2015-08-28 07:10:31 -0700307void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) {
John Reck1bcacfd2017-11-03 10:12:19 -0700308 mRenderThread.queue().post([=]() { mContext->addRenderNode(node, placeFront); });
Skuhneea7a7fb2015-08-28 07:10:31 -0700309}
310
311void RenderProxy::removeRenderNode(RenderNode* node) {
John Reck1bcacfd2017-11-03 10:12:19 -0700312 mRenderThread.queue().post([=]() { mContext->removeRenderNode(node); });
Skuhneea7a7fb2015-08-28 07:10:31 -0700313}
314
315void RenderProxy::drawRenderNode(RenderNode* node) {
John Reck1bcacfd2017-11-03 10:12:19 -0700316 mRenderThread.queue().runSync([=]() { mContext->prepareAndDraw(node); });
Skuhneea7a7fb2015-08-28 07:10:31 -0700317}
318
Skuhneb8160872015-09-22 09:51:39 -0700319void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) {
John Reckf138b172017-09-08 11:00:42 -0700320 mDrawFrameTask.setContentDrawBounds(left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700321}
322
John Reck5cca8f22018-12-10 17:06:22 -0800323void RenderProxy::setPictureCapturedCallback(
324 const std::function<void(sk_sp<SkPicture>&&)>& callback) {
325 mRenderThread.queue().post(
John Reck0fa0cbc2019-04-05 16:57:46 -0700326 [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
John Reck5cca8f22018-12-10 17:06:22 -0800327}
328
Huihong Luo054b8d32021-02-24 18:48:12 -0800329void RenderProxy::setASurfaceTransactionCallback(
Huihong Luo4df41512021-06-24 10:04:32 -0700330 const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
Huihong Luo054b8d32021-02-24 18:48:12 -0800331 mRenderThread.queue().post(
332 [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
333}
334
Huihong Luo34f42fd2021-05-03 14:47:36 -0700335void RenderProxy::setPrepareSurfaceControlForWebviewCallback(
336 const std::function<void()>& callback) {
337 mRenderThread.queue().post(
338 [this, cb = callback]() { mContext->setPrepareSurfaceControlForWebviewCallback(cb); });
339}
340
chaviwb6803712021-12-13 15:46:29 -0600341void RenderProxy::setFrameCallback(
342 std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback) {
Mihai Popa95688002018-02-23 16:10:11 +0000343 mDrawFrameTask.setFrameCallback(std::move(callback));
344}
345
chaviw9c137532021-08-20 12:15:48 -0500346void RenderProxy::setFrameCommitCallback(std::function<void(bool)>&& callback) {
347 mDrawFrameTask.setFrameCommitCallback(std::move(callback));
348}
349
350void RenderProxy::setFrameCompleteCallback(std::function<void()>&& callback) {
John Reckcc2eee82018-05-17 10:44:00 -0700351 mDrawFrameTask.setFrameCompleteCallback(std::move(callback));
352}
353
John Reckf8441e62017-10-23 13:10:41 -0700354void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
John Reck0fa0cbc2019-04-05 16:57:46 -0700355 mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
John Reckf8441e62017-10-23 13:10:41 -0700356 mContext->addFrameMetricsObserver(observer.get());
357 });
Andres Morales06f5bc72015-12-15 15:21:31 -0800358}
359
John Reckf8441e62017-10-23 13:10:41 -0700360void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
John Reck0fa0cbc2019-04-05 16:57:46 -0700361 mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
John Reckf8441e62017-10-23 13:10:41 -0700362 mContext->removeFrameMetricsObserver(observer.get());
363 });
John Reck10dd0582016-03-31 16:36:16 -0700364}
365
John Reckbb3a3582018-09-26 11:21:08 -0700366void RenderProxy::setForceDark(bool enable) {
John Reck5cca8f22018-12-10 17:06:22 -0800367 mRenderThread.queue().post([this, enable]() { mContext->setForceDark(enable); });
John Reckbb3a3582018-09-26 11:21:08 -0700368}
369
Alec Mouri43fe6fc2019-12-23 07:46:19 -0800370int RenderProxy::copySurfaceInto(ANativeWindow* window, int left, int top, int right, int bottom,
John Reck1bcacfd2017-11-03 10:12:19 -0700371 SkBitmap* bitmap) {
John Reckf8441e62017-10-23 13:10:41 -0700372 auto& thread = RenderThread::getInstance();
373 return static_cast<int>(thread.queue().runSync([&]() -> auto {
Alec Mouri8a82b142019-12-17 09:41:48 -0800374 return thread.readback().copySurfaceInto(window, Rect(left, top, right, bottom), bitmap);
John Reckf8441e62017-10-23 13:10:41 -0700375 }));
John Reck43871902016-08-01 14:39:24 -0700376}
377
sergeyvec4a4b12016-10-20 18:39:04 -0700378void RenderProxy::prepareToDraw(Bitmap& bitmap) {
John Reck43871902016-08-01 14:39:24 -0700379 // If we haven't spun up a hardware accelerated window yet, there's no
380 // point in precaching these bitmaps as it can't impact jank.
381 // We also don't know if we even will spin up a hardware-accelerated
382 // window or not.
383 if (!RenderThread::hasInstance()) return;
384 RenderThread* renderThread = &RenderThread::getInstance();
sergeyvec4a4b12016-10-20 18:39:04 -0700385 bitmap.ref();
John Reckf8441e62017-10-23 13:10:41 -0700386 auto task = [renderThread, &bitmap]() {
387 CanvasContext::prepareToDraw(*renderThread, &bitmap);
388 bitmap.unref();
389 };
John Reck43871902016-08-01 14:39:24 -0700390 nsecs_t lastVsync = renderThread->timeLord().latestVsync();
391 nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos();
Jerome Gaillarde218c692019-06-14 12:58:57 +0100392 nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(SYSTEM_TIME_MONOTONIC);
John Reck43871902016-08-01 14:39:24 -0700393 // We expect the UI thread to take 4ms and for RT to be active from VSYNC+4ms to
394 // VSYNC+12ms or so, so aim for the gap during which RT is expected to
395 // be idle
396 // TODO: Make this concept a first-class supported thing? RT could use
397 // knowledge of pending draws to better schedule this task
398 if (timeToNextVsync > -6_ms && timeToNextVsync < 1_ms) {
John Reckf8441e62017-10-23 13:10:41 -0700399 renderThread->queue().postAt(estimatedNextVsync + 8_ms, task);
John Reck43871902016-08-01 14:39:24 -0700400 } else {
John Reckf8441e62017-10-23 13:10:41 -0700401 renderThread->queue().post(task);
John Reck43871902016-08-01 14:39:24 -0700402 }
403}
404
Stan Iliev1a025a72018-09-05 16:35:11 -0400405int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
John Reckfbeac3c2019-03-29 11:24:56 -0700406 ATRACE_NAME("HardwareBitmap readback");
Stan Iliev6983bc42017-02-02 14:11:53 -0500407 RenderThread& thread = RenderThread::getInstance();
John Reck1072fff2018-04-12 15:20:09 -0700408 if (gettid() == thread.getTid()) {
John Reck1bcacfd2017-11-03 10:12:19 -0700409 // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
Stan Iliev1a025a72018-09-05 16:35:11 -0400410 return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap);
Stan Iliev6983bc42017-02-02 14:11:53 -0500411 } else {
John Reck5cca8f22018-12-10 17:06:22 -0800412 return thread.queue().runSync(
413 [&]() -> int { return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap); });
Stan Iliev6983bc42017-02-02 14:11:53 -0500414 }
sergeyv59eecb522016-11-17 17:54:57 -0800415}
416
John Reck76005182021-06-09 22:43:05 -0400417int RenderProxy::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) {
418 RenderThread& thread = RenderThread::getInstance();
419 if (gettid() == thread.getTid()) {
420 // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
421 return (int)thread.readback().copyImageInto(image, bitmap);
422 } else {
423 return thread.queue().runSync(
424 [&]() -> int { return (int)thread.readback().copyImageInto(image, bitmap); });
425 }
426}
427
John Recka8963062017-06-14 10:47:50 -0700428void RenderProxy::disableVsync() {
429 Properties::disableVsync = true;
430}
431
Stan Iliev898123b2019-02-14 14:57:44 -0500432void RenderProxy::preload() {
433 // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
434 auto& thread = RenderThread::getInstance();
John Reck0fa0cbc2019-04-05 16:57:46 -0700435 thread.queue().post([&thread]() { thread.preload(); });
Stan Iliev898123b2019-02-14 14:57:44 -0500436}
437
chaviw01053d432022-03-18 17:54:00 -0500438void RenderProxy::setRtAnimationsEnabled(bool enabled) {
439 if (RenderThread::hasInstance()) {
440 RenderThread::getInstance().queue().post(
441 [enabled]() { Properties::enableRTAnimations = enabled; });
442 } else {
443 Properties::enableRTAnimations = enabled;
444 }
445}
446
John Reck4f02bf42014-01-03 18:09:17 -0800447} /* namespace renderthread */
448} /* namespace uirenderer */
449} /* namespace android */