blob: 9d16ee86739e7c8742d28bf325e9b46dcde4b328 [file] [log] [blame]
John Reck283bb462018-12-13 16:40:14 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "WebViewFunctorManager.h"
18
Igor Kraskevich2cec1582024-03-13 11:23:40 +000019#include <log/log.h>
John Reck283bb462018-12-13 16:40:14 -080020#include <private/hwui/WebViewFunctor.h>
Igor Kraskevich2cec1582024-03-13 11:23:40 +000021#include <utils/Trace.h>
22
23#include <atomic>
24
John Reck283bb462018-12-13 16:40:14 -080025#include "Properties.h"
Huihong Luo054b8d32021-02-24 18:48:12 -080026#include "renderthread/CanvasContext.h"
Bo Liu1b0278c2019-01-03 16:36:24 -080027#include "renderthread/RenderThread.h"
John Reck283bb462018-12-13 16:40:14 -080028
John Reck283bb462018-12-13 16:40:14 -080029namespace android::uirenderer {
30
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -050031namespace {
32class ScopedCurrentFunctor {
33public:
34 ScopedCurrentFunctor(WebViewFunctor* functor) {
35 ALOG_ASSERT(!sCurrentFunctor);
36 ALOG_ASSERT(functor);
37 sCurrentFunctor = functor;
38 }
39 ~ScopedCurrentFunctor() {
40 ALOG_ASSERT(sCurrentFunctor);
41 sCurrentFunctor = nullptr;
42 }
43
44 static ASurfaceControl* getSurfaceControl() {
45 ALOG_ASSERT(sCurrentFunctor);
46 return sCurrentFunctor->getSurfaceControl();
47 }
48 static void mergeTransaction(ASurfaceTransaction* transaction) {
49 ALOG_ASSERT(sCurrentFunctor);
50 sCurrentFunctor->mergeTransaction(transaction);
51 }
52
53private:
54 static WebViewFunctor* sCurrentFunctor;
55};
56
57WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
58} // namespace
59
John Reck283bb462018-12-13 16:40:14 -080060RenderMode WebViewFunctor_queryPlatformRenderMode() {
61 auto pipelineType = Properties::getRenderPipelineType();
62 switch (pipelineType) {
63 case RenderPipelineType::SkiaGL:
64 return RenderMode::OpenGL_ES;
65 case RenderPipelineType::SkiaVulkan:
66 return RenderMode::Vulkan;
67 default:
68 LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType);
69 }
70}
71
Bo Liud6668e72018-12-14 19:37:41 -080072int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype,
73 RenderMode functorMode) {
John Reck283bb462018-12-13 16:40:14 -080074 if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) {
75 ALOGW("Unknown rendermode %d", (int)functorMode);
76 return -1;
77 }
78 if (functorMode == RenderMode::Vulkan &&
79 WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) {
80 ALOGW("Unable to map from GLES platform to a vulkan functor");
81 return -1;
82 }
Bo Liud6668e72018-12-14 19:37:41 -080083 return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode);
John Reck283bb462018-12-13 16:40:14 -080084}
85
86void WebViewFunctor_release(int functor) {
87 WebViewFunctorManager::instance().releaseFunctor(functor);
88}
89
Jerome Gaillard9da39e72024-04-09 14:43:21 +010090void WebViewFunctor_reportRenderingThreads(int functor, const pid_t* thread_ids, size_t size) {
Igor Kraskevich63ebd832024-03-12 11:51:35 +000091 WebViewFunctorManager::instance().reportRenderingThreads(functor, thread_ids, size);
92}
93
John Reck283bb462018-12-13 16:40:14 -080094static std::atomic_int sNextId{1};
95
Bo Liud6668e72018-12-14 19:37:41 -080096WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
97 RenderMode functorMode)
98 : mData(data) {
John Reck283bb462018-12-13 16:40:14 -080099 mFunctor = sNextId++;
100 mCallbacks = callbacks;
101 mMode = functorMode;
102}
103
104WebViewFunctor::~WebViewFunctor() {
105 destroyContext();
106
107 ATRACE_NAME("WebViewFunctor::onDestroy");
Huihong Luo9c5158f72021-07-23 12:35:59 -0700108 if (mSurfaceControl) {
109 removeOverlays();
110 }
Bo Liud6668e72018-12-14 19:37:41 -0800111 mCallbacks.onDestroyed(mFunctor, mData);
John Reck283bb462018-12-13 16:40:14 -0800112}
113
114void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
115 ATRACE_NAME("WebViewFunctor::sync");
Bo Liud6668e72018-12-14 19:37:41 -0800116 mCallbacks.onSync(mFunctor, mData, syncData);
John Reck283bb462018-12-13 16:40:14 -0800117}
118
Huihong Luoec68b7c2021-06-25 21:54:16 -0700119void WebViewFunctor::onRemovedFromTree() {
120 ATRACE_NAME("WebViewFunctor::onRemovedFromTree");
121 if (mSurfaceControl) {
122 removeOverlays();
123 }
124}
125
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500126bool WebViewFunctor::prepareRootSurfaceControl() {
127 if (!Properties::enableWebViewOverlays) return false;
128
129 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
130 if (!activeContext) return false;
131
132 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
133 if (!rootSurfaceControl) return false;
134
135 int32_t rgid = activeContext->getSurfaceControlGenerationId();
136 if (mParentSurfaceControlGenerationId != rgid) {
137 reparentSurfaceControl(rootSurfaceControl);
138 mParentSurfaceControlGenerationId = rgid;
139 }
140
141 return true;
142}
143
John Reck283bb462018-12-13 16:40:14 -0800144void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
145 ATRACE_NAME("WebViewFunctor::drawGl");
146 if (!mHasContext) {
147 mHasContext = true;
148 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500149 ScopedCurrentFunctor currentFunctor(this);
150
151 WebViewOverlayData overlayParams = {
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500152 .overlaysMode = OverlaysMode::Disabled,
153 .getSurfaceControl = currentFunctor.getSurfaceControl,
154 .mergeTransaction = currentFunctor.mergeTransaction,
155 };
Huihong Luo054b8d32021-02-24 18:48:12 -0800156
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500157 if (!drawInfo.isLayer && prepareRootSurfaceControl()) {
158 overlayParams.overlaysMode = OverlaysMode::Enabled;
Huihong Luo054b8d32021-02-24 18:48:12 -0800159 }
160
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500161 mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
John Reck283bb462018-12-13 16:40:14 -0800162}
163
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800164void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
165 ATRACE_NAME("WebViewFunctor::initVk");
166 if (!mHasContext) {
167 mHasContext = true;
168 } else {
169 return;
170 }
171 mCallbacks.vk.initialize(mFunctor, mData, params);
172}
173
174void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
175 ATRACE_NAME("WebViewFunctor::drawVk");
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500176 ScopedCurrentFunctor currentFunctor(this);
177
178 WebViewOverlayData overlayParams = {
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500179 .overlaysMode = OverlaysMode::Disabled,
180 .getSurfaceControl = currentFunctor.getSurfaceControl,
181 .mergeTransaction = currentFunctor.mergeTransaction,
182 };
Huihong Luo054b8d32021-02-24 18:48:12 -0800183
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500184 if (!params.is_layer && prepareRootSurfaceControl()) {
185 overlayParams.overlaysMode = OverlaysMode::Enabled;
186 }
187
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500188 mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800189}
190
191void WebViewFunctor::postDrawVk() {
192 ATRACE_NAME("WebViewFunctor::postDrawVk");
193 mCallbacks.vk.postDraw(mFunctor, mData);
194}
195
John Reck283bb462018-12-13 16:40:14 -0800196void WebViewFunctor::destroyContext() {
197 if (mHasContext) {
198 mHasContext = false;
199 ATRACE_NAME("WebViewFunctor::onContextDestroyed");
Bo Liud6668e72018-12-14 19:37:41 -0800200 mCallbacks.onContextDestroyed(mFunctor, mData);
Bo Liu1b0278c2019-01-03 16:36:24 -0800201
202 // grContext may be null in unit tests.
203 auto* grContext = renderthread::RenderThread::getInstance().getGrContext();
204 if (grContext) grContext->resetContext();
John Reck283bb462018-12-13 16:40:14 -0800205 }
206}
207
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500208void WebViewFunctor::removeOverlays() {
209 ScopedCurrentFunctor currentFunctor(this);
210 mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
Huihong Luo054b8d32021-02-24 18:48:12 -0800211 if (mSurfaceControl) {
Huihong Luoec68b7c2021-06-25 21:54:16 -0700212 reparentSurfaceControl(nullptr);
Huihong Luo054b8d32021-02-24 18:48:12 -0800213 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
214 funcs.releaseFunc(mSurfaceControl);
215 mSurfaceControl = nullptr;
216 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500217}
218
219ASurfaceControl* WebViewFunctor::getSurfaceControl() {
Huihong Luo054b8d32021-02-24 18:48:12 -0800220 ATRACE_NAME("WebViewFunctor::getSurfaceControl");
221 if (mSurfaceControl != nullptr) return mSurfaceControl;
222
223 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
224 LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
225
226 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
227 LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
228
229 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
Huihong Luo540fdf82021-06-25 13:59:39 -0700230 mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
Huihong Luo054b8d32021-02-24 18:48:12 -0800231 mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
232 ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
Huihong Luo34f42fd2021-05-03 14:47:36 -0700233 activeContext->prepareSurfaceControlForWebview();
234 funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
Huihong Luo054b8d32021-02-24 18:48:12 -0800235 funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
236 ASURFACE_TRANSACTION_VISIBILITY_SHOW);
237 funcs.transactionApplyFunc(transaction);
238 funcs.transactionDeleteFunc(transaction);
239 return mSurfaceControl;
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500240}
241
242void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
Huihong Luo054b8d32021-02-24 18:48:12 -0800243 ATRACE_NAME("WebViewFunctor::mergeTransaction");
244 if (transaction == nullptr) return;
Huihong Luoec68b7c2021-06-25 21:54:16 -0700245 bool done = false;
Huihong Luo054b8d32021-02-24 18:48:12 -0800246 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
Huihong Luoec68b7c2021-06-25 21:54:16 -0700247 // activeContext might be null when called from mCallbacks.removeOverlays()
248 if (activeContext != nullptr) {
249 done = activeContext->mergeTransaction(transaction, mSurfaceControl);
250 }
Huihong Luo054b8d32021-02-24 18:48:12 -0800251 if (!done) {
252 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
253 funcs.transactionApplyFunc(transaction);
254 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500255}
256
Huihong Luo540fdf82021-06-25 13:59:39 -0700257void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
258 ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
259 if (mSurfaceControl == nullptr) return;
260
261 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
262 ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
263 funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
264 mergeTransaction(transaction);
265 funcs.transactionDeleteFunc(transaction);
266}
267
Jerome Gaillard9da39e72024-04-09 14:43:21 +0100268void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) {
269 mRenderingThreads = std::vector<pid_t>(thread_ids, thread_ids + size);
Igor Kraskevich63ebd832024-03-12 11:51:35 +0000270}
271
John Reck283bb462018-12-13 16:40:14 -0800272WebViewFunctorManager& WebViewFunctorManager::instance() {
273 static WebViewFunctorManager sInstance;
274 return sInstance;
275}
276
John Reckfaa1b0a2021-05-13 10:28:38 -0400277static void validateCallbacks(const WebViewFunctorCallbacks& callbacks) {
278 // TODO: Should we do a stack peek to see if this is really webview?
279 LOG_ALWAYS_FATAL_IF(callbacks.onSync == nullptr, "onSync is null");
280 LOG_ALWAYS_FATAL_IF(callbacks.onContextDestroyed == nullptr, "onContextDestroyed is null");
281 LOG_ALWAYS_FATAL_IF(callbacks.onDestroyed == nullptr, "onDestroyed is null");
282 LOG_ALWAYS_FATAL_IF(callbacks.removeOverlays == nullptr, "removeOverlays is null");
283 switch (auto mode = WebViewFunctor_queryPlatformRenderMode()) {
284 case RenderMode::OpenGL_ES:
285 LOG_ALWAYS_FATAL_IF(callbacks.gles.draw == nullptr, "gles.draw is null");
286 break;
287 case RenderMode::Vulkan:
288 LOG_ALWAYS_FATAL_IF(callbacks.vk.initialize == nullptr, "vk.initialize is null");
289 LOG_ALWAYS_FATAL_IF(callbacks.vk.draw == nullptr, "vk.draw is null");
290 LOG_ALWAYS_FATAL_IF(callbacks.vk.postDraw == nullptr, "vk.postDraw is null");
291 break;
292 default:
293 LOG_ALWAYS_FATAL("unknown platform mode? %d", (int)mode);
294 break;
295 }
296}
297
Bo Liud6668e72018-12-14 19:37:41 -0800298int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
John Reck283bb462018-12-13 16:40:14 -0800299 RenderMode functorMode) {
John Reckfaa1b0a2021-05-13 10:28:38 -0400300 validateCallbacks(callbacks);
Bo Liud6668e72018-12-14 19:37:41 -0800301 auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
John Reck283bb462018-12-13 16:40:14 -0800302 int id = object->id();
303 auto handle = object->createHandle();
304 {
305 std::lock_guard _lock{mLock};
306 mActiveFunctors.push_back(std::move(handle));
307 mFunctors.push_back(std::move(object));
308 }
309 return id;
310}
311
312void WebViewFunctorManager::releaseFunctor(int functor) {
313 sp<WebViewFunctor::Handle> toRelease;
314 {
315 std::lock_guard _lock{mLock};
316 for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) {
317 if ((*iter)->id() == functor) {
318 toRelease = std::move(*iter);
319 mActiveFunctors.erase(iter);
320 break;
321 }
322 }
323 }
324}
325
326void WebViewFunctorManager::onContextDestroyed() {
327 // WARNING: SKETCHY
328 // Because we know that we always remove from mFunctors on RenderThread, the same
329 // thread that always invokes onContextDestroyed, we know that the functor pointers
330 // will remain valid without the lock held.
331 // However, we won't block new functors from being added in the meantime.
332 mLock.lock();
333 const size_t size = mFunctors.size();
334 WebViewFunctor* toDestroyContext[size];
335 for (size_t i = 0; i < size; i++) {
336 toDestroyContext[i] = mFunctors[i].get();
337 }
338 mLock.unlock();
339 for (size_t i = 0; i < size; i++) {
340 toDestroyContext[i]->destroyContext();
341 }
342}
343
344void WebViewFunctorManager::destroyFunctor(int functor) {
345 std::unique_ptr<WebViewFunctor> toRelease;
346 {
347 std::lock_guard _lock{mLock};
348 for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) {
349 if ((*iter)->id() == functor) {
350 toRelease = std::move(*iter);
351 mFunctors.erase(iter);
352 break;
353 }
354 }
355 }
356}
357
Jerome Gaillard9da39e72024-04-09 14:43:21 +0100358void WebViewFunctorManager::reportRenderingThreads(int functor, const pid_t* thread_ids,
Igor Kraskevich63ebd832024-03-12 11:51:35 +0000359 size_t size) {
360 std::lock_guard _lock{mLock};
361 for (auto& iter : mFunctors) {
362 if (iter->id() == functor) {
363 iter->reportRenderingThreads(thread_ids, size);
364 break;
365 }
366 }
367}
368
Jerome Gaillard9da39e72024-04-09 14:43:21 +0100369std::vector<pid_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() {
370 std::vector<pid_t> renderingThreads;
Igor Kraskevich2cec1582024-03-13 11:23:40 +0000371 std::lock_guard _lock{mLock};
372 for (const auto& iter : mActiveFunctors) {
373 const auto& functorThreads = iter->getRenderingThreads();
374 for (const auto& tid : functorThreads) {
375 if (std::find(renderingThreads.begin(), renderingThreads.end(), tid) ==
376 renderingThreads.end()) {
377 renderingThreads.push_back(tid);
378 }
379 }
380 }
381 return renderingThreads;
382}
383
John Reck283bb462018-12-13 16:40:14 -0800384sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
385 std::lock_guard _lock{mLock};
386 for (auto& iter : mActiveFunctors) {
387 if (iter->id() == functor) {
388 return iter;
389 }
390 }
391 return nullptr;
392}
393
Bo Liud6668e72018-12-14 19:37:41 -0800394} // namespace android::uirenderer