blob: 671c66f11e3217e9fb641a92c4a32b9309deaefb [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"
Bo Liu1b0278c2019-01-03 16:36:24 -080021#include "renderthread/RenderThread.h"
John Reck283bb462018-12-13 16:40:14 -080022
23#include <log/log.h>
24#include <utils/Trace.h>
25#include <atomic>
26
27namespace android::uirenderer {
28
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -050029namespace {
30class ScopedCurrentFunctor {
31public:
32 ScopedCurrentFunctor(WebViewFunctor* functor) {
33 ALOG_ASSERT(!sCurrentFunctor);
34 ALOG_ASSERT(functor);
35 sCurrentFunctor = functor;
36 }
37 ~ScopedCurrentFunctor() {
38 ALOG_ASSERT(sCurrentFunctor);
39 sCurrentFunctor = nullptr;
40 }
41
42 static ASurfaceControl* getSurfaceControl() {
43 ALOG_ASSERT(sCurrentFunctor);
44 return sCurrentFunctor->getSurfaceControl();
45 }
46 static void mergeTransaction(ASurfaceTransaction* transaction) {
47 ALOG_ASSERT(sCurrentFunctor);
48 sCurrentFunctor->mergeTransaction(transaction);
49 }
50
51private:
52 static WebViewFunctor* sCurrentFunctor;
53};
54
55WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
56} // namespace
57
John Reck283bb462018-12-13 16:40:14 -080058RenderMode WebViewFunctor_queryPlatformRenderMode() {
59 auto pipelineType = Properties::getRenderPipelineType();
60 switch (pipelineType) {
61 case RenderPipelineType::SkiaGL:
62 return RenderMode::OpenGL_ES;
63 case RenderPipelineType::SkiaVulkan:
64 return RenderMode::Vulkan;
65 default:
66 LOG_ALWAYS_FATAL("Unknown render pipeline type: %d", (int)pipelineType);
67 }
68}
69
Bo Liud6668e72018-12-14 19:37:41 -080070int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype,
71 RenderMode functorMode) {
John Reck283bb462018-12-13 16:40:14 -080072 if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) {
73 ALOGW("Unknown rendermode %d", (int)functorMode);
74 return -1;
75 }
76 if (functorMode == RenderMode::Vulkan &&
77 WebViewFunctor_queryPlatformRenderMode() != RenderMode::Vulkan) {
78 ALOGW("Unable to map from GLES platform to a vulkan functor");
79 return -1;
80 }
Bo Liud6668e72018-12-14 19:37:41 -080081 return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode);
John Reck283bb462018-12-13 16:40:14 -080082}
83
84void WebViewFunctor_release(int functor) {
85 WebViewFunctorManager::instance().releaseFunctor(functor);
86}
87
88static std::atomic_int sNextId{1};
89
Bo Liud6668e72018-12-14 19:37:41 -080090WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
91 RenderMode functorMode)
92 : mData(data) {
John Reck283bb462018-12-13 16:40:14 -080093 mFunctor = sNextId++;
94 mCallbacks = callbacks;
95 mMode = functorMode;
96}
97
98WebViewFunctor::~WebViewFunctor() {
99 destroyContext();
100
101 ATRACE_NAME("WebViewFunctor::onDestroy");
Bo Liud6668e72018-12-14 19:37:41 -0800102 mCallbacks.onDestroyed(mFunctor, mData);
John Reck283bb462018-12-13 16:40:14 -0800103}
104
105void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
106 ATRACE_NAME("WebViewFunctor::sync");
Bo Liud6668e72018-12-14 19:37:41 -0800107 mCallbacks.onSync(mFunctor, mData, syncData);
John Reck283bb462018-12-13 16:40:14 -0800108}
109
110void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
111 ATRACE_NAME("WebViewFunctor::drawGl");
112 if (!mHasContext) {
113 mHasContext = true;
114 }
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500115 ScopedCurrentFunctor currentFunctor(this);
116
117 WebViewOverlayData overlayParams = {
118 // TODO:
119 .overlaysMode = OverlaysMode::Disabled,
120 .getSurfaceControl = currentFunctor.getSurfaceControl,
121 .mergeTransaction = currentFunctor.mergeTransaction,
122 };
123 mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
John Reck283bb462018-12-13 16:40:14 -0800124}
125
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800126void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
127 ATRACE_NAME("WebViewFunctor::initVk");
128 if (!mHasContext) {
129 mHasContext = true;
130 } else {
131 return;
132 }
133 mCallbacks.vk.initialize(mFunctor, mData, params);
134}
135
136void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
137 ATRACE_NAME("WebViewFunctor::drawVk");
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500138 ScopedCurrentFunctor currentFunctor(this);
139
140 WebViewOverlayData overlayParams = {
141 // TODO
142 .overlaysMode = OverlaysMode::Disabled,
143 .getSurfaceControl = currentFunctor.getSurfaceControl,
144 .mergeTransaction = currentFunctor.mergeTransaction,
145 };
146 mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
Bo Liu7b8c1eb2019-01-08 20:17:55 -0800147}
148
149void WebViewFunctor::postDrawVk() {
150 ATRACE_NAME("WebViewFunctor::postDrawVk");
151 mCallbacks.vk.postDraw(mFunctor, mData);
152}
153
John Reck283bb462018-12-13 16:40:14 -0800154void WebViewFunctor::destroyContext() {
155 if (mHasContext) {
156 mHasContext = false;
157 ATRACE_NAME("WebViewFunctor::onContextDestroyed");
Bo Liud6668e72018-12-14 19:37:41 -0800158 mCallbacks.onContextDestroyed(mFunctor, mData);
Bo Liu1b0278c2019-01-03 16:36:24 -0800159
160 // grContext may be null in unit tests.
161 auto* grContext = renderthread::RenderThread::getInstance().getGrContext();
162 if (grContext) grContext->resetContext();
John Reck283bb462018-12-13 16:40:14 -0800163 }
164}
165
Vasiliy Telezhnikov6b237642020-11-12 18:14:58 -0500166void WebViewFunctor::removeOverlays() {
167 ScopedCurrentFunctor currentFunctor(this);
168 mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
169}
170
171ASurfaceControl* WebViewFunctor::getSurfaceControl() {
172 // TODO
173 return nullptr;
174}
175
176void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
177 // TODO
178}
179
John Reck283bb462018-12-13 16:40:14 -0800180WebViewFunctorManager& WebViewFunctorManager::instance() {
181 static WebViewFunctorManager sInstance;
182 return sInstance;
183}
184
Bo Liud6668e72018-12-14 19:37:41 -0800185int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
John Reck283bb462018-12-13 16:40:14 -0800186 RenderMode functorMode) {
Bo Liud6668e72018-12-14 19:37:41 -0800187 auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
John Reck283bb462018-12-13 16:40:14 -0800188 int id = object->id();
189 auto handle = object->createHandle();
190 {
191 std::lock_guard _lock{mLock};
192 mActiveFunctors.push_back(std::move(handle));
193 mFunctors.push_back(std::move(object));
194 }
195 return id;
196}
197
198void WebViewFunctorManager::releaseFunctor(int functor) {
199 sp<WebViewFunctor::Handle> toRelease;
200 {
201 std::lock_guard _lock{mLock};
202 for (auto iter = mActiveFunctors.begin(); iter != mActiveFunctors.end(); iter++) {
203 if ((*iter)->id() == functor) {
204 toRelease = std::move(*iter);
205 mActiveFunctors.erase(iter);
206 break;
207 }
208 }
209 }
210}
211
212void WebViewFunctorManager::onContextDestroyed() {
213 // WARNING: SKETCHY
214 // Because we know that we always remove from mFunctors on RenderThread, the same
215 // thread that always invokes onContextDestroyed, we know that the functor pointers
216 // will remain valid without the lock held.
217 // However, we won't block new functors from being added in the meantime.
218 mLock.lock();
219 const size_t size = mFunctors.size();
220 WebViewFunctor* toDestroyContext[size];
221 for (size_t i = 0; i < size; i++) {
222 toDestroyContext[i] = mFunctors[i].get();
223 }
224 mLock.unlock();
225 for (size_t i = 0; i < size; i++) {
226 toDestroyContext[i]->destroyContext();
227 }
228}
229
230void WebViewFunctorManager::destroyFunctor(int functor) {
231 std::unique_ptr<WebViewFunctor> toRelease;
232 {
233 std::lock_guard _lock{mLock};
234 for (auto iter = mFunctors.begin(); iter != mFunctors.end(); iter++) {
235 if ((*iter)->id() == functor) {
236 toRelease = std::move(*iter);
237 mFunctors.erase(iter);
238 break;
239 }
240 }
241 }
242}
243
244sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
245 std::lock_guard _lock{mLock};
246 for (auto& iter : mActiveFunctors) {
247 if (iter->id() == functor) {
248 return iter;
249 }
250 }
251 return nullptr;
252}
253
Bo Liud6668e72018-12-14 19:37:41 -0800254} // namespace android::uirenderer