diff options
| -rw-r--r-- | libs/hwui/WebViewFunctorManager.cpp | 63 | ||||
| -rw-r--r-- | libs/hwui/WebViewFunctorManager.h | 6 | ||||
| -rw-r--r-- | libs/hwui/private/hwui/WebViewFunctor.h | 45 | ||||
| -rw-r--r-- | libs/hwui/tests/common/TestUtils.h | 3 | ||||
| -rw-r--r-- | native/webview/plat_support/draw_fn.h | 83 | ||||
| -rw-r--r-- | native/webview/plat_support/draw_functor.cpp | 61 |
6 files changed, 249 insertions, 12 deletions
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index 68541b4b31f0..671c66f11e32 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -26,6 +26,35 @@ namespace android::uirenderer { +namespace { +class ScopedCurrentFunctor { +public: + ScopedCurrentFunctor(WebViewFunctor* functor) { + ALOG_ASSERT(!sCurrentFunctor); + ALOG_ASSERT(functor); + sCurrentFunctor = functor; + } + ~ScopedCurrentFunctor() { + ALOG_ASSERT(sCurrentFunctor); + sCurrentFunctor = nullptr; + } + + static ASurfaceControl* getSurfaceControl() { + ALOG_ASSERT(sCurrentFunctor); + return sCurrentFunctor->getSurfaceControl(); + } + static void mergeTransaction(ASurfaceTransaction* transaction) { + ALOG_ASSERT(sCurrentFunctor); + sCurrentFunctor->mergeTransaction(transaction); + } + +private: + static WebViewFunctor* sCurrentFunctor; +}; + +WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr; +} // namespace + RenderMode WebViewFunctor_queryPlatformRenderMode() { auto pipelineType = Properties::getRenderPipelineType(); switch (pipelineType) { @@ -83,7 +112,15 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { if (!mHasContext) { mHasContext = true; } - mCallbacks.gles.draw(mFunctor, mData, drawInfo); + ScopedCurrentFunctor currentFunctor(this); + + WebViewOverlayData overlayParams = { + // TODO: + .overlaysMode = OverlaysMode::Disabled, + .getSurfaceControl = currentFunctor.getSurfaceControl, + .mergeTransaction = currentFunctor.mergeTransaction, + }; + mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams); } void WebViewFunctor::initVk(const VkFunctorInitParams& params) { @@ -98,7 +135,15 @@ void WebViewFunctor::initVk(const VkFunctorInitParams& params) { void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) { ATRACE_NAME("WebViewFunctor::drawVk"); - mCallbacks.vk.draw(mFunctor, mData, params); + ScopedCurrentFunctor currentFunctor(this); + + WebViewOverlayData overlayParams = { + // TODO + .overlaysMode = OverlaysMode::Disabled, + .getSurfaceControl = currentFunctor.getSurfaceControl, + .mergeTransaction = currentFunctor.mergeTransaction, + }; + mCallbacks.vk.draw(mFunctor, mData, params, overlayParams); } void WebViewFunctor::postDrawVk() { @@ -118,6 +163,20 @@ void WebViewFunctor::destroyContext() { } } +void WebViewFunctor::removeOverlays() { + ScopedCurrentFunctor currentFunctor(this); + mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction); +} + +ASurfaceControl* WebViewFunctor::getSurfaceControl() { + // TODO + return nullptr; +} + +void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) { + // TODO +} + WebViewFunctorManager& WebViewFunctorManager::instance() { static WebViewFunctorManager sInstance; return sInstance; diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h index 675b738c6406..737d60525aa9 100644 --- a/libs/hwui/WebViewFunctorManager.h +++ b/libs/hwui/WebViewFunctorManager.h @@ -56,6 +56,8 @@ public: void postDrawVk() { mReference.postDrawVk(); } + void removeOverlays() { mReference.removeOverlays(); } + private: friend class WebViewFunctor; @@ -71,6 +73,10 @@ public: void drawVk(const VkFunctorDrawParams& params); void postDrawVk(); void destroyContext(); + void removeOverlays(); + + ASurfaceControl* getSurfaceControl(); + void mergeTransaction(ASurfaceTransaction* transaction); sp<Handle> createHandle() { LOG_ALWAYS_FATAL_IF(mCreatedHandle); diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h index 96da947ace08..22ae59e5137b 100644 --- a/libs/hwui/private/hwui/WebViewFunctor.h +++ b/libs/hwui/private/hwui/WebViewFunctor.h @@ -17,6 +17,15 @@ #ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H #define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H +#ifdef __ANDROID__ // Layoutlib does not support surface control +#include <android/surface_control.h> +#else +// To avoid ifdefs around overlay implementation all over the place we typedef these to void *. They +// won't be used. +typedef void* ASurfaceControl; +typedef void* ASurfaceTransaction; +#endif + #include <cutils/compiler.h> #include <private/hwui/DrawGlInfo.h> #include <private/hwui/DrawVkInfo.h> @@ -28,6 +37,14 @@ enum class RenderMode { Vulkan, }; +enum class OverlaysMode { + // Indicated that webview should not promote anything to overlays this draw + // and remove all visible overlays. + Disabled, + // Indicates that webview can use overlays. + Enabled +}; + // Static for the lifetime of the process ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode(); @@ -35,6 +52,23 @@ struct WebViewSyncData { bool applyForceDark; }; +struct WebViewOverlayData { + // Desired overlay mode for this draw. + OverlaysMode overlaysMode; + + // Returns parent ASurfaceControl for WebView overlays. It will be have same + // geometry as the surface we draw into and positioned below it (underlay). + // This does not pass ownership to webview, but guaranteed to be alive until + // transaction from next removeOverlays call or functor destruction will be + // finished. + ASurfaceControl* (*getSurfaceControl)(); + + // Merges WebView transaction to be applied synchronously with current draw. + // This doesn't pass ownership of the transaction, changes will be copied and + // webview can free transaction right after the call. + void (*mergeTransaction)(ASurfaceTransaction*); +}; + struct WebViewFunctorCallbacks { // kModeSync, called on RenderThread void (*onSync)(int functor, void* data, const WebViewSyncData& syncData); @@ -48,16 +82,23 @@ struct WebViewFunctorCallbacks { // this functor had ever been drawn. void (*onDestroyed)(int functor, void* data); + // Called on render thread to force webview hide all overlays and stop updating them. + // Should happen during hwui draw (e.g can be called instead of draw if webview + // isn't visible and won't receive draw) and support MergeTransaction call. + void (*removeOverlays)(int functor, void* data, void (*mergeTransaction)(ASurfaceTransaction*)); + union { struct { // Called on RenderThread. initialize is guaranteed to happen before this call - void (*draw)(int functor, void* data, const DrawGlInfo& params); + void (*draw)(int functor, void* data, const DrawGlInfo& params, + const WebViewOverlayData& overlayParams); } gles; struct { // Called either the first time the functor is used or the first time it's used after // a call to onContextDestroyed. void (*initialize)(int functor, void* data, const VkFunctorInitParams& params); - void (*draw)(int functor, void* data, const VkFunctorDrawParams& params); + void (*draw)(int functor, void* data, const VkFunctorDrawParams& params, + const WebViewOverlayData& overlayParams); void (*postDraw)(int functor, void*); } vk; }; diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 36c5a8c1b3de..c1d8b761514b 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -323,7 +323,8 @@ public: }; switch (mode) { case RenderMode::OpenGL_ES: - callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) { + callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params, + const WebViewOverlayData& overlay_params) { expectOnRenderThread("draw"); sMockFunctorCounts[functor].glesDraw++; }; diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h index 42cad43af8fc..44fe56fcaf4b 100644 --- a/native/webview/plat_support/draw_fn.h +++ b/native/webview/plat_support/draw_fn.h @@ -10,6 +10,7 @@ #ifndef ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_ #define ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_ +#include <android/surface_control.h> #include <vulkan/vulkan.h> #ifdef __cplusplus @@ -21,7 +22,31 @@ extern "C" { // // 1 is Android Q. This matches kAwDrawGLInfoVersion version 3. // 2 Adds transfer_function_* and color_space_toXYZD50 to AwDrawFn_DrawGLParams. -static const int kAwDrawFnVersion = 2; +// 3 Adds SurfaceControl related functions. +static const int kAwDrawFnVersion = 3; + +// Returns parent ASurfaceControl for WebView overlays. It will be have same +// geometry as the surface we draw into and positioned below it (underlay). +// This does not pass ownership to webview, but guaranteed to be alive until +// transaction from next removeOverlays call or functor destruction will be +// finished. +typedef ASurfaceControl* AwDrawFn_GetSurfaceControl(); + +// Merges WebView transaction to be applied synchronously with current draw. +// This doesn't pass ownership of the transaction, changes will be copied and +// webview can free transaction right after the call. +typedef void AwDrawFn_MergeTransaction(ASurfaceTransaction* transaction); + +enum AwDrawFnOverlaysMode { + // Indicated that webview should not promote anything to overlays this draw + // and remove all visible overlays. + // Added in version 3. + AW_DRAW_FN_OVERLAYS_MODE_DISABLED = 0, + + // Indicates that webview can use overlays. + // Added in version 3. + AW_DRAW_FN_OVERLAYS_MODE_ENABLED = 1, +}; struct AwDrawFn_OnSyncParams { int version; @@ -60,6 +85,19 @@ struct AwDrawFn_DrawGLParams { float transfer_function_e; float transfer_function_f; float color_space_toXYZD50[9]; + + // Input: Indicates how webview should use overlays for this draw. + // Added in version 3. + AwDrawFnOverlaysMode overlays_mode; + + // Input: WebView can call it to obtain parent surface control for overlays. + // Added in version 3. + AwDrawFn_GetSurfaceControl* get_surface_control; + + // Input: WebView call this to apply ASurfaceTransaction synchronously with + // the draw. + // Added in version 3. + AwDrawFn_MergeTransaction* merge_transaction; }; struct AwDrawFn_InitVkParams { @@ -122,12 +160,33 @@ struct AwDrawFn_DrawVkParams { int clip_top; int clip_right; int clip_bottom; + + // Input: Indicates how webview should use overlays for this draw. + // Added in version 3. + AwDrawFnOverlaysMode overlays_mode; + + // Input: WebView can call it to obtain parent surface control for overlays. + // Added in version 3. + AwDrawFn_GetSurfaceControl* get_surface_control; + + // Input: WebView call this to apply ASurfaceTransaction synchronously with + // the draw. + // Added in version 3. + AwDrawFn_MergeTransaction* merge_transaction; }; struct AwDrawFn_PostDrawVkParams { int version; }; +struct AwDrawFn_RemoveOverlaysParams { + int version; + // Input: WebView call this to apply ASurfaceTransaction synchronously with + // the draw. + // Added in version 3. + AwDrawFn_MergeTransaction* merge_transaction; +}; + // Called on render thread while UI thread is blocked. Called for both GL and // VK. typedef void AwDrawFn_OnSync(int functor, @@ -166,8 +225,15 @@ typedef void AwDrawFn_PostDrawVk(int functor, void* data, AwDrawFn_PostDrawVkParams* params); +// Can be called to make webview hide all overlays and stop updating them until +// next draw. WebView must obtain new ASurfaceControl after this call to use as +// parent for the overlays on next draw. +typedef void AwDrawFn_RemoveOverlays(int functor, + void* data, + AwDrawFn_RemoveOverlaysParams* params); + struct AwDrawFnFunctorCallbacks { - // No version here since this is passed from chromium to android. + // version is passed in CreateFunctor call. AwDrawFn_OnSync* on_sync; AwDrawFn_OnContextDestroyed* on_context_destroyed; AwDrawFn_OnDestroyed* on_destroyed; @@ -175,6 +241,8 @@ struct AwDrawFnFunctorCallbacks { AwDrawFn_InitVk* init_vk; AwDrawFn_DrawVk* draw_vk; AwDrawFn_PostDrawVk* post_draw_vk; + // Added in version 3. + AwDrawFn_RemoveOverlays* remove_overlays; }; enum AwDrawFnRenderMode { @@ -185,10 +253,16 @@ enum AwDrawFnRenderMode { // Get the render mode. Result is static for the process. typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void); -// Create a functor. |functor_callbacks| should be valid until OnDestroyed. +// This available up to version 3, use the one below. typedef int AwDrawFn_CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks); +// Create a functor. |functor_callbacks| should be valid until OnDestroyed. +typedef int AwDrawFn_CreateFunctor_v3( + void* data, + int version, + 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 // released, and it should be considered alive & active until that point. @@ -197,8 +271,11 @@ typedef void AwDrawFn_ReleaseFunctor(int functor); struct AwDrawFnFunctionTable { int version; AwDrawFn_QueryRenderMode* query_render_mode; + // Available up to version 3. AwDrawFn_CreateFunctor* create_functor; AwDrawFn_ReleaseFunctor* release_functor; + // Added in version 3. + AwDrawFn_CreateFunctor_v3* create_functor_v3; }; #ifdef __cplusplus diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp index 7cce61b87d12..ea57ea070369 100644 --- a/native/webview/plat_support/draw_functor.cpp +++ b/native/webview/plat_support/draw_functor.cpp @@ -32,6 +32,15 @@ struct SupportData { AwDrawFnFunctorCallbacks callbacks; }; +AwDrawFnOverlaysMode GetOverlaysMode(uirenderer::OverlaysMode overlays_mode) { + switch (overlays_mode) { + case uirenderer::OverlaysMode::Disabled: + return AW_DRAW_FN_OVERLAYS_MODE_DISABLED; + case uirenderer::OverlaysMode::Enabled: + return AW_DRAW_FN_OVERLAYS_MODE_ENABLED; + } +} + void onSync(int functor, void* data, const uirenderer::WebViewSyncData& syncData) { AwDrawFn_OnSyncParams params = { @@ -53,8 +62,20 @@ void onDestroyed(int functor, void* data) { delete support; } +void removeOverlays(int functor, void* data, + AwDrawFn_MergeTransaction merge_transaction) { + AwDrawFn_RemoveOverlaysParams params = { + .version = kAwDrawFnVersion, + .merge_transaction = merge_transaction + }; + SupportData* support = static_cast<SupportData*>(data); + if (support->callbacks.remove_overlays) + support->callbacks.remove_overlays(functor, support->data, ¶ms); +} + void draw_gl(int functor, void* data, - const uirenderer::DrawGlInfo& draw_gl_params) { + const uirenderer::DrawGlInfo& draw_gl_params, + const uirenderer::WebViewOverlayData& overlay_params) { float gabcdef[7]; draw_gl_params.color_space_ptr->transferFn(gabcdef); AwDrawFn_DrawGLParams params = { @@ -73,6 +94,9 @@ void draw_gl(int functor, void* data, .transfer_function_d = gabcdef[4], .transfer_function_e = gabcdef[5], .transfer_function_f = gabcdef[6], + .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode), + .get_surface_control = overlay_params.getSurfaceControl, + .merge_transaction = overlay_params.mergeTransaction }; COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform), mismatched_transform_matrix_sizes); @@ -118,7 +142,9 @@ void initializeVk(int functor, void* data, support->callbacks.init_vk(functor, support->data, ¶ms); } -void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw_vk_params) { +void drawVk(int functor, void* data, + const uirenderer::VkFunctorDrawParams& draw_vk_params, + const uirenderer::WebViewOverlayData& overlay_params) { SupportData* support = static_cast<SupportData*>(data); float gabcdef[7]; draw_vk_params.color_space_ptr->transferFn(gabcdef); @@ -142,6 +168,9 @@ void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw .clip_top = draw_vk_params.clip_top, .clip_right = draw_vk_params.clip_right, .clip_bottom = draw_vk_params.clip_bottom, + .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode), + .get_surface_control = overlay_params.getSurfaceControl, + .merge_transaction = overlay_params.mergeTransaction }; COMPILE_ASSERT(sizeof(params.color_space_toXYZD50) == sizeof(skcms_Matrix3x3), gamut_transform_size_mismatch); @@ -161,12 +190,14 @@ void postDrawVk(int functor, void* data) { support->callbacks.post_draw_vk(functor, support->data, ¶ms); } -int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { +int CreateFunctor_v3(void* data, int version, + AwDrawFnFunctorCallbacks* functor_callbacks) { static bool callbacks_initialized = false; static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = { .onSync = &onSync, .onContextDestroyed = &onContextDestroyed, .onDestroyed = &onDestroyed, + .removeOverlays = &removeOverlays, }; if (!callbacks_initialized) { switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) { @@ -183,8 +214,23 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { } SupportData* support = new SupportData{ .data = data, - .callbacks = *functor_callbacks, }; + + // These callbacks are available on all versions. + support->callbacks = { + .on_sync = functor_callbacks->on_sync, + .on_context_destroyed = functor_callbacks->on_context_destroyed, + .on_destroyed = functor_callbacks->on_destroyed, + .draw_gl = functor_callbacks->draw_gl, + .init_vk = functor_callbacks->init_vk, + .draw_vk = functor_callbacks->draw_vk, + .post_draw_vk = functor_callbacks->post_draw_vk, + }; + + if (version >= 3) { + support->callbacks.remove_overlays = functor_callbacks->remove_overlays; + } + int functor = uirenderer::WebViewFunctor_create( support, webview_functor_callbacks, uirenderer::WebViewFunctor_queryPlatformRenderMode()); @@ -192,6 +238,12 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { return functor; } +int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { + const int kVersionForDeprecatedCreateFunctor = 2; + return CreateFunctor_v3(data, kVersionForDeprecatedCreateFunctor, + functor_callbacks); +} + void ReleaseFunctor(int functor) { uirenderer::WebViewFunctor_release(functor); } @@ -211,6 +263,7 @@ jlong GetDrawFnFunctionTable() { .query_render_mode = &QueryRenderMode, .create_functor = &CreateFunctor, .release_functor = &ReleaseFunctor, + .create_functor_v3 = &CreateFunctor_v3, }; return reinterpret_cast<intptr_t>(&function_table); } |