Set custom Skia GrContextOptions for WebView on Android TV
This creates a new embedder delegate that allows the embedder to modify the GrContextOptions passed to skia. Behind a flag that is disabled by default, this CL disables mip map sharpening and sets MSAA sample count to 0. Bug: 364872963 Change-Id: Ifec3c530d0a9bf837b313b01ed7c41094446e483 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5982515 Reviewed-by: Peter Beverloo <peter@chromium.org> Reviewed-by: Alexander Timin <altimin@chromium.org> Commit-Queue: Alex Mitra <alexmitra@chromium.org> Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org> Cr-Commit-Position: refs/heads/main@{#1389835}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
43ac25ca0d
commit
c246bcc072
android_webview
components/viz/service
content
gpu
command_buffer
ipc
@ -6,6 +6,7 @@ include_rules = [
|
||||
"+android_webview/common/aw_features.h",
|
||||
"+android_webview/common/aw_switches.h",
|
||||
"+android_webview/common/crash_reporter/crash_keys.h",
|
||||
"+android_webview/common/gfx",
|
||||
"+android_webview/public/browser",
|
||||
"+components/viz/service/gl",
|
||||
"+components/viz/service/main",
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "android_webview/common/gfx/aw_gr_context_options_provider.h"
|
||||
#include "android_webview/public/browser/draw_fn.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/functional/bind.h"
|
||||
@ -20,6 +21,7 @@
|
||||
#include "gpu/vulkan/vulkan_fence_helper.h"
|
||||
#include "gpu/vulkan/vulkan_function_pointers.h"
|
||||
#include "gpu/vulkan/vulkan_util.h"
|
||||
#include "third_party/skia/include/gpu/ganesh/GrContextOptions.h"
|
||||
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
|
||||
#include "third_party/skia/include/gpu/ganesh/vk/GrVkDirectContext.h"
|
||||
#include "third_party/skia/include/gpu/vk/VulkanBackendContext.h"
|
||||
@ -156,7 +158,11 @@ bool AwVulkanContextProvider::Globals::Initialize(
|
||||
gpu::CreateSkiaVulkanMemoryAllocator(device_queue.get()),
|
||||
.fGetProc = get_proc,
|
||||
};
|
||||
gr_context = GrDirectContexts::MakeVulkan(backend_context);
|
||||
GrContextOptions options;
|
||||
std::unique_ptr<AwGrContextOptionsProvider> options_provider =
|
||||
std::make_unique<AwGrContextOptionsProvider>();
|
||||
options_provider->SetCustomGrContextOptions(options);
|
||||
gr_context = GrDirectContexts::MakeVulkan(backend_context, options);
|
||||
if (!gr_context) {
|
||||
LOG(ERROR) << "Unable to initialize GrContext.";
|
||||
return false;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "android_webview/browser/gfx/gpu_service_webview.h"
|
||||
#include "android_webview/browser/gfx/skia_output_surface_dependency_webview.h"
|
||||
#include "android_webview/browser/gfx/task_queue_webview.h"
|
||||
#include "android_webview/common/aw_features.h"
|
||||
#include "android_webview/common/crash_reporter/crash_keys.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
@ -103,7 +104,9 @@ void OnContextLost(std::unique_ptr<bool> expect_loss,
|
||||
|
||||
OutputSurfaceProviderWebView::OutputSurfaceProviderWebView(
|
||||
AwVulkanContextProvider* vulkan_context_provider)
|
||||
: vulkan_context_provider_(vulkan_context_provider) {
|
||||
: vulkan_context_provider_(vulkan_context_provider),
|
||||
aw_gr_context_options_provider_(
|
||||
std::make_unique<AwGrContextOptionsProvider>()) {
|
||||
// Should be kept in sync with compositor_impl_android.cc.
|
||||
renderer_settings_.allow_antialiasing = false;
|
||||
renderer_settings_.highp_threshold_min = 2048;
|
||||
@ -111,7 +114,7 @@ OutputSurfaceProviderWebView::OutputSurfaceProviderWebView(
|
||||
// Webview does not own the surface so should not clear it.
|
||||
renderer_settings_.should_clear_root_render_pass = false;
|
||||
|
||||
enable_vulkan_ = features::IsUsingVulkan();
|
||||
enable_vulkan_ = ::features::IsUsingVulkan();
|
||||
DCHECK(!enable_vulkan_ || vulkan_context_provider_);
|
||||
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
@ -212,10 +215,15 @@ void OutputSurfaceProviderWebView::InitializeContext() {
|
||||
expect_context_loss_ = expect_context_loss_ptr.get();
|
||||
shared_context_state_ = base::MakeRefCounted<gpu::SharedContextState>(
|
||||
share_group, std::move(gl_surface_for_scs), std::move(gl_context),
|
||||
false /* use_virtualized_gl_contexts */,
|
||||
/*use_virtualized_gl_contexts=*/false,
|
||||
base::BindOnce(&OnContextLost, std::move(expect_context_loss_ptr)),
|
||||
GpuServiceWebView::GetInstance()->gpu_preferences().gr_context_type,
|
||||
vulkan_context_provider_);
|
||||
vulkan_context_provider_, /*metal_context_provider=*/nullptr,
|
||||
/*dawn_context_provider=*/nullptr, /*peak_memory_monitor=*/nullptr,
|
||||
/*created_on_compositor_gpu_thread=*/false,
|
||||
base::FeatureList::IsEnabled(features::kWebViewDisableSharpeningAndMSAA)
|
||||
? aw_gr_context_options_provider_.get()
|
||||
: nullptr);
|
||||
if (!enable_vulkan_) {
|
||||
auto feature_info = base::MakeRefCounted<gpu::gles2::FeatureInfo>(
|
||||
workarounds, GpuServiceWebView::GetInstance()->gpu_feature_info());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "android_webview/browser/gfx/aw_gl_surface.h"
|
||||
#include "android_webview/common/gfx/aw_gr_context_options_provider.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "components/viz/common/display/renderer_settings.h"
|
||||
@ -57,6 +58,8 @@ class OutputSurfaceProviderWebView {
|
||||
void InitializeContext();
|
||||
|
||||
const raw_ptr<AwVulkanContextProvider> vulkan_context_provider_;
|
||||
const std::unique_ptr<AwGrContextOptionsProvider>
|
||||
aw_gr_context_options_provider_;
|
||||
// The member variables are effectively const after constructor, so it's safe
|
||||
// to call accessors on different threads.
|
||||
viz::RendererSettings renderer_settings_;
|
||||
|
@ -27,6 +27,8 @@ source_set("common") {
|
||||
"crash_reporter/crash_keys.cc",
|
||||
"crash_reporter/crash_keys.h",
|
||||
"devtools_instrumentation.h",
|
||||
"gfx/aw_gr_context_options_provider.cc",
|
||||
"gfx/aw_gr_context_options_provider.h",
|
||||
"url_constants.cc",
|
||||
"url_constants.h",
|
||||
]
|
||||
@ -44,6 +46,7 @@ source_set("common") {
|
||||
"//components/version_info:generate_version_info",
|
||||
"//components/version_info/android:channel_getter",
|
||||
"//content/public/common",
|
||||
"//gpu/command_buffer/service:gles2",
|
||||
"//gpu/config",
|
||||
"//ipc",
|
||||
"//mojo/public/cpp/bindings",
|
||||
|
@ -29,6 +29,13 @@ BASE_FEATURE(kWebViewDigitalAssetLinksLoadIncludes,
|
||||
"WebViewDigitalAssetLinksLoadIncludes",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
// Disables MSAA and default sharpening when rendering scaled elements. This is
|
||||
// often preferable when rendering images/video but can have adverse effects for
|
||||
// text on some displays.
|
||||
BASE_FEATURE(kWebViewDisableSharpeningAndMSAA,
|
||||
"WebViewDisableSharpeningAndMSAA",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
// Allows JS DataTransfer Files from content URIs in drag-drop.
|
||||
BASE_FEATURE(kWebViewDragDropFiles,
|
||||
"WebViewDragDropFiles",
|
||||
|
@ -18,6 +18,7 @@ namespace android_webview::features {
|
||||
BASE_DECLARE_FEATURE(kWebViewAutoSAA);
|
||||
BASE_DECLARE_FEATURE(kWebViewBackForwardCache);
|
||||
BASE_DECLARE_FEATURE(kWebViewDigitalAssetLinksLoadIncludes);
|
||||
BASE_DECLARE_FEATURE(kWebViewDisableSharpeningAndMSAA);
|
||||
BASE_DECLARE_FEATURE(kWebViewDragDropFiles);
|
||||
BASE_DECLARE_FEATURE(kWebViewExtraHeadersSameOriginOnly);
|
||||
BASE_DECLARE_FEATURE(kWebViewFileSystemAccess);
|
||||
|
21
android_webview/common/gfx/aw_gr_context_options_provider.cc
Normal file
21
android_webview/common/gfx/aw_gr_context_options_provider.cc
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "android_webview/common/gfx/aw_gr_context_options_provider.h"
|
||||
|
||||
#include "android_webview/common/aw_features.h"
|
||||
|
||||
namespace android_webview {
|
||||
|
||||
void AwGrContextOptionsProvider::SetCustomGrContextOptions(
|
||||
GrContextOptions& options) const {
|
||||
if (base::FeatureList::IsEnabled(
|
||||
features::kWebViewDisableSharpeningAndMSAA)) {
|
||||
// crbug.com/364872963
|
||||
options.fInternalMultisampleCount = 0;
|
||||
options.fSharpenMipmappedTextures = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android_webview
|
25
android_webview/common/gfx/aw_gr_context_options_provider.h
Normal file
25
android_webview/common/gfx/aw_gr_context_options_provider.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ANDROID_WEBVIEW_COMMON_GFX_AW_GR_CONTEXT_OPTIONS_PROVIDER_H_
|
||||
#define ANDROID_WEBVIEW_COMMON_GFX_AW_GR_CONTEXT_OPTIONS_PROVIDER_H_
|
||||
|
||||
#include "gpu/command_buffer/service/shared_context_state.h"
|
||||
|
||||
namespace android_webview {
|
||||
|
||||
// Used by gfx to set custom GrContextOptions which get passed to skia. These
|
||||
// options control how content is rendered on screen.
|
||||
class AwGrContextOptionsProvider
|
||||
: public gpu::SharedContextState::GrContextOptionsProvider {
|
||||
public:
|
||||
AwGrContextOptionsProvider() = default;
|
||||
virtual ~AwGrContextOptionsProvider() = default;
|
||||
|
||||
void SetCustomGrContextOptions(GrContextOptions& options) const override;
|
||||
};
|
||||
|
||||
} // namespace android_webview
|
||||
|
||||
#endif // ANDROID_WEBVIEW_COMMON_GFX_AW_GR_CONTEXT_OPTIONS_PROVIDER_H_
|
@ -9,6 +9,7 @@ source_set("gpu") {
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//android_webview/common:common",
|
||||
"//base",
|
||||
"//content/public/gpu",
|
||||
]
|
||||
|
@ -12,12 +12,14 @@ AwContentGpuClient::AwContentGpuClient(
|
||||
GetSyncPointManagerCallback sync_point_manager_callback,
|
||||
GetSharedImageManagerCallback shared_image_manager_callback,
|
||||
GetSchedulerCallback scheduler_callback,
|
||||
GetVizCompositorThreadRunnerCallback viz_compositor_thread_runner_callback)
|
||||
GetVizCompositorThreadRunnerCallback viz_compositor_thread_runner_callback,
|
||||
const AwGrContextOptionsProvider* gr_context_options_provider)
|
||||
: sync_point_manager_callback_(std::move(sync_point_manager_callback)),
|
||||
shared_image_manager_callback_(std::move(shared_image_manager_callback)),
|
||||
scheduler_callback_(std::move(scheduler_callback)),
|
||||
viz_compositor_thread_runner_callback_(
|
||||
std::move(viz_compositor_thread_runner_callback)) {}
|
||||
std::move(viz_compositor_thread_runner_callback)),
|
||||
gr_context_options_provider_(gr_context_options_provider) {}
|
||||
|
||||
AwContentGpuClient::~AwContentGpuClient() {}
|
||||
|
||||
@ -38,4 +40,9 @@ AwContentGpuClient::GetVizCompositorThreadRunner() {
|
||||
return viz_compositor_thread_runner_callback_.Run();
|
||||
}
|
||||
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
AwContentGpuClient::GetGrContextOptionsProvider() {
|
||||
return gr_context_options_provider_;
|
||||
}
|
||||
|
||||
} // namespace android_webview
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef ANDROID_WEBVIEW_GPU_AW_CONTENT_GPU_CLIENT_H_
|
||||
#define ANDROID_WEBVIEW_GPU_AW_CONTENT_GPU_CLIENT_H_
|
||||
|
||||
#include "android_webview/common/gfx/aw_gr_context_options_provider.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "content/public/gpu/content_gpu_client.h"
|
||||
|
||||
@ -25,7 +26,8 @@ class AwContentGpuClient : public content::ContentGpuClient {
|
||||
GetSharedImageManagerCallback shared_image_manager_callback,
|
||||
GetSchedulerCallback scheduler_callback,
|
||||
GetVizCompositorThreadRunnerCallback
|
||||
viz_compositor_thread_runner_callback);
|
||||
viz_compositor_thread_runner_callback,
|
||||
const AwGrContextOptionsProvider* gr_context_options_provider);
|
||||
|
||||
AwContentGpuClient(const AwContentGpuClient&) = delete;
|
||||
AwContentGpuClient& operator=(const AwContentGpuClient&) = delete;
|
||||
@ -37,12 +39,15 @@ class AwContentGpuClient : public content::ContentGpuClient {
|
||||
gpu::SharedImageManager* GetSharedImageManager() override;
|
||||
gpu::Scheduler* GetScheduler() override;
|
||||
viz::VizCompositorThreadRunner* GetVizCompositorThreadRunner() override;
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
GetGrContextOptionsProvider() override;
|
||||
|
||||
private:
|
||||
GetSyncPointManagerCallback sync_point_manager_callback_;
|
||||
GetSharedImageManagerCallback shared_image_manager_callback_;
|
||||
GetSchedulerCallback scheduler_callback_;
|
||||
GetVizCompositorThreadRunnerCallback viz_compositor_thread_runner_callback_;
|
||||
raw_ptr<const AwGrContextOptionsProvider> gr_context_options_provider_;
|
||||
};
|
||||
|
||||
} // namespace android_webview
|
||||
|
@ -380,7 +380,8 @@ content::ContentGpuClient* AwMainDelegate::CreateContentGpuClient() {
|
||||
base::BindRepeating(&GetSyncPointManager),
|
||||
base::BindRepeating(&GetSharedImageManager),
|
||||
base::BindRepeating(&GetScheduler),
|
||||
base::BindRepeating(&GetVizCompositorThreadRunner));
|
||||
base::BindRepeating(&GetVizCompositorThreadRunner),
|
||||
&aw_gr_context_options_provider_);
|
||||
return content_gpu_client_.get();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "android_webview/browser/aw_feature_list_creator.h"
|
||||
#include "android_webview/common/aw_content_client.h"
|
||||
#include "android_webview/common/gfx/aw_gr_context_options_provider.h"
|
||||
#include "components/memory_system/memory_system.h"
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
|
||||
@ -65,6 +66,7 @@ class AwMainDelegate : public content::ContentMainDelegate {
|
||||
std::unique_ptr<AwContentBrowserClient> content_browser_client_;
|
||||
std::unique_ptr<AwContentGpuClient> content_gpu_client_;
|
||||
std::unique_ptr<AwContentRendererClient> content_renderer_client_;
|
||||
AwGrContextOptionsProvider aw_gr_context_options_provider_;
|
||||
|
||||
memory_system::MemorySystem memory_system_;
|
||||
};
|
||||
|
@ -555,7 +555,9 @@ void GpuServiceImpl::InitializeWithHost(
|
||||
gpu::SyncPointManager* sync_point_manager,
|
||||
gpu::SharedImageManager* shared_image_manager,
|
||||
gpu::Scheduler* scheduler,
|
||||
base::WaitableEvent* shutdown_event) {
|
||||
base::WaitableEvent* shutdown_event,
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
gr_context_options_provider) {
|
||||
if (!sync_point_manager) {
|
||||
sync_point_manager = CreateSyncPointManager();
|
||||
}
|
||||
@ -577,6 +579,8 @@ void GpuServiceImpl::InitializeWithHost(
|
||||
shutdown_event = CreateShutdownEvent();
|
||||
}
|
||||
|
||||
gr_context_options_provider_ = gr_context_options_provider;
|
||||
|
||||
InitializeWithHostInternal(
|
||||
std::move(pending_gpu_host), std::move(use_shader_cache_shm_count),
|
||||
default_offscreen_surface, std::move(creation_params), sync_point_manager,
|
||||
@ -647,7 +651,7 @@ void GpuServiceImpl::InitializeWithHostInternal(
|
||||
std::move(default_offscreen_surface),
|
||||
image_decode_accelerator_worker_.get(), vulkan_context_provider(),
|
||||
metal_context_provider(), dawn_context_provider(),
|
||||
dawn_caching_interface_factory());
|
||||
dawn_caching_interface_factory(), gr_context_options_provider_);
|
||||
|
||||
media_gpu_channel_manager_ = std::make_unique<media::MediaGpuChannelManager>(
|
||||
gpu_channel_manager_.get());
|
||||
|
@ -154,7 +154,9 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl
|
||||
gpu::SyncPointManager* sync_point_manager = nullptr,
|
||||
gpu::SharedImageManager* shared_image_manager = nullptr,
|
||||
gpu::Scheduler* scheduler = nullptr,
|
||||
base::WaitableEvent* shutdown_event = nullptr);
|
||||
base::WaitableEvent* shutdown_event = nullptr,
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
gr_context_options_provider = nullptr);
|
||||
#else
|
||||
void InitializeWithHost(
|
||||
mojo::PendingRemote<mojom::GpuHost> gpu_host,
|
||||
@ -662,6 +664,9 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl
|
||||
std::unique_ptr<base::WaitableEvent> owned_shutdown_event_;
|
||||
raw_ptr<base::WaitableEvent> shutdown_event_ = nullptr;
|
||||
|
||||
raw_ptr<const gpu::SharedContextState::GrContextOptionsProvider>
|
||||
gr_context_options_provider_ = nullptr;
|
||||
|
||||
// Callback that safely exits GPU process.
|
||||
base::OnceCallback<void(ExitCode)> exit_callback_;
|
||||
base::AtomicFlag is_exiting_;
|
||||
|
@ -207,7 +207,8 @@ void VizMainImpl::CreateGpuService(
|
||||
gpu::GpuProcessShmCount(std::move(use_shader_cache_shm_region)),
|
||||
gpu_init_->TakeDefaultOffscreenSurface(), std::move(params),
|
||||
dependencies_.sync_point_manager, dependencies_.shared_image_manager,
|
||||
dependencies_.scheduler, dependencies_.shutdown_event);
|
||||
dependencies_.scheduler, dependencies_.shutdown_event,
|
||||
dependencies_.gr_context_options_provider);
|
||||
#else
|
||||
gpu_service_->InitializeWithHost(
|
||||
gpu_host.Unbind(),
|
||||
|
@ -102,6 +102,8 @@ class VizMainImpl : public mojom::VizMain {
|
||||
raw_ptr<gpu::SharedImageManager> shared_image_manager = nullptr;
|
||||
raw_ptr<gpu::Scheduler> scheduler = nullptr;
|
||||
raw_ptr<VizCompositorThreadRunner> viz_compositor_thread_runner = nullptr;
|
||||
raw_ptr<const gpu::SharedContextState::GrContextOptionsProvider>
|
||||
gr_context_options_provider = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -97,6 +97,8 @@ viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() {
|
||||
deps.scheduler = GetContentClient()->gpu()->GetScheduler();
|
||||
deps.viz_compositor_thread_runner =
|
||||
GetContentClient()->gpu()->GetVizCompositorThreadRunner();
|
||||
deps.gr_context_options_provider =
|
||||
GetContentClient()->gpu()->GetGrContextOptionsProvider();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -34,6 +34,7 @@ target(link_target_type, "gpu_sources") {
|
||||
"//content/gpu:gpu_sources",
|
||||
"//content/public/common:common_sources",
|
||||
"//gpu/command_buffer/service",
|
||||
"//gpu/command_buffer/service:gles2",
|
||||
"//gpu/config",
|
||||
]
|
||||
|
||||
|
@ -23,6 +23,11 @@ viz::VizCompositorThreadRunner*
|
||||
ContentGpuClient::GetVizCompositorThreadRunner() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
ContentGpuClient::GetGrContextOptionsProvider() {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace content
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "build/buildflag.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "gpu/command_buffer/service/shared_context_state.h"
|
||||
#include "mojo/public/cpp/bindings/binder_map.h"
|
||||
|
||||
namespace gpu {
|
||||
@ -57,6 +58,8 @@ class CONTENT_EXPORT ContentGpuClient {
|
||||
virtual gpu::SharedImageManager* GetSharedImageManager();
|
||||
virtual gpu::Scheduler* GetScheduler();
|
||||
virtual viz::VizCompositorThreadRunner* GetVizCompositorThreadRunner();
|
||||
virtual const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
GetGrContextOptionsProvider();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -368,7 +368,8 @@ SharedContextState::SharedContextState(
|
||||
viz::MetalContextProvider* metal_context_provider,
|
||||
DawnContextProvider* dawn_context_provider,
|
||||
base::WeakPtr<gpu::MemoryTracker::Observer> peak_memory_monitor,
|
||||
bool created_on_compositor_gpu_thread)
|
||||
bool created_on_compositor_gpu_thread,
|
||||
const GrContextOptionsProvider* gr_context_options_provider)
|
||||
: use_virtualized_gl_contexts_(use_virtualized_gl_contexts),
|
||||
context_lost_callback_(std::move(context_lost_callback)),
|
||||
gr_context_type_(gr_context_type),
|
||||
@ -378,6 +379,7 @@ SharedContextState::SharedContextState(
|
||||
vk_context_provider_(vulkan_context_provider),
|
||||
metal_context_provider_(metal_context_provider),
|
||||
dawn_context_provider_(dawn_context_provider),
|
||||
gr_context_options_provider_(gr_context_options_provider),
|
||||
created_on_compositor_gpu_thread_(created_on_compositor_gpu_thread),
|
||||
share_group_(std::move(share_group)),
|
||||
context_(context),
|
||||
@ -577,6 +579,10 @@ bool SharedContextState::InitializeGanesh(
|
||||
if (gpu_preferences.force_max_texture_size)
|
||||
options.fMaxTextureSizeOverride = gpu_preferences.force_max_texture_size;
|
||||
|
||||
if (gr_context_options_provider_) {
|
||||
gr_context_options_provider_->SetCustomGrContextOptions(options);
|
||||
}
|
||||
|
||||
if (gr_context_type_ == GrContextType::kGL) {
|
||||
DCHECK(context_->IsCurrent(nullptr));
|
||||
sk_sp<GrGLInterface> gr_gl_interface(gl::init::CreateGrGLInterface(
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/lru_cache.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/memory_pressure_listener.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
@ -87,6 +88,16 @@ class GPU_GLES2_EXPORT SharedContextState
|
||||
using ContextLostCallback =
|
||||
base::OnceCallback<void(bool, error::ContextLostReason)>;
|
||||
|
||||
// This interface is used by the embedder to set custom GrContextOptions which
|
||||
// are passed to Skia.
|
||||
class GrContextOptionsProvider {
|
||||
public:
|
||||
~GrContextOptionsProvider() = default;
|
||||
// The passed GrContextOptions will have the default fields set. The
|
||||
// embedder may modify the options as needed.
|
||||
virtual void SetCustomGrContextOptions(GrContextOptions& options) const = 0;
|
||||
};
|
||||
|
||||
// TODO(vikassoni): Refactor code to have seperate constructor for GL and
|
||||
// Vulkan and not initialize/use GL related info for vulkan and vice-versa.
|
||||
SharedContextState(
|
||||
@ -100,7 +111,9 @@ class GPU_GLES2_EXPORT SharedContextState
|
||||
viz::MetalContextProvider* metal_context_provider = nullptr,
|
||||
DawnContextProvider* dawn_context_provider = nullptr,
|
||||
base::WeakPtr<gpu::MemoryTracker::Observer> peak_memory_monitor = nullptr,
|
||||
bool created_on_compositor_gpu_thread = false);
|
||||
bool created_on_compositor_gpu_thread = false,
|
||||
const gpu::SharedContextState::GrContextOptionsProvider*
|
||||
gr_context_options_provider = nullptr);
|
||||
|
||||
SharedContextState(const SharedContextState&) = delete;
|
||||
SharedContextState& operator=(const SharedContextState&) = delete;
|
||||
@ -285,6 +298,10 @@ class GPU_GLES2_EXPORT SharedContextState
|
||||
private:
|
||||
friend class base::RefCounted<SharedContextState>;
|
||||
friend class raster::RasterDecoderTestBase;
|
||||
FRIEND_TEST_ALL_PREFIXES(SharedContextStateTest,
|
||||
GLOptionsProviderSetsCustomOptions);
|
||||
FRIEND_TEST_ALL_PREFIXES(SharedContextStateTest,
|
||||
VulkanOptionsProviderSetsCustomOptions);
|
||||
|
||||
// Observer which is notified when SkiaOutputSurfaceImpl takes ownership of a
|
||||
// shared image, and forward information to both histograms and task manager.
|
||||
@ -383,6 +400,8 @@ class GPU_GLES2_EXPORT SharedContextState
|
||||
const raw_ptr<viz::VulkanContextProvider> vk_context_provider_ = nullptr;
|
||||
const raw_ptr<viz::MetalContextProvider> metal_context_provider_ = nullptr;
|
||||
const raw_ptr<DawnContextProvider> dawn_context_provider_ = nullptr;
|
||||
raw_ptr<const GrContextOptionsProvider> gr_context_options_provider_ =
|
||||
nullptr;
|
||||
bool created_on_compositor_gpu_thread_ = false;
|
||||
bool is_drdc_enabled_ = false;
|
||||
raw_ptr<GrDirectContext, DanglingUntriaged> gr_context_ = nullptr;
|
||||
|
@ -22,12 +22,14 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/gl/gl_context_stub.h"
|
||||
#include "ui/gl/gl_mock.h"
|
||||
#include "ui/gl/gl_share_group.h"
|
||||
#include "ui/gl/gl_surface_stub.h"
|
||||
#include "ui/gl/init/gl_factory.h"
|
||||
#include "ui/gl/test/gl_surface_test_support.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::SetArgPointee;
|
||||
using ::testing::StrictMock;
|
||||
@ -39,6 +41,15 @@ class SharedContextStateTest : public ::testing::Test {
|
||||
SharedContextStateTest() = default;
|
||||
};
|
||||
|
||||
class MockGrContextOptionsProvider
|
||||
: public SharedContextState::GrContextOptionsProvider {
|
||||
public:
|
||||
MOCK_METHOD(void,
|
||||
SetCustomGrContextOptions,
|
||||
(GrContextOptions & options),
|
||||
(const, override));
|
||||
};
|
||||
|
||||
TEST_F(SharedContextStateTest, InitFailsIfLostContext) {
|
||||
const ContextType context_type = CONTEXT_TYPE_OPENGLES2;
|
||||
|
||||
@ -100,4 +111,88 @@ TEST_F(SharedContextStateTest, InitFailsIfLostContext) {
|
||||
gl::GLSurfaceTestSupport::ShutdownGL(display);
|
||||
}
|
||||
|
||||
TEST_F(SharedContextStateTest, GLOptionsProviderSetsCustomOptions) {
|
||||
gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress);
|
||||
auto* display = gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
|
||||
ASSERT_TRUE(display);
|
||||
{
|
||||
NiceMock<gl::MockGLInterface> gl_interface;
|
||||
gl::MockGLInterface::SetGLInterface(&gl_interface);
|
||||
|
||||
InSequence sequence;
|
||||
|
||||
auto share_group = base::MakeRefCounted<gl::GLShareGroup>();
|
||||
auto surface = base::MakeRefCounted<gl::GLSurfaceStub>();
|
||||
auto context = base::MakeRefCounted<gl::GLContextStub>(share_group.get());
|
||||
const char gl_version[] = "OpenGL ES 2.0";
|
||||
context->SetGLVersionString(gl_version);
|
||||
const char gl_extensions[] = "GL_KHR_robustness";
|
||||
context->SetExtensionsString(gl_extensions);
|
||||
|
||||
// The stub ctx needs to be initialized so that the gl::GLContext can
|
||||
// store the offscreen stub |surface|.
|
||||
context->Initialize(surface.get(), {});
|
||||
context->MakeCurrent(surface.get());
|
||||
GpuDriverBugWorkarounds workarounds;
|
||||
|
||||
auto shared_context_state = base::MakeRefCounted<SharedContextState>(
|
||||
share_group.get(), surface, context,
|
||||
false /* use_virtualized_gl_contexts */, base::DoNothing(),
|
||||
GrContextType::kGL);
|
||||
StrictMock<MockGrContextOptionsProvider> provider;
|
||||
shared_context_state->gr_context_options_provider_ = &provider;
|
||||
EXPECT_CALL(provider, SetCustomGrContextOptions(_))
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
shared_context_state->InitializeGanesh(
|
||||
GpuPreferences(), workarounds, /*cache=*/nullptr,
|
||||
/*use_shader_cache_shm_count=*/nullptr, /*progress_reporter=*/nullptr);
|
||||
}
|
||||
gl::GLSurfaceTestSupport::ShutdownGL(display);
|
||||
}
|
||||
|
||||
TEST_F(SharedContextStateTest, VulkanOptionsProviderSetsCustomOptions) {
|
||||
gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress);
|
||||
auto* display = gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
|
||||
ASSERT_TRUE(display);
|
||||
{
|
||||
NiceMock<gl::MockGLInterface> gl_interface;
|
||||
gl::MockGLInterface::SetGLInterface(&gl_interface);
|
||||
// This line and passing kVulkan into InitializeGanesh should ensure we go
|
||||
// down the Vulkan code path.
|
||||
gl::SetGLImplementationParts(
|
||||
gl::GLImplementationParts(gl::ANGLEImplementation::kVulkan));
|
||||
|
||||
InSequence sequence;
|
||||
|
||||
auto share_group = base::MakeRefCounted<gl::GLShareGroup>();
|
||||
auto surface = base::MakeRefCounted<gl::GLSurfaceStub>();
|
||||
auto context = base::MakeRefCounted<gl::GLContextStub>(share_group.get());
|
||||
const char gl_version[] = "OpenGL ES 2.0";
|
||||
context->SetGLVersionString(gl_version);
|
||||
const char gl_extensions[] = "GL_KHR_robustness";
|
||||
context->SetExtensionsString(gl_extensions);
|
||||
|
||||
// The stub ctx needs to be initialized so that the gl::GLContext can
|
||||
// store the offscreen stub |surface|.
|
||||
context->Initialize(surface.get(), {});
|
||||
context->MakeCurrent(surface.get());
|
||||
GpuDriverBugWorkarounds workarounds;
|
||||
|
||||
auto shared_context_state = base::MakeRefCounted<SharedContextState>(
|
||||
share_group.get(), surface, context,
|
||||
false /* use_virtualized_gl_contexts */, base::DoNothing(),
|
||||
GrContextType::kVulkan);
|
||||
StrictMock<MockGrContextOptionsProvider> provider;
|
||||
shared_context_state->gr_context_options_provider_ = &provider;
|
||||
EXPECT_CALL(provider, SetCustomGrContextOptions(_))
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
shared_context_state->InitializeGanesh(
|
||||
GpuPreferences(), workarounds, /*cache=*/nullptr,
|
||||
/*use_shader_cache_shm_count=*/nullptr, /*progress_reporter=*/nullptr);
|
||||
}
|
||||
gl::GLSurfaceTestSupport::ShutdownGL(display);
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
|
@ -342,7 +342,9 @@ GpuChannelManager::GpuChannelManager(
|
||||
viz::VulkanContextProvider* vulkan_context_provider,
|
||||
viz::MetalContextProvider* metal_context_provider,
|
||||
DawnContextProvider* dawn_context_provider,
|
||||
webgpu::DawnCachingInterfaceFactory* dawn_caching_interface_factory)
|
||||
webgpu::DawnCachingInterfaceFactory* dawn_caching_interface_factory,
|
||||
const SharedContextState::GrContextOptionsProvider*
|
||||
gr_context_options_provider)
|
||||
: task_runner_(task_runner),
|
||||
io_task_runner_(io_task_runner),
|
||||
gpu_preferences_(gpu_preferences),
|
||||
@ -370,7 +372,8 @@ GpuChannelManager::GpuChannelManager(
|
||||
vulkan_context_provider_(vulkan_context_provider),
|
||||
metal_context_provider_(metal_context_provider),
|
||||
dawn_context_provider_(dawn_context_provider),
|
||||
peak_memory_monitor_(this, task_runner) {
|
||||
peak_memory_monitor_(this, task_runner),
|
||||
gr_context_options_provider_(gr_context_options_provider) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
DCHECK(task_runner->BelongsToCurrentThread());
|
||||
DCHECK(io_task_runner);
|
||||
@ -1003,7 +1006,8 @@ scoped_refptr<SharedContextState> GpuChannelManager::GetSharedContextState(
|
||||
context_lost_count_ + 1),
|
||||
gpu_preferences_.gr_context_type, vulkan_context_provider_,
|
||||
metal_context_provider_, dawn_context_provider_,
|
||||
peak_memory_monitor_.GetWeakPtr());
|
||||
peak_memory_monitor_.GetWeakPtr(),
|
||||
/*created_on_compositor_gpu_thread=*/false, gr_context_options_provider_);
|
||||
|
||||
// Initialize GL context, so Vulkan and GL interop can work properly.
|
||||
auto feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
|
||||
|
@ -111,7 +111,9 @@ class GPU_IPC_SERVICE_EXPORT GpuChannelManager
|
||||
viz::MetalContextProvider* metal_context_provider = nullptr,
|
||||
DawnContextProvider* dawn_context_provider = nullptr,
|
||||
webgpu::DawnCachingInterfaceFactory* dawn_caching_interface_factory =
|
||||
nullptr);
|
||||
nullptr,
|
||||
const SharedContextState::GrContextOptionsProvider*
|
||||
gr_context_options_provider = nullptr);
|
||||
|
||||
GpuChannelManager(const GpuChannelManager&) = delete;
|
||||
GpuChannelManager& operator=(const GpuChannelManager&) = delete;
|
||||
@ -405,6 +407,9 @@ class GPU_IPC_SERVICE_EXPORT GpuChannelManager
|
||||
|
||||
GpuPeakMemoryMonitor peak_memory_monitor_;
|
||||
|
||||
raw_ptr<const SharedContextState::GrContextOptionsProvider>
|
||||
gr_context_options_provider_ = nullptr;
|
||||
|
||||
// Creation time of GpuChannelManger.
|
||||
const base::TimeTicks creation_time_ = base::TimeTicks::Now();
|
||||
|
||||
|
Reference in New Issue
Block a user