diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/graphics/gpu')
13 files changed, 139 insertions, 201 deletions
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc index 594e4408c43..0007fdc67c5 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc @@ -12,15 +12,15 @@ namespace blink { DawnControlClientHolder::DawnControlClientHolder( std::unique_ptr<WebGraphicsContext3DProvider> context_provider) : context_provider_(std::move(context_provider)), - interface_(context_provider_->WebGPUInterface()), - destroyed_(false) {} + interface_(context_provider_->WebGPUInterface()) {} -void DawnControlClientHolder::MarkDestroyed() { - destroyed_ = true; +void DawnControlClientHolder::Destroy() { + interface_ = nullptr; + context_provider_.reset(); } bool DawnControlClientHolder::IsDestroyed() const { - return destroyed_; + return !interface_; } WebGraphicsContext3DProvider* DawnControlClientHolder::GetContextProvider() @@ -29,12 +29,11 @@ WebGraphicsContext3DProvider* DawnControlClientHolder::GetContextProvider() } gpu::webgpu::WebGPUInterface* DawnControlClientHolder::GetInterface() const { - DCHECK(!destroyed_); + DCHECK(interface_); return interface_; } const DawnProcTable& DawnControlClientHolder::GetProcs() const { - DCHECK(!destroyed_); DCHECK(interface_); return interface_->GetProcs(); } diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h index 20e93d3e591..af143834c51 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_ #include <dawn/dawn.h> +#include <dawn/dawn_proc_table.h> #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -22,15 +23,15 @@ class WebGPUInterface; namespace blink { // This class holds the WebGPUInterface and a |destroyed_| flag. -// DawnControlClientHolder::MarkDestroyed() should be called if the -// backing WebGPUInterface has been destroyed. +// DawnControlClientHolder::Destroy() should be called to destroy the backing +// WebGPUInterface. class PLATFORM_EXPORT DawnControlClientHolder : public RefCounted<DawnControlClientHolder> { public: DawnControlClientHolder( std::unique_ptr<WebGraphicsContext3DProvider> context_provider); - void MarkDestroyed(); + void Destroy(); bool IsDestroyed() const; WebGraphicsContext3DProvider* GetContextProvider() const; @@ -43,7 +44,6 @@ class PLATFORM_EXPORT DawnControlClientHolder std::unique_ptr<WebGraphicsContext3DProvider> context_provider_; gpu::webgpu::WebGPUInterface* interface_; - bool destroyed_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index d54fa99d5cb..65b672a3573 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc @@ -253,6 +253,8 @@ void DrawingBuffer::SetIsHidden(bool hidden) { is_hidden_ = hidden; if (is_hidden_) recycled_color_buffer_queue_.clear(); + gl_->ContextVisibilityHintCHROMIUM(is_hidden_ ? GL_FALSE : GL_TRUE); + gl_->Flush(); } void DrawingBuffer::SetFilterQuality(SkFilterQuality filter_quality) { @@ -557,9 +559,10 @@ scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage( // to transferToImageBitmap are made back-to-back, or when the context gets // lost. We intentionally leave the transparent black image in legacy color // space. - sk_sp<SkSurface> surface = - SkSurface::MakeRasterN32Premul(size_.Width(), size_.Height()); - return StaticBitmapImage::Create(surface->makeImageSnapshot()); + SkBitmap black_bitmap; + black_bitmap.allocN32Pixels(size_.Width(), size_.Height()); + black_bitmap.eraseARGB(0, 0, 0, 0); + return StaticBitmapImage::Create(SkImage::MakeFromBitmap(black_bitmap)); } DCHECK_EQ(size_.Width(), transferable_resource.size.width()); @@ -670,12 +673,11 @@ DrawingBuffer::ColorBuffer::~ColorBuffer() { sii->DestroySharedImage(receive_sync_token, mailbox); gpu_memory_buffer.reset(); - gl->DeleteTextures(1, &texture_id); - if (rgb_workaround_texture_id) { - sii->DestroySharedImage(receive_sync_token, rgb_workaround_mailbox); - // Avoid deleting this texture if it was unused. - gl->DeleteTextures(1, &rgb_workaround_texture_id); - } + gl->DeleteTextures(1u, &texture_id); + + // Avoid deleting this texture if it was unused. + if (rgb_workaround_texture_id) + gl->DeleteTextures(1u, &rgb_workaround_texture_id); } bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) { @@ -810,16 +812,6 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) { allocate_alpha_channel_ = false; have_alpha_channel_ = true; } - if (UsingSwapChain()) { - // Swap chains always have an alpha channel, and multisample resolve - // doesn't work if we pretend we don't have one. - // This configuration will - // - allow invalid CopyTexImage to RGBA targets - // - fail valid FramebufferBlit from RGB targets - // TODO(sunnyps): Copy into intermediate texture for blitFramebuffer. - allocate_alpha_channel_ = true; - have_alpha_channel_ = true; - } } state_restorer_->SetFramebufferBindingDirty(); @@ -1071,33 +1063,9 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) { AttachColorBufferToReadFramebuffer(); if (WantExplicitResolve()) { - state_restorer_->SetFramebufferBindingDirty(); - state_restorer_->SetRenderbufferBindingDirty(); - gl_->BindFramebuffer(GL_FRAMEBUFFER, multisample_fbo_); - gl_->BindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_); - // Note that the multisample rendertarget will allocate an alpha channel - // based on |have_alpha_channel_|, not |allocate_alpha_channel_|, since it - // will resolve into the ColorBuffer. - GLenum internal_format = have_alpha_channel_ ? GL_RGBA8_OES : GL_RGB8_OES; - if (use_half_float_storage_) { - DCHECK(want_alpha_channel_); - internal_format = GL_RGBA16F_EXT; - } - if (has_eqaa_support) { - gl_->RenderbufferStorageMultisampleAdvancedAMD( - GL_RENDERBUFFER, sample_count_, eqaa_storage_sample_count_, - internal_format, size.Width(), size.Height()); - } else { - gl_->RenderbufferStorageMultisampleCHROMIUM( - GL_RENDERBUFFER, sample_count_, internal_format, size.Width(), - size.Height()); - } - - if (gl_->GetError() == GL_OUT_OF_MEMORY) + if (!ReallocateMultisampleRenderbuffer(size)) { return false; - - gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, multisample_renderbuffer_); + } } if (WantDepthOrStencil()) { @@ -1276,6 +1244,47 @@ void DrawingBuffer::ResolveIfNeeded() { !contents_change_resolved_) ResolveMultisampleFramebufferInternal(); contents_change_resolved_ = true; + + auto* gl = ContextProvider()->ContextGL(); + if (gl->DidGpuSwitch() == GL_TRUE) { + // TODO(crbug.com/681341): handle preserveDrawingBuffer:true, and + // user-allocated multisampled renderbuffers, by dispatching a context lost + // event. + if (WantExplicitResolve()) { + ReallocateMultisampleRenderbuffer(size_); + } + } +} + +bool DrawingBuffer::ReallocateMultisampleRenderbuffer(const IntSize& size) { + state_restorer_->SetFramebufferBindingDirty(); + state_restorer_->SetRenderbufferBindingDirty(); + gl_->BindFramebuffer(GL_FRAMEBUFFER, multisample_fbo_); + gl_->BindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_); + // Note that the multisample rendertarget will allocate an alpha channel + // based on |have_alpha_channel_|, not |allocate_alpha_channel_|, since it + // will resolve into the ColorBuffer. + GLenum internal_format = have_alpha_channel_ ? GL_RGBA8_OES : GL_RGB8_OES; + if (use_half_float_storage_) { + DCHECK(want_alpha_channel_); + internal_format = GL_RGBA16F_EXT; + } + if (has_eqaa_support) { + gl_->RenderbufferStorageMultisampleAdvancedAMD( + GL_RENDERBUFFER, sample_count_, eqaa_storage_sample_count_, + internal_format, size.Width(), size.Height()); + } else { + gl_->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, sample_count_, + internal_format, size.Width(), + size.Height()); + } + + if (gl_->GetError() == GL_OUT_OF_MEMORY) + return false; + + gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, multisample_renderbuffer_); + return true; } void DrawingBuffer::RestoreFramebufferBindings() { @@ -1301,7 +1310,7 @@ void DrawingBuffer::Bind(GLenum target) { gl_->BindFramebuffer(target, WantExplicitResolve() ? multisample_fbo_ : fbo_); } -scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray( +sk_sp<SkData> DrawingBuffer::PaintRenderingResultsToDataArray( SourceDrawingBuffer source_buffer) { ScopedStateRestorer scoped_state_restorer(this); @@ -1318,19 +1327,10 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray( if (!data_size.IsValid()) return nullptr; - unsigned byte_length = width * height * 4; - if (RuntimeEnabledFeatures::CanvasColorManagementEnabled() && - use_half_float_storage_) { - byte_length *= 2; - } - scoped_refptr<ArrayBuffer> dst_buffer = - ArrayBuffer::CreateOrNull(byte_length, 1); + unsigned byte_length = data_size.ValueOrDie<unsigned>(); + sk_sp<SkData> dst_buffer = TryAllocateSkData(byte_length); if (!dst_buffer) return nullptr; - scoped_refptr<Uint8Array> data_array = - Uint8Array::Create(std::move(dst_buffer), 0, byte_length); - if (!data_array) - return nullptr; GLuint fbo = 0; state_restorer_->SetFramebufferBindingDirty(); @@ -1344,10 +1344,10 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray( gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); } - ReadBackFramebuffer(static_cast<unsigned char*>(data_array->Data()), width, - height, kReadbackRGBA, + auto* writable_data = static_cast<uint8_t*>(dst_buffer->writable_data()); + ReadBackFramebuffer(writable_data, width, height, kReadbackRGBA, WebGLImageConversion::kAlphaDoNothing); - FlipVertically(static_cast<uint8_t*>(data_array->Data()), width, height); + FlipVertically(writable_data, width, height); if (fbo) { gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -1355,7 +1355,7 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray( gl_->DeleteFramebuffers(1, &fbo); } - return data_array; + return dst_buffer; } void DrawingBuffer::ReadBackFramebuffer(unsigned char* pixels, @@ -1502,7 +1502,6 @@ scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer( format = use_half_float_storage_ ? viz::RGBA_F16 : viz::RGBA_8888; } else { DCHECK(!use_half_float_storage_); - DCHECK(!UsingSwapChain()); format = viz::RGBX_8888; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h index 2cd5b3a58d1..2aa58412c39 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h @@ -235,8 +235,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, const IntRect& src_sub_rectangle, SourceDrawingBuffer); - scoped_refptr<Uint8Array> PaintRenderingResultsToDataArray( - SourceDrawingBuffer); + sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer); int SampleCount() const { return sample_count_; } bool ExplicitResolveOfMultisampleData() const { @@ -367,9 +366,6 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, // situation (the alpha channel is zeroed), requiring more fixups. GLuint rgb_workaround_texture_id = 0; - // The mailbox for |rgb_workaround_texture_id|. - gpu::Mailbox rgb_workaround_mailbox; - // The mailbox used to send this buffer to the compositor. gpu::Mailbox mailbox; @@ -478,6 +474,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, bool SetupRGBEmulationForBlitFramebuffer(bool is_user_draw_framebuffer_bound); void CleanupRGBEmulationForBlitFramebuffer(); + // Reallocate Multisampled renderbuffer, used by explicit resolve when resize + // and GPU switch + bool ReallocateMultisampleRenderbuffer(const IntSize&); + // Weak, reset by beginDestruction. Client* client_ = nullptr; diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc index e4a3331a283..68c1c5063ca 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc @@ -36,7 +36,7 @@ void GrTextureMailboxReleaseProc(void* data) { namespace blink { -void GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox, +bool GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox, GLenum& out_texture_target, const sk_sp<SkImage>& image, GLenum filter) { @@ -51,6 +51,9 @@ void GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox, DCHECK(gr); DCHECK(gl); GrTexture* gr_texture = image->getTexture(); + if (!gr_texture) + return false; + DCHECK(gr == gr_texture->getContext()); GrBackendTexture backend_texture = image->getBackendTexture(true); @@ -84,6 +87,7 @@ void GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox, gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->BindTexture(texture_target, 0); gr_texture->textureParamsModified(); + return true; } void GraphicsContext3DUtils::RegisterMailbox(GrTexture* gr_texture, diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h index f103ac3c74d..403becdd9f4 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h @@ -34,7 +34,7 @@ class PLATFORM_EXPORT GraphicsContext3DUtils { // mailbox for a given texture. The caching of pre-existing mailboxes survives // when the texture gets recycled by skia for creating a new SkSurface or // SkImage with a pre-existing GrTexture backing. - void GetMailboxForSkImage(gpu::Mailbox&, + bool GetMailboxForSkImage(gpu::Mailbox&, GLenum&, const sk_sp<SkImage>&, GLenum filter); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index 9f23d5d2e10..ecad1895ee6 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc @@ -46,6 +46,11 @@ ImageLayerBridge::~ImageLayerBridge() { void ImageLayerBridge::SetImage(scoped_refptr<StaticBitmapImage> image) { if (disposed_) return; + // There could be the case that the current SkImage (encapsulated in the image + // parameter of the function) is null, that means that something went wrong + // during the creation of the image and we should not try and setImage with it + if (image && !image->PaintImageForCurrentFrame().GetSkImage()) + return; image_ = std::move(image); if (image_) { @@ -58,16 +63,15 @@ void ImageLayerBridge::SetImage(scoped_refptr<StaticBitmapImage> image) { // ensure its opacity is not used. layer_->SetForceTextureToOpaque(!image_->CurrentFrameKnownToBeOpaque()); } - } - if (!has_presented_since_last_set_image_ && image_ && - image_->IsTextureBacked()) { - // If the layer bridge is not presenting, the GrContext may not be getting - // flushed regularly. The flush is normally triggered inside the - // m_image->EnsureMailbox() call of - // ImageLayerBridge::PrepareTransferableResource. To prevent a potential - // memory leak we must flush the GrContext here. - image_->PaintImageForCurrentFrame().GetSkImage()->getBackendTexture( - true); // GrContext flush. + if (!has_presented_since_last_set_image_ && image_->IsTextureBacked()) { + // If the layer bridge is not presenting, the GrContext may not be getting + // flushed regularly. The flush is normally triggered inside the + // m_image->EnsureMailbox() call of + // ImageLayerBridge::PrepareTransferableResource. To prevent a potential + // memory leak we must flush the GrContext here. + image_->PaintImageForCurrentFrame().GetSkImage()->getBackendTexture( + true); // GrContext flush. + } } has_presented_since_last_set_image_ = false; } @@ -242,9 +246,9 @@ cc::Layer* ImageLayerBridge::CcLayer() const { } ImageLayerBridge::RegisteredBitmap::RegisteredBitmap() = default; -ImageLayerBridge::RegisteredBitmap::RegisteredBitmap( - RegisteredBitmap&& other) noexcept = default; +ImageLayerBridge::RegisteredBitmap::RegisteredBitmap(RegisteredBitmap&& other) = + default; ImageLayerBridge::RegisteredBitmap& ImageLayerBridge::RegisteredBitmap:: -operator=(RegisteredBitmap&& other) noexcept = default; +operator=(RegisteredBitmap&& other) = default; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h index bea81dfbdd4..d550eb47af5 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h @@ -30,9 +30,8 @@ class Size; namespace blink { class PLATFORM_EXPORT ImageLayerBridge - : public GarbageCollectedFinalized<ImageLayerBridge>, + : public GarbageCollected<ImageLayerBridge>, public cc::TextureLayerClient { - public: ImageLayerBridge(OpacityMode); ~ImageLayerBridge() override; @@ -65,8 +64,8 @@ class PLATFORM_EXPORT ImageLayerBridge // only with software compositing. struct RegisteredBitmap { RegisteredBitmap(); - RegisteredBitmap(RegisteredBitmap&& other) noexcept; - RegisteredBitmap& operator=(RegisteredBitmap&& other) noexcept; + RegisteredBitmap(RegisteredBitmap&& other); + RegisteredBitmap& operator=(RegisteredBitmap&& other); scoped_refptr<cc::CrossThreadSharedBitmap> bitmap; cc::SharedBitmapIdRegistration registration; diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc index 7de8d47211e..f3bfe43141c 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc @@ -58,6 +58,10 @@ static void CreateContextProviderOnMainThread( context_attributes.enable_raster_interface = true; context_attributes.support_grcontext = true; + // The shared GPU context should not trigger a switch to the high-performance + // GPU. + context_attributes.prefer_low_power_gpu = true; + *gpu_compositing_disabled = Platform::Current()->IsGpuCompositingDisabled(); if (*gpu_compositing_disabled && only_if_gpu_compositing) { waitable_event->Signal(); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc index 832820921f4..1592804d496 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc @@ -7,6 +7,7 @@ #include <memory> #include "base/test/null_task_runner.h" +#include "components/viz/test/test_gles2_interface.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -15,6 +16,7 @@ #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/khronos/GLES2/gl2ext.h" @@ -71,9 +73,6 @@ class MailboxMockGLES2Interface : public TestGLES2Interface { MOCK_METHOD1(GenUnverifiedSyncTokenCHROMIUM, void(GLbyte*)); }; -class MailboxSharedGpuContextTest - : public SharedGpuContextTestBase<MailboxMockGLES2Interface> {}; - // Test fixure that simulate a graphics context creation failure, when using gpu // compositing. class BadSharedGpuContextTest : public Test { @@ -210,13 +209,18 @@ TEST_F(SoftwareCompositingTest, CompositingMode) { EXPECT_FALSE(SharedGpuContext::IsGpuCompositingEnabled()); } -class FakeMailboxGenerator { - STACK_ALLOCATED(); - +class MailboxSharedGpuContextTest : public Test { public: - void ProduceTexture(GLuint texture, GLbyte* name) { *name = counter_++; } + void SetUp() override { + task_runner_ = base::MakeRefCounted<base::NullTaskRunner>(); + handle_ = std::make_unique<base::ThreadTaskRunnerHandle>(task_runner_); + context_ = viz::TestContextProvider::Create(); + InitializeSharedGpuContext(context_.get()); + } - GLbyte counter_ = 1; + scoped_refptr<viz::TestContextProvider> context_; + scoped_refptr<base::NullTaskRunner> task_runner_; + std::unique_ptr<base::ThreadTaskRunnerHandle> handle_; }; TEST_F(MailboxSharedGpuContextTest, MailboxCaching) { @@ -231,104 +235,25 @@ TEST_F(MailboxSharedGpuContextTest, MailboxCaching) { CanvasResourceProvider::kDefaultPresentationMode, nullptr // canvas_resource_dispatcher ); + ASSERT_TRUE(resource_provider->IsAccelerated()); EXPECT_TRUE(resource_provider && resource_provider->IsValid()); scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot(); - testing::Mock::VerifyAndClearExpectations(&gl_); - - FakeMailboxGenerator mailboxGenerator; - gpu::Mailbox mailbox; - GLenum texture_target; - mailbox.name[0] = 0; - - EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, mailbox.name)) - .Times(1) - .WillOnce(testing::Invoke(&mailboxGenerator, - &FakeMailboxGenerator::ProduceTexture)); - - SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage( - mailbox, texture_target, image->PaintImageForCurrentFrame().GetSkImage(), - GL_NEAREST); - - EXPECT_EQ(mailbox.name[0], 1); - - testing::Mock::VerifyAndClearExpectations(&gl_); - - EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, mailbox.name)) - .Times(0); // ProduceTextureDirectCHROMIUM must not be called! - - mailbox.name[0] = 0; - SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage( - mailbox, texture_target, image->PaintImageForCurrentFrame().GetSkImage(), - GL_NEAREST); - EXPECT_EQ(mailbox.name[0], 1); - - testing::Mock::VerifyAndClearExpectations(&gl_); -} - -TEST_F(MailboxSharedGpuContextTest, MailboxCacheSurvivesSkiaRecycling) { - IntSize size(10, 10); - std::unique_ptr<CanvasResourceProvider> resource_provider = - CanvasResourceProvider::Create( - size, - CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage, - SharedGpuContext::ContextProviderWrapper(), - 0, // msaa_sample_count - kLow_SkFilterQuality, CanvasColorParams(), - CanvasResourceProvider::kDefaultPresentationMode, - nullptr // canvas_resource_dispatcher - ); - EXPECT_TRUE(resource_provider && resource_provider->IsValid()); - scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot(); - testing::Mock::VerifyAndClearExpectations(&gl_); - - FakeMailboxGenerator mailboxGenerator; - gpu::Mailbox mailbox; - GLenum texture_target; - mailbox.name[0] = 0; - - EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, mailbox.name)) - .Times(1) - .WillOnce(testing::Invoke(&mailboxGenerator, - &FakeMailboxGenerator::ProduceTexture)); + GLenum texture_target = GL_TEXTURE_2D; + gpu::Mailbox mailbox[3]; + // Creating the SkImage representation from the shared image mailbox registers + // the same mailbox mapping to this SkImage with the cache. This ensures we + // don't recreate a non-shared image mailbox if going from SkImage to mailbox. + mailbox[0] = image->GetMailbox(); SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage( - mailbox, texture_target, image->PaintImageForCurrentFrame().GetSkImage(), - GL_NEAREST); - - EXPECT_EQ(mailbox.name[0], 1); - testing::Mock::VerifyAndClearExpectations(&gl_); - - // Destroy image and surface to return texture to recleable resource pool - image = nullptr; - resource_provider = nullptr; - - testing::Mock::VerifyAndClearExpectations(&gl_); - - // Re-creating surface should recycle the old GrTexture inside skia - resource_provider = CanvasResourceProvider::Create( - size, CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage, - SharedGpuContext::ContextProviderWrapper(), - 0, // msaa_sample_count - kLow_SkFilterQuality, CanvasColorParams(), - CanvasResourceProvider::kDefaultPresentationMode, - nullptr // canvas_resource_dispatcher - ); + mailbox[1], texture_target, + image->PaintImageForCurrentFrame().GetSkImage(), GL_NEAREST); + EXPECT_EQ(mailbox[0], mailbox[1]); - EXPECT_TRUE(resource_provider && resource_provider->IsValid()); - image = resource_provider->Snapshot(); - - testing::Mock::VerifyAndClearExpectations(&gl_); - - EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, mailbox.name)) - .Times(0); // ProduceTextureDirectCHROMIUM must not be called! - - mailbox.name[0] = 0; SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage( - mailbox, texture_target, image->PaintImageForCurrentFrame().GetSkImage(), - GL_NEAREST); - EXPECT_EQ(mailbox.name[0], 1); - - testing::Mock::VerifyAndClearExpectations(&gl_); + mailbox[2], texture_target, + image->PaintImageForCurrentFrame().GetSkImage(), GL_NEAREST); + EXPECT_EQ(mailbox[1], mailbox[2]); } } // unnamed namespace diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc index 7681d87d34c..928096a88d0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc @@ -72,7 +72,7 @@ void WebGPUSwapBufferProvider::Neuter() { layer_ = nullptr; } - if (current_swap_buffer_) { + if (current_swap_buffer_ && !dawn_control_client_->IsDestroyed()) { // Ensure we wait for previous WebGPU commands before destroying the shared // image. gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); @@ -87,7 +87,7 @@ void WebGPUSwapBufferProvider::Neuter() { DawnTexture WebGPUSwapBufferProvider::GetNewTexture(DawnDevice device, const IntSize& size) { - DCHECK(!current_swap_buffer_); + DCHECK(!current_swap_buffer_ && !dawn_control_client_->IsDestroyed()); gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); gpu::SharedImageInterface* sii = @@ -132,7 +132,7 @@ bool WebGPUSwapBufferProvider::PrepareTransferableResource( cc::SharedBitmapIdRegistrar* bitmap_registrar, viz::TransferableResource* out_resource, std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { - DCHECK(!neutered_); + DCHECK(!neutered_ && !dawn_control_client_->IsDestroyed()); if (!current_swap_buffer_ || neutered_) { return false; @@ -206,6 +206,9 @@ WebGPUSwapBufferProvider::SwapBuffer::SwapBuffer( access_finished_token(creation_token) {} WebGPUSwapBufferProvider::SwapBuffer::~SwapBuffer() { + if (swap_buffers->dawn_control_client_->IsDestroyed()) { + return; + } gpu::SharedImageInterface* sii = swap_buffers->dawn_control_client_->GetContextProvider() ->SharedImageInterface(); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc index bb3177ba6fd..e599e2eda72 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h" +#include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "gpu/command_buffer/client/gles2_interface.h" diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h index 1ffe2ab566c..4bd102781f0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h @@ -28,7 +28,7 @@ class GpuMemoryBufferImageCopy; class Image; class PLATFORM_EXPORT XRFrameTransport final - : public GarbageCollectedFinalized<XRFrameTransport>, + : public GarbageCollected<XRFrameTransport>, public device::mojom::blink::XRPresentationClient { public: explicit XRFrameTransport(); |