Commit d77817c5 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Use RasterDecoder for CPU raster

This CL uses RasterDecoder for CPU rasterization (one-copy and
zero-copy) on worker background raster threads in two cases:

(1) in renderers whenever GPU raster is blacklisted or cannot create
    GrContext (similar to
    LayerTreeHostImpl::GetGpuRasterizationCapabilities)

(2) in browser whenever GPU raster is not requested

This CL copies some of the logic in LTHI::GetGpuRasterizationCapabilities
to RenderThreadImpl::SharedCompositorWorkerContextProvider.
I copied it so that if we fail GPU rasterization using GLES2Decoder, we
can fallback to CPU raster using a RasterDecoder.

This change should be safe because we have been fuzzing all
RasterDecoder entry points for about 1 quarter.

When testing this CL, I noticed that chrome://gpu was reporting
rasterization status incorrectly with --force-gpu-rasterization flag,
so I fixed that too.

Bug: 880911
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I8d93b9d0bfe30e9ee0d5e522be0d9f8155a28726
Reviewed-on: https://chromium-review.googlesource.com/c/1258206
Commit-Queue: Jonathan Backer <backer@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#598801}
parent 2ac4c6ca
...@@ -119,6 +119,7 @@ ...@@ -119,6 +119,7 @@
#include "device/gamepad/public/cpp/gamepads.h" #include "device/gamepad/public/cpp/gamepads.h"
#include "gin/public/debug.h" #include "gin/public/debug.h"
#include "gpu/GLES2/gl2extchromium.h" #include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h" #include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/client/shared_memory_limits.h"
...@@ -1974,7 +1975,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink( ...@@ -1974,7 +1975,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
} }
scoped_refptr<viz::RasterContextProvider> worker_context_provider = scoped_refptr<viz::RasterContextProvider> worker_context_provider =
SharedCompositorWorkerContextProvider(); SharedCompositorWorkerContextProvider(/*try_gpu_rasterization=*/true);
if (!worker_context_provider) { if (!worker_context_provider) {
// Cause the compositor to wait and try again. // Cause the compositor to wait and try again.
std::move(callback).Run(nullptr); std::move(callback).Run(nullptr);
...@@ -2267,7 +2268,8 @@ base::TaskRunner* RenderThreadImpl::GetWorkerTaskRunner() { ...@@ -2267,7 +2268,8 @@ base::TaskRunner* RenderThreadImpl::GetWorkerTaskRunner() {
} }
scoped_refptr<viz::RasterContextProvider> scoped_refptr<viz::RasterContextProvider>
RenderThreadImpl::SharedCompositorWorkerContextProvider() { RenderThreadImpl::SharedCompositorWorkerContextProvider(
bool try_gpu_rasterization) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
// Try to reuse existing shared worker context provider. // Try to reuse existing shared worker context provider.
if (shared_worker_context_provider_) { if (shared_worker_context_provider_) {
...@@ -2290,9 +2292,15 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() { ...@@ -2290,9 +2292,15 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() {
gpu_channel_host->gpu_feature_info() gpu_channel_host->gpu_feature_info()
.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] == .status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
gpu::kGpuFeatureStatusEnabled; gpu::kGpuFeatureStatusEnabled;
bool support_gles2_interface = !support_oop_rasterization; bool support_gpu_rasterization =
try_gpu_rasterization && !support_oop_rasterization &&
(IsGpuRasterizationForced() ||
gpu_channel_host->gpu_feature_info()
.status_values[gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION] ==
gpu::kGpuFeatureStatusEnabled);
bool support_gles2_interface = support_gpu_rasterization;
bool support_raster_interface = true; bool support_raster_interface = true;
bool support_grcontext = !support_oop_rasterization; bool support_grcontext = support_gpu_rasterization;
bool automatic_flushes = false; bool automatic_flushes = false;
auto shared_memory_limits = auto shared_memory_limits =
support_oop_rasterization ? gpu::SharedMemoryLimits::ForOOPRasterContext() support_oop_rasterization ? gpu::SharedMemoryLimits::ForOOPRasterContext()
...@@ -2304,8 +2312,38 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() { ...@@ -2304,8 +2312,38 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() {
automatic_flushes, ws::command_buffer_metrics::ContextType::RENDER_WORKER, automatic_flushes, ws::command_buffer_metrics::ContextType::RENDER_WORKER,
kGpuStreamIdWorker, kGpuStreamPriorityWorker); kGpuStreamIdWorker, kGpuStreamPriorityWorker);
auto result = shared_worker_context_provider_->BindToCurrentThread(); auto result = shared_worker_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) if (result != gpu::ContextResult::kSuccess) {
shared_worker_context_provider_ = nullptr; shared_worker_context_provider_ = nullptr;
return nullptr;
}
// Check if we really have support for GPU rasterization.
if (support_gpu_rasterization) {
bool really_support_gpu_rasterization = false;
{
viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
shared_worker_context_provider_.get());
bool forced_or_supported =
IsGpuRasterizationForced() ||
shared_worker_context_provider_->ContextCapabilities()
.gpu_rasterization;
if (forced_or_supported &&
shared_worker_context_provider_->ContextSupport()
->HasGrContextSupport()) {
// Do not check GrContext above. It is lazy-created, and we only want to
// create it if it might be used.
GrContext* gr_context = shared_worker_context_provider_->GrContext();
really_support_gpu_rasterization = !!gr_context;
}
}
// If not really supported, recreate context with different attributes.
if (!really_support_gpu_rasterization) {
shared_worker_context_provider_ = nullptr;
return SharedCompositorWorkerContextProvider(
/*try_gpu_rasterization=*/false);
}
}
return shared_worker_context_provider_; return shared_worker_context_provider_;
} }
......
...@@ -396,7 +396,7 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -396,7 +396,7 @@ class CONTENT_EXPORT RenderThreadImpl
// Returns a worker context provider that will be bound on the compositor // Returns a worker context provider that will be bound on the compositor
// thread. // thread.
scoped_refptr<viz::RasterContextProvider> scoped_refptr<viz::RasterContextProvider>
SharedCompositorWorkerContextProvider(); SharedCompositorWorkerContextProvider(bool try_gpu_rasterization);
media::GpuVideoAcceleratorFactories* GetGpuFactories(); media::GpuVideoAcceleratorFactories* GetGpuFactories();
......
...@@ -1243,7 +1243,12 @@ void RasterDecoderImpl::RestoreBufferBindings() const { ...@@ -1243,7 +1243,12 @@ void RasterDecoderImpl::RestoreBufferBindings() const {
} }
void RasterDecoderImpl::RestoreFramebufferBindings() const { void RasterDecoderImpl::RestoreFramebufferBindings() const {
NOTIMPLEMENTED(); PessimisticallyResetGrContext();
state_.fbo_binding_for_scissor_workaround_dirty = true;
state_.stencil_state_changed_since_validation = true;
if (workarounds().flush_on_framebuffer_change)
api()->glFlushFn();
} }
void RasterDecoderImpl::RestoreRenderbufferBindings() { void RasterDecoderImpl::RestoreRenderbufferBindings() {
......
...@@ -29,6 +29,9 @@ constexpr gfx::Size kBufferSize(100, 100); ...@@ -29,6 +29,9 @@ constexpr gfx::Size kBufferSize(100, 100);
class RasterInProcessCommandBufferTest : public ::testing::Test { class RasterInProcessCommandBufferTest : public ::testing::Test {
public: public:
std::unique_ptr<RasterInProcessContext> CreateRasterInProcessContext() { std::unique_ptr<RasterInProcessContext> CreateRasterInProcessContext() {
if (!RasterInProcessContext::SupportedInTest())
return nullptr;
ContextCreationAttribs attributes; ContextCreationAttribs attributes;
attributes.bind_generates_resource = false; attributes.bind_generates_resource = false;
attributes.enable_oop_rasterization = true; attributes.enable_oop_rasterization = true;
...@@ -46,6 +49,8 @@ class RasterInProcessCommandBufferTest : public ::testing::Test { ...@@ -46,6 +49,8 @@ class RasterInProcessCommandBufferTest : public ::testing::Test {
} }
void SetUp() override { void SetUp() override {
if (!RasterInProcessContext::SupportedInTest())
return;
gpu_memory_buffer_factory_ = GpuMemoryBufferFactory::CreateNativeType(); gpu_memory_buffer_factory_ = GpuMemoryBufferFactory::CreateNativeType();
gpu_memory_buffer_manager_ = gpu_memory_buffer_manager_ =
std::make_unique<viz::TestGpuMemoryBufferManager>(); std::make_unique<viz::TestGpuMemoryBufferManager>();
...@@ -69,6 +74,9 @@ class RasterInProcessCommandBufferTest : public ::testing::Test { ...@@ -69,6 +74,9 @@ class RasterInProcessCommandBufferTest : public ::testing::Test {
} // namespace } // namespace
TEST_F(RasterInProcessCommandBufferTest, CreateImage) { TEST_F(RasterInProcessCommandBufferTest, CreateImage) {
if (!RasterInProcessContext::SupportedInTest())
return;
// Calling CreateImageCHROMIUM() should allocate an image id. // Calling CreateImageCHROMIUM() should allocate an image id.
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer1 = std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer1 =
gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
...@@ -96,6 +104,9 @@ TEST_F(RasterInProcessCommandBufferTest, CreateImage) { ...@@ -96,6 +104,9 @@ TEST_F(RasterInProcessCommandBufferTest, CreateImage) {
} }
TEST_F(RasterInProcessCommandBufferTest, SetColorSpaceMetadata) { TEST_F(RasterInProcessCommandBufferTest, SetColorSpaceMetadata) {
if (!RasterInProcessContext::SupportedInTest())
return;
GLuint texture_id = GLuint texture_id =
ri_->CreateTexture(/*use_buffer=*/true, kBufferUsage, kResourceFormat); ri_->CreateTexture(/*use_buffer=*/true, kBufferUsage, kResourceFormat);
...@@ -116,6 +127,9 @@ TEST_F(RasterInProcessCommandBufferTest, SetColorSpaceMetadata) { ...@@ -116,6 +127,9 @@ TEST_F(RasterInProcessCommandBufferTest, SetColorSpaceMetadata) {
} }
TEST_F(RasterInProcessCommandBufferTest, TexStorage2DImage) { TEST_F(RasterInProcessCommandBufferTest, TexStorage2DImage) {
if (!RasterInProcessContext::SupportedInTest())
return;
// Check for GPU and driver support // Check for GPU and driver support
if (!context_->GetCapabilities().texture_storage_image) { if (!context_->GetCapabilities().texture_storage_image) {
return; return;
...@@ -154,6 +168,9 @@ TEST_F(RasterInProcessCommandBufferTest, TexStorage2DImage) { ...@@ -154,6 +168,9 @@ TEST_F(RasterInProcessCommandBufferTest, TexStorage2DImage) {
TEST_F(RasterInProcessCommandBufferTest, TEST_F(RasterInProcessCommandBufferTest,
WhitelistBetweenBeginEndRasterCHROMIUM) { WhitelistBetweenBeginEndRasterCHROMIUM) {
if (!RasterInProcessContext::SupportedInTest())
return;
// Check for GPU and driver support // Check for GPU and driver support
if (!context_->GetCapabilities().supports_oop_raster) { if (!context_->GetCapabilities().supports_oop_raster) {
return; return;
......
...@@ -577,12 +577,10 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread( ...@@ -577,12 +577,10 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread(
return ContextResult::kTransientFailure; return ContextResult::kTransientFailure;
} }
bool supports_oop_rasterization = bool use_passthrough_cmd_decoder =
task_executor_->gpu_feature_info() task_executor_->gpu_preferences().use_passthrough_cmd_decoder &&
.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] == gles2::PassthroughCommandDecoderSupported();
kGpuFeatureStatusEnabled; if (!use_passthrough_cmd_decoder &&
if (supports_oop_rasterization && params.attribs.enable_oop_rasterization &&
params.attribs.enable_raster_interface && params.attribs.enable_raster_interface &&
!params.attribs.enable_gles2_interface) { !params.attribs.enable_gles2_interface) {
scoped_refptr<raster::RasterDecoderContextState> context_state = scoped_refptr<raster::RasterDecoderContextState> context_state =
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_creation_attribs.h" #include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_switches.h" #include "gpu/config/gpu_switches.h"
#include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/common/surface_handle.h"
...@@ -133,4 +134,13 @@ int RasterInProcessContext::GetRasterDecoderIdForTest() const { ...@@ -133,4 +134,13 @@ int RasterInProcessContext::GetRasterDecoderIdForTest() const {
return command_buffer_->GetRasterDecoderIdForTest(); return command_buffer_->GetRasterDecoderIdForTest();
} }
// static
bool RasterInProcessContext::SupportedInTest() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
GpuPreferences gpu_preferences = gles2::ParseGpuPreferences(command_line);
return !gpu_preferences.use_passthrough_cmd_decoder ||
!gles2::PassthroughCommandDecoderSupported();
}
} // namespace gpu } // namespace gpu
...@@ -67,6 +67,10 @@ class RasterInProcessContext { ...@@ -67,6 +67,10 @@ class RasterInProcessContext {
InProcessCommandBuffer* GetCommandBufferForTest() const; InProcessCommandBuffer* GetCommandBufferForTest() const;
int GetRasterDecoderIdForTest() const; int GetRasterDecoderIdForTest() const;
// Test only function. Returns false if using passthrough decoding, which is
// currently unsupported.
static bool SupportedInTest();
private: private:
std::unique_ptr<CommandBufferHelper> helper_; std::unique_ptr<CommandBufferHelper> helper_;
std::unique_ptr<TransferBuffer> transfer_buffer_; std::unique_ptr<TransferBuffer> transfer_buffer_;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/scheduler.h" #include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/ipc/common/command_buffer_id.h" #include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h" #include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/service/gles2_command_buffer_stub.h" #include "gpu/ipc/service/gles2_command_buffer_stub.h"
...@@ -600,11 +601,10 @@ void GpuChannel::OnCreateCommandBuffer( ...@@ -600,11 +601,10 @@ void GpuChannel::OnCreateCommandBuffer(
} }
std::unique_ptr<CommandBufferStub> stub; std::unique_ptr<CommandBufferStub> stub;
bool use_passthrough_cmd_decoder =
gpu_channel_manager_->gpu_preferences().use_passthrough_cmd_decoder &&
gles2::PassthroughCommandDecoderSupported();
bool supports_oop_rasterization =
gpu_channel_manager_->gpu_feature_info()
.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] ==
kGpuFeatureStatusEnabled;
if (init_params.attribs.context_type == CONTEXT_TYPE_WEBGPU) { if (init_params.attribs.context_type == CONTEXT_TYPE_WEBGPU) {
if (!gpu_channel_manager_->gpu_preferences().enable_webgpu) { if (!gpu_channel_manager_->gpu_preferences().enable_webgpu) {
DLOG(ERROR) << "ContextResult::kFatalFailure: WebGPU not enabled"; DLOG(ERROR) << "ContextResult::kFatalFailure: WebGPU not enabled";
...@@ -613,8 +613,7 @@ void GpuChannel::OnCreateCommandBuffer( ...@@ -613,8 +613,7 @@ void GpuChannel::OnCreateCommandBuffer(
stub = std::make_unique<WebGPUCommandBufferStub>( stub = std::make_unique<WebGPUCommandBufferStub>(
this, init_params, command_buffer_id, sequence_id, stream_id, route_id); this, init_params, command_buffer_id, sequence_id, stream_id, route_id);
} else if (supports_oop_rasterization && } else if (!use_passthrough_cmd_decoder &&
init_params.attribs.enable_oop_rasterization &&
init_params.attribs.enable_raster_interface && init_params.attribs.enable_raster_interface &&
!init_params.attribs.enable_gles2_interface) { !init_params.attribs.enable_gles2_interface) {
stub = std::make_unique<RasterCommandBufferStub>( stub = std::make_unique<RasterCommandBufferStub>(
......
...@@ -170,9 +170,9 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() { ...@@ -170,9 +170,9 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
impl_ = nullptr; impl_ = nullptr;
webgpu_interface_ = std::move(webgpu_impl); webgpu_interface_ = std::move(webgpu_impl);
helper_ = std::move(webgpu_helper); helper_ = std::move(webgpu_helper);
} else if (attributes_.enable_oop_rasterization) { } else if (!command_buffer_->channel()->gpu_info().passthrough_cmd_decoder &&
DCHECK(attributes_.enable_raster_interface); attributes_.enable_raster_interface &&
DCHECK(!attributes_.enable_gles2_interface); !attributes_.enable_gles2_interface) {
DCHECK(!support_grcontext_); DCHECK(!support_grcontext_);
// The raster helper writes the command buffer protocol. // The raster helper writes the command buffer protocol.
auto raster_helper = auto raster_helper =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment