xref: /aosp_15_r20/frameworks/base/libs/hwui/renderthread/RenderThread.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include "RenderThread.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <android-base/properties.h>
20*d57664e9SAndroid Build Coastguard Worker #include <dlfcn.h>
21*d57664e9SAndroid Build Coastguard Worker #include <gui/TraceUtils.h>
22*d57664e9SAndroid Build Coastguard Worker #include <include/gpu/ganesh/GrContextOptions.h>
23*d57664e9SAndroid Build Coastguard Worker #include <include/gpu/ganesh/gl/GrGLDirectContext.h>
24*d57664e9SAndroid Build Coastguard Worker #include <include/gpu/ganesh/gl/GrGLInterface.h>
25*d57664e9SAndroid Build Coastguard Worker #include <private/android/choreographer.h>
26*d57664e9SAndroid Build Coastguard Worker #include <sys/resource.h>
27*d57664e9SAndroid Build Coastguard Worker #include <ui/FatVector.h>
28*d57664e9SAndroid Build Coastguard Worker #include <utils/Condition.h>
29*d57664e9SAndroid Build Coastguard Worker #include <utils/Log.h>
30*d57664e9SAndroid Build Coastguard Worker #include <utils/Mutex.h>
31*d57664e9SAndroid Build Coastguard Worker 
32*d57664e9SAndroid Build Coastguard Worker #include <thread>
33*d57664e9SAndroid Build Coastguard Worker 
34*d57664e9SAndroid Build Coastguard Worker #include "../HardwareBitmapUploader.h"
35*d57664e9SAndroid Build Coastguard Worker #include "CacheManager.h"
36*d57664e9SAndroid Build Coastguard Worker #include "CanvasContext.h"
37*d57664e9SAndroid Build Coastguard Worker #include "DeviceInfo.h"
38*d57664e9SAndroid Build Coastguard Worker #include "EglManager.h"
39*d57664e9SAndroid Build Coastguard Worker #include "Properties.h"
40*d57664e9SAndroid Build Coastguard Worker #include "Readback.h"
41*d57664e9SAndroid Build Coastguard Worker #include "RenderProxy.h"
42*d57664e9SAndroid Build Coastguard Worker #include "VulkanManager.h"
43*d57664e9SAndroid Build Coastguard Worker #include "hwui/Bitmap.h"
44*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/SkiaOpenGLPipeline.h"
45*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/SkiaVulkanPipeline.h"
46*d57664e9SAndroid Build Coastguard Worker #include "renderstate/RenderState.h"
47*d57664e9SAndroid Build Coastguard Worker #include "utils/TimeUtils.h"
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker namespace android {
50*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
51*d57664e9SAndroid Build Coastguard Worker namespace renderthread {
52*d57664e9SAndroid Build Coastguard Worker 
53*d57664e9SAndroid Build Coastguard Worker static bool gHasRenderThreadInstance = false;
54*d57664e9SAndroid Build Coastguard Worker 
55*d57664e9SAndroid Build Coastguard Worker static JVMAttachHook gOnStartHook = nullptr;
56*d57664e9SAndroid Build Coastguard Worker 
ASurfaceControlFunctions()57*d57664e9SAndroid Build Coastguard Worker ASurfaceControlFunctions::ASurfaceControlFunctions() {
58*d57664e9SAndroid Build Coastguard Worker     void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
59*d57664e9SAndroid Build Coastguard Worker     createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
60*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
61*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceControl_create!");
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker     acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
64*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
65*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControl_acquire!");
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker     releaseFunc = (ASC_release) dlsym(handle_, "ASurfaceControl_release");
68*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(releaseFunc == nullptr,
69*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControl_release!");
70*d57664e9SAndroid Build Coastguard Worker 
71*d57664e9SAndroid Build Coastguard Worker     registerListenerFunc = (ASC_registerSurfaceStatsListener) dlsym(handle_,
72*d57664e9SAndroid Build Coastguard Worker             "ASurfaceControl_registerSurfaceStatsListener");
73*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(registerListenerFunc == nullptr,
74*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControl_registerSurfaceStatsListener!");
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker     unregisterListenerFunc = (ASC_unregisterSurfaceStatsListener) dlsym(handle_,
77*d57664e9SAndroid Build Coastguard Worker             "ASurfaceControl_unregisterSurfaceStatsListener");
78*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(unregisterListenerFunc == nullptr,
79*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControl_unregisterSurfaceStatsListener!");
80*d57664e9SAndroid Build Coastguard Worker 
81*d57664e9SAndroid Build Coastguard Worker     getAcquireTimeFunc = (ASCStats_getAcquireTime) dlsym(handle_,
82*d57664e9SAndroid Build Coastguard Worker             "ASurfaceControlStats_getAcquireTime");
83*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(getAcquireTimeFunc == nullptr,
84*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControlStats_getAcquireTime!");
85*d57664e9SAndroid Build Coastguard Worker 
86*d57664e9SAndroid Build Coastguard Worker     getFrameNumberFunc = (ASCStats_getFrameNumber) dlsym(handle_,
87*d57664e9SAndroid Build Coastguard Worker             "ASurfaceControlStats_getFrameNumber");
88*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
89*d57664e9SAndroid Build Coastguard Worker             "Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
90*d57664e9SAndroid Build Coastguard Worker 
91*d57664e9SAndroid Build Coastguard Worker     transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
92*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
93*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceTransaction_create!");
94*d57664e9SAndroid Build Coastguard Worker 
95*d57664e9SAndroid Build Coastguard Worker     transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
96*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
97*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceTransaction_delete!");
98*d57664e9SAndroid Build Coastguard Worker 
99*d57664e9SAndroid Build Coastguard Worker     transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
100*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
101*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceTransaction_apply!");
102*d57664e9SAndroid Build Coastguard Worker 
103*d57664e9SAndroid Build Coastguard Worker     transactionReparentFunc = (AST_reparent)dlsym(handle_, "ASurfaceTransaction_reparent");
104*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionReparentFunc == nullptr,
105*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol transactionReparentFunc!");
106*d57664e9SAndroid Build Coastguard Worker 
107*d57664e9SAndroid Build Coastguard Worker     transactionSetVisibilityFunc =
108*d57664e9SAndroid Build Coastguard Worker             (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
109*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
110*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceTransaction_setVisibility!");
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker     transactionSetZOrderFunc = (AST_setZOrder)dlsym(handle_, "ASurfaceTransaction_setZOrder");
113*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(transactionSetZOrderFunc == nullptr,
114*d57664e9SAndroid Build Coastguard Worker                         "Failed to find required symbol ASurfaceTransaction_setZOrder!");
115*d57664e9SAndroid Build Coastguard Worker }
116*d57664e9SAndroid Build Coastguard Worker 
extendedFrameCallback(const AChoreographerFrameCallbackData * cbData,void * data)117*d57664e9SAndroid Build Coastguard Worker void RenderThread::extendedFrameCallback(const AChoreographerFrameCallbackData* cbData,
118*d57664e9SAndroid Build Coastguard Worker                                          void* data) {
119*d57664e9SAndroid Build Coastguard Worker     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
120*d57664e9SAndroid Build Coastguard Worker     size_t preferredFrameTimelineIndex =
121*d57664e9SAndroid Build Coastguard Worker             AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(cbData);
122*d57664e9SAndroid Build Coastguard Worker     AVsyncId vsyncId = AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
123*d57664e9SAndroid Build Coastguard Worker             cbData, preferredFrameTimelineIndex);
124*d57664e9SAndroid Build Coastguard Worker     int64_t frameDeadline = AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(
125*d57664e9SAndroid Build Coastguard Worker             cbData, preferredFrameTimelineIndex);
126*d57664e9SAndroid Build Coastguard Worker     int64_t frameTimeNanos = AChoreographerFrameCallbackData_getFrameTimeNanos(cbData);
127*d57664e9SAndroid Build Coastguard Worker     // TODO(b/193273294): Remove when shared memory in use w/ expected present time always current.
128*d57664e9SAndroid Build Coastguard Worker     int64_t frameInterval = AChoreographer_getFrameInterval(rt->mChoreographer);
129*d57664e9SAndroid Build Coastguard Worker     rt->frameCallback(vsyncId, frameDeadline, frameTimeNanos, frameInterval);
130*d57664e9SAndroid Build Coastguard Worker }
131*d57664e9SAndroid Build Coastguard Worker 
frameCallback(int64_t vsyncId,int64_t frameDeadline,int64_t frameTimeNanos,int64_t frameInterval)132*d57664e9SAndroid Build Coastguard Worker void RenderThread::frameCallback(int64_t vsyncId, int64_t frameDeadline, int64_t frameTimeNanos,
133*d57664e9SAndroid Build Coastguard Worker                                  int64_t frameInterval) {
134*d57664e9SAndroid Build Coastguard Worker     mVsyncRequested = false;
135*d57664e9SAndroid Build Coastguard Worker     if (timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId, frameDeadline,
136*d57664e9SAndroid Build Coastguard Worker                                  frameInterval) &&
137*d57664e9SAndroid Build Coastguard Worker         !mFrameCallbackTaskPending) {
138*d57664e9SAndroid Build Coastguard Worker         mFrameCallbackTaskPending = true;
139*d57664e9SAndroid Build Coastguard Worker 
140*d57664e9SAndroid Build Coastguard Worker         using SteadyClock = std::chrono::steady_clock;
141*d57664e9SAndroid Build Coastguard Worker         using Nanos = std::chrono::nanoseconds;
142*d57664e9SAndroid Build Coastguard Worker         using toNsecs_t = std::chrono::duration<nsecs_t, std::nano>;
143*d57664e9SAndroid Build Coastguard Worker         using toFloatMillis = std::chrono::duration<float, std::milli>;
144*d57664e9SAndroid Build Coastguard Worker 
145*d57664e9SAndroid Build Coastguard Worker         const auto frameTimeTimePoint = SteadyClock::time_point(Nanos(frameTimeNanos));
146*d57664e9SAndroid Build Coastguard Worker         const auto deadlineTimePoint = SteadyClock::time_point(Nanos(frameDeadline));
147*d57664e9SAndroid Build Coastguard Worker 
148*d57664e9SAndroid Build Coastguard Worker         const auto timeUntilDeadline = deadlineTimePoint - frameTimeTimePoint;
149*d57664e9SAndroid Build Coastguard Worker         const auto runAt = (frameTimeTimePoint + (timeUntilDeadline / 4));
150*d57664e9SAndroid Build Coastguard Worker 
151*d57664e9SAndroid Build Coastguard Worker         ATRACE_FORMAT("queue mFrameCallbackTask to run after %.2fms",
152*d57664e9SAndroid Build Coastguard Worker                       toFloatMillis(runAt - SteadyClock::now()).count());
153*d57664e9SAndroid Build Coastguard Worker         queue().postAt(toNsecs_t(runAt.time_since_epoch()).count(),
154*d57664e9SAndroid Build Coastguard Worker                        [this]() { dispatchFrameCallbacks(); });
155*d57664e9SAndroid Build Coastguard Worker     }
156*d57664e9SAndroid Build Coastguard Worker }
157*d57664e9SAndroid Build Coastguard Worker 
refreshRateCallback(int64_t vsyncPeriod,void * data)158*d57664e9SAndroid Build Coastguard Worker void RenderThread::refreshRateCallback(int64_t vsyncPeriod, void* data) {
159*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("refreshRateCallback");
160*d57664e9SAndroid Build Coastguard Worker     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
161*d57664e9SAndroid Build Coastguard Worker     DeviceInfo::get()->onRefreshRateChanged(vsyncPeriod);
162*d57664e9SAndroid Build Coastguard Worker     rt->setupFrameInterval();
163*d57664e9SAndroid Build Coastguard Worker }
164*d57664e9SAndroid Build Coastguard Worker 
165*d57664e9SAndroid Build Coastguard Worker class ChoreographerSource : public VsyncSource {
166*d57664e9SAndroid Build Coastguard Worker public:
ChoreographerSource(RenderThread * renderThread)167*d57664e9SAndroid Build Coastguard Worker     ChoreographerSource(RenderThread* renderThread) : mRenderThread(renderThread) {}
168*d57664e9SAndroid Build Coastguard Worker 
requestNextVsync()169*d57664e9SAndroid Build Coastguard Worker     virtual void requestNextVsync() override {
170*d57664e9SAndroid Build Coastguard Worker         AChoreographer_postVsyncCallback(mRenderThread->mChoreographer,
171*d57664e9SAndroid Build Coastguard Worker                                          RenderThread::extendedFrameCallback, mRenderThread);
172*d57664e9SAndroid Build Coastguard Worker     }
173*d57664e9SAndroid Build Coastguard Worker 
drainPendingEvents()174*d57664e9SAndroid Build Coastguard Worker     virtual void drainPendingEvents() override {
175*d57664e9SAndroid Build Coastguard Worker         AChoreographer_handlePendingEvents(mRenderThread->mChoreographer, mRenderThread);
176*d57664e9SAndroid Build Coastguard Worker     }
177*d57664e9SAndroid Build Coastguard Worker 
178*d57664e9SAndroid Build Coastguard Worker private:
179*d57664e9SAndroid Build Coastguard Worker     RenderThread* mRenderThread;
180*d57664e9SAndroid Build Coastguard Worker };
181*d57664e9SAndroid Build Coastguard Worker 
182*d57664e9SAndroid Build Coastguard Worker class DummyVsyncSource : public VsyncSource {
183*d57664e9SAndroid Build Coastguard Worker public:
DummyVsyncSource(RenderThread * renderThread)184*d57664e9SAndroid Build Coastguard Worker     DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {}
185*d57664e9SAndroid Build Coastguard Worker 
requestNextVsync()186*d57664e9SAndroid Build Coastguard Worker     virtual void requestNextVsync() override {
187*d57664e9SAndroid Build Coastguard Worker         mRenderThread->queue().postDelayed(16_ms, [this]() {
188*d57664e9SAndroid Build Coastguard Worker             mRenderThread->frameCallback(UiFrameInfoBuilder::INVALID_VSYNC_ID,
189*d57664e9SAndroid Build Coastguard Worker                                          std::numeric_limits<int64_t>::max(),
190*d57664e9SAndroid Build Coastguard Worker                                          systemTime(SYSTEM_TIME_MONOTONIC), 16_ms);
191*d57664e9SAndroid Build Coastguard Worker         });
192*d57664e9SAndroid Build Coastguard Worker     }
193*d57664e9SAndroid Build Coastguard Worker 
drainPendingEvents()194*d57664e9SAndroid Build Coastguard Worker     virtual void drainPendingEvents() override {
195*d57664e9SAndroid Build Coastguard Worker         mRenderThread->frameCallback(UiFrameInfoBuilder::INVALID_VSYNC_ID,
196*d57664e9SAndroid Build Coastguard Worker                                      std::numeric_limits<int64_t>::max(),
197*d57664e9SAndroid Build Coastguard Worker                                      systemTime(SYSTEM_TIME_MONOTONIC), 16_ms);
198*d57664e9SAndroid Build Coastguard Worker     }
199*d57664e9SAndroid Build Coastguard Worker 
200*d57664e9SAndroid Build Coastguard Worker private:
201*d57664e9SAndroid Build Coastguard Worker     RenderThread* mRenderThread;
202*d57664e9SAndroid Build Coastguard Worker };
203*d57664e9SAndroid Build Coastguard Worker 
hasInstance()204*d57664e9SAndroid Build Coastguard Worker bool RenderThread::hasInstance() {
205*d57664e9SAndroid Build Coastguard Worker     return gHasRenderThreadInstance;
206*d57664e9SAndroid Build Coastguard Worker }
207*d57664e9SAndroid Build Coastguard Worker 
setOnStartHook(JVMAttachHook onStartHook)208*d57664e9SAndroid Build Coastguard Worker void RenderThread::setOnStartHook(JVMAttachHook onStartHook) {
209*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(hasInstance(), "can't set an onStartHook after we've started...");
210*d57664e9SAndroid Build Coastguard Worker     gOnStartHook = onStartHook;
211*d57664e9SAndroid Build Coastguard Worker }
212*d57664e9SAndroid Build Coastguard Worker 
getOnStartHook()213*d57664e9SAndroid Build Coastguard Worker JVMAttachHook RenderThread::getOnStartHook() {
214*d57664e9SAndroid Build Coastguard Worker     return gOnStartHook;
215*d57664e9SAndroid Build Coastguard Worker }
216*d57664e9SAndroid Build Coastguard Worker 
getInstance()217*d57664e9SAndroid Build Coastguard Worker RenderThread& RenderThread::getInstance() {
218*d57664e9SAndroid Build Coastguard Worker     [[clang::no_destroy]] static sp<RenderThread> sInstance = []() {
219*d57664e9SAndroid Build Coastguard Worker         sp<RenderThread> thread = sp<RenderThread>::make();
220*d57664e9SAndroid Build Coastguard Worker         thread->start("RenderThread");
221*d57664e9SAndroid Build Coastguard Worker         return thread;
222*d57664e9SAndroid Build Coastguard Worker     }();
223*d57664e9SAndroid Build Coastguard Worker     gHasRenderThreadInstance = true;
224*d57664e9SAndroid Build Coastguard Worker     return *sInstance;
225*d57664e9SAndroid Build Coastguard Worker }
226*d57664e9SAndroid Build Coastguard Worker 
RenderThread()227*d57664e9SAndroid Build Coastguard Worker RenderThread::RenderThread()
228*d57664e9SAndroid Build Coastguard Worker         : ThreadBase()
229*d57664e9SAndroid Build Coastguard Worker         , mVsyncSource(nullptr)
230*d57664e9SAndroid Build Coastguard Worker         , mVsyncRequested(false)
231*d57664e9SAndroid Build Coastguard Worker         , mFrameCallbackTaskPending(false)
232*d57664e9SAndroid Build Coastguard Worker         , mRenderState(nullptr)
233*d57664e9SAndroid Build Coastguard Worker         , mEglManager(nullptr)
234*d57664e9SAndroid Build Coastguard Worker         , mFunctorManager(WebViewFunctorManager::instance())
235*d57664e9SAndroid Build Coastguard Worker         , mGlobalProfileData(mJankDataMutex) {
236*d57664e9SAndroid Build Coastguard Worker     Properties::load();
237*d57664e9SAndroid Build Coastguard Worker }
238*d57664e9SAndroid Build Coastguard Worker 
~RenderThread()239*d57664e9SAndroid Build Coastguard Worker RenderThread::~RenderThread() {
240*d57664e9SAndroid Build Coastguard Worker     // Note that if this fatal assertion is removed then member variables must
241*d57664e9SAndroid Build Coastguard Worker     // be properly destroyed.
242*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL("Can't destroy the render thread");
243*d57664e9SAndroid Build Coastguard Worker }
244*d57664e9SAndroid Build Coastguard Worker 
initializeChoreographer()245*d57664e9SAndroid Build Coastguard Worker void RenderThread::initializeChoreographer() {
246*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second Choreographer?");
247*d57664e9SAndroid Build Coastguard Worker 
248*d57664e9SAndroid Build Coastguard Worker     if (!Properties::isolatedProcess) {
249*d57664e9SAndroid Build Coastguard Worker         mChoreographer = AChoreographer_create();
250*d57664e9SAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(mChoreographer == nullptr, "Initialization of Choreographer failed");
251*d57664e9SAndroid Build Coastguard Worker         AChoreographer_registerRefreshRateCallback(mChoreographer,
252*d57664e9SAndroid Build Coastguard Worker                                                    RenderThread::refreshRateCallback, this);
253*d57664e9SAndroid Build Coastguard Worker 
254*d57664e9SAndroid Build Coastguard Worker         // Register the FD
255*d57664e9SAndroid Build Coastguard Worker         mLooper->addFd(AChoreographer_getFd(mChoreographer), 0, Looper::EVENT_INPUT,
256*d57664e9SAndroid Build Coastguard Worker                        RenderThread::choreographerCallback, this);
257*d57664e9SAndroid Build Coastguard Worker         mVsyncSource = new ChoreographerSource(this);
258*d57664e9SAndroid Build Coastguard Worker     } else {
259*d57664e9SAndroid Build Coastguard Worker         mVsyncSource = new DummyVsyncSource(this);
260*d57664e9SAndroid Build Coastguard Worker     }
261*d57664e9SAndroid Build Coastguard Worker }
262*d57664e9SAndroid Build Coastguard Worker 
initThreadLocals()263*d57664e9SAndroid Build Coastguard Worker void RenderThread::initThreadLocals() {
264*d57664e9SAndroid Build Coastguard Worker     setupFrameInterval();
265*d57664e9SAndroid Build Coastguard Worker     initializeChoreographer();
266*d57664e9SAndroid Build Coastguard Worker     mEglManager = new EglManager();
267*d57664e9SAndroid Build Coastguard Worker     mRenderState = new RenderState(*this);
268*d57664e9SAndroid Build Coastguard Worker     mVkManager = VulkanManager::getInstance();
269*d57664e9SAndroid Build Coastguard Worker     mCacheManager = new CacheManager(*this);
270*d57664e9SAndroid Build Coastguard Worker }
271*d57664e9SAndroid Build Coastguard Worker 
setupFrameInterval()272*d57664e9SAndroid Build Coastguard Worker void RenderThread::setupFrameInterval() {
273*d57664e9SAndroid Build Coastguard Worker     nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod();
274*d57664e9SAndroid Build Coastguard Worker     mTimeLord.setFrameInterval(frameIntervalNanos);
275*d57664e9SAndroid Build Coastguard Worker }
276*d57664e9SAndroid Build Coastguard Worker 
requireGlContext()277*d57664e9SAndroid Build Coastguard Worker void RenderThread::requireGlContext() {
278*d57664e9SAndroid Build Coastguard Worker     if (mEglManager->hasEglContext()) {
279*d57664e9SAndroid Build Coastguard Worker         return;
280*d57664e9SAndroid Build Coastguard Worker     }
281*d57664e9SAndroid Build Coastguard Worker     mEglManager->initialize();
282*d57664e9SAndroid Build Coastguard Worker 
283*d57664e9SAndroid Build Coastguard Worker     sk_sp<const GrGLInterface> glInterface = GrGLMakeNativeInterface();
284*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!glInterface.get());
285*d57664e9SAndroid Build Coastguard Worker 
286*d57664e9SAndroid Build Coastguard Worker     GrContextOptions options;
287*d57664e9SAndroid Build Coastguard Worker     initGrContextOptions(options);
288*d57664e9SAndroid Build Coastguard Worker     auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
289*d57664e9SAndroid Build Coastguard Worker     auto size = glesVersion ? strlen(glesVersion) : -1;
290*d57664e9SAndroid Build Coastguard Worker     cacheManager().configureContext(&options, glesVersion, size);
291*d57664e9SAndroid Build Coastguard Worker     sk_sp<GrDirectContext> grContext(GrDirectContexts::MakeGL(std::move(glInterface), options));
292*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!grContext.get());
293*d57664e9SAndroid Build Coastguard Worker     setGrContext(grContext);
294*d57664e9SAndroid Build Coastguard Worker }
295*d57664e9SAndroid Build Coastguard Worker 
requireVkContext()296*d57664e9SAndroid Build Coastguard Worker void RenderThread::requireVkContext() {
297*d57664e9SAndroid Build Coastguard Worker     // the getter creates the context in the event it had been destroyed by destroyRenderingContext
298*d57664e9SAndroid Build Coastguard Worker     // Also check if we have a GrContext before returning fast. VulkanManager may be shared with
299*d57664e9SAndroid Build Coastguard Worker     // the HardwareBitmapUploader which initializes the Vk context without persisting the GrContext
300*d57664e9SAndroid Build Coastguard Worker     // in the rendering thread.
301*d57664e9SAndroid Build Coastguard Worker     if (vulkanManager().hasVkContext() && mGrContext) {
302*d57664e9SAndroid Build Coastguard Worker         return;
303*d57664e9SAndroid Build Coastguard Worker     }
304*d57664e9SAndroid Build Coastguard Worker     mVkManager->initialize();
305*d57664e9SAndroid Build Coastguard Worker     GrContextOptions options;
306*d57664e9SAndroid Build Coastguard Worker     initGrContextOptions(options);
307*d57664e9SAndroid Build Coastguard Worker     auto vkDriverVersion = mVkManager->getDriverVersion();
308*d57664e9SAndroid Build Coastguard Worker     cacheManager().configureContext(&options, &vkDriverVersion, sizeof(vkDriverVersion));
309*d57664e9SAndroid Build Coastguard Worker     sk_sp<GrDirectContext> grContext = mVkManager->createContext(options);
310*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!grContext.get());
311*d57664e9SAndroid Build Coastguard Worker     setGrContext(grContext);
312*d57664e9SAndroid Build Coastguard Worker }
313*d57664e9SAndroid Build Coastguard Worker 
initGrContextOptions(GrContextOptions & options)314*d57664e9SAndroid Build Coastguard Worker void RenderThread::initGrContextOptions(GrContextOptions& options) {
315*d57664e9SAndroid Build Coastguard Worker     options.fPreferExternalImagesOverES3 = true;
316*d57664e9SAndroid Build Coastguard Worker     options.fDisableDistanceFieldPaths = true;
317*d57664e9SAndroid Build Coastguard Worker     if (android::base::GetBoolProperty(PROPERTY_REDUCE_OPS_TASK_SPLITTING, true)) {
318*d57664e9SAndroid Build Coastguard Worker         options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kYes;
319*d57664e9SAndroid Build Coastguard Worker     } else {
320*d57664e9SAndroid Build Coastguard Worker         options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
321*d57664e9SAndroid Build Coastguard Worker     }
322*d57664e9SAndroid Build Coastguard Worker }
323*d57664e9SAndroid Build Coastguard Worker 
destroyRenderingContext()324*d57664e9SAndroid Build Coastguard Worker void RenderThread::destroyRenderingContext() {
325*d57664e9SAndroid Build Coastguard Worker     mFunctorManager.onContextDestroyed();
326*d57664e9SAndroid Build Coastguard Worker     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
327*d57664e9SAndroid Build Coastguard Worker         if (mEglManager->hasEglContext()) {
328*d57664e9SAndroid Build Coastguard Worker             setGrContext(nullptr);
329*d57664e9SAndroid Build Coastguard Worker             mEglManager->destroy();
330*d57664e9SAndroid Build Coastguard Worker         }
331*d57664e9SAndroid Build Coastguard Worker     } else {
332*d57664e9SAndroid Build Coastguard Worker         setGrContext(nullptr);
333*d57664e9SAndroid Build Coastguard Worker         mVkManager.clear();
334*d57664e9SAndroid Build Coastguard Worker     }
335*d57664e9SAndroid Build Coastguard Worker }
336*d57664e9SAndroid Build Coastguard Worker 
vulkanManager()337*d57664e9SAndroid Build Coastguard Worker VulkanManager& RenderThread::vulkanManager() {
338*d57664e9SAndroid Build Coastguard Worker     if (!mVkManager.get()) {
339*d57664e9SAndroid Build Coastguard Worker         mVkManager = VulkanManager::getInstance();
340*d57664e9SAndroid Build Coastguard Worker     }
341*d57664e9SAndroid Build Coastguard Worker     return *mVkManager.get();
342*d57664e9SAndroid Build Coastguard Worker }
343*d57664e9SAndroid Build Coastguard Worker 
pipelineToString()344*d57664e9SAndroid Build Coastguard Worker static const char* pipelineToString() {
345*d57664e9SAndroid Build Coastguard Worker     switch (auto renderType = Properties::getRenderPipelineType()) {
346*d57664e9SAndroid Build Coastguard Worker         case RenderPipelineType::SkiaGL:
347*d57664e9SAndroid Build Coastguard Worker             return "Skia (OpenGL)";
348*d57664e9SAndroid Build Coastguard Worker         case RenderPipelineType::SkiaVulkan:
349*d57664e9SAndroid Build Coastguard Worker             return "Skia (Vulkan)";
350*d57664e9SAndroid Build Coastguard Worker         default:
351*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
352*d57664e9SAndroid Build Coastguard Worker     }
353*d57664e9SAndroid Build Coastguard Worker }
354*d57664e9SAndroid Build Coastguard Worker 
dumpGraphicsMemory(int fd,bool includeProfileData)355*d57664e9SAndroid Build Coastguard Worker void RenderThread::dumpGraphicsMemory(int fd, bool includeProfileData) {
356*d57664e9SAndroid Build Coastguard Worker     if (includeProfileData) {
357*d57664e9SAndroid Build Coastguard Worker         globalProfileData()->dump(fd);
358*d57664e9SAndroid Build Coastguard Worker     }
359*d57664e9SAndroid Build Coastguard Worker 
360*d57664e9SAndroid Build Coastguard Worker     String8 cachesOutput;
361*d57664e9SAndroid Build Coastguard Worker     mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
362*d57664e9SAndroid Build Coastguard Worker     dprintf(fd, "\nPipeline=%s\n%s", pipelineToString(), cachesOutput.c_str());
363*d57664e9SAndroid Build Coastguard Worker     for (auto&& context : mCacheManager->mCanvasContexts) {
364*d57664e9SAndroid Build Coastguard Worker         context->visitAllRenderNodes([&](const RenderNode& node) {
365*d57664e9SAndroid Build Coastguard Worker             if (node.isTextureView()) {
366*d57664e9SAndroid Build Coastguard Worker                 dprintf(fd, "TextureView: %dx%d\n", node.getWidth(), node.getHeight());
367*d57664e9SAndroid Build Coastguard Worker             }
368*d57664e9SAndroid Build Coastguard Worker         });
369*d57664e9SAndroid Build Coastguard Worker     }
370*d57664e9SAndroid Build Coastguard Worker     dprintf(fd, "\n");
371*d57664e9SAndroid Build Coastguard Worker }
372*d57664e9SAndroid Build Coastguard Worker 
getMemoryUsage(size_t * cpuUsage,size_t * gpuUsage)373*d57664e9SAndroid Build Coastguard Worker void RenderThread::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
374*d57664e9SAndroid Build Coastguard Worker     mCacheManager->getMemoryUsage(cpuUsage, gpuUsage);
375*d57664e9SAndroid Build Coastguard Worker }
376*d57664e9SAndroid Build Coastguard Worker 
readback()377*d57664e9SAndroid Build Coastguard Worker Readback& RenderThread::readback() {
378*d57664e9SAndroid Build Coastguard Worker     if (!mReadback) {
379*d57664e9SAndroid Build Coastguard Worker         mReadback = new Readback(*this);
380*d57664e9SAndroid Build Coastguard Worker     }
381*d57664e9SAndroid Build Coastguard Worker 
382*d57664e9SAndroid Build Coastguard Worker     return *mReadback;
383*d57664e9SAndroid Build Coastguard Worker }
384*d57664e9SAndroid Build Coastguard Worker 
setGrContext(sk_sp<GrDirectContext> context)385*d57664e9SAndroid Build Coastguard Worker void RenderThread::setGrContext(sk_sp<GrDirectContext> context) {
386*d57664e9SAndroid Build Coastguard Worker     mCacheManager->reset(context);
387*d57664e9SAndroid Build Coastguard Worker     if (mGrContext) {
388*d57664e9SAndroid Build Coastguard Worker         mRenderState->onContextDestroyed();
389*d57664e9SAndroid Build Coastguard Worker         mGrContext->releaseResourcesAndAbandonContext();
390*d57664e9SAndroid Build Coastguard Worker     }
391*d57664e9SAndroid Build Coastguard Worker     mGrContext = std::move(context);
392*d57664e9SAndroid Build Coastguard Worker     if (mGrContext) {
393*d57664e9SAndroid Build Coastguard Worker         DeviceInfo::setMaxTextureSize(mGrContext->maxRenderTargetSize());
394*d57664e9SAndroid Build Coastguard Worker     }
395*d57664e9SAndroid Build Coastguard Worker }
396*d57664e9SAndroid Build Coastguard Worker 
requireGrContext()397*d57664e9SAndroid Build Coastguard Worker sk_sp<GrDirectContext> RenderThread::requireGrContext() {
398*d57664e9SAndroid Build Coastguard Worker     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
399*d57664e9SAndroid Build Coastguard Worker         requireGlContext();
400*d57664e9SAndroid Build Coastguard Worker     } else {
401*d57664e9SAndroid Build Coastguard Worker         requireVkContext();
402*d57664e9SAndroid Build Coastguard Worker     }
403*d57664e9SAndroid Build Coastguard Worker     return mGrContext;
404*d57664e9SAndroid Build Coastguard Worker }
405*d57664e9SAndroid Build Coastguard Worker 
choreographerCallback(int fd,int events,void * data)406*d57664e9SAndroid Build Coastguard Worker int RenderThread::choreographerCallback(int fd, int events, void* data) {
407*d57664e9SAndroid Build Coastguard Worker     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
408*d57664e9SAndroid Build Coastguard Worker         ALOGE("Display event receiver pipe was closed or an error occurred.  "
409*d57664e9SAndroid Build Coastguard Worker               "events=0x%x",
410*d57664e9SAndroid Build Coastguard Worker               events);
411*d57664e9SAndroid Build Coastguard Worker         return 0;  // remove the callback
412*d57664e9SAndroid Build Coastguard Worker     }
413*d57664e9SAndroid Build Coastguard Worker 
414*d57664e9SAndroid Build Coastguard Worker     if (!(events & Looper::EVENT_INPUT)) {
415*d57664e9SAndroid Build Coastguard Worker         ALOGW("Received spurious callback for unhandled poll event.  "
416*d57664e9SAndroid Build Coastguard Worker               "events=0x%x",
417*d57664e9SAndroid Build Coastguard Worker               events);
418*d57664e9SAndroid Build Coastguard Worker         return 1;  // keep the callback
419*d57664e9SAndroid Build Coastguard Worker     }
420*d57664e9SAndroid Build Coastguard Worker     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
421*d57664e9SAndroid Build Coastguard Worker     AChoreographer_handlePendingEvents(rt->mChoreographer, data);
422*d57664e9SAndroid Build Coastguard Worker 
423*d57664e9SAndroid Build Coastguard Worker     return 1;
424*d57664e9SAndroid Build Coastguard Worker }
425*d57664e9SAndroid Build Coastguard Worker 
dispatchFrameCallbacks()426*d57664e9SAndroid Build Coastguard Worker void RenderThread::dispatchFrameCallbacks() {
427*d57664e9SAndroid Build Coastguard Worker     ATRACE_CALL();
428*d57664e9SAndroid Build Coastguard Worker     mFrameCallbackTaskPending = false;
429*d57664e9SAndroid Build Coastguard Worker 
430*d57664e9SAndroid Build Coastguard Worker     std::set<IFrameCallback*> callbacks;
431*d57664e9SAndroid Build Coastguard Worker     mFrameCallbacks.swap(callbacks);
432*d57664e9SAndroid Build Coastguard Worker 
433*d57664e9SAndroid Build Coastguard Worker     if (callbacks.size()) {
434*d57664e9SAndroid Build Coastguard Worker         // Assume one of them will probably animate again so preemptively
435*d57664e9SAndroid Build Coastguard Worker         // request the next vsync in case it occurs mid-frame
436*d57664e9SAndroid Build Coastguard Worker         requestVsync();
437*d57664e9SAndroid Build Coastguard Worker         for (std::set<IFrameCallback*>::iterator it = callbacks.begin(); it != callbacks.end();
438*d57664e9SAndroid Build Coastguard Worker              it++) {
439*d57664e9SAndroid Build Coastguard Worker             (*it)->doFrame();
440*d57664e9SAndroid Build Coastguard Worker         }
441*d57664e9SAndroid Build Coastguard Worker     }
442*d57664e9SAndroid Build Coastguard Worker }
443*d57664e9SAndroid Build Coastguard Worker 
requestVsync()444*d57664e9SAndroid Build Coastguard Worker void RenderThread::requestVsync() {
445*d57664e9SAndroid Build Coastguard Worker     if (!mVsyncRequested) {
446*d57664e9SAndroid Build Coastguard Worker         mVsyncRequested = true;
447*d57664e9SAndroid Build Coastguard Worker         mVsyncSource->requestNextVsync();
448*d57664e9SAndroid Build Coastguard Worker     }
449*d57664e9SAndroid Build Coastguard Worker }
450*d57664e9SAndroid Build Coastguard Worker 
threadLoop()451*d57664e9SAndroid Build Coastguard Worker bool RenderThread::threadLoop() {
452*d57664e9SAndroid Build Coastguard Worker     setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
453*d57664e9SAndroid Build Coastguard Worker     Looper::setForThread(mLooper);
454*d57664e9SAndroid Build Coastguard Worker     if (gOnStartHook) {
455*d57664e9SAndroid Build Coastguard Worker         gOnStartHook("RenderThread");
456*d57664e9SAndroid Build Coastguard Worker     }
457*d57664e9SAndroid Build Coastguard Worker     initThreadLocals();
458*d57664e9SAndroid Build Coastguard Worker 
459*d57664e9SAndroid Build Coastguard Worker     while (true) {
460*d57664e9SAndroid Build Coastguard Worker         waitForWork();
461*d57664e9SAndroid Build Coastguard Worker         processQueue();
462*d57664e9SAndroid Build Coastguard Worker 
463*d57664e9SAndroid Build Coastguard Worker         if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
464*d57664e9SAndroid Build Coastguard Worker             mVsyncSource->drainPendingEvents();
465*d57664e9SAndroid Build Coastguard Worker             mFrameCallbacks.insert(mPendingRegistrationFrameCallbacks.begin(),
466*d57664e9SAndroid Build Coastguard Worker                                    mPendingRegistrationFrameCallbacks.end());
467*d57664e9SAndroid Build Coastguard Worker             mPendingRegistrationFrameCallbacks.clear();
468*d57664e9SAndroid Build Coastguard Worker             requestVsync();
469*d57664e9SAndroid Build Coastguard Worker         }
470*d57664e9SAndroid Build Coastguard Worker 
471*d57664e9SAndroid Build Coastguard Worker         if (!mFrameCallbackTaskPending && !mVsyncRequested && mFrameCallbacks.size()) {
472*d57664e9SAndroid Build Coastguard Worker             // TODO: Clean this up. This is working around an issue where a combination
473*d57664e9SAndroid Build Coastguard Worker             // of bad timing and slow drawing can result in dropping a stale vsync
474*d57664e9SAndroid Build Coastguard Worker             // on the floor (correct!) but fails to schedule to listen for the
475*d57664e9SAndroid Build Coastguard Worker             // next vsync (oops), so none of the callbacks are run.
476*d57664e9SAndroid Build Coastguard Worker             requestVsync();
477*d57664e9SAndroid Build Coastguard Worker         }
478*d57664e9SAndroid Build Coastguard Worker 
479*d57664e9SAndroid Build Coastguard Worker         mCacheManager->onThreadIdle();
480*d57664e9SAndroid Build Coastguard Worker     }
481*d57664e9SAndroid Build Coastguard Worker 
482*d57664e9SAndroid Build Coastguard Worker     return false;
483*d57664e9SAndroid Build Coastguard Worker }
484*d57664e9SAndroid Build Coastguard Worker 
postFrameCallback(IFrameCallback * callback)485*d57664e9SAndroid Build Coastguard Worker void RenderThread::postFrameCallback(IFrameCallback* callback) {
486*d57664e9SAndroid Build Coastguard Worker     mPendingRegistrationFrameCallbacks.insert(callback);
487*d57664e9SAndroid Build Coastguard Worker }
488*d57664e9SAndroid Build Coastguard Worker 
removeFrameCallback(IFrameCallback * callback)489*d57664e9SAndroid Build Coastguard Worker bool RenderThread::removeFrameCallback(IFrameCallback* callback) {
490*d57664e9SAndroid Build Coastguard Worker     size_t erased;
491*d57664e9SAndroid Build Coastguard Worker     erased = mFrameCallbacks.erase(callback);
492*d57664e9SAndroid Build Coastguard Worker     erased |= mPendingRegistrationFrameCallbacks.erase(callback);
493*d57664e9SAndroid Build Coastguard Worker     return erased;
494*d57664e9SAndroid Build Coastguard Worker }
495*d57664e9SAndroid Build Coastguard Worker 
pushBackFrameCallback(IFrameCallback * callback)496*d57664e9SAndroid Build Coastguard Worker void RenderThread::pushBackFrameCallback(IFrameCallback* callback) {
497*d57664e9SAndroid Build Coastguard Worker     if (mFrameCallbacks.erase(callback)) {
498*d57664e9SAndroid Build Coastguard Worker         mPendingRegistrationFrameCallbacks.insert(callback);
499*d57664e9SAndroid Build Coastguard Worker     }
500*d57664e9SAndroid Build Coastguard Worker }
501*d57664e9SAndroid Build Coastguard Worker 
allocateHardwareBitmap(SkBitmap & skBitmap)502*d57664e9SAndroid Build Coastguard Worker sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
503*d57664e9SAndroid Build Coastguard Worker     auto renderType = Properties::getRenderPipelineType();
504*d57664e9SAndroid Build Coastguard Worker     switch (renderType) {
505*d57664e9SAndroid Build Coastguard Worker         case RenderPipelineType::SkiaVulkan:
506*d57664e9SAndroid Build Coastguard Worker             return skiapipeline::SkiaVulkanPipeline::allocateHardwareBitmap(*this, skBitmap);
507*d57664e9SAndroid Build Coastguard Worker         default:
508*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
509*d57664e9SAndroid Build Coastguard Worker             break;
510*d57664e9SAndroid Build Coastguard Worker     }
511*d57664e9SAndroid Build Coastguard Worker     return nullptr;
512*d57664e9SAndroid Build Coastguard Worker }
513*d57664e9SAndroid Build Coastguard Worker 
isCurrent()514*d57664e9SAndroid Build Coastguard Worker bool RenderThread::isCurrent() {
515*d57664e9SAndroid Build Coastguard Worker     return gettid() == getInstance().getTid();
516*d57664e9SAndroid Build Coastguard Worker }
517*d57664e9SAndroid Build Coastguard Worker 
preload()518*d57664e9SAndroid Build Coastguard Worker void RenderThread::preload() {
519*d57664e9SAndroid Build Coastguard Worker     // EGL driver is always preloaded only if HWUI renders with GL.
520*d57664e9SAndroid Build Coastguard Worker     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
521*d57664e9SAndroid Build Coastguard Worker         std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
522*d57664e9SAndroid Build Coastguard Worker         eglInitThread.detach();
523*d57664e9SAndroid Build Coastguard Worker     } else {
524*d57664e9SAndroid Build Coastguard Worker         requireVkContext();
525*d57664e9SAndroid Build Coastguard Worker     }
526*d57664e9SAndroid Build Coastguard Worker     HardwareBitmapUploader::initialize();
527*d57664e9SAndroid Build Coastguard Worker }
528*d57664e9SAndroid Build Coastguard Worker 
trimMemory(TrimLevel level)529*d57664e9SAndroid Build Coastguard Worker void RenderThread::trimMemory(TrimLevel level) {
530*d57664e9SAndroid Build Coastguard Worker     ATRACE_CALL();
531*d57664e9SAndroid Build Coastguard Worker     cacheManager().trimMemory(level);
532*d57664e9SAndroid Build Coastguard Worker }
533*d57664e9SAndroid Build Coastguard Worker 
trimCaches(CacheTrimLevel level)534*d57664e9SAndroid Build Coastguard Worker void RenderThread::trimCaches(CacheTrimLevel level) {
535*d57664e9SAndroid Build Coastguard Worker     ATRACE_CALL();
536*d57664e9SAndroid Build Coastguard Worker     cacheManager().trimCaches(level);
537*d57664e9SAndroid Build Coastguard Worker }
538*d57664e9SAndroid Build Coastguard Worker 
539*d57664e9SAndroid Build Coastguard Worker } /* namespace renderthread */
540*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */
541*d57664e9SAndroid Build Coastguard Worker } /* namespace android */
542