xref: /aosp_15_r20/frameworks/base/libs/hwui/WebViewFunctorManager.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2018 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 "WebViewFunctorManager.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <log/log.h>
20*d57664e9SAndroid Build Coastguard Worker #include <private/hwui/WebViewFunctor.h>
21*d57664e9SAndroid Build Coastguard Worker #include <utils/Trace.h>
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker #include <atomic>
24*d57664e9SAndroid Build Coastguard Worker 
25*d57664e9SAndroid Build Coastguard Worker #include "Properties.h"
26*d57664e9SAndroid Build Coastguard Worker #include "renderthread/CanvasContext.h"
27*d57664e9SAndroid Build Coastguard Worker #include "renderthread/RenderThread.h"
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker namespace android::uirenderer {
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker namespace {
32*d57664e9SAndroid Build Coastguard Worker class ScopedCurrentFunctor {
33*d57664e9SAndroid Build Coastguard Worker public:
ScopedCurrentFunctor(WebViewFunctor * functor)34*d57664e9SAndroid Build Coastguard Worker     ScopedCurrentFunctor(WebViewFunctor* functor) {
35*d57664e9SAndroid Build Coastguard Worker         ALOG_ASSERT(!sCurrentFunctor);
36*d57664e9SAndroid Build Coastguard Worker         ALOG_ASSERT(functor);
37*d57664e9SAndroid Build Coastguard Worker         sCurrentFunctor = functor;
38*d57664e9SAndroid Build Coastguard Worker     }
~ScopedCurrentFunctor()39*d57664e9SAndroid Build Coastguard Worker     ~ScopedCurrentFunctor() {
40*d57664e9SAndroid Build Coastguard Worker         ALOG_ASSERT(sCurrentFunctor);
41*d57664e9SAndroid Build Coastguard Worker         sCurrentFunctor = nullptr;
42*d57664e9SAndroid Build Coastguard Worker     }
43*d57664e9SAndroid Build Coastguard Worker 
getSurfaceControl()44*d57664e9SAndroid Build Coastguard Worker     static ASurfaceControl* getSurfaceControl() {
45*d57664e9SAndroid Build Coastguard Worker         ALOG_ASSERT(sCurrentFunctor);
46*d57664e9SAndroid Build Coastguard Worker         return sCurrentFunctor->getSurfaceControl();
47*d57664e9SAndroid Build Coastguard Worker     }
mergeTransaction(ASurfaceTransaction * transaction)48*d57664e9SAndroid Build Coastguard Worker     static void mergeTransaction(ASurfaceTransaction* transaction) {
49*d57664e9SAndroid Build Coastguard Worker         ALOG_ASSERT(sCurrentFunctor);
50*d57664e9SAndroid Build Coastguard Worker         sCurrentFunctor->mergeTransaction(transaction);
51*d57664e9SAndroid Build Coastguard Worker     }
52*d57664e9SAndroid Build Coastguard Worker 
53*d57664e9SAndroid Build Coastguard Worker private:
54*d57664e9SAndroid Build Coastguard Worker     static WebViewFunctor* sCurrentFunctor;
55*d57664e9SAndroid Build Coastguard Worker };
56*d57664e9SAndroid Build Coastguard Worker 
57*d57664e9SAndroid Build Coastguard Worker WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
58*d57664e9SAndroid Build Coastguard Worker }  // namespace
59*d57664e9SAndroid Build Coastguard Worker 
WebViewFunctor_queryPlatformRenderMode()60*d57664e9SAndroid Build Coastguard Worker RenderMode WebViewFunctor_queryPlatformRenderMode() {
61*d57664e9SAndroid Build Coastguard Worker     auto pipelineType = Properties::getRenderPipelineType();
62*d57664e9SAndroid Build Coastguard Worker     switch (pipelineType) {
63*d57664e9SAndroid Build Coastguard Worker         case RenderPipelineType::SkiaGL:
64*d57664e9SAndroid Build Coastguard Worker             return RenderMode::OpenGL_ES;
65*d57664e9SAndroid Build Coastguard Worker         case RenderPipelineType::SkiaVulkan:
66*d57664e9SAndroid Build Coastguard Worker             return RenderMode::Vulkan;
67*d57664e9SAndroid Build Coastguard Worker         default:
68*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType);
69*d57664e9SAndroid Build Coastguard Worker     }
70*d57664e9SAndroid Build Coastguard Worker }
71*d57664e9SAndroid Build Coastguard Worker 
WebViewFunctor_create(void * data,const WebViewFunctorCallbacks & prototype,RenderMode functorMode)72*d57664e9SAndroid Build Coastguard Worker int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype,
73*d57664e9SAndroid Build Coastguard Worker                           RenderMode functorMode) {
74*d57664e9SAndroid Build Coastguard Worker     if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) {
75*d57664e9SAndroid Build Coastguard Worker         ALOGW("Unknown rendermode %d", (int)functorMode);
76*d57664e9SAndroid Build Coastguard Worker         return -1;
77*d57664e9SAndroid Build Coastguard Worker     }
78*d57664e9SAndroid Build Coastguard Worker     if (functorMode == RenderMode::Vulkan &&
79*d57664e9SAndroid Build Coastguard Worker         WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) {
80*d57664e9SAndroid Build Coastguard Worker         ALOGW("Unable to map from GLES platform to a vulkan functor");
81*d57664e9SAndroid Build Coastguard Worker         return -1;
82*d57664e9SAndroid Build Coastguard Worker     }
83*d57664e9SAndroid Build Coastguard Worker     return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode);
84*d57664e9SAndroid Build Coastguard Worker }
85*d57664e9SAndroid Build Coastguard Worker 
WebViewFunctor_release(int functor)86*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor_release(int functor) {
87*d57664e9SAndroid Build Coastguard Worker     WebViewFunctorManager::instance().releaseFunctor(functor);
88*d57664e9SAndroid Build Coastguard Worker }
89*d57664e9SAndroid Build Coastguard Worker 
WebViewFunctor_reportRenderingThreads(int functor,const pid_t * thread_ids,size_t size)90*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor_reportRenderingThreads(int functor, const pid_t* thread_ids, size_t size) {
91*d57664e9SAndroid Build Coastguard Worker     WebViewFunctorManager::instance().reportRenderingThreads(functor, thread_ids, size);
92*d57664e9SAndroid Build Coastguard Worker }
93*d57664e9SAndroid Build Coastguard Worker 
94*d57664e9SAndroid Build Coastguard Worker static std::atomic_int sNextId{1};
95*d57664e9SAndroid Build Coastguard Worker 
WebViewFunctor(void * data,const WebViewFunctorCallbacks & callbacks,RenderMode functorMode)96*d57664e9SAndroid Build Coastguard Worker WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
97*d57664e9SAndroid Build Coastguard Worker                                RenderMode functorMode)
98*d57664e9SAndroid Build Coastguard Worker         : mData(data) {
99*d57664e9SAndroid Build Coastguard Worker     mFunctor = sNextId++;
100*d57664e9SAndroid Build Coastguard Worker     mCallbacks = callbacks;
101*d57664e9SAndroid Build Coastguard Worker     mMode = functorMode;
102*d57664e9SAndroid Build Coastguard Worker }
103*d57664e9SAndroid Build Coastguard Worker 
~WebViewFunctor()104*d57664e9SAndroid Build Coastguard Worker WebViewFunctor::~WebViewFunctor() {
105*d57664e9SAndroid Build Coastguard Worker     destroyContext();
106*d57664e9SAndroid Build Coastguard Worker 
107*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::onDestroy");
108*d57664e9SAndroid Build Coastguard Worker     if (mSurfaceControl) {
109*d57664e9SAndroid Build Coastguard Worker         removeOverlays();
110*d57664e9SAndroid Build Coastguard Worker     }
111*d57664e9SAndroid Build Coastguard Worker     mCallbacks.onDestroyed(mFunctor, mData);
112*d57664e9SAndroid Build Coastguard Worker }
113*d57664e9SAndroid Build Coastguard Worker 
sync(const WebViewSyncData & syncData) const114*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
115*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::sync");
116*d57664e9SAndroid Build Coastguard Worker     mCallbacks.onSync(mFunctor, mData, syncData);
117*d57664e9SAndroid Build Coastguard Worker }
118*d57664e9SAndroid Build Coastguard Worker 
onRemovedFromTree()119*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::onRemovedFromTree() {
120*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::onRemovedFromTree");
121*d57664e9SAndroid Build Coastguard Worker     if (mSurfaceControl) {
122*d57664e9SAndroid Build Coastguard Worker         removeOverlays();
123*d57664e9SAndroid Build Coastguard Worker     }
124*d57664e9SAndroid Build Coastguard Worker }
125*d57664e9SAndroid Build Coastguard Worker 
prepareRootSurfaceControl()126*d57664e9SAndroid Build Coastguard Worker bool WebViewFunctor::prepareRootSurfaceControl() {
127*d57664e9SAndroid Build Coastguard Worker     if (!Properties::enableWebViewOverlays) return false;
128*d57664e9SAndroid Build Coastguard Worker 
129*d57664e9SAndroid Build Coastguard Worker     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
130*d57664e9SAndroid Build Coastguard Worker     if (!activeContext) return false;
131*d57664e9SAndroid Build Coastguard Worker 
132*d57664e9SAndroid Build Coastguard Worker     ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
133*d57664e9SAndroid Build Coastguard Worker     if (!rootSurfaceControl) return false;
134*d57664e9SAndroid Build Coastguard Worker 
135*d57664e9SAndroid Build Coastguard Worker     int32_t rgid = activeContext->getSurfaceControlGenerationId();
136*d57664e9SAndroid Build Coastguard Worker     if (mParentSurfaceControlGenerationId != rgid) {
137*d57664e9SAndroid Build Coastguard Worker         reparentSurfaceControl(rootSurfaceControl);
138*d57664e9SAndroid Build Coastguard Worker         mParentSurfaceControlGenerationId = rgid;
139*d57664e9SAndroid Build Coastguard Worker     }
140*d57664e9SAndroid Build Coastguard Worker 
141*d57664e9SAndroid Build Coastguard Worker     return true;
142*d57664e9SAndroid Build Coastguard Worker }
143*d57664e9SAndroid Build Coastguard Worker 
drawGl(const DrawGlInfo & drawInfo)144*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
145*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::drawGl");
146*d57664e9SAndroid Build Coastguard Worker     if (!mHasContext) {
147*d57664e9SAndroid Build Coastguard Worker         mHasContext = true;
148*d57664e9SAndroid Build Coastguard Worker     }
149*d57664e9SAndroid Build Coastguard Worker     ScopedCurrentFunctor currentFunctor(this);
150*d57664e9SAndroid Build Coastguard Worker 
151*d57664e9SAndroid Build Coastguard Worker     WebViewOverlayData overlayParams = {
152*d57664e9SAndroid Build Coastguard Worker             .overlaysMode = OverlaysMode::Disabled,
153*d57664e9SAndroid Build Coastguard Worker             .getSurfaceControl = currentFunctor.getSurfaceControl,
154*d57664e9SAndroid Build Coastguard Worker             .mergeTransaction = currentFunctor.mergeTransaction,
155*d57664e9SAndroid Build Coastguard Worker     };
156*d57664e9SAndroid Build Coastguard Worker 
157*d57664e9SAndroid Build Coastguard Worker     if (!drawInfo.isLayer && prepareRootSurfaceControl()) {
158*d57664e9SAndroid Build Coastguard Worker         overlayParams.overlaysMode = OverlaysMode::Enabled;
159*d57664e9SAndroid Build Coastguard Worker     }
160*d57664e9SAndroid Build Coastguard Worker 
161*d57664e9SAndroid Build Coastguard Worker     mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
162*d57664e9SAndroid Build Coastguard Worker }
163*d57664e9SAndroid Build Coastguard Worker 
initVk(const VkFunctorInitParams & params)164*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
165*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::initVk");
166*d57664e9SAndroid Build Coastguard Worker     if (!mHasContext) {
167*d57664e9SAndroid Build Coastguard Worker         mHasContext = true;
168*d57664e9SAndroid Build Coastguard Worker     } else {
169*d57664e9SAndroid Build Coastguard Worker         return;
170*d57664e9SAndroid Build Coastguard Worker     }
171*d57664e9SAndroid Build Coastguard Worker     mCallbacks.vk.initialize(mFunctor, mData, params);
172*d57664e9SAndroid Build Coastguard Worker }
173*d57664e9SAndroid Build Coastguard Worker 
drawVk(const VkFunctorDrawParams & params)174*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
175*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::drawVk");
176*d57664e9SAndroid Build Coastguard Worker     ScopedCurrentFunctor currentFunctor(this);
177*d57664e9SAndroid Build Coastguard Worker 
178*d57664e9SAndroid Build Coastguard Worker     WebViewOverlayData overlayParams = {
179*d57664e9SAndroid Build Coastguard Worker             .overlaysMode = OverlaysMode::Disabled,
180*d57664e9SAndroid Build Coastguard Worker             .getSurfaceControl = currentFunctor.getSurfaceControl,
181*d57664e9SAndroid Build Coastguard Worker             .mergeTransaction = currentFunctor.mergeTransaction,
182*d57664e9SAndroid Build Coastguard Worker     };
183*d57664e9SAndroid Build Coastguard Worker 
184*d57664e9SAndroid Build Coastguard Worker     if (!params.is_layer && prepareRootSurfaceControl()) {
185*d57664e9SAndroid Build Coastguard Worker         overlayParams.overlaysMode = OverlaysMode::Enabled;
186*d57664e9SAndroid Build Coastguard Worker     }
187*d57664e9SAndroid Build Coastguard Worker 
188*d57664e9SAndroid Build Coastguard Worker     mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
189*d57664e9SAndroid Build Coastguard Worker }
190*d57664e9SAndroid Build Coastguard Worker 
postDrawVk()191*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::postDrawVk() {
192*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::postDrawVk");
193*d57664e9SAndroid Build Coastguard Worker     mCallbacks.vk.postDraw(mFunctor, mData);
194*d57664e9SAndroid Build Coastguard Worker }
195*d57664e9SAndroid Build Coastguard Worker 
destroyContext()196*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::destroyContext() {
197*d57664e9SAndroid Build Coastguard Worker     if (mHasContext) {
198*d57664e9SAndroid Build Coastguard Worker         mHasContext = false;
199*d57664e9SAndroid Build Coastguard Worker         ATRACE_NAME("WebViewFunctor::onContextDestroyed");
200*d57664e9SAndroid Build Coastguard Worker         mCallbacks.onContextDestroyed(mFunctor, mData);
201*d57664e9SAndroid Build Coastguard Worker 
202*d57664e9SAndroid Build Coastguard Worker         // grContext may be null in unit tests.
203*d57664e9SAndroid Build Coastguard Worker         auto* grContext = renderthread::RenderThread::getInstance().getGrContext();
204*d57664e9SAndroid Build Coastguard Worker         if (grContext) grContext->resetContext();
205*d57664e9SAndroid Build Coastguard Worker     }
206*d57664e9SAndroid Build Coastguard Worker }
207*d57664e9SAndroid Build Coastguard Worker 
removeOverlays()208*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::removeOverlays() {
209*d57664e9SAndroid Build Coastguard Worker     ScopedCurrentFunctor currentFunctor(this);
210*d57664e9SAndroid Build Coastguard Worker     mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
211*d57664e9SAndroid Build Coastguard Worker     if (mSurfaceControl) {
212*d57664e9SAndroid Build Coastguard Worker         reparentSurfaceControl(nullptr);
213*d57664e9SAndroid Build Coastguard Worker         auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
214*d57664e9SAndroid Build Coastguard Worker         funcs.releaseFunc(mSurfaceControl);
215*d57664e9SAndroid Build Coastguard Worker         mSurfaceControl = nullptr;
216*d57664e9SAndroid Build Coastguard Worker     }
217*d57664e9SAndroid Build Coastguard Worker }
218*d57664e9SAndroid Build Coastguard Worker 
getSurfaceControl()219*d57664e9SAndroid Build Coastguard Worker ASurfaceControl* WebViewFunctor::getSurfaceControl() {
220*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::getSurfaceControl");
221*d57664e9SAndroid Build Coastguard Worker     if (mSurfaceControl != nullptr) return mSurfaceControl;
222*d57664e9SAndroid Build Coastguard Worker 
223*d57664e9SAndroid Build Coastguard Worker     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
224*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
225*d57664e9SAndroid Build Coastguard Worker 
226*d57664e9SAndroid Build Coastguard Worker     ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
227*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
228*d57664e9SAndroid Build Coastguard Worker 
229*d57664e9SAndroid Build Coastguard Worker     auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
230*d57664e9SAndroid Build Coastguard Worker     mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
231*d57664e9SAndroid Build Coastguard Worker     mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
232*d57664e9SAndroid Build Coastguard Worker     ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
233*d57664e9SAndroid Build Coastguard Worker     activeContext->prepareSurfaceControlForWebview();
234*d57664e9SAndroid Build Coastguard Worker     funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
235*d57664e9SAndroid Build Coastguard Worker     funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
236*d57664e9SAndroid Build Coastguard Worker                                        ASURFACE_TRANSACTION_VISIBILITY_SHOW);
237*d57664e9SAndroid Build Coastguard Worker     funcs.transactionApplyFunc(transaction);
238*d57664e9SAndroid Build Coastguard Worker     funcs.transactionDeleteFunc(transaction);
239*d57664e9SAndroid Build Coastguard Worker     return mSurfaceControl;
240*d57664e9SAndroid Build Coastguard Worker }
241*d57664e9SAndroid Build Coastguard Worker 
mergeTransaction(ASurfaceTransaction * transaction)242*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
243*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::mergeTransaction");
244*d57664e9SAndroid Build Coastguard Worker     if (transaction == nullptr) return;
245*d57664e9SAndroid Build Coastguard Worker     bool done = false;
246*d57664e9SAndroid Build Coastguard Worker     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
247*d57664e9SAndroid Build Coastguard Worker     // activeContext might be null when called from mCallbacks.removeOverlays()
248*d57664e9SAndroid Build Coastguard Worker     if (activeContext != nullptr) {
249*d57664e9SAndroid Build Coastguard Worker         done = activeContext->mergeTransaction(transaction, mSurfaceControl);
250*d57664e9SAndroid Build Coastguard Worker     }
251*d57664e9SAndroid Build Coastguard Worker     if (!done) {
252*d57664e9SAndroid Build Coastguard Worker         auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
253*d57664e9SAndroid Build Coastguard Worker         funcs.transactionApplyFunc(transaction);
254*d57664e9SAndroid Build Coastguard Worker     }
255*d57664e9SAndroid Build Coastguard Worker }
256*d57664e9SAndroid Build Coastguard Worker 
reparentSurfaceControl(ASurfaceControl * parent)257*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
258*d57664e9SAndroid Build Coastguard Worker     ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
259*d57664e9SAndroid Build Coastguard Worker     if (mSurfaceControl == nullptr) return;
260*d57664e9SAndroid Build Coastguard Worker 
261*d57664e9SAndroid Build Coastguard Worker     auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
262*d57664e9SAndroid Build Coastguard Worker     ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
263*d57664e9SAndroid Build Coastguard Worker     funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
264*d57664e9SAndroid Build Coastguard Worker     mergeTransaction(transaction);
265*d57664e9SAndroid Build Coastguard Worker     funcs.transactionDeleteFunc(transaction);
266*d57664e9SAndroid Build Coastguard Worker }
267*d57664e9SAndroid Build Coastguard Worker 
reportRenderingThreads(const pid_t * thread_ids,size_t size)268*d57664e9SAndroid Build Coastguard Worker void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) {
269*d57664e9SAndroid Build Coastguard Worker     mRenderingThreads = std::vector<pid_t>(thread_ids, thread_ids + size);
270*d57664e9SAndroid Build Coastguard Worker }
271*d57664e9SAndroid Build Coastguard Worker 
instance()272*d57664e9SAndroid Build Coastguard Worker WebViewFunctorManager& WebViewFunctorManager::instance() {
273*d57664e9SAndroid Build Coastguard Worker     static WebViewFunctorManager sInstance;
274*d57664e9SAndroid Build Coastguard Worker     return sInstance;
275*d57664e9SAndroid Build Coastguard Worker }
276*d57664e9SAndroid Build Coastguard Worker 
validateCallbacks(const WebViewFunctorCallbacks & callbacks)277*d57664e9SAndroid Build Coastguard Worker static void validateCallbacks(const WebViewFunctorCallbacks& callbacks) {
278*d57664e9SAndroid Build Coastguard Worker     // TODO: Should we do a stack peek to see if this is really webview?
279*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(callbacks.onSync == nullptr, "onSync is null");
280*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(callbacks.onContextDestroyed == nullptr, "onContextDestroyed is null");
281*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(callbacks.onDestroyed == nullptr, "onDestroyed is null");
282*d57664e9SAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(callbacks.removeOverlays == nullptr, "removeOverlays is null");
283*d57664e9SAndroid Build Coastguard Worker     switch (auto mode = WebViewFunctor_queryPlatformRenderMode()) {
284*d57664e9SAndroid Build Coastguard Worker         case RenderMode::OpenGL_ES:
285*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(callbacks.gles.draw == nullptr, "gles.draw is null");
286*d57664e9SAndroid Build Coastguard Worker             break;
287*d57664e9SAndroid Build Coastguard Worker         case RenderMode::Vulkan:
288*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(callbacks.vk.initialize == nullptr, "vk.initialize is null");
289*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(callbacks.vk.draw == nullptr, "vk.draw is null");
290*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(callbacks.vk.postDraw == nullptr, "vk.postDraw is null");
291*d57664e9SAndroid Build Coastguard Worker             break;
292*d57664e9SAndroid Build Coastguard Worker         default:
293*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("unknown platform mode? %d", (int)mode);
294*d57664e9SAndroid Build Coastguard Worker             break;
295*d57664e9SAndroid Build Coastguard Worker     }
296*d57664e9SAndroid Build Coastguard Worker }
297*d57664e9SAndroid Build Coastguard Worker 
createFunctor(void * data,const WebViewFunctorCallbacks & callbacks,RenderMode functorMode)298*d57664e9SAndroid Build Coastguard Worker int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
299*d57664e9SAndroid Build Coastguard Worker                                          RenderMode functorMode) {
300*d57664e9SAndroid Build Coastguard Worker     validateCallbacks(callbacks);
301*d57664e9SAndroid Build Coastguard Worker     auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
302*d57664e9SAndroid Build Coastguard Worker     int id = object->id();
303*d57664e9SAndroid Build Coastguard Worker     auto handle = object->createHandle();
304*d57664e9SAndroid Build Coastguard Worker     {
305*d57664e9SAndroid Build Coastguard Worker         std::lock_guard _lock{mLock};
306*d57664e9SAndroid Build Coastguard Worker         mActiveFunctors.push_back(std::move(handle));
307*d57664e9SAndroid Build Coastguard Worker         mFunctors.push_back(std::move(object));
308*d57664e9SAndroid Build Coastguard Worker     }
309*d57664e9SAndroid Build Coastguard Worker     return id;
310*d57664e9SAndroid Build Coastguard Worker }
311*d57664e9SAndroid Build Coastguard Worker 
releaseFunctor(int functor)312*d57664e9SAndroid Build Coastguard Worker void WebViewFunctorManager::releaseFunctor(int functor) {
313*d57664e9SAndroid Build Coastguard Worker     sp<WebViewFunctor::Handle> toRelease;
314*d57664e9SAndroid Build Coastguard Worker     {
315*d57664e9SAndroid Build Coastguard Worker         std::lock_guard _lock{mLock};
316*d57664e9SAndroid Build Coastguard Worker         for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) {
317*d57664e9SAndroid Build Coastguard Worker             if ((*iter)->id() == functor) {
318*d57664e9SAndroid Build Coastguard Worker                 toRelease = std::move(*iter);
319*d57664e9SAndroid Build Coastguard Worker                 mActiveFunctors.erase(iter);
320*d57664e9SAndroid Build Coastguard Worker                 break;
321*d57664e9SAndroid Build Coastguard Worker             }
322*d57664e9SAndroid Build Coastguard Worker         }
323*d57664e9SAndroid Build Coastguard Worker     }
324*d57664e9SAndroid Build Coastguard Worker }
325*d57664e9SAndroid Build Coastguard Worker 
onContextDestroyed()326*d57664e9SAndroid Build Coastguard Worker void WebViewFunctorManager::onContextDestroyed() {
327*d57664e9SAndroid Build Coastguard Worker     // WARNING: SKETCHY
328*d57664e9SAndroid Build Coastguard Worker     // Because we know that we always remove from mFunctors on RenderThread, the same
329*d57664e9SAndroid Build Coastguard Worker     // thread that always invokes onContextDestroyed, we know that the functor pointers
330*d57664e9SAndroid Build Coastguard Worker     // will remain valid without the lock held.
331*d57664e9SAndroid Build Coastguard Worker     // However, we won't block new functors from being added in the meantime.
332*d57664e9SAndroid Build Coastguard Worker     mLock.lock();
333*d57664e9SAndroid Build Coastguard Worker     const size_t size = mFunctors.size();
334*d57664e9SAndroid Build Coastguard Worker     WebViewFunctor* toDestroyContext[size];
335*d57664e9SAndroid Build Coastguard Worker     for (size_t i = 0; i < size; i++) {
336*d57664e9SAndroid Build Coastguard Worker         toDestroyContext[i] = mFunctors[i].get();
337*d57664e9SAndroid Build Coastguard Worker     }
338*d57664e9SAndroid Build Coastguard Worker     mLock.unlock();
339*d57664e9SAndroid Build Coastguard Worker     for (size_t i = 0; i < size; i++) {
340*d57664e9SAndroid Build Coastguard Worker         toDestroyContext[i]->destroyContext();
341*d57664e9SAndroid Build Coastguard Worker     }
342*d57664e9SAndroid Build Coastguard Worker }
343*d57664e9SAndroid Build Coastguard Worker 
destroyFunctor(int functor)344*d57664e9SAndroid Build Coastguard Worker void WebViewFunctorManager::destroyFunctor(int functor) {
345*d57664e9SAndroid Build Coastguard Worker     std::unique_ptr<WebViewFunctor> toRelease;
346*d57664e9SAndroid Build Coastguard Worker     {
347*d57664e9SAndroid Build Coastguard Worker         std::lock_guard _lock{mLock};
348*d57664e9SAndroid Build Coastguard Worker         for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) {
349*d57664e9SAndroid Build Coastguard Worker             if ((*iter)->id() == functor) {
350*d57664e9SAndroid Build Coastguard Worker                 toRelease = std::move(*iter);
351*d57664e9SAndroid Build Coastguard Worker                 mFunctors.erase(iter);
352*d57664e9SAndroid Build Coastguard Worker                 break;
353*d57664e9SAndroid Build Coastguard Worker             }
354*d57664e9SAndroid Build Coastguard Worker         }
355*d57664e9SAndroid Build Coastguard Worker     }
356*d57664e9SAndroid Build Coastguard Worker }
357*d57664e9SAndroid Build Coastguard Worker 
reportRenderingThreads(int functor,const pid_t * thread_ids,size_t size)358*d57664e9SAndroid Build Coastguard Worker void WebViewFunctorManager::reportRenderingThreads(int functor, const pid_t* thread_ids,
359*d57664e9SAndroid Build Coastguard Worker                                                    size_t size) {
360*d57664e9SAndroid Build Coastguard Worker     std::lock_guard _lock{mLock};
361*d57664e9SAndroid Build Coastguard Worker     for (auto& iter : mFunctors) {
362*d57664e9SAndroid Build Coastguard Worker         if (iter->id() == functor) {
363*d57664e9SAndroid Build Coastguard Worker             iter->reportRenderingThreads(thread_ids, size);
364*d57664e9SAndroid Build Coastguard Worker             break;
365*d57664e9SAndroid Build Coastguard Worker         }
366*d57664e9SAndroid Build Coastguard Worker     }
367*d57664e9SAndroid Build Coastguard Worker }
368*d57664e9SAndroid Build Coastguard Worker 
getRenderingThreadsForActiveFunctors()369*d57664e9SAndroid Build Coastguard Worker std::vector<pid_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() {
370*d57664e9SAndroid Build Coastguard Worker     std::vector<pid_t> renderingThreads;
371*d57664e9SAndroid Build Coastguard Worker     std::lock_guard _lock{mLock};
372*d57664e9SAndroid Build Coastguard Worker     for (const auto& iter : mActiveFunctors) {
373*d57664e9SAndroid Build Coastguard Worker         const auto& functorThreads = iter->getRenderingThreads();
374*d57664e9SAndroid Build Coastguard Worker         for (const auto& tid : functorThreads) {
375*d57664e9SAndroid Build Coastguard Worker             if (std::find(renderingThreads.begin(), renderingThreads.end(), tid) ==
376*d57664e9SAndroid Build Coastguard Worker                 renderingThreads.end()) {
377*d57664e9SAndroid Build Coastguard Worker                 renderingThreads.push_back(tid);
378*d57664e9SAndroid Build Coastguard Worker             }
379*d57664e9SAndroid Build Coastguard Worker         }
380*d57664e9SAndroid Build Coastguard Worker     }
381*d57664e9SAndroid Build Coastguard Worker     return renderingThreads;
382*d57664e9SAndroid Build Coastguard Worker }
383*d57664e9SAndroid Build Coastguard Worker 
handleFor(int functor)384*d57664e9SAndroid Build Coastguard Worker sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
385*d57664e9SAndroid Build Coastguard Worker     std::lock_guard _lock{mLock};
386*d57664e9SAndroid Build Coastguard Worker     for (auto& iter : mActiveFunctors) {
387*d57664e9SAndroid Build Coastguard Worker         if (iter->id() == functor) {
388*d57664e9SAndroid Build Coastguard Worker             return iter;
389*d57664e9SAndroid Build Coastguard Worker         }
390*d57664e9SAndroid Build Coastguard Worker     }
391*d57664e9SAndroid Build Coastguard Worker     return nullptr;
392*d57664e9SAndroid Build Coastguard Worker }
393*d57664e9SAndroid Build Coastguard Worker 
394*d57664e9SAndroid Build Coastguard Worker }  // namespace android::uirenderer
395