From d6668e7c0c59c0cf91bfb4d0491c526cd1d5e439 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Fri, 14 Dec 2018 19:37:41 -0800 Subject: [PATCH] Plumb new functor in native/webview Add plumbing to native/webview for the new functor. Add a void* data parameter to avoid having to use a thread safe map for in both the plumbing and in webview. Test: Compiles and webview runs Bug: 120997728 Change-Id: I0f9f3acb05688a5afcf95974bc0b3b117f33a8e3 --- api/system-current.txt | 1 + core/java/android/webkit/WebViewDelegate.java | 14 ++ libs/hwui/WebViewFunctorManager.cpp | 23 +-- libs/hwui/WebViewFunctorManager.h | 5 +- libs/hwui/private/hwui/WebViewFunctor.h | 15 +- libs/hwui/tests/common/TestUtils.h | 8 +- libs/hwui/tests/unit/SkiaDisplayListTests.cpp | 4 +- .../tests/unit/WebViewFunctorManagerTests.cpp | 18 +-- native/webview/plat_support/Android.bp | 1 + native/webview/plat_support/draw_fn.h | 18 +-- native/webview/plat_support/draw_functor.cpp | 144 ++++++++++++++++++ .../webview/plat_support/jni_entry_point.cpp | 2 + 12 files changed, 210 insertions(+), 43 deletions(-) create mode 100644 native/webview/plat_support/draw_functor.cpp diff --git a/api/system-current.txt b/api/system-current.txt index 751ef34f0ae19..35d0f17696bf3 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -7760,6 +7760,7 @@ package android.webkit { method public void callDrawGlFunction(android.graphics.Canvas, long, java.lang.Runnable); method public boolean canInvokeDrawGlFunctor(android.view.View); method public void detachDrawGlFunctor(android.view.View, long); + method public void drawWebViewFunctor(android.graphics.Canvas, int); method public android.app.Application getApplication(); method public java.lang.String getDataDirectorySuffix(); method public java.lang.String getErrorString(android.content.Context, int); diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index 6ab7f66aedd34..ef69b6333cce0 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -137,6 +137,20 @@ public final class WebViewDelegate { ((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable); } + /** + * Call webview draw functor. See API in draw_fn.h. + * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}). + * @param functor created by AwDrawFn_CreateFunctor in draw_fn.h. + */ + public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) { + if (!(canvas instanceof RecordingCanvas)) { + // Canvas#isHardwareAccelerated() is only true for subclasses of RecordingCanvas. + throw new IllegalArgumentException(canvas.getClass().getName() + + " is not a RecordingCanvas canvas"); + } + ((RecordingCanvas) canvas).drawWebViewFunctor(functor); + } + /** * Detaches the draw GL functor. * diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index 20e77b4537066..5b7ae70e821ce 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -37,7 +37,8 @@ RenderMode WebViewFunctor_queryPlatformRenderMode() { } } -int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode) { +int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype, + RenderMode functorMode) { if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) { ALOGW("Unknown rendermode %d", (int)functorMode); return -1; @@ -47,7 +48,7 @@ int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode f ALOGW("Unable to map from GLES platform to a vulkan functor"); return -1; } - return WebViewFunctorManager::instance().createFunctor(prototype, functorMode); + return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode); } void WebViewFunctor_release(int functor) { @@ -56,7 +57,9 @@ void WebViewFunctor_release(int functor) { static std::atomic_int sNextId{1}; -WebViewFunctor::WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { +WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks, + RenderMode functorMode) + : mData(data) { mFunctor = sNextId++; mCallbacks = callbacks; mMode = functorMode; @@ -66,12 +69,12 @@ WebViewFunctor::~WebViewFunctor() { destroyContext(); ATRACE_NAME("WebViewFunctor::onDestroy"); - mCallbacks.onDestroyed(mFunctor); + mCallbacks.onDestroyed(mFunctor, mData); } void WebViewFunctor::sync(const WebViewSyncData& syncData) const { ATRACE_NAME("WebViewFunctor::sync"); - mCallbacks.onSync(mFunctor, syncData); + mCallbacks.onSync(mFunctor, mData, syncData); } void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { @@ -79,14 +82,14 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { if (!mHasContext) { mHasContext = true; } - mCallbacks.gles.draw(mFunctor, drawInfo); + mCallbacks.gles.draw(mFunctor, mData, drawInfo); } void WebViewFunctor::destroyContext() { if (mHasContext) { mHasContext = false; ATRACE_NAME("WebViewFunctor::onContextDestroyed"); - mCallbacks.onContextDestroyed(mFunctor); + mCallbacks.onContextDestroyed(mFunctor, mData); } } @@ -95,9 +98,9 @@ WebViewFunctorManager& WebViewFunctorManager::instance() { return sInstance; } -int WebViewFunctorManager::createFunctor(const WebViewFunctorCallbacks& callbacks, +int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { - auto object = std::make_unique(callbacks, functorMode); + auto object = std::make_unique(data, callbacks, functorMode); int id = object->id(); auto handle = object->createHandle(); { @@ -164,4 +167,4 @@ sp WebViewFunctorManager::handleFor(int functor) { return nullptr; } -} // namespace android::uirenderer \ No newline at end of file +} // namespace android::uirenderer diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h index 2a621dd411e3a..1719ce7cca758 100644 --- a/libs/hwui/WebViewFunctorManager.h +++ b/libs/hwui/WebViewFunctorManager.h @@ -29,7 +29,7 @@ class WebViewFunctorManager; class WebViewFunctor { public: - WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); + WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); ~WebViewFunctor(); class Handle : public LightRefBase { @@ -63,6 +63,7 @@ public: private: WebViewFunctorCallbacks mCallbacks; + void* const mData; int mFunctor; RenderMode mMode; bool mHasContext = false; @@ -73,7 +74,7 @@ class WebViewFunctorManager { public: static WebViewFunctorManager& instance(); - int createFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); + int createFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); void releaseFunctor(int functor); void onContextDestroyed(); void destroyFunctor(int functor); diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h index e5346aabaee31..da3d06a4d60c5 100644 --- a/libs/hwui/private/hwui/WebViewFunctor.h +++ b/libs/hwui/private/hwui/WebViewFunctor.h @@ -17,6 +17,7 @@ #ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H #define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H +#include #include namespace android::uirenderer { @@ -27,7 +28,7 @@ enum class RenderMode { }; // Static for the lifetime of the process -RenderMode WebViewFunctor_queryPlatformRenderMode(); +ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode(); struct WebViewSyncData { bool applyForceDark; @@ -35,21 +36,21 @@ struct WebViewSyncData { struct WebViewFunctorCallbacks { // kModeSync, called on RenderThread - void (*onSync)(int functor, const WebViewSyncData& syncData); + void (*onSync)(int functor, void* data, const WebViewSyncData& syncData); // Called when either the context is destroyed _or_ when the functor's last reference goes // away. Will always be called with an active context and always on renderthread. - void (*onContextDestroyed)(int functor); + void (*onContextDestroyed)(int functor, void* data); // Called when the last reference to the handle goes away and the handle is considered // irrevocably destroyed. Will always be proceeded by a call to onContextDestroyed if // this functor had ever been drawn. - void (*onDestroyed)(int functor); + void (*onDestroyed)(int functor, void* data); union { struct { // Called on RenderThread. initialize is guaranteed to happen before this call - void (*draw)(int functor, const DrawGlInfo& params); + void (*draw)(int functor, void* data, const DrawGlInfo& params); } gles; // TODO: VK support. The current DrawVkInfo is monolithic and needs to be split up for // what params are valid on what callbacks @@ -70,12 +71,12 @@ struct WebViewFunctorCallbacks { // Creates a new WebViewFunctor from the given prototype. The prototype is copied after // this function returns. Caller retains full ownership of it. // Returns -1 if the creation fails (such as an unsupported functorMode + platform mode combination) -int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode); +ANDROID_API int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype, RenderMode functorMode); // May be called on any thread to signal that the functor should be destroyed. // The functor will receive an onDestroyed when the last usage of it is released, // and it should be considered alive & active until that point. -void WebViewFunctor_release(int functor); +ANDROID_API void WebViewFunctor_release(int functor); } // namespace android::uirenderer diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 5ff8993e67798..6a1ca5a25361c 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -315,24 +315,24 @@ public: static WebViewFunctorCallbacks createMockFunctor(RenderMode mode) { auto callbacks = WebViewFunctorCallbacks{ .onSync = - [](int functor, const WebViewSyncData& data) { + [](int functor, void* client_data, const WebViewSyncData& data) { expectOnRenderThread(); sMockFunctorCounts[functor].sync++; }, .onContextDestroyed = - [](int functor) { + [](int functor, void* client_data) { expectOnRenderThread(); sMockFunctorCounts[functor].contextDestroyed++; }, .onDestroyed = - [](int functor) { + [](int functor, void* client_data) { expectOnRenderThread(); sMockFunctorCounts[functor].destroyed++; }, }; switch (mode) { case RenderMode::OpenGL_ES: - callbacks.gles.draw = [](int functor, const DrawGlInfo& params) { + callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) { expectOnRenderThread(); sMockFunctorCounts[functor].glesDraw++; }; diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp index 53bf84f13fd62..1b4cf7e144bd8 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -100,8 +100,8 @@ TEST(SkiaDisplayList, syncContexts) { GLFunctorDrawable functorDrawable(&functor, nullptr, &dummyCanvas); skiaDL.mChildFunctors.push_back(&functorDrawable); - int functor2 = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor2 = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); auto& counts = TestUtils::countsForFunctor(functor2); skiaDL.mChildFunctors.push_back( skiaDL.allocateDrawable(functor2, &dummyCanvas)); diff --git a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp index c8169aff1c5e0..e1fb8b7069ff5 100644 --- a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp +++ b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp @@ -27,8 +27,8 @@ using namespace android; using namespace android::uirenderer; TEST(WebViewFunctor, createDestroyGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); WebViewFunctor_release(functor); TestUtils::runOnRenderThreadUnmanaged([](renderthread::RenderThread&) { @@ -41,8 +41,8 @@ TEST(WebViewFunctor, createDestroyGLES) { } TEST(WebViewFunctor, createSyncHandleGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -82,8 +82,8 @@ TEST(WebViewFunctor, createSyncHandleGLES) { } TEST(WebViewFunctor, createSyncDrawGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -109,8 +109,8 @@ TEST(WebViewFunctor, createSyncDrawGLES) { } TEST(WebViewFunctor, contextDestroyed) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -151,4 +151,4 @@ TEST(WebViewFunctor, contextDestroyed) { EXPECT_EQ(2, counts.glesDraw); EXPECT_EQ(2, counts.contextDestroyed); EXPECT_EQ(1, counts.destroyed); -} \ No newline at end of file +} diff --git a/native/webview/plat_support/Android.bp b/native/webview/plat_support/Android.bp index 96c9c1c85a603..09362566d915d 100644 --- a/native/webview/plat_support/Android.bp +++ b/native/webview/plat_support/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { name: "libwebviewchromium_plat_support", srcs: [ + "draw_functor.cpp", "draw_gl_functor.cpp", "draw_vk_functor.cpp", "functor_utils.cpp", diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h index 8d48a58ac293e..6afd8837594c6 100644 --- a/native/webview/plat_support/draw_fn.h +++ b/native/webview/plat_support/draw_fn.h @@ -129,31 +129,31 @@ struct AwDrawFn_PostDrawVkParams { // Called on render thread while UI thread is blocked. Called for both GL and // VK. -typedef void AwDrawFn_OnSync(int functor, AwDrawFn_OnSyncParams* params); +typedef void AwDrawFn_OnSync(int functor, void* data, AwDrawFn_OnSyncParams* params); // Called on render thread when either the context is destroyed _or_ when the // functor's last reference goes away. Will always be called with an active // context. Called for both GL and VK. -typedef void AwDrawFn_OnContextDestroyed(int functor); +typedef void AwDrawFn_OnContextDestroyed(int functor, void* data); // Called on render thread when the last reference to the handle goes away and -// the handle is considered irrevocably destroyed. Will always be proceeded by +// the handle is considered irrevocably destroyed. Will always be preceded by // a call to OnContextDestroyed if this functor had ever been drawn. Called for // both GL and VK. -typedef void AwDrawFn_OnDestroyed(int functor); +typedef void AwDrawFn_OnDestroyed(int functor, void* data); // Only called for GL. -typedef void AwDrawFn_DrawGL(int functor, AwDrawFn_DrawGLParams* params); +typedef void AwDrawFn_DrawGL(int functor, void* data, AwDrawFn_DrawGLParams* params); // Initialize vulkan state. Needs to be called again after any // OnContextDestroyed. Only called for Vulkan. -typedef void AwDrawFn_InitVk(int functor, AwDrawFn_InitVkParams* params); +typedef void AwDrawFn_InitVk(int functor, void* data, AwDrawFn_InitVkParams* params); // Only called for Vulkan. -typedef void AwDrawFn_DrawVk(int functor, AwDrawFn_DrawVkParams* params); +typedef void AwDrawFn_DrawVk(int functor, void* data, AwDrawFn_DrawVkParams* params); // Only called for Vulkan. -typedef void AwDrawFn_PostDrawVk(int functor, +typedef void AwDrawFn_PostDrawVk(int functor, void* data, AwDrawFn_PostDrawVkParams* params); struct AwDrawFnFunctorCallbacks { @@ -176,7 +176,7 @@ enum AwDrawFnRenderMode { typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void); // Create a functor. |functor_callbacks| should be valid until OnDestroyed. -typedef int AwDrawFn_CreateFunctor(AwDrawFnFunctorCallbacks* functor_callbacks); +typedef int AwDrawFn_CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks); // May be called on any thread to signal that the functor should be destroyed. // The functor will receive an onDestroyed when the last usage of it is diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp new file mode 100644 index 0000000000000..820bac509d2e8 --- /dev/null +++ b/native/webview/plat_support/draw_functor.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "draw_fn.h" + +#include +#include +#include + +#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) +#define COMPILE_ASSERT(expr, err) \ +__unused static const char (err)[(expr) ? 1 : -1] = ""; + +namespace android { +namespace { + +struct SupportData { + void* const data; + AwDrawFnFunctorCallbacks callbacks; +}; + +void onSync(int functor, void* data, + const uirenderer::WebViewSyncData& syncData) { + AwDrawFn_OnSyncParams params = { + .version = kAwDrawFnVersion, + .apply_force_dark = syncData.applyForceDark, + }; + SupportData* support = static_cast(data); + support->callbacks.on_sync(functor, support->data, ¶ms); +} + +void onContextDestroyed(int functor, void* data) { + SupportData* support = static_cast(data); + support->callbacks.on_context_destroyed(functor, support->data); +} + +void onDestroyed(int functor, void* data) { + SupportData* support = static_cast(data); + support->callbacks.on_destroyed(functor, support->data); + delete support; +} + +void draw_gl(int functor, void* data, + const uirenderer::DrawGlInfo& draw_gl_params) { + AwDrawFn_DrawGLParams params = { + .version = kAwDrawFnVersion, + .clip_left = draw_gl_params.clipLeft, + .clip_top = draw_gl_params.clipTop, + .clip_right = draw_gl_params.clipRight, + .clip_bottom = draw_gl_params.clipBottom, + .width = draw_gl_params.width, + .height = draw_gl_params.height, + .is_layer = draw_gl_params.isLayer, + }; + COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform), + mismatched_transform_matrix_sizes); + for (int i = 0; i < NELEM(params.transform); ++i) { + params.transform[i] = draw_gl_params.transform[i]; + } + SupportData* support = static_cast(data); + support->callbacks.draw_gl(functor, support->data, ¶ms); +} + +int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { + static bool callbacks_initialized = false; + static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = { + .onSync = &onSync, + .onContextDestroyed = &onContextDestroyed, + .onDestroyed = &onDestroyed, + }; + if (!callbacks_initialized) { + switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) { + case uirenderer::RenderMode::OpenGL_ES: + webview_functor_callbacks.gles.draw = &draw_gl; + break; + case uirenderer::RenderMode::Vulkan: + break; + } + callbacks_initialized = true; + } + SupportData* support = new SupportData{ + .data = data, + .callbacks = *functor_callbacks, + }; + int functor = uirenderer::WebViewFunctor_create( + support, webview_functor_callbacks, + uirenderer::WebViewFunctor_queryPlatformRenderMode()); + if (functor <= 0) delete support; + return functor; +} + +void ReleaseFunctor(int functor) { + uirenderer::WebViewFunctor_release(functor); +} + +AwDrawFnRenderMode QueryRenderMode(void) { + switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) { + case uirenderer::RenderMode::OpenGL_ES: + return AW_DRAW_FN_RENDER_MODE_OPENGL_ES; + case uirenderer::RenderMode::Vulkan: + return AW_DRAW_FN_RENDER_MODE_VULKAN; + } +} + +jlong GetDrawFnFunctionTable() { + static AwDrawFnFunctionTable function_table = { + .version = kAwDrawFnVersion, + .query_render_mode = &QueryRenderMode, + .create_functor = &CreateFunctor, + .release_functor = &ReleaseFunctor, + }; + return reinterpret_cast(&function_table); +} + +const char kClassName[] = "com/android/webview/chromium/DrawFunctor"; +const JNINativeMethod kJniMethods[] = { + {"nativeGetFunctionTable", "()J", + reinterpret_cast(GetDrawFnFunctionTable)}, +}; + +} // namespace + +void RegisterDrawFunctor(JNIEnv* env) { + jclass clazz = env->FindClass(kClassName); + LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); + + int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); + LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); +} + +} // namespace android diff --git a/native/webview/plat_support/jni_entry_point.cpp b/native/webview/plat_support/jni_entry_point.cpp index 4771be1bc258f..9599fa6da516e 100644 --- a/native/webview/plat_support/jni_entry_point.cpp +++ b/native/webview/plat_support/jni_entry_point.cpp @@ -21,6 +21,7 @@ namespace android { +void RegisterDrawFunctor(JNIEnv* env); void RegisterDrawGLFunctor(JNIEnv* env); void RegisterGraphicsUtils(JNIEnv* env); @@ -30,6 +31,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint ret = vm->AttachCurrentThread(&env, NULL); LOG_ALWAYS_FATAL_IF(ret != JNI_OK, "AttachCurrentThread failed"); + android::RegisterDrawFunctor(env); android::RegisterDrawGLFunctor(env); android::RegisterGraphicsUtils(env);