• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 "draw_fn.h"
18 
19 #include <jni.h>
20 #include <private/hwui/WebViewFunctor.h>
21 #include <utils/Log.h>
22 
23 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
24 #define COMPILE_ASSERT(expr, err) \
25 __unused static const char (err)[(expr) ? 1 : -1] = "";
26 
27 namespace android {
28 namespace {
29 
30 struct SupportData {
31   void* const data;
32   AwDrawFnFunctorCallbacks callbacks;
33 };
34 
GetOverlaysMode(uirenderer::OverlaysMode overlays_mode)35 AwDrawFnOverlaysMode GetOverlaysMode(uirenderer::OverlaysMode overlays_mode) {
36   switch (overlays_mode) {
37     case uirenderer::OverlaysMode::Disabled:
38       return AW_DRAW_FN_OVERLAYS_MODE_DISABLED;
39     case uirenderer::OverlaysMode::Enabled:
40       return AW_DRAW_FN_OVERLAYS_MODE_ENABLED;
41   }
42 }
43 
onSync(int functor,void * data,const uirenderer::WebViewSyncData & syncData)44 void onSync(int functor, void* data,
45             const uirenderer::WebViewSyncData& syncData) {
46   AwDrawFn_OnSyncParams params = {
47       .version = kAwDrawFnVersion,
48       .apply_force_dark = syncData.applyForceDark,
49   };
50   SupportData* support = static_cast<SupportData*>(data);
51   support->callbacks.on_sync(functor, support->data, &params);
52 }
53 
onContextDestroyed(int functor,void * data)54 void onContextDestroyed(int functor, void* data) {
55   SupportData* support = static_cast<SupportData*>(data);
56   support->callbacks.on_context_destroyed(functor, support->data);
57 }
58 
onDestroyed(int functor,void * data)59 void onDestroyed(int functor, void* data) {
60   SupportData* support = static_cast<SupportData*>(data);
61   support->callbacks.on_destroyed(functor, support->data);
62   delete support;
63 }
64 
removeOverlays(int functor,void * data,AwDrawFn_MergeTransaction merge_transaction)65 void removeOverlays(int functor, void* data,
66                     AwDrawFn_MergeTransaction merge_transaction) {
67   AwDrawFn_RemoveOverlaysParams params = {
68       .version = kAwDrawFnVersion,
69       .merge_transaction = merge_transaction
70   };
71   SupportData* support = static_cast<SupportData*>(data);
72   if (support->callbacks.remove_overlays)
73     support->callbacks.remove_overlays(functor, support->data, &params);
74 }
75 
draw_gl(int functor,void * data,const uirenderer::DrawGlInfo & draw_gl_params,const uirenderer::WebViewOverlayData & overlay_params)76 void draw_gl(int functor, void* data,
77              const uirenderer::DrawGlInfo& draw_gl_params,
78              const uirenderer::WebViewOverlayData& overlay_params) {
79   float gabcdef[7];
80   if (draw_gl_params.color_space_ptr) {
81       draw_gl_params.color_space_ptr->transferFn(gabcdef);
82   } else {
83       // Assume sRGB.
84       gabcdef[0] = SkNamedTransferFn::kSRGB.g;
85       gabcdef[1] = SkNamedTransferFn::kSRGB.a;
86       gabcdef[2] = SkNamedTransferFn::kSRGB.b;
87       gabcdef[3] = SkNamedTransferFn::kSRGB.c;
88       gabcdef[4] = SkNamedTransferFn::kSRGB.d;
89       gabcdef[5] = SkNamedTransferFn::kSRGB.e;
90       gabcdef[6] = SkNamedTransferFn::kSRGB.f;
91   }
92   AwDrawFn_DrawGLParams params = {
93       .version = kAwDrawFnVersion,
94       .clip_left = draw_gl_params.clipLeft,
95       .clip_top = draw_gl_params.clipTop,
96       .clip_right = draw_gl_params.clipRight,
97       .clip_bottom = draw_gl_params.clipBottom,
98       .width = draw_gl_params.width,
99       .height = draw_gl_params.height,
100       .deprecated_0 = false,
101       .transfer_function_g = gabcdef[0],
102       .transfer_function_a = gabcdef[1],
103       .transfer_function_b = gabcdef[2],
104       .transfer_function_c = gabcdef[3],
105       .transfer_function_d = gabcdef[4],
106       .transfer_function_e = gabcdef[5],
107       .transfer_function_f = gabcdef[6],
108       .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
109       .get_surface_control = overlay_params.getSurfaceControl,
110       .merge_transaction = overlay_params.mergeTransaction
111   };
112   COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform),
113                  mismatched_transform_matrix_sizes);
114   for (int i = 0; i < NELEM(params.transform); ++i) {
115     params.transform[i] = draw_gl_params.transform[i];
116   }
117   COMPILE_ASSERT(sizeof(params.color_space_toXYZD50) == sizeof(skcms_Matrix3x3),
118                  gamut_transform_size_mismatch);
119   if (draw_gl_params.color_space_ptr) {
120       draw_gl_params.color_space_ptr->toXYZD50(
121               reinterpret_cast<skcms_Matrix3x3*>(&params.color_space_toXYZD50));
122   } else {
123       // Assume sRGB.
124       memcpy(&params.color_space_toXYZD50, &SkNamedGamut::kSRGB,
125              sizeof(params.color_space_toXYZD50));
126   }
127 
128   SupportData* support = static_cast<SupportData*>(data);
129   support->callbacks.draw_gl(functor, support->data, &params);
130 }
131 
initializeVk(int functor,void * data,const uirenderer::VkFunctorInitParams & init_vk_params)132 void initializeVk(int functor, void* data,
133                   const uirenderer::VkFunctorInitParams& init_vk_params) {
134   SupportData* support = static_cast<SupportData*>(data);
135   VkPhysicalDeviceFeatures2 device_features_2;
136   if (init_vk_params.device_features_2)
137     device_features_2 = *init_vk_params.device_features_2;
138 
139   AwDrawFn_InitVkParams params{
140       .version = kAwDrawFnVersion,
141       .instance = init_vk_params.instance,
142       .physical_device = init_vk_params.physical_device,
143       .device = init_vk_params.device,
144       .queue = init_vk_params.queue,
145       .graphics_queue_index = init_vk_params.graphics_queue_index,
146       .api_version = init_vk_params.api_version,
147       .enabled_instance_extension_names =
148           init_vk_params.enabled_instance_extension_names,
149       .enabled_instance_extension_names_length =
150           init_vk_params.enabled_instance_extension_names_length,
151       .enabled_device_extension_names =
152           init_vk_params.enabled_device_extension_names,
153       .enabled_device_extension_names_length =
154           init_vk_params.enabled_device_extension_names_length,
155       .device_features = nullptr,
156       .device_features_2 =
157           init_vk_params.device_features_2 ? &device_features_2 : nullptr,
158   };
159   support->callbacks.init_vk(functor, support->data, &params);
160 }
161 
drawVk(int functor,void * data,const uirenderer::VkFunctorDrawParams & draw_vk_params,const uirenderer::WebViewOverlayData & overlay_params)162 void drawVk(int functor, void* data,
163             const uirenderer::VkFunctorDrawParams& draw_vk_params,
164             const uirenderer::WebViewOverlayData& overlay_params) {
165   SupportData* support = static_cast<SupportData*>(data);
166   float gabcdef[7];
167   if (draw_vk_params.color_space_ptr) {
168       draw_vk_params.color_space_ptr->transferFn(gabcdef);
169   } else {
170       // Assume sRGB.
171       gabcdef[0] = SkNamedTransferFn::kSRGB.g;
172       gabcdef[1] = SkNamedTransferFn::kSRGB.a;
173       gabcdef[2] = SkNamedTransferFn::kSRGB.b;
174       gabcdef[3] = SkNamedTransferFn::kSRGB.c;
175       gabcdef[4] = SkNamedTransferFn::kSRGB.d;
176       gabcdef[5] = SkNamedTransferFn::kSRGB.e;
177       gabcdef[6] = SkNamedTransferFn::kSRGB.f;
178   }
179   AwDrawFn_DrawVkParams params{
180       .version = kAwDrawFnVersion,
181       .width = draw_vk_params.width,
182       .height = draw_vk_params.height,
183       .deprecated_0 = false,
184       .secondary_command_buffer = draw_vk_params.secondary_command_buffer,
185       .color_attachment_index = draw_vk_params.color_attachment_index,
186       .compatible_render_pass = draw_vk_params.compatible_render_pass,
187       .format = draw_vk_params.format,
188       .transfer_function_g = gabcdef[0],
189       .transfer_function_a = gabcdef[1],
190       .transfer_function_b = gabcdef[2],
191       .transfer_function_c = gabcdef[3],
192       .transfer_function_d = gabcdef[4],
193       .transfer_function_e = gabcdef[5],
194       .transfer_function_f = gabcdef[6],
195       .clip_left = draw_vk_params.clip_left,
196       .clip_top = draw_vk_params.clip_top,
197       .clip_right = draw_vk_params.clip_right,
198       .clip_bottom = draw_vk_params.clip_bottom,
199       .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
200       .get_surface_control = overlay_params.getSurfaceControl,
201       .merge_transaction = overlay_params.mergeTransaction
202   };
203   COMPILE_ASSERT(sizeof(params.color_space_toXYZD50) == sizeof(skcms_Matrix3x3),
204                  gamut_transform_size_mismatch);
205   if (draw_vk_params.color_space_ptr) {
206       draw_vk_params.color_space_ptr->toXYZD50(
207               reinterpret_cast<skcms_Matrix3x3*>(&params.color_space_toXYZD50));
208   } else {
209       // Assume sRGB.
210       memcpy(&params.color_space_toXYZD50, &SkNamedGamut::kSRGB,
211              sizeof(params.color_space_toXYZD50));
212   }
213   COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_vk_params.transform),
214                  mismatched_transform_matrix_sizes);
215   for (int i = 0; i < NELEM(params.transform); ++i) {
216     params.transform[i] = draw_vk_params.transform[i];
217   }
218   support->callbacks.draw_vk(functor, support->data, &params);
219 }
220 
postDrawVk(int functor,void * data)221 void postDrawVk(int functor, void* data) {
222   SupportData* support = static_cast<SupportData*>(data);
223   AwDrawFn_PostDrawVkParams params{.version = kAwDrawFnVersion};
224   support->callbacks.post_draw_vk(functor, support->data, &params);
225 }
226 
CreateFunctor_v3(void * data,int version,AwDrawFnFunctorCallbacks * functor_callbacks)227 int CreateFunctor_v3(void* data, int version,
228                      AwDrawFnFunctorCallbacks* functor_callbacks) {
229     static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = [] {
230         uirenderer::WebViewFunctorCallbacks ret = {
231                 .onSync = &onSync,
232                 .onContextDestroyed = &onContextDestroyed,
233                 .onDestroyed = &onDestroyed,
234                 .removeOverlays = &removeOverlays,
235         };
236         switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
237             case uirenderer::RenderMode::OpenGL_ES:
238                 ret.gles.draw = &draw_gl;
239                 break;
240             case uirenderer::RenderMode::Vulkan:
241                 ret.vk.initialize = &initializeVk;
242                 ret.vk.draw = &drawVk;
243                 ret.vk.postDraw = &postDrawVk;
244                 break;
245         }
246         return ret;
247     }();
248     SupportData* support = new SupportData{
249             .data = data,
250     };
251 
252     // These callbacks are available on all versions.
253     support->callbacks = {
254             .on_sync = functor_callbacks->on_sync,
255             .on_context_destroyed = functor_callbacks->on_context_destroyed,
256             .on_destroyed = functor_callbacks->on_destroyed,
257             .draw_gl = functor_callbacks->draw_gl,
258             .init_vk = functor_callbacks->init_vk,
259             .draw_vk = functor_callbacks->draw_vk,
260             .post_draw_vk = functor_callbacks->post_draw_vk,
261     };
262 
263     if (version >= 3) {
264         support->callbacks.remove_overlays = functor_callbacks->remove_overlays;
265     }
266 
267   int functor = uirenderer::WebViewFunctor_create(
268       support, webview_functor_callbacks,
269       uirenderer::WebViewFunctor_queryPlatformRenderMode());
270   if (functor <= 0) delete support;
271   return functor;
272 }
273 
CreateFunctor(void * data,AwDrawFnFunctorCallbacks * functor_callbacks)274 int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
275   const int kVersionForDeprecatedCreateFunctor = 2;
276   return CreateFunctor_v3(data, kVersionForDeprecatedCreateFunctor,
277                           functor_callbacks);
278 }
279 
ReleaseFunctor(int functor)280 void ReleaseFunctor(int functor) {
281   uirenderer::WebViewFunctor_release(functor);
282 }
283 
QueryRenderMode(void)284 AwDrawFnRenderMode QueryRenderMode(void) {
285   switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
286     case uirenderer::RenderMode::OpenGL_ES:
287       return AW_DRAW_FN_RENDER_MODE_OPENGL_ES;
288     case uirenderer::RenderMode::Vulkan:
289       return AW_DRAW_FN_RENDER_MODE_VULKAN;
290   }
291 }
292 
GetDrawFnFunctionTable()293 jlong GetDrawFnFunctionTable() {
294   static AwDrawFnFunctionTable function_table = {
295     .version = kAwDrawFnVersion,
296     .query_render_mode = &QueryRenderMode,
297     .create_functor = &CreateFunctor,
298     .release_functor = &ReleaseFunctor,
299     .create_functor_v3 = &CreateFunctor_v3,
300   };
301   return reinterpret_cast<intptr_t>(&function_table);
302 }
303 
304 const char kClassName[] = "com/android/webview/chromium/DrawFunctor";
305 const JNINativeMethod kJniMethods[] = {
306     {"nativeGetFunctionTable", "()J",
307      reinterpret_cast<void*>(GetDrawFnFunctionTable)},
308 };
309 
310 }  // namespace
311 
RegisterDrawFunctor(JNIEnv * env)312 void RegisterDrawFunctor(JNIEnv* env) {
313   jclass clazz = env->FindClass(kClassName);
314   LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
315 
316   int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
317   LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
318 }
319 
320 }  // namespace android
321