blob: 5b4ab5f2d3b1bcd4c826629c160de9ffcaebc0a9 [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
19#include <private/hwui/WebViewFunctor.h>
20#include "Properties.h"
Huihong Luo054b8d32021-02-24 18:48:12 -080021#include "renderthread/CanvasContext.h"
Bo Liu1b0278c2019-01-03 16:36:24 -080022#include "renderthread/RenderThread.h"
John Reck283bb462018-12-13 16:40:14 -080023
24#include <log/log.h>
25#include <utils/Trace.h>
26#include <atomic>
27
28namespace android::uirenderer {
29
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -050030namespace {
31class ScopedCurrentFunctor {
32public:
33 ScopedCurrentFunctor(WebViewFunctor* functor) {
34 ALOG_ASSERT(!sCurrentFunctor);
35 ALOG_ASSERT(functor);
36 sCurrentFunctor = functor;
37 }
38 ~ScopedCurrentFunctor() {
39 ALOG_ASSERT(sCurrentFunctor);
40 sCurrentFunctor = nullptr;
41 }
42
43 static ASurfaceControl* getSurfaceControl() {
44 ALOG_ASSERT(sCurrentFunctor);
45 return sCurrentFunctor->getSurfaceControl();
46 }
47 static void mergeTransaction(ASurfaceTransaction* transaction) {
48 ALOG_ASSERT(sCurrentFunctor);
49 sCurrentFunctor->mergeTransaction(transaction);
50 }
51
52private:
53 static WebViewFunctor* sCurrentFunctor;
54};
55
56WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
57} // namespace
58
John Reck283bb462018-12-13 16:40:14 -080059RenderMode WebViewFunctor_queryPlatformRenderMode() {
60 auto pipelineType = Properties::getRenderPipelineType();
61 switch (pipelineType) {
62 case RenderPipelineType::SkiaGL:
63 return RenderMode::OpenGL_ES;
64 case RenderPipelineType::SkiaVulkan:
65 return RenderMode::Vulkan;
66 default:
67 LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType);
68 }
69}
70
Bo Liud6668e72018-12-14 19:37:41 -080071int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype,
72 RenderMode functorMode) {
John Reck283bb462018-12-13 16:40:14 -080073 if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) {
74 ALOGW("Unknown rendermode %d", (int)functorMode);
75 return -1;
76 }
77 if (functorMode == RenderMode::Vulkan &&
78 WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) {
79 ALOGW("Unable to map from GLES platform to a vulkan functor");
80 return -1;
81 }
Bo Liud6668e72018-12-14 19:37:41 -080082 return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode);
John Reck283bb462018-12-13 16:40:14 -080083}
84
85void WebViewFunctor_release(int functor) {
86 WebViewFunctorManager::instance().releaseFunctor(functor);
87}
88
Igor Kraskevich63ebd832024-03-12 11:51:35 +000089void WebViewFunctor_reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size) {
90 WebViewFunctorManager::instance().reportRenderingThreads(functor, thread_ids, size);
91}
92
John Reck283bb462018-12-13 16:40:14 -080093static std::atomic_int sNextId{1};
94
Bo Liud6668e72018-12-14 19:37:41 -080095WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
96 RenderMode functorMode)
97 : mData(data) {
John Reck283bb462018-12-13 16:40:14 -080098 mFunctor = sNextId++;
99 mCallbacks = callbacks;
100 mMode = functorMode;
101}
102
103WebViewFunctor::~WebViewFunctor() {
104 destroyContext();
105
106 ATRACE_NAME("WebViewFunctor::onDestroy");
Huihong Luo9c5158f72021-07-23 12:35:59 -0700107 if (mSurfaceControl) {
108 removeOverlays();
109 }
Bo Liud6668e72018-12-14 19:37:41 -0800110 mCallbacks.onDestroyed(mFunctor, mData);
John Reck283bb462018-12-13 16:40:14 -0800111}
112
113void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
114 ATRACE_NAME("WebViewFunctor::sync");
Bo Liud6668e72018-12-14 19:37:41 -0800115 mCallbacks.onSync(mFunctor, mData, syncData);
John Reck283bb462018-12-13 16:40:14 -0800116}
117
Huihong Luoec68b7c2021-06-25 21:54:16 -0700118void WebViewFunctor::onRemovedFromTree() {
119 ATRACE_NAME("WebViewFunctor::onRemovedFromTree");
120 if (mSurfaceControl) {
121 removeOverlays();
122 }
123}
124
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500125bool WebViewFunctor::prepareRootSurfaceControl() {
126 if (!Properties::enableWebViewOverlays) return false;
127
128 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
129 if (!activeContext) return false;
130
131 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
132 if (!rootSurfaceControl) return false;
133
134 int32_t rgid = activeContext->getSurfaceControlGenerationId();
135 if (mParentSurfaceControlGenerationId != rgid) {
136 reparentSurfaceControl(rootSurfaceControl);
137 mParentSurfaceControlGenerationId = rgid;
138 }
139
140 return true;
141}
142
John Reck283bb462018-12-13 16:40:14 -0800143void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
144 ATRACE_NAME("WebViewFunctor::drawGl");
145 if (!mHasContext) {
146 mHasContext = true;
147 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500148 ScopedCurrentFunctor currentFunctor(this);
149
150 WebViewOverlayData overlayParams = {
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500151 .overlaysMode = OverlaysMode::Disabled,
152 .getSurfaceControl = currentFunctor.getSurfaceControl,
153 .mergeTransaction = currentFunctor.mergeTransaction,
154 };
Huihong Luo054b8d32021-02-24 18:48:12 -0800155
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500156 if (!drawInfo.isLayer && prepareRootSurfaceControl()) {
157 overlayParams.overlaysMode = OverlaysMode::Enabled;
Huihong Luo054b8d32021-02-24 18:48:12 -0800158 }
159
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500160 mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
John Reck283bb462018-12-13 16:40:14 -0800161}
162
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800163void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
164 ATRACE_NAME("WebViewFunctor::initVk");
165 if (!mHasContext) {
166 mHasContext = true;
167 } else {
168 return;
169 }
170 mCallbacks.vk.initialize(mFunctor, mData, params);
171}
172
173void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
174 ATRACE_NAME("WebViewFunctor::drawVk");
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500175 ScopedCurrentFunctor currentFunctor(this);
176
177 WebViewOverlayData overlayParams = {
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500178 .overlaysMode = OverlaysMode::Disabled,
179 .getSurfaceControl = currentFunctor.getSurfaceControl,
180 .mergeTransaction = currentFunctor.mergeTransaction,
181 };
Huihong Luo054b8d32021-02-24 18:48:12 -0800182
Vasiliy Telezhnikov372a21b2021-11-17 13:50:56 -0500183 if (!params.is_layer && prepareRootSurfaceControl()) {
184 overlayParams.overlaysMode = OverlaysMode::Enabled;
185 }
186
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500187 mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800188}
189
190void WebViewFunctor::postDrawVk() {
191 ATRACE_NAME("WebViewFunctor::postDrawVk");
192 mCallbacks.vk.postDraw(mFunctor, mData);
193}
194
John Reck283bb462018-12-13 16:40:14 -0800195void WebViewFunctor::destroyContext() {
196 if (mHasContext) {
197 mHasContext = false;
198 ATRACE_NAME("WebViewFunctor::onContextDestroyed");
Bo Liud6668e72018-12-14 19:37:41 -0800199 mCallbacks.onContextDestroyed(mFunctor, mData);
Bo Liu1b0278c2019-01-03 16:36:24 -0800200
201 // grContext may be null in unit tests.
202 auto* grContext = renderthread::RenderThread::getInstance().getGrContext();
203 if (grContext) grContext->resetContext();
John Reck283bb462018-12-13 16:40:14 -0800204 }
205}
206
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500207void WebViewFunctor::removeOverlays() {
208 ScopedCurrentFunctor currentFunctor(this);
209 mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
Huihong Luo054b8d32021-02-24 18:48:12 -0800210 if (mSurfaceControl) {
Huihong Luoec68b7c2021-06-25 21:54:16 -0700211 reparentSurfaceControl(nullptr);
Huihong Luo054b8d32021-02-24 18:48:12 -0800212 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
213 funcs.releaseFunc(mSurfaceControl);
214 mSurfaceControl = nullptr;
215 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500216}
217
218ASurfaceControl* WebViewFunctor::getSurfaceControl() {
Huihong Luo054b8d32021-02-24 18:48:12 -0800219 ATRACE_NAME("WebViewFunctor::getSurfaceControl");
220 if (mSurfaceControl != nullptr) return mSurfaceControl;
221
222 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
223 LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
224
225 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
226 LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
227
228 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
Huihong Luo540fdf82021-06-25 13:59:39 -0700229 mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
Huihong Luo054b8d32021-02-24 18:48:12 -0800230 mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
231 ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
Huihong Luo34f42fd2021-05-03 14:47:36 -0700232 activeContext->prepareSurfaceControlForWebview();
233 funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
Huihong Luo054b8d32021-02-24 18:48:12 -0800234 funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
235 ASURFACE_TRANSACTION_VISIBILITY_SHOW);
236 funcs.transactionApplyFunc(transaction);
237 funcs.transactionDeleteFunc(transaction);
238 return mSurfaceControl;
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500239}
240
241void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
Huihong Luo054b8d32021-02-24 18:48:12 -0800242 ATRACE_NAME("WebViewFunctor::mergeTransaction");
243 if (transaction == nullptr) return;
Huihong Luoec68b7c2021-06-25 21:54:16 -0700244 bool done = false;
Huihong Luo054b8d32021-02-24 18:48:12 -0800245 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
Huihong Luoec68b7c2021-06-25 21:54:16 -0700246 // activeContext might be null when called from mCallbacks.removeOverlays()
247 if (activeContext != nullptr) {
248 done = activeContext->mergeTransaction(transaction, mSurfaceControl);
249 }
Huihong Luo054b8d32021-02-24 18:48:12 -0800250 if (!done) {
251 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
252 funcs.transactionApplyFunc(transaction);
253 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500254}
255
Huihong Luo540fdf82021-06-25 13:59:39 -0700256void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
257 ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
258 if (mSurfaceControl == nullptr) return;
259
260 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
261 ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
262 funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
263 mergeTransaction(transaction);
264 funcs.transactionDeleteFunc(transaction);
265}
266
Igor Kraskevich63ebd832024-03-12 11:51:35 +0000267void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) {
268 // TODO(b/329219352): Pass the threads to HWUI and update the ADPF session.
269}
270
John Reck283bb462018-12-13 16:40:14 -0800271WebViewFunctorManager& WebViewFunctorManager::instance() {
272 static WebViewFunctorManager sInstance;
273 return sInstance;
274}
275
John Reckfaa1b0a2021-05-13 10:28:38 -0400276static void validateCallbacks(const WebViewFunctorCallbacks& callbacks) {
277 // TODO: Should we do a stack peek to see if this is really webview?
278 LOG_ALWAYS_FATAL_IF(callbacks.onSync == nullptr, "onSync is null");
279 LOG_ALWAYS_FATAL_IF(callbacks.onContextDestroyed == nullptr, "onContextDestroyed is null");
280 LOG_ALWAYS_FATAL_IF(callbacks.onDestroyed == nullptr, "onDestroyed is null");
281 LOG_ALWAYS_FATAL_IF(callbacks.removeOverlays == nullptr, "removeOverlays is null");
282 switch (auto mode = WebViewFunctor_queryPlatformRenderMode()) {
283 case RenderMode::OpenGL_ES:
284 LOG_ALWAYS_FATAL_IF(callbacks.gles.draw == nullptr, "gles.draw is null");
285 break;
286 case RenderMode::Vulkan:
287 LOG_ALWAYS_FATAL_IF(callbacks.vk.initialize == nullptr, "vk.initialize is null");
288 LOG_ALWAYS_FATAL_IF(callbacks.vk.draw == nullptr, "vk.draw is null");
289 LOG_ALWAYS_FATAL_IF(callbacks.vk.postDraw == nullptr, "vk.postDraw is null");
290 break;
291 default:
292 LOG_ALWAYS_FATAL("unknown platform mode? %d", (int)mode);
293 break;
294 }
295}
296
Bo Liud6668e72018-12-14 19:37:41 -0800297int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
John Reck283bb462018-12-13 16:40:14 -0800298 RenderMode functorMode) {
John Reckfaa1b0a2021-05-13 10:28:38 -0400299 validateCallbacks(callbacks);
Bo Liud6668e72018-12-14 19:37:41 -0800300 auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
John Reck283bb462018-12-13 16:40:14 -0800301 int id = object->id();
302 auto handle = object->createHandle();
303 {
304 std::lock_guard _lock{mLock};
305 mActiveFunctors.push_back(std::move(handle));
306 mFunctors.push_back(std::move(object));
307 }
308 return id;
309}
310
311void WebViewFunctorManager::releaseFunctor(int functor) {
312 sp<WebViewFunctor::Handle> toRelease;
313 {
314 std::lock_guard _lock{mLock};
315 for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) {
316 if ((*iter)->id() == functor) {
317 toRelease = std::move(*iter);
318 mActiveFunctors.erase(iter);
319 break;
320 }
321 }
322 }
323}
324
325void WebViewFunctorManager::onContextDestroyed() {
326 // WARNING: SKETCHY
327 // Because we know that we always remove from mFunctors on RenderThread, the same
328 // thread that always invokes onContextDestroyed, we know that the functor pointers
329 // will remain valid without the lock held.
330 // However, we won't block new functors from being added in the meantime.
331 mLock.lock();
332 const size_t size = mFunctors.size();
333 WebViewFunctor* toDestroyContext[size];
334 for (size_t i = 0; i < size; i++) {
335 toDestroyContext[i] = mFunctors[i].get();
336 }
337 mLock.unlock();
338 for (size_t i = 0; i < size; i++) {
339 toDestroyContext[i]->destroyContext();
340 }
341}
342
343void WebViewFunctorManager::destroyFunctor(int functor) {
344 std::unique_ptr<WebViewFunctor> toRelease;
345 {
346 std::lock_guard _lock{mLock};
347 for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) {
348 if ((*iter)->id() == functor) {
349 toRelease = std::move(*iter);
350 mFunctors.erase(iter);
351 break;
352 }
353 }
354 }
355}
356
Igor Kraskevich63ebd832024-03-12 11:51:35 +0000357void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* thread_ids,
358 size_t size) {
359 std::lock_guard _lock{mLock};
360 for (auto& iter : mFunctors) {
361 if (iter->id() == functor) {
362 iter->reportRenderingThreads(thread_ids, size);
363 break;
364 }
365 }
366}
367
John Reck283bb462018-12-13 16:40:14 -0800368sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
369 std::lock_guard _lock{mLock};
370 for (auto& iter : mActiveFunctors) {
371 if (iter->id() == functor) {
372 return iter;
373 }
374 }
375 return nullptr;
376}
377
Bo Liud6668e72018-12-14 19:37:41 -0800378} // namespace android::uirenderer