blob: 979678d1c4b620f0ca67415157e0f9ac0539e43e [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
89static std::atomic_int sNextId{1};
90
Bo Liud6668e72018-12-14 19:37:41 -080091WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
92 RenderMode functorMode)
93 : mData(data) {
John Reck283bb462018-12-13 16:40:14 -080094 mFunctor = sNextId++;
95 mCallbacks = callbacks;
96 mMode = functorMode;
97}
98
99WebViewFunctor::~WebViewFunctor() {
100 destroyContext();
101
102 ATRACE_NAME("WebViewFunctor::onDestroy");
Bo Liud6668e72018-12-14 19:37:41 -0800103 mCallbacks.onDestroyed(mFunctor, mData);
John Reck283bb462018-12-13 16:40:14 -0800104}
105
106void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
107 ATRACE_NAME("WebViewFunctor::sync");
Bo Liud6668e72018-12-14 19:37:41 -0800108 mCallbacks.onSync(mFunctor, mData, syncData);
John Reck283bb462018-12-13 16:40:14 -0800109}
110
111void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
112 ATRACE_NAME("WebViewFunctor::drawGl");
113 if (!mHasContext) {
114 mHasContext = true;
115 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500116 ScopedCurrentFunctor currentFunctor(this);
117
118 WebViewOverlayData overlayParams = {
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500119 .overlaysMode = OverlaysMode::Disabled,
120 .getSurfaceControl = currentFunctor.getSurfaceControl,
121 .mergeTransaction = currentFunctor.mergeTransaction,
122 };
Huihong Luo054b8d32021-02-24 18:48:12 -0800123
124 if (!drawInfo.isLayer) {
125 renderthread::CanvasContext* activeContext =
126 renderthread::CanvasContext::getActiveContext();
127 if (activeContext != nullptr) {
128 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
129 if (rootSurfaceControl) overlayParams.overlaysMode = OverlaysMode::Enabled;
130 }
131 }
132
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500133 mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
John Reck283bb462018-12-13 16:40:14 -0800134}
135
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800136void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
137 ATRACE_NAME("WebViewFunctor::initVk");
138 if (!mHasContext) {
139 mHasContext = true;
140 } else {
141 return;
142 }
143 mCallbacks.vk.initialize(mFunctor, mData, params);
144}
145
146void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
147 ATRACE_NAME("WebViewFunctor::drawVk");
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
156 // TODO, enable surface control once offscreen mode figured out
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500157 mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800158}
159
160void WebViewFunctor::postDrawVk() {
161 ATRACE_NAME("WebViewFunctor::postDrawVk");
162 mCallbacks.vk.postDraw(mFunctor, mData);
163}
164
John Reck283bb462018-12-13 16:40:14 -0800165void WebViewFunctor::destroyContext() {
166 if (mHasContext) {
167 mHasContext = false;
168 ATRACE_NAME("WebViewFunctor::onContextDestroyed");
Bo Liud6668e72018-12-14 19:37:41 -0800169 mCallbacks.onContextDestroyed(mFunctor, mData);
Bo Liu1b0278c2019-01-03 16:36:24 -0800170
171 // grContext may be null in unit tests.
172 auto* grContext = renderthread::RenderThread::getInstance().getGrContext();
173 if (grContext) grContext->resetContext();
John Reck283bb462018-12-13 16:40:14 -0800174 }
175}
176
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500177void WebViewFunctor::removeOverlays() {
178 ScopedCurrentFunctor currentFunctor(this);
179 mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
Huihong Luo054b8d32021-02-24 18:48:12 -0800180 if (mSurfaceControl) {
181 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
182 funcs.releaseFunc(mSurfaceControl);
183 mSurfaceControl = nullptr;
184 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500185}
186
187ASurfaceControl* WebViewFunctor::getSurfaceControl() {
Huihong Luo054b8d32021-02-24 18:48:12 -0800188 ATRACE_NAME("WebViewFunctor::getSurfaceControl");
189 if (mSurfaceControl != nullptr) return mSurfaceControl;
190
191 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
192 LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
193
194 ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
195 LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
196
197 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
198 mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
199 ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
200 funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
201 ASURFACE_TRANSACTION_VISIBILITY_SHOW);
202 funcs.transactionApplyFunc(transaction);
203 funcs.transactionDeleteFunc(transaction);
204 return mSurfaceControl;
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500205}
206
207void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
Huihong Luo054b8d32021-02-24 18:48:12 -0800208 ATRACE_NAME("WebViewFunctor::mergeTransaction");
209 if (transaction == nullptr) return;
210 renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
211 LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
212 bool done = activeContext->mergeTransaction(transaction, mSurfaceControl);
213 if (!done) {
214 auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
215 funcs.transactionApplyFunc(transaction);
216 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500217}
218
John Reck283bb462018-12-13 16:40:14 -0800219WebViewFunctorManager& WebViewFunctorManager::instance() {
220 static WebViewFunctorManager sInstance;
221 return sInstance;
222}
223
Bo Liud6668e72018-12-14 19:37:41 -0800224int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
John Reck283bb462018-12-13 16:40:14 -0800225 RenderMode functorMode) {
Bo Liud6668e72018-12-14 19:37:41 -0800226 auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
John Reck283bb462018-12-13 16:40:14 -0800227 int id = object->id();
228 auto handle = object->createHandle();
229 {
230 std::lock_guard _lock{mLock};
231 mActiveFunctors.push_back(std::move(handle));
232 mFunctors.push_back(std::move(object));
233 }
234 return id;
235}
236
237void WebViewFunctorManager::releaseFunctor(int functor) {
238 sp<WebViewFunctor::Handle> toRelease;
239 {
240 std::lock_guard _lock{mLock};
241 for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) {
242 if ((*iter)->id() == functor) {
243 toRelease = std::move(*iter);
244 mActiveFunctors.erase(iter);
245 break;
246 }
247 }
248 }
249}
250
251void WebViewFunctorManager::onContextDestroyed() {
252 // WARNING: SKETCHY
253 // Because we know that we always remove from mFunctors on RenderThread, the same
254 // thread that always invokes onContextDestroyed, we know that the functor pointers
255 // will remain valid without the lock held.
256 // However, we won't block new functors from being added in the meantime.
257 mLock.lock();
258 const size_t size = mFunctors.size();
259 WebViewFunctor* toDestroyContext[size];
260 for (size_t i = 0; i < size; i++) {
261 toDestroyContext[i] = mFunctors[i].get();
262 }
263 mLock.unlock();
264 for (size_t i = 0; i < size; i++) {
265 toDestroyContext[i]->destroyContext();
266 }
267}
268
269void WebViewFunctorManager::destroyFunctor(int functor) {
270 std::unique_ptr<WebViewFunctor> toRelease;
271 {
272 std::lock_guard _lock{mLock};
273 for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) {
274 if ((*iter)->id() == functor) {
275 toRelease = std::move(*iter);
276 mFunctors.erase(iter);
277 break;
278 }
279 }
280 }
281}
282
283sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
284 std::lock_guard _lock{mLock};
285 for (auto& iter : mActiveFunctors) {
286 if (iter->id() == functor) {
287 return iter;
288 }
289 }
290 return nullptr;
291}
292
Bo Liud6668e72018-12-14 19:37:41 -0800293} // namespace android::uirenderer