diff options
Diffstat (limited to 'chromium/gpu')
156 files changed, 1449 insertions, 2062 deletions
diff --git a/chromium/gpu/BUILD.gn b/chromium/gpu/BUILD.gn index c3653079338..bddfc37a9b4 100644 --- a/chromium/gpu/BUILD.gn +++ b/chromium/gpu/BUILD.gn @@ -475,7 +475,6 @@ test("gpu_unittests") { "command_buffer/client/webgpu_implementation_unittest.cc", "command_buffer/client/webgpu_implementation_unittest_autogen.h", "command_buffer/common/activity_flags_unittest.cc", - "command_buffer/common/bitfield_helpers_test.cc", "command_buffer/common/buffer_unittest.cc", "command_buffer/common/command_buffer_shared_test.cc", "command_buffer/common/debug_marker_manager_unittest.cc", diff --git a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py index 48e9e7a9e9e..a87151d9324 100755 --- a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -4058,72 +4058,6 @@ _FUNCTION_INFO = { 'client_test': False, 'extension': True, }, - 'BeginRasterCHROMIUM': { - 'decoder_func': 'DoBeginRasterCHROMIUM', - 'impl_func': True, - 'unit_test': False, - 'extension': 'CHROMIUM_raster_transport', - 'extension_flag': 'chromium_raster_transport', - }, - 'RasterCHROMIUM': { - 'decoder_func': 'DoRasterCHROMIUM', - 'internal': True, - 'impl_func': True, - 'unit_test': False, - 'cmd_args': 'GLuint raster_shm_id, GLuint raster_shm_offset,' - 'GLsizeiptr raster_shm_size, GLuint font_shm_id,' - 'GLuint font_shm_offset, GLsizeiptr font_shm_size', - 'extension': 'CHROMIUM_raster_transport', - 'extension_flag': 'chromium_raster_transport', - }, - 'MapRasterCHROMIUM': { - 'type': 'NoCommand', - 'extension': "CHROMIUM_raster_transport", - }, - 'UnmapRasterCHROMIUM': { - 'type': 'NoCommand', - 'extension': "CHROMIUM_raster_transport", - }, - 'MapFontBufferCHROMIUM': { - 'type': 'NoCommand', - 'extension': "CHROMIUM_raster_transport", - }, - 'EndRasterCHROMIUM': { - 'decoder_func': 'DoEndRasterCHROMIUM', - 'impl_func': True, - 'unit_test': False, - 'extension': 'CHROMIUM_raster_transport', - 'extension_flag': 'chromium_raster_transport', - }, - 'CreateTransferCacheEntryINTERNAL': { - 'decoder_func': 'DoCreateTransferCacheEntryINTERNAL', - 'cmd_args': 'GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, ' - 'GLuint handle_shm_offset, GLuint data_shm_id, ' - 'GLuint data_shm_offset, GLuint data_size', - 'internal': True, - 'impl_func': True, - 'client_test': False, - 'unit_test': False, - 'extension': True, - }, - 'DeleteTransferCacheEntryINTERNAL': { - 'decoder_func': 'DoDeleteTransferCacheEntryINTERNAL', - 'cmd_args': 'GLuint entry_type, GLuint entry_id', - 'internal': True, - 'impl_func': True, - 'client_test': False, - 'unit_test': False, - 'extension': True, - }, - 'UnlockTransferCacheEntryINTERNAL': { - 'decoder_func': 'DoUnlockTransferCacheEntryINTERNAL', - 'cmd_args': 'GLuint entry_type, GLuint entry_id', - 'internal': True, - 'impl_func': True, - 'client_test': False, - 'unit_test': False, - 'extension': True, - }, 'TexStorage2DImageCHROMIUM': { 'decoder_func': 'DoTexStorage2DImageCHROMIUM', 'unit_test': False, diff --git a/chromium/gpu/command_buffer/client/buffer_tracker_unittest.cc b/chromium/gpu/command_buffer/client/buffer_tracker_unittest.cc index 5c42da33060..d446f54da7c 100644 --- a/chromium/gpu/command_buffer/client/buffer_tracker_unittest.cc +++ b/chromium/gpu/command_buffer/client/buffer_tracker_unittest.cc @@ -57,12 +57,12 @@ class BufferTrackerTest : public testing::Test { kNumCommandEntries * sizeof(CommandBufferEntry); void SetUp() override { - command_buffer_.reset(new MockClientCommandBufferImpl()); - helper_.reset(new GLES2CmdHelper(command_buffer_.get())); + command_buffer_ = std::make_unique<MockClientCommandBufferImpl>(); + helper_ = std::make_unique<GLES2CmdHelper>(command_buffer_.get()); helper_->Initialize(kCommandBufferSizeBytes); - mapped_memory_.reset( - new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); - buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); + mapped_memory_ = std::make_unique<MappedMemoryManager>( + helper_.get(), MappedMemoryManager::kNoLimit); + buffer_tracker_ = std::make_unique<BufferTracker>(mapped_memory_.get()); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/client/client_test_helper.cc b/chromium/gpu/command_buffer/client/client_test_helper.cc index 4fd55a3274a..8512d4fb581 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.cc +++ b/chromium/gpu/command_buffer/client/client_test_helper.cc @@ -98,11 +98,8 @@ void FakeCommandBufferServiceBase::SetContextLostReason( state_.context_lost_reason = reason; } -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const int32_t FakeCommandBufferServiceBase::kTransferBufferBaseId; const int32_t FakeCommandBufferServiceBase::kMaxTransferBuffers; -#endif MockClientCommandBuffer::MockClientCommandBuffer() { DelegateToFake(); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc index d8837590454..978efe7ec8d 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -41,8 +41,9 @@ const int32_t kUnusedCommandId = 5; // we use 0 and 2 currently. class CommandBufferHelperTest : public testing::Test { protected: void SetUp() override { - command_buffer_.reset(new CommandBufferDirectLocked()); - api_mock_.reset(new AsyncAPIMock(true, command_buffer_->service())); + command_buffer_ = std::make_unique<CommandBufferDirectLocked>(); + api_mock_ = + std::make_unique<AsyncAPIMock>(true, command_buffer_->service()); command_buffer_->set_handler(api_mock_.get()); // ignore noops in the mock - we don't want to inspect the internals of the @@ -50,7 +51,7 @@ class CommandBufferHelperTest : public testing::Test { EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, _, _)) .WillRepeatedly(Return(error::kNoError)); - helper_.reset(new CommandBufferHelper(command_buffer_.get())); + helper_ = std::make_unique<CommandBufferHelper>(command_buffer_.get()); helper_->Initialize(kCommandBufferSizeBytes); test_command_next_id_ = kUnusedCommandId; diff --git a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc index 060f62ff0d4..158154386cb 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc @@ -36,8 +36,9 @@ class BaseFencedAllocatorTest : public testing::Test { static const int kAllocAlignment = 16; void SetUp() override { - command_buffer_.reset(new CommandBufferDirect()); - api_mock_.reset(new AsyncAPIMock(true, command_buffer_->service())); + command_buffer_ = std::make_unique<CommandBufferDirect>(); + api_mock_ = + std::make_unique<AsyncAPIMock>(true, command_buffer_->service()); command_buffer_->set_handler(api_mock_.get()); // ignore noops in the mock - we don't want to inspect the internals of the @@ -49,7 +50,7 @@ class BaseFencedAllocatorTest : public testing::Test { .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), Return(error::kNoError))); - helper_.reset(new CommandBufferHelper(command_buffer_.get())); + helper_ = std::make_unique<CommandBufferHelper>(command_buffer_.get()); helper_->Initialize(kBufferSize); } @@ -61,9 +62,7 @@ class BaseFencedAllocatorTest : public testing::Test { base::test::SingleThreadTaskEnvironment task_environment_; }; -#ifndef _MSC_VER const unsigned int BaseFencedAllocatorTest::kBufferSize; -#endif // Test fixture for FencedAllocator test - Creates a FencedAllocator, using a // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling @@ -73,7 +72,7 @@ class FencedAllocatorTest : public BaseFencedAllocatorTest { protected: void SetUp() override { BaseFencedAllocatorTest::SetUp(); - allocator_.reset(new FencedAllocator(kBufferSize, helper_.get())); + allocator_ = std::make_unique<FencedAllocator>(kBufferSize, helper_.get()); } void TearDown() override { @@ -383,9 +382,8 @@ class FencedAllocatorWrapperTest : public BaseFencedAllocatorTest { // something. buffer_.reset(static_cast<char*>(base::AlignedAlloc( kBufferSize, kAllocAlignment))); - allocator_.reset(new FencedAllocatorWrapper(kBufferSize, - helper_.get(), - buffer_.get())); + allocator_ = std::make_unique<FencedAllocatorWrapper>( + kBufferSize, helper_.get(), buffer_.get()); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/client/gl_helper.cc b/chromium/gpu/command_buffer/client/gl_helper.cc index 3d4aaf2c5b7..6a733de5247 100644 --- a/chromium/gpu/command_buffer/client/gl_helper.cc +++ b/chromium/gpu/command_buffer/client/gl_helper.cc @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include <utility> @@ -500,14 +501,14 @@ void GLHelper::ReadbackTextureAsync(GLuint texture, void GLHelper::InitCopyTextToImpl() { // Lazily initialize |copy_texture_to_impl_| if (!copy_texture_to_impl_) - copy_texture_to_impl_.reset( - new CopyTextureToImpl(gl_, context_support_, this)); + copy_texture_to_impl_ = + std::make_unique<CopyTextureToImpl>(gl_, context_support_, this); } void GLHelper::InitScalerImpl() { // Lazily initialize |scaler_impl_| if (!scaler_impl_) - scaler_impl_.reset(new GLHelperScaling(gl_, this)); + scaler_impl_ = std::make_unique<GLHelperScaling>(gl_, this); } GLint GLHelper::MaxDrawBuffers() { diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc index 6400b35a7e9..11b6ce54fb7 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc @@ -16,6 +16,7 @@ #include <algorithm> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -290,7 +291,7 @@ gpu::ContextResult GLES2Implementation::Initialize( helper_); for (int i = 0; i < static_cast<int>(IdNamespaces::kNumIdNamespaces); ++i) - id_allocators_[i].reset(new IdAllocator()); + id_allocators_[i] = std::make_unique<IdAllocator>(); if (support_client_side_arrays_) { GetIdHandler(SharedIdNamespaces::kBuffers) @@ -298,9 +299,9 @@ gpu::ContextResult GLES2Implementation::Initialize( &reserved_ids_[0]); } - vertex_array_object_manager_.reset(new VertexArrayObjectManager( + vertex_array_object_manager_ = std::make_unique<VertexArrayObjectManager>( capabilities_.max_vertex_attribs, reserved_ids_[0], reserved_ids_[1], - support_client_side_arrays_)); + support_client_side_arrays_); // GL_BIND_GENERATES_RESOURCE_CHROMIUM state must be the same // on Client & Service. diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc index cbf99f5358b..1f4f495faf1 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -621,8 +621,6 @@ void GLES3ImplementationTest::SetUp() { ASSERT_TRUE(Initialize(init_options)); } -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const uint8_t GLES2ImplementationTest::kInitialValue; const int32_t GLES2ImplementationTest::kNumCommandEntries; const int32_t GLES2ImplementationTest::kCommandBufferSizeBytes; @@ -649,7 +647,6 @@ const GLuint GLES2ImplementationTest::kTexturesStartId; const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId; const GLuint GLES2ImplementationTest::kQueriesStartId; const GLuint GLES2ImplementationTest::kVertexArraysStartId; -#endif TEST_F(GLES2ImplementationTest, Basic) { EXPECT_TRUE(gl_->share_group()); diff --git a/chromium/gpu/command_buffer/client/implementation_base.cc b/chromium/gpu/command_buffer/client/implementation_base.cc index 33636128bf1..0492f62a9f7 100644 --- a/chromium/gpu/command_buffer/client/implementation_base.cc +++ b/chromium/gpu/command_buffer/client/implementation_base.cc @@ -20,10 +20,8 @@ namespace gpu { -#if !defined(_MSC_VER) const uint32_t ImplementationBase::kMaxSizeOfSimpleResult; const uint32_t ImplementationBase::kStartingOffset; -#endif ImplementationBase::ImplementationBase(CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer, diff --git a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc index e6ed987c482..9d115cc2304 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -33,8 +33,9 @@ class MappedMemoryTestBase : public testing::Test { static const unsigned int kBufferSize = 1024; void SetUp() override { - command_buffer_.reset(new CommandBufferDirectLocked()); - api_mock_.reset(new AsyncAPIMock(true, command_buffer_->service())); + command_buffer_ = std::make_unique<CommandBufferDirectLocked>(); + api_mock_ = + std::make_unique<AsyncAPIMock>(true, command_buffer_->service()); command_buffer_->set_handler(api_mock_.get()); // ignore noops in the mock - we don't want to inspect the internals of the @@ -46,7 +47,7 @@ class MappedMemoryTestBase : public testing::Test { .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), Return(error::kNoError))); - helper_.reset(new CommandBufferHelper(command_buffer_.get())); + helper_ = std::make_unique<CommandBufferHelper>(command_buffer_.get()); helper_->Initialize(kBufferSize); } @@ -58,9 +59,7 @@ class MappedMemoryTestBase : public testing::Test { base::test::SingleThreadTaskEnvironment task_environment_; }; -#ifndef _MSC_VER const unsigned int MappedMemoryTestBase::kBufferSize; -#endif // Test fixture for MemoryChunk test - Creates a MemoryChunk, using a // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling @@ -77,7 +76,7 @@ class MemoryChunkTest : public MappedMemoryTestBase { shared_memory_region.Map(); buffer_ = MakeBufferFromSharedMemory(std::move(shared_memory_region), std::move(shared_memory_mapping)); - chunk_.reset(new MemoryChunk(kShmId, buffer_, helper_.get())); + chunk_ = std::make_unique<MemoryChunk>(kShmId, buffer_, helper_.get()); } void TearDown() override { @@ -93,9 +92,7 @@ class MemoryChunkTest : public MappedMemoryTestBase { scoped_refptr<gpu::Buffer> buffer_; }; -#ifndef _MSC_VER const int32_t MemoryChunkTest::kShmId; -#endif TEST_F(MemoryChunkTest, Basic) { const unsigned int kSize = 16; @@ -136,8 +133,8 @@ class MappedMemoryManagerTest : public MappedMemoryTestBase { protected: void SetUp() override { MappedMemoryTestBase::SetUp(); - manager_.reset( - new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); + manager_ = std::make_unique<MappedMemoryManager>( + helper_.get(), MappedMemoryManager::kNoLimit); } void TearDown() override { @@ -328,7 +325,7 @@ TEST_F(MappedMemoryManagerTest, ChunkSizeMultiple) { TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { const unsigned int kChunkSize = 2048; // Reset the manager with a memory limit. - manager_.reset(new MappedMemoryManager(helper_.get(), kChunkSize)); + manager_ = std::make_unique<MappedMemoryManager>(helper_.get(), kChunkSize); manager_->set_chunk_size_multiple(kChunkSize); // Allocate one chunk worth of memory. @@ -359,7 +356,7 @@ TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { const unsigned int kSize = 1024; // Reset the manager with a memory limit. - manager_.reset(new MappedMemoryManager(helper_.get(), kSize)); + manager_ = std::make_unique<MappedMemoryManager>(helper_.get(), kSize); const unsigned int kChunkSize = 2 * 1024; manager_->set_chunk_size_multiple(kChunkSize); @@ -411,7 +408,7 @@ TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { TEST_F(MappedMemoryManagerTest, MaxAllocationTest) { const unsigned int kSize = 1024; // Reset the manager with a memory limit. - manager_.reset(new MappedMemoryManager(helper_.get(), kSize)); + manager_ = std::make_unique<MappedMemoryManager>(helper_.get(), kSize); const size_t kLimit = 512; manager_->set_chunk_size_multiple(kLimit); diff --git a/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc b/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc index c533d99dfa3..c9e652d6a97 100644 --- a/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc +++ b/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc @@ -65,7 +65,7 @@ class ProgramInfoManagerTest : public testing::Test { }; void SetUp() override { - program_info_manager_.reset(new ProgramInfoManager); + program_info_manager_ = std::make_unique<ProgramInfoManager>(); program_info_manager_->CreateInfo(kClientProgramId); { base::AutoLock auto_lock(program_info_manager_->lock_); diff --git a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc index 515e52dbc3c..0b3982d0a15 100644 --- a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc +++ b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc @@ -34,12 +34,12 @@ class QuerySyncManagerTest : public testing::Test { kNumCommandEntries * sizeof(CommandBufferEntry); void SetUp() override { - command_buffer_.reset(new MockClientCommandBuffer()); - helper_.reset(new GLES2CmdHelper(command_buffer_.get())); + command_buffer_ = std::make_unique<MockClientCommandBuffer>(); + helper_ = std::make_unique<GLES2CmdHelper>(command_buffer_.get()); helper_->Initialize(kCommandBufferSizeBytes); - mapped_memory_.reset( - new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); - sync_manager_.reset(new QuerySyncManager(mapped_memory_.get())); + mapped_memory_ = std::make_unique<MappedMemoryManager>( + helper_.get(), MappedMemoryManager::kNoLimit); + sync_manager_ = std::make_unique<QuerySyncManager>(mapped_memory_.get()); } void TearDown() override { @@ -209,12 +209,12 @@ class QueryTrackerTest : public testing::Test { kNumCommandEntries * sizeof(CommandBufferEntry); void SetUp() override { - command_buffer_.reset(new MockClientCommandBuffer()); - helper_.reset(new GLES2CmdHelper(command_buffer_.get())); + command_buffer_ = std::make_unique<MockClientCommandBuffer>(); + helper_ = std::make_unique<GLES2CmdHelper>(command_buffer_.get()); helper_->Initialize(kCommandBufferSizeBytes); - mapped_memory_.reset( - new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); - query_tracker_.reset(new QueryTracker(mapped_memory_.get())); + mapped_memory_ = std::make_unique<MappedMemoryManager>( + helper_.get(), MappedMemoryManager::kNoLimit); + query_tracker_ = std::make_unique<QueryTracker>(mapped_memory_.get()); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/client/raster_cmd_helper_autogen.h b/chromium/gpu/command_buffer/client/raster_cmd_helper_autogen.h index c7ae12020f9..dd4a13dc3be 100644 --- a/chromium/gpu/command_buffer/client/raster_cmd_helper_autogen.h +++ b/chromium/gpu/command_buffer/client/raster_cmd_helper_autogen.h @@ -89,6 +89,7 @@ void LoseContextCHROMIUM(GLenum current, GLenum other) { } void BeginRasterCHROMIUMImmediate(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const GLbyte* mailbox) { @@ -98,7 +99,8 @@ void BeginRasterCHROMIUMImmediate(GLuint sk_color, GetImmediateCmdSpaceTotalSize<raster::cmds::BeginRasterCHROMIUMImmediate>( size); if (c) { - c->Init(sk_color, msaa_sample_count, can_use_lcd_text, mailbox); + c->Init(sk_color, needs_clear, msaa_sample_count, can_use_lcd_text, + mailbox); } } diff --git a/chromium/gpu/command_buffer/client/raster_implementation.cc b/chromium/gpu/command_buffer/client/raster_implementation.cc index bf6f3d12f43..3075f4ef146 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation.cc +++ b/chromium/gpu/command_buffer/client/raster_implementation.cc @@ -1159,14 +1159,15 @@ void RasterImplementation::ConvertYUVAMailboxesToRGB( void RasterImplementation::BeginRasterCHROMIUM( GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, const GLbyte* mailbox) { DCHECK(!raster_properties_); - helper_->BeginRasterCHROMIUMImmediate(sk_color, msaa_sample_count, - can_use_lcd_text, mailbox); + helper_->BeginRasterCHROMIUMImmediate( + sk_color, needs_clear, msaa_sample_count, can_use_lcd_text, mailbox); raster_properties_.emplace(sk_color, can_use_lcd_text, color_space.ToSkColorSpace()); diff --git a/chromium/gpu/command_buffer/client/raster_implementation.h b/chromium/gpu/command_buffer/client/raster_implementation.h index a20721265cc..71ee88e98b3 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation.h +++ b/chromium/gpu/command_buffer/client/raster_implementation.h @@ -138,6 +138,7 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface, const gpu::Mailbox yuva_plane_mailboxes[]) override; void BeginRasterCHROMIUM(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, diff --git a/chromium/gpu/command_buffer/client/raster_implementation_gles.cc b/chromium/gpu/command_buffer/client/raster_implementation_gles.cc index 4e60eb15cfa..43abd04fe71 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/chromium/gpu/command_buffer/client/raster_implementation_gles.cc @@ -39,6 +39,8 @@ GLenum SkColorTypeToGLDataFormat(SkColorType color_type) { return GL_RGBA; case kBGRA_8888_SkColorType: return GL_BGRA_EXT; + case kR8G8_unorm_SkColorType: + return GL_RG_EXT; case kGray_8_SkColorType: return GL_LUMINANCE; default: @@ -52,6 +54,7 @@ GLenum SkColorTypeToGLDataType(SkColorType color_type) { switch (color_type) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: + case kR8G8_unorm_SkColorType: case kGray_8_SkColorType: return GL_UNSIGNED_BYTE; default: @@ -206,6 +209,7 @@ void RasterImplementationGLES::ConvertYUVAMailboxesToRGB( void RasterImplementationGLES::BeginRasterCHROMIUM( GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, diff --git a/chromium/gpu/command_buffer/client/raster_implementation_gles.h b/chromium/gpu/command_buffer/client/raster_implementation_gles.h index d5700b64e57..e98a837d214 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation_gles.h +++ b/chromium/gpu/command_buffer/client/raster_implementation_gles.h @@ -86,6 +86,7 @@ class RASTER_EXPORT RasterImplementationGLES : public RasterInterface { // OOP-Raster void BeginRasterCHROMIUM(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, diff --git a/chromium/gpu/command_buffer/client/raster_implementation_gles_unittest.cc b/chromium/gpu/command_buffer/client/raster_implementation_gles_unittest.cc index e9f95f40f04..f12cc0edcbb 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation_gles_unittest.cc +++ b/chromium/gpu/command_buffer/client/raster_implementation_gles_unittest.cc @@ -145,19 +145,6 @@ class RasterMockGLES2Interface : public gles2::GLES2InterfaceStub { GLsizei width, GLsizei height)); - // OOP-Raster - MOCK_METHOD6(BeginRasterCHROMIUM, - void(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_id)); - MOCK_METHOD2(RasterCHROMIUM, void(GLsizeiptr size, const void* list)); - MOCK_METHOD1(MapRasterCHROMIUM, void*(GLsizeiptr size)); - MOCK_METHOD1(UnmapRasterCHROMIUM, void(GLsizeiptr written)); - MOCK_METHOD0(EndRasterCHROMIUM, void()); - MOCK_METHOD2(PixelStorei, void(GLenum pname, GLint param)); MOCK_METHOD2(TraceBeginCHROMIUM, void(const char* category_name, const char* trace_name)); diff --git a/chromium/gpu/command_buffer/client/raster_implementation_unittest.cc b/chromium/gpu/command_buffer/client/raster_implementation_unittest.cc index f59d22b9b77..cb03fa4278a 100644 --- a/chromium/gpu/command_buffer/client/raster_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/raster_implementation_unittest.cc @@ -324,8 +324,6 @@ class RasterImplementationManualInitTest : public RasterImplementationTest { void SetUp() override {} }; -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const uint8_t RasterImplementationTest::kInitialValue; const uint32_t RasterImplementationTest::kNumCommandEntries; const uint32_t RasterImplementationTest::kCommandBufferSizeBytes; @@ -338,7 +336,6 @@ const GLuint RasterImplementationTest::kStartId; const GLuint RasterImplementationTest::kBuffersStartId; const GLuint RasterImplementationTest::kTexturesStartId; const GLuint RasterImplementationTest::kQueriesStartId; -#endif TEST_F(RasterImplementationTest, GetBucketContents) { const uint32_t kBucketId = RasterImplementation::kResultBucketId; diff --git a/chromium/gpu/command_buffer/client/raster_interface.h b/chromium/gpu/command_buffer/client/raster_interface.h index ae17b169ac4..3e19a082e2c 100644 --- a/chromium/gpu/command_buffer/client/raster_interface.h +++ b/chromium/gpu/command_buffer/client/raster_interface.h @@ -74,6 +74,7 @@ class RasterInterface : public InterfaceBase { // OOP-Raster virtual void BeginRasterCHROMIUM(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const gfx::ColorSpace& color_space, diff --git a/chromium/gpu/command_buffer/client/ring_buffer_test.cc b/chromium/gpu/command_buffer/client/ring_buffer_test.cc index 65ddddc6553..56c1db12e6a 100644 --- a/chromium/gpu/command_buffer/client/ring_buffer_test.cc +++ b/chromium/gpu/command_buffer/client/ring_buffer_test.cc @@ -88,10 +88,8 @@ class BaseRingBufferTest : public testing::Test { base::test::SingleThreadTaskEnvironment task_environment_; }; -#ifndef _MSC_VER const unsigned int BaseRingBufferTest::kBaseOffset; const unsigned int BaseRingBufferTest::kBufferSize; -#endif // Test fixture for RingBuffer test - Creates a RingBuffer, using a // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling diff --git a/chromium/gpu/command_buffer/client/share_group.cc b/chromium/gpu/command_buffer/client/share_group.cc index a9233874578..fc978cb112f 100644 --- a/chromium/gpu/command_buffer/client/share_group.cc +++ b/chromium/gpu/command_buffer/client/share_group.cc @@ -6,6 +6,7 @@ #include <stdint.h> +#include <memory> #include <vector> #include "base/containers/stack.h" @@ -369,9 +370,9 @@ ShareGroup::ShareGroup(bool bind_generates_resource, uint64_t tracing_guid) i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces); ++i) { if (i == static_cast<int>(SharedIdNamespaces::kProgramsAndShaders)) { - id_handlers_[i].reset(new NonReusedIdHandler()); + id_handlers_[i] = std::make_unique<NonReusedIdHandler>(); } else { - id_handlers_[i].reset(new IdHandler()); + id_handlers_[i] = std::make_unique<IdHandler>(); } } } else { @@ -379,15 +380,15 @@ ShareGroup::ShareGroup(bool bind_generates_resource, uint64_t tracing_guid) i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces); ++i) { if (i == static_cast<int>(SharedIdNamespaces::kProgramsAndShaders)) { - id_handlers_[i].reset(new NonReusedIdHandler()); + id_handlers_[i] = std::make_unique<NonReusedIdHandler>(); } else { - id_handlers_[i].reset(new StrictIdHandler(i)); + id_handlers_[i] = std::make_unique<StrictIdHandler>(i); } } } - program_info_manager_.reset(new ProgramInfoManager); + program_info_manager_ = std::make_unique<ProgramInfoManager>(); for (auto& range_id_handler : range_id_handlers_) { - range_id_handler.reset(new RangeIdHandler()); + range_id_handler = std::make_unique<RangeIdHandler>(); } } diff --git a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc index 254983f1b1e..5a9a09c561c 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc @@ -63,15 +63,16 @@ class TransferBufferTest : public testing::Test { }; void TransferBufferTest::SetUp() { - command_buffer_.reset(new StrictMock<MockClientCommandBufferMockFlush>()); + command_buffer_ = + std::make_unique<StrictMock<MockClientCommandBufferMockFlush>>(); - helper_.reset(new CommandBufferHelper(command_buffer())); + helper_ = std::make_unique<CommandBufferHelper>(command_buffer()); ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes), gpu::ContextResult::kSuccess); transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId(); - transfer_buffer_.reset(new TransferBuffer(helper_.get())); + transfer_buffer_ = std::make_unique<TransferBuffer>(helper_.get()); } void TransferBufferTest::TearDown() { @@ -89,14 +90,11 @@ void TransferBufferTest::TearDown() { transfer_buffer_.reset(); } -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const int32_t TransferBufferTest::kNumCommandEntries; const int32_t TransferBufferTest::kCommandBufferSizeBytes; const uint32_t TransferBufferTest::kStartingOffset; const uint32_t TransferBufferTest::kAlignment; const uint32_t TransferBufferTest::kTransferBufferSize; -#endif TEST_F(TransferBufferTest, Basic) { Initialize(); @@ -275,7 +273,8 @@ class TransferBufferExpandContractTest : public testing::Test { }; void TransferBufferExpandContractTest::SetUp() { - command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>()); + command_buffer_ = + std::make_unique<StrictMock<MockClientCommandBufferCanFail>>(); command_buffer_->SetTokenForSetGetBuffer(0); EXPECT_CALL(*command_buffer(), @@ -285,7 +284,7 @@ void TransferBufferExpandContractTest::SetUp() { &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) .RetiresOnSaturation(); - helper_.reset(new CommandBufferHelper(command_buffer())); + helper_ = std::make_unique<CommandBufferHelper>(command_buffer()); ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes), gpu::ContextResult::kSuccess); @@ -298,7 +297,7 @@ void TransferBufferExpandContractTest::SetUp() { &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) .RetiresOnSaturation(); - transfer_buffer_.reset(new TransferBuffer(helper_.get())); + transfer_buffer_ = std::make_unique<TransferBuffer>(helper_.get()); ASSERT_TRUE(transfer_buffer_->Initialize( kStartTransferBufferSize, kStartingOffset, kMinTransferBufferSize, kMaxTransferBufferSize, kAlignment)); @@ -324,8 +323,6 @@ void TransferBufferExpandContractTest::TearDown() { transfer_buffer_.reset(); } -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const int32_t TransferBufferExpandContractTest::kNumCommandEntries; const int32_t TransferBufferExpandContractTest::kCommandBufferSizeBytes; const uint32_t TransferBufferExpandContractTest::kStartingOffset; @@ -333,7 +330,6 @@ const uint32_t TransferBufferExpandContractTest::kAlignment; const uint32_t TransferBufferExpandContractTest::kStartTransferBufferSize; const uint32_t TransferBufferExpandContractTest::kMaxTransferBufferSize; const uint32_t TransferBufferExpandContractTest::kMinTransferBufferSize; -#endif TEST_F(TransferBufferExpandContractTest, ExpandWithSmallAllocations) { int32_t token = helper_->InsertToken(); diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc b/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc index b532ef7527f..f11e84de21b 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc @@ -37,12 +37,9 @@ class VertexArrayObjectManagerTest : public testing::Test { std::unique_ptr<VertexArrayObjectManager> manager_; }; -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const GLuint VertexArrayObjectManagerTest::kMaxAttribs; const GLuint VertexArrayObjectManagerTest::kClientSideArrayBuffer; const GLuint VertexArrayObjectManagerTest::kClientSideElementArrayBuffer; -#endif TEST_F(VertexArrayObjectManagerTest, Basic) { EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers()); diff --git a/chromium/gpu/command_buffer/client/webgpu_implementation_unittest.cc b/chromium/gpu/command_buffer/client/webgpu_implementation_unittest.cc index f0ba7951d90..35276a7bb63 100644 --- a/chromium/gpu/command_buffer/client/webgpu_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/webgpu_implementation_unittest.cc @@ -6,6 +6,8 @@ #include "gpu/command_buffer/client/webgpu_implementation.h" +#include <memory> + #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/client/mock_transfer_buffer.h" #include "gpu/command_buffer/client/shared_memory_limits.h" @@ -45,16 +47,16 @@ class WebGPUImplementationTest : public testing::Test { bool Initialize() { SharedMemoryLimits limits = SharedMemoryLimitsForTesting(); - command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); + command_buffer_ = std::make_unique<StrictMock<MockClientCommandBuffer>>(); - transfer_buffer_.reset( - new MockTransferBuffer(command_buffer_.get(), kTransferBufferSize, - ImplementationBase::kStartingOffset, - ImplementationBase::kAlignment, false)); + transfer_buffer_ = std::make_unique<MockTransferBuffer>( + command_buffer_.get(), kTransferBufferSize, + ImplementationBase::kStartingOffset, ImplementationBase::kAlignment, + false); - helper_.reset(new WebGPUCmdHelper(command_buffer_.get())); + helper_ = std::make_unique<WebGPUCmdHelper>(command_buffer_.get()); helper_->Initialize(limits.command_buffer_size); - gpu_control_.reset(new StrictMock<MockClientGpuControl>()); + gpu_control_ = std::make_unique<StrictMock<MockClientGpuControl>>(); EXPECT_CALL(*gpu_control_, GetCapabilities()) .WillOnce(ReturnRef(capabilities_)); @@ -62,8 +64,8 @@ class WebGPUImplementationTest : public testing::Test { { InSequence sequence; - gl_.reset(new WebGPUImplementation(helper_.get(), transfer_buffer_.get(), - gpu_control_.get())); + gl_ = std::make_unique<WebGPUImplementation>( + helper_.get(), transfer_buffer_.get(), gpu_control_.get()); } // The client should be set to something non-null. diff --git a/chromium/gpu/command_buffer/common/BUILD.gn b/chromium/gpu/command_buffer/common/BUILD.gn index 2ef911b49e9..2041a24124d 100644 --- a/chromium/gpu/command_buffer/common/BUILD.gn +++ b/chromium/gpu/command_buffer/common/BUILD.gn @@ -51,7 +51,6 @@ source_set("common_sources") { sources = [ "activity_flags.cc", "activity_flags.h", - "bitfield_helpers.h", "buffer.cc", "buffer.h", "capabilities.cc", diff --git a/chromium/gpu/command_buffer/common/bitfield_helpers.h b/chromium/gpu/command_buffer/common/bitfield_helpers.h deleted file mode 100644 index 62841eec5ad..00000000000 --- a/chromium/gpu/command_buffer/common/bitfield_helpers.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains a helper template class used to access bit fields in -// unsigned int_ts. - -#ifndef GPU_COMMAND_BUFFER_COMMON_BITFIELD_HELPERS_H_ -#define GPU_COMMAND_BUFFER_COMMON_BITFIELD_HELPERS_H_ - -namespace gpu { - -// Bitfield template class, used to access bit fields in unsigned int_ts. -template<int shift, int length> class BitField { - public: - static const unsigned int kShift = shift; - static const unsigned int kLength = length; - // the following is really (1<<length)-1 but also work for length == 32 - // without compiler warning. - static const unsigned int kMask = 1U + ((1U << (length-1)) - 1U) * 2U; - - // Gets the value contained in this field. - static unsigned int Get(unsigned int container) { - return (container >> kShift) & kMask; - } - - // Makes a value that can be or-ed into this field. - static unsigned int MakeValue(unsigned int value) { - return (value & kMask) << kShift; - } - - // Changes the value of this field. - static void Set(unsigned int *container, unsigned int field_value) { - *container = (*container & ~(kMask << kShift)) | MakeValue(field_value); - } -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_COMMON_BITFIELD_HELPERS_H_ diff --git a/chromium/gpu/command_buffer/common/bitfield_helpers_test.cc b/chromium/gpu/command_buffer/common/bitfield_helpers_test.cc deleted file mode 100644 index 705e9337e4f..00000000000 --- a/chromium/gpu/command_buffer/common/bitfield_helpers_test.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Tests for the bitfield helper class. - -#include "testing/gtest/include/gtest/gtest.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" - -namespace gpu { - -// Tests that BitField<>::Get returns the right bits. -TEST(BitFieldTest, TestGet) { - unsigned int value = 0x12345678u; - EXPECT_EQ(0x8u, (BitField<0, 4>::Get(value))); - EXPECT_EQ(0x45u, (BitField<12, 8>::Get(value))); - EXPECT_EQ(0x12345678u, (BitField<0, 32>::Get(value))); -} - -// Tests that BitField<>::MakeValue generates the right bits. -TEST(BitFieldTest, TestMakeValue) { - EXPECT_EQ(0x00000003u, (BitField<0, 4>::MakeValue(0x3))); - EXPECT_EQ(0x00023000u, (BitField<12, 8>::MakeValue(0x123))); - EXPECT_EQ(0x87654321u, (BitField<0, 32>::MakeValue(0x87654321))); -} - -// Tests that BitField<>::Set modifies the right bits. -TEST(BitFieldTest, TestSet) { - unsigned int value = 0x12345678u; - BitField<0, 4>::Set(&value, 0x9); - EXPECT_EQ(0x12345679u, value); - BitField<12, 8>::Set(&value, 0x123); - EXPECT_EQ(0x12323679u, value); - BitField<0, 32>::Set(&value, 0x87654321); - EXPECT_EQ(0x87654321u, value); -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/cmd_buffer_common.h b/chromium/gpu/command_buffer/common/cmd_buffer_common.h index a4a01c35c3b..88ee04d0ff1 100644 --- a/chromium/gpu/command_buffer/common/cmd_buffer_common.h +++ b/chromium/gpu/command_buffer/common/cmd_buffer_common.h @@ -12,7 +12,6 @@ #include "base/check_op.h" #include "base/macros.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" #include "gpu/gpu_export.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc b/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc index 70bfa0471e6..f8a0b668496 100644 --- a/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc +++ b/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc @@ -21,7 +21,7 @@ namespace gpu { class CommandBufferSharedTest : public testing::Test { protected: void SetUp() override { - shared_state_.reset(new CommandBufferSharedState()); + shared_state_ = std::make_unique<CommandBufferSharedState>(); shared_state_->Initialize(); } diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format.h b/chromium/gpu/command_buffer/common/gles2_cmd_format.h index 188a21224ea..46318da8c94 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format.h @@ -16,7 +16,6 @@ #include "base/macros.h" #include "base/rand_util.h" #include "base/trace_event/trace_event.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/common_cmd_format.h" #include "gpu/command_buffer/common/constants.h" diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc b/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc index a3b8e34a9df..a1bc7750b3d 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc @@ -53,10 +53,7 @@ class GLES2FormatTest : public testing::Test { unsigned char buffer_[1024]; }; -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const unsigned char GLES2FormatTest::kInitialValue; -#endif #include "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h" diff --git a/chromium/gpu/command_buffer/common/raster_cmd_format.h b/chromium/gpu/command_buffer/common/raster_cmd_format.h index c8b8b072c68..e43a51f9973 100644 --- a/chromium/gpu/command_buffer/common/raster_cmd_format.h +++ b/chromium/gpu/command_buffer/common/raster_cmd_format.h @@ -14,7 +14,6 @@ #include "base/atomicops.h" #include "base/macros.h" #include "components/viz/common/resources/resource_format.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/common_cmd_format.h" #include "gpu/command_buffer/common/constants.h" diff --git a/chromium/gpu/command_buffer/common/raster_cmd_format_autogen.h b/chromium/gpu/command_buffer/common/raster_cmd_format_autogen.h index f44f654cf01..b112cb2a810 100644 --- a/chromium/gpu/command_buffer/common/raster_cmd_format_autogen.h +++ b/chromium/gpu/command_buffer/common/raster_cmd_format_autogen.h @@ -389,11 +389,13 @@ struct BeginRasterCHROMIUMImmediate { void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } void Init(GLuint _sk_color, + GLboolean _needs_clear, GLuint _msaa_sample_count, GLboolean _can_use_lcd_text, const GLbyte* _mailbox) { SetHeader(); sk_color = _sk_color; + needs_clear = _needs_clear; msaa_sample_count = _msaa_sample_count; can_use_lcd_text = _can_use_lcd_text; memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize()); @@ -401,33 +403,38 @@ struct BeginRasterCHROMIUMImmediate { void* Set(void* cmd, GLuint _sk_color, + GLboolean _needs_clear, GLuint _msaa_sample_count, GLboolean _can_use_lcd_text, const GLbyte* _mailbox) { - static_cast<ValueType*>(cmd)->Init(_sk_color, _msaa_sample_count, - _can_use_lcd_text, _mailbox); + static_cast<ValueType*>(cmd)->Init(_sk_color, _needs_clear, + _msaa_sample_count, _can_use_lcd_text, + _mailbox); const uint32_t size = ComputeSize(); return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); } gpu::CommandHeader header; uint32_t sk_color; + uint32_t needs_clear; uint32_t msaa_sample_count; uint32_t can_use_lcd_text; }; -static_assert(sizeof(BeginRasterCHROMIUMImmediate) == 16, - "size of BeginRasterCHROMIUMImmediate should be 16"); +static_assert(sizeof(BeginRasterCHROMIUMImmediate) == 20, + "size of BeginRasterCHROMIUMImmediate should be 20"); static_assert(offsetof(BeginRasterCHROMIUMImmediate, header) == 0, "offset of BeginRasterCHROMIUMImmediate header should be 0"); static_assert(offsetof(BeginRasterCHROMIUMImmediate, sk_color) == 4, "offset of BeginRasterCHROMIUMImmediate sk_color should be 4"); +static_assert(offsetof(BeginRasterCHROMIUMImmediate, needs_clear) == 8, + "offset of BeginRasterCHROMIUMImmediate needs_clear should be 8"); static_assert( - offsetof(BeginRasterCHROMIUMImmediate, msaa_sample_count) == 8, - "offset of BeginRasterCHROMIUMImmediate msaa_sample_count should be 8"); + offsetof(BeginRasterCHROMIUMImmediate, msaa_sample_count) == 12, + "offset of BeginRasterCHROMIUMImmediate msaa_sample_count should be 12"); static_assert( - offsetof(BeginRasterCHROMIUMImmediate, can_use_lcd_text) == 12, - "offset of BeginRasterCHROMIUMImmediate can_use_lcd_text should be 12"); + offsetof(BeginRasterCHROMIUMImmediate, can_use_lcd_text) == 16, + "offset of BeginRasterCHROMIUMImmediate can_use_lcd_text should be 16"); struct RasterCHROMIUM { typedef RasterCHROMIUM ValueType; diff --git a/chromium/gpu/command_buffer/common/raster_cmd_format_test.cc b/chromium/gpu/command_buffer/common/raster_cmd_format_test.cc index fa15cc2b345..744b1a050f7 100644 --- a/chromium/gpu/command_buffer/common/raster_cmd_format_test.cc +++ b/chromium/gpu/command_buffer/common/raster_cmd_format_test.cc @@ -54,10 +54,7 @@ class RasterFormatTest : public testing::Test { unsigned char buffer_[1024]; }; -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const unsigned char RasterFormatTest::kInitialValue; -#endif #include "gpu/command_buffer/common/raster_cmd_format_test_autogen.h" diff --git a/chromium/gpu/command_buffer/common/raster_cmd_format_test_autogen.h b/chromium/gpu/command_buffer/common/raster_cmd_format_test_autogen.h index a2fcf388324..6fab8971908 100644 --- a/chromium/gpu/command_buffer/common/raster_cmd_format_test_autogen.h +++ b/chromium/gpu/command_buffer/common/raster_cmd_format_test_autogen.h @@ -159,15 +159,16 @@ TEST_F(RasterFormatTest, BeginRasterCHROMIUMImmediate) { cmds::BeginRasterCHROMIUMImmediate& cmd = *GetBufferAs<cmds::BeginRasterCHROMIUMImmediate>(); void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), - static_cast<GLboolean>(13), data); + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLboolean>(12), + static_cast<GLuint>(13), static_cast<GLboolean>(14), data); EXPECT_EQ(static_cast<uint32_t>(cmds::BeginRasterCHROMIUMImmediate::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLuint>(11), cmd.sk_color); - EXPECT_EQ(static_cast<GLuint>(12), cmd.msaa_sample_count); - EXPECT_EQ(static_cast<GLboolean>(13), cmd.can_use_lcd_text); + EXPECT_EQ(static_cast<GLboolean>(12), cmd.needs_clear); + EXPECT_EQ(static_cast<GLuint>(13), cmd.msaa_sample_count); + EXPECT_EQ(static_cast<GLboolean>(14), cmd.can_use_lcd_text); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); } diff --git a/chromium/gpu/command_buffer/common/webgpu_cmd_format_test.cc b/chromium/gpu/command_buffer/common/webgpu_cmd_format_test.cc index 95af7e20151..91530e486c4 100644 --- a/chromium/gpu/command_buffer/common/webgpu_cmd_format_test.cc +++ b/chromium/gpu/command_buffer/common/webgpu_cmd_format_test.cc @@ -54,10 +54,7 @@ class WebGPUFormatTest : public testing::Test { unsigned char buffer_[1024]; }; -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER const unsigned char WebGPUFormatTest::kInitialValue; -#endif #include "gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h" diff --git a/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt b/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt index f6e6d2f6c26..d25f7de0368 100644 --- a/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt +++ b/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt @@ -24,7 +24,7 @@ GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM (GLenumResetStatus cur GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); // Extension CHROMIUM_raster_transport -GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const GLbyte* mailbox); +GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint sk_color, GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLuint raster_shm_id, GLuint raster_shm_offset, GLuint raster_shm_size, GLuint font_shm_id, GLuint font_shm_offset, GLuint font_shm_size); GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void); GL_APICALL void GL_APIENTRY glCreateTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, GLuint handle_shm_offset, GLuint data_shm_id, GLuint data_shm_offset, GLuint data_size); diff --git a/chromium/gpu/command_buffer/service/BUILD.gn b/chromium/gpu/command_buffer/service/BUILD.gn index 959e04c2f03..11e5f269fd3 100644 --- a/chromium/gpu/command_buffer/service/BUILD.gn +++ b/chromium/gpu/command_buffer/service/BUILD.gn @@ -178,8 +178,6 @@ target(link_target_type, "gles2_sources") { "mailbox_manager_factory.h", "mailbox_manager_impl.cc", "mailbox_manager_impl.h", - "mailbox_manager_sync.cc", - "mailbox_manager_sync.h", "memory_program_cache.cc", "memory_program_cache.h", "multi_draw_manager.cc", @@ -317,7 +315,6 @@ target(link_target_type, "gles2_sources") { "//skia:buildflags", "//third_party/angle:angle_image_util", "//third_party/angle:commit_id", - "//third_party/angle:translator", "//third_party/protobuf:protobuf_lite", "//third_party/re2", "//third_party/zlib", @@ -328,6 +325,13 @@ target(link_target_type, "gles2_sources") { "//ui/gl/init", ] + # If statically linked against ANGLE, link against angle:translator which is already included with ANGLE. + if (use_static_angle) { + deps += [ "//third_party/angle:translator" ] + } else { + deps += [ "//third_party/angle:translator_gl_d3d_only" ] + } + if (use_ozone) { deps += [ "//ui/base:features", diff --git a/chromium/gpu/command_buffer/service/buffer_manager.cc b/chromium/gpu/command_buffer/service/buffer_manager.cc index 89e6cfff428..3b020c15324 100644 --- a/chromium/gpu/command_buffer/service/buffer_manager.cc +++ b/chromium/gpu/command_buffer/service/buffer_manager.cc @@ -7,6 +7,7 @@ #include <stdint.h> #include <limits> +#include <memory> #include "base/check_op.h" #include "base/format_macros.h" @@ -356,8 +357,8 @@ bool Buffer::GetMaxValueForRange( void Buffer::SetMappedRange(GLintptr offset, GLsizeiptr size, GLenum access, void* pointer, scoped_refptr<gpu::Buffer> shm, unsigned int shm_offset) { - mapped_range_.reset( - new MappedRange(offset, size, access, pointer, shm, shm_offset)); + mapped_range_ = std::make_unique<MappedRange>(offset, size, access, pointer, + shm, shm_offset); } void Buffer::RemoveMappedRange() { diff --git a/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc index 02a839e392b..6968432500c 100644 --- a/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -35,8 +35,8 @@ class BufferManagerTestBase : public GpuServiceTest { TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions); feature_info->InitializeForTesting(); } - error_state_.reset(new MockErrorState()); - manager_.reset(new BufferManager(memory_tracker, feature_info)); + error_state_ = std::make_unique<MockErrorState>(); + manager_ = std::make_unique<BufferManager>(memory_tracker, feature_info); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc b/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc index 2a5810c9707..e182ec9f889 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc +++ b/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc @@ -45,7 +45,8 @@ class CommandBufferServiceTest : public testing::Test, void MakeService(unsigned int entry_count) { command_buffer_service_ = std::make_unique<CommandBufferService>(this, nullptr); - api_mock_.reset(new AsyncAPIMock(false, command_buffer_service_.get())); + api_mock_ = + std::make_unique<AsyncAPIMock>(false, command_buffer_service_.get()); SetNewGetBuffer(entry_count * sizeof(CommandBufferEntry)); } diff --git a/chromium/gpu/command_buffer/service/context_group.cc b/chromium/gpu/command_buffer/service/context_group.cc index 88f4127f187..898c5a82e02 100644 --- a/chromium/gpu/command_buffer/service/context_group.cc +++ b/chromium/gpu/command_buffer/service/context_group.cc @@ -8,6 +8,7 @@ #include <stdint.h> #include <algorithm> +#include <memory> #include <string> #include "base/command_line.h" @@ -396,11 +397,11 @@ gpu::ContextResult ContextGroup::Initialize( // Managers are not used by the passthrough command decoder. Save memory by // not allocating them. if (!use_passthrough_cmd_decoder_) { - texture_manager_.reset(new TextureManager( + texture_manager_ = std::make_unique<TextureManager>( memory_tracker_.get(), feature_info_.get(), max_texture_size, max_cube_map_texture_size, max_rectangle_texture_size, max_3d_texture_size, max_array_texture_layers, bind_generates_resource_, - progress_reporter_, discardable_manager_)); + progress_reporter_, discardable_manager_); } const GLint kMinTextureImageUnits = 8; diff --git a/chromium/gpu/command_buffer/service/context_group_unittest.cc b/chromium/gpu/command_buffer/service/context_group_unittest.cc index a3c4c70be78..5cb347b1e46 100644 --- a/chromium/gpu/command_buffer/service/context_group_unittest.cc +++ b/chromium/gpu/command_buffer/service/context_group_unittest.cc @@ -45,8 +45,8 @@ class ContextGroupTest : public GpuServiceTest { protected: void SetUp() override { GpuServiceTest::SetUp(); - decoder_.reset( - new MockGLES2Decoder(&client_, &command_buffer_service_, &outputter_)); + decoder_ = std::make_unique<MockGLES2Decoder>( + &client_, &command_buffer_service_, &outputter_); scoped_refptr<FeatureInfo> feature_info = new FeatureInfo; group_ = scoped_refptr<ContextGroup>(new ContextGroup( gpu_preferences_, false, &mailbox_manager_, diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc index 04eabf3558b..b5004ff1cae 100644 --- a/chromium/gpu/command_buffer/service/feature_info.cc +++ b/chromium/gpu/command_buffer/service/feature_info.cc @@ -6,6 +6,7 @@ #include <stddef.h> +#include <memory> #include <set> #include <vector> @@ -475,8 +476,8 @@ void FeatureInfo::InitializeFeatures() { const char* renderer_str = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - gl_version_info_.reset( - new gl::GLVersionInfo(version_str, renderer_str, extensions)); + gl_version_info_ = std::make_unique<gl::GLVersionInfo>( + version_str, renderer_str, extensions); bool enable_es3 = IsWebGL2OrES3OrHigherContext(); @@ -493,7 +494,6 @@ void FeatureInfo::InitializeFeatures() { // changed on another decoder that does expose them. ScopedPixelUnpackBufferOverride scoped_pbo_override(has_pixel_buffers, 0); - AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); AddExtensionString("GL_CHROMIUM_bind_uniform_location"); AddExtensionString("GL_CHROMIUM_color_space_metadata"); @@ -526,6 +526,16 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.angle_translated_shader_source = true; } + // The validating command decoder always supports + // ANGLE_translated_shader_source regardless of the underlying context. But + // passthrough relies on the underlying ANGLE context which can't always + // support it (e.g. on Vulkan shaders are translated directly to binary + // SPIR-V). + if (!is_passthrough_cmd_decoder_ || + feature_flags_.angle_translated_shader_source) { + AddExtensionString("GL_ANGLE_translated_shader_source"); + } + // Check if we should allow GL_EXT_texture_compression_dxt1 and // GL_EXT_texture_compression_s3tc. bool enable_dxt1 = false; diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 5cf6f4f9f5d..c783a2e6673 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -5,6 +5,8 @@ #include <stddef.h> #include <stdint.h> +#include <memory> + #include "base/stl_util.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/service/error_state_mock.h" @@ -47,14 +49,12 @@ class FramebufferManagerTest : public GpuServiceTest { : manager_(1, 1, nullptr), feature_info_(new FeatureInfo()), discardable_manager_(GpuPreferences()) { - texture_manager_.reset(new TextureManager( + texture_manager_ = std::make_unique<TextureManager>( nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr, &discardable_manager_)); - renderbuffer_manager_.reset(new RenderbufferManager(nullptr, - kMaxRenderbufferSize, - kMaxSamples, - feature_info_.get())); + kUseDefaultTextures, nullptr, &discardable_manager_); + renderbuffer_manager_ = std::make_unique<RenderbufferManager>( + nullptr, kMaxRenderbufferSize, kMaxSamples, feature_info_.get()); } ~FramebufferManagerTest() override { manager_.Destroy(false); @@ -127,14 +127,12 @@ class FramebufferInfoTestBase : public GpuServiceTest { &framebuffer_completeness_cache_), feature_info_(new FeatureInfo()), discardable_manager_(GpuPreferences()) { - texture_manager_.reset(new TextureManager( + texture_manager_ = std::make_unique<TextureManager>( nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr, &discardable_manager_)); - renderbuffer_manager_.reset(new RenderbufferManager(nullptr, - kMaxRenderbufferSize, - kMaxSamples, - feature_info_.get())); + kUseDefaultTextures, nullptr, &discardable_manager_); + renderbuffer_manager_ = std::make_unique<RenderbufferManager>( + nullptr, kMaxRenderbufferSize, kMaxSamples, feature_info_.get()); } ~FramebufferInfoTestBase() override { manager_.Destroy(false); @@ -157,10 +155,11 @@ class FramebufferInfoTestBase : public GpuServiceTest { TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(), extensions, "", gl_version, context_type_); feature_info_->InitializeForTesting(context_type_); - decoder_.reset( - new MockGLES2Decoder(&client_, &command_buffer_service_, &outputter_)); + decoder_ = std::make_unique<MockGLES2Decoder>( + &client_, &command_buffer_service_, &outputter_); manager_.CreateFramebuffer(kClient1Id, kService1Id); - error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); + error_state_ = + std::make_unique<::testing::StrictMock<gles2::MockErrorState>>(); framebuffer_ = manager_.GetFramebuffer(kClient1Id); ASSERT_TRUE(framebuffer_ != nullptr); } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc index 1d1671fd64e..9a91e39ad8d 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -83,6 +83,7 @@ #include "gpu/command_buffer/service/validating_abstract_texture_impl.h" #include "gpu/command_buffer/service/vertex_array_manager.h" #include "gpu/command_buffer/service/vertex_attrib_manager.h" +#include "gpu/config/gpu_finch_features.h" #include "gpu/config/gpu_preferences.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/color_space.h" @@ -2959,11 +2960,11 @@ ScopedResolvedFramebufferBinder::ScopedResolvedFramebufferBinder( GLuint targetid; if (internal) { if (!decoder_->offscreen_resolved_frame_buffer_.get()) { - decoder_->offscreen_resolved_frame_buffer_.reset( - new BackFramebuffer(decoder_)); + decoder_->offscreen_resolved_frame_buffer_ = + std::make_unique<BackFramebuffer>(decoder_); decoder_->offscreen_resolved_frame_buffer_->Create(); - decoder_->offscreen_resolved_color_texture_.reset( - new BackTexture(decoder)); + decoder_->offscreen_resolved_color_texture_ = + std::make_unique<BackTexture>(decoder); decoder_->offscreen_resolved_color_texture_->Create(); DCHECK(decoder_->offscreen_saved_color_format_); @@ -3589,7 +3590,7 @@ gpu::ContextResult GLES2DecoderImpl::Initialize( surface_->SetForceGlFlushOnSwapBuffers(); // Create GPU Tracer for timing values. - gpu_tracer_.reset(new GPUTracer(this)); + gpu_tracer_ = std::make_unique<GPUTracer>(this); if (workarounds().disable_timestamp_queries) { // Forcing time elapsed query for any GPU Timing Client forces it for all @@ -3668,8 +3669,8 @@ gpu::ContextResult GLES2DecoderImpl::Initialize( // However, we set it to true everywhere, not to trust drivers to handle // out-of-bounds buffer accesses. bool needs_emulation = true; - transform_feedback_manager_.reset(new TransformFeedbackManager( - group_->max_transform_feedback_separate_attribs(), needs_emulation)); + transform_feedback_manager_ = std::make_unique<TransformFeedbackManager>( + group_->max_transform_feedback_separate_attribs(), needs_emulation); // Register this object as a GPU switching observer. if (feature_info_->IsWebGLContext()) { @@ -3704,7 +3705,7 @@ gpu::ContextResult GLES2DecoderImpl::Initialize( state_.indexed_uniform_buffer_bindings->SetIsBound(true); state_.InitGenericAttribs(group_->max_vertex_attribs()); - vertex_array_manager_.reset(new VertexArrayManager()); + vertex_array_manager_ = std::make_unique<VertexArrayManager>(); GLuint default_vertex_attrib_service_id = 0; if (features().native_vertex_array_object) { @@ -3722,17 +3723,18 @@ gpu::ContextResult GLES2DecoderImpl::Initialize( // vertex_attrib_manager is set to default_vertex_attrib_manager by this call DoBindVertexArrayOES(0); - framebuffer_manager_.reset(new FramebufferManager( + framebuffer_manager_ = std::make_unique<FramebufferManager>( group_->max_draw_buffers(), group_->max_color_attachments(), - group_->framebuffer_completeness_cache())); + group_->framebuffer_completeness_cache()); group_->texture_manager()->AddFramebufferManager(framebuffer_manager_.get()); - query_manager_.reset(new GLES2QueryManager(this, feature_info_.get())); + query_manager_ = + std::make_unique<GLES2QueryManager>(this, feature_info_.get()); - gpu_fence_manager_.reset(new GpuFenceManager()); + gpu_fence_manager_ = std::make_unique<GpuFenceManager>(); - multi_draw_manager_.reset( - new MultiDrawManager(MultiDrawManager::IndexStorageType::Offset)); + multi_draw_manager_ = std::make_unique<MultiDrawManager>( + MultiDrawManager::IndexStorageType::Offset); util_.set_num_compressed_texture_formats( validators_->compressed_texture_format.GetValues().size()); @@ -3996,30 +3998,33 @@ gpu::ContextResult GLES2DecoderImpl::Initialize( if (offscreen) { // Create the target frame buffer. This is the one that the client renders // directly to. - offscreen_target_frame_buffer_.reset(new BackFramebuffer(this)); + offscreen_target_frame_buffer_ = std::make_unique<BackFramebuffer>(this); offscreen_target_frame_buffer_->Create(); // Due to GLES2 format limitations, either the color texture (for // non-multisampling) or the color render buffer (for multisampling) will be // attached to the offscreen frame buffer. The render buffer has more // limited formats available to it, but the texture can't do multisampling. if (IsOffscreenBufferMultisampled()) { - offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_color_render_buffer_ = + std::make_unique<BackRenderbuffer>(this); offscreen_target_color_render_buffer_->Create(); } else { - offscreen_target_color_texture_.reset(new BackTexture(this)); + offscreen_target_color_texture_ = std::make_unique<BackTexture>(this); offscreen_target_color_texture_->Create(); } - offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_depth_render_buffer_ = + std::make_unique<BackRenderbuffer>(this); offscreen_target_depth_render_buffer_->Create(); - offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_stencil_render_buffer_ = + std::make_unique<BackRenderbuffer>(this); offscreen_target_stencil_render_buffer_->Create(); if (!offscreen_single_buffer_) { // Create the saved offscreen texture. The target frame buffer is copied // here when SwapBuffers is called. - offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this)); + offscreen_saved_frame_buffer_ = std::make_unique<BackFramebuffer>(this); offscreen_saved_frame_buffer_->Create(); - offscreen_saved_color_texture_.reset(new BackTexture(this)); + offscreen_saved_color_texture_ = std::make_unique<BackTexture>(this); offscreen_saved_color_texture_->Create(); } @@ -4271,11 +4276,13 @@ Capabilities GLES2DecoderImpl::GetCapabilities() { feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; caps.texture_format_etc1_npot = caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only; - // Whether or not a texture will be bound to an EGLImage is - // dependent on whether we are using the sync mailbox manager. + // Vulkan currently doesn't support single-component cross-thread shared + // images. caps.disable_one_component_textures = - mailbox_manager()->UsesSync() && - workarounds().avoid_one_component_egl_images; + group_->shared_image_manager() && + group_->shared_image_manager()->display_context_on_another_thread() && + (workarounds().avoid_one_component_egl_images || + features::IsUsingVulkan()); caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle; caps.texture_usage = feature_info_->feature_flags().angle_texture_usage; caps.texture_storage = feature_info_->feature_flags().ext_texture_storage; @@ -4560,8 +4567,6 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS; if (workarounds().regenerate_struct_names) driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES; - if (workarounds().remove_pow_with_constant_exponent) - driver_bug_workarounds |= SH_REMOVE_POW_WITH_CONSTANT_EXPONENT; if (workarounds().emulate_abs_int_function) driver_bug_workarounds |= SH_EMULATE_ABS_INT_FUNCTION; if (workarounds().rewrite_texelfetchoffset_to_texelfetch) @@ -4574,8 +4579,6 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { driver_bug_workarounds |= SH_EMULATE_ISNAN_FLOAT_FUNCTION; if (workarounds().use_unused_standard_shared_blocks) driver_bug_workarounds |= SH_USE_UNUSED_STANDARD_SHARED_BLOCKS; - if (workarounds().dont_remove_invariant_for_fragment_input) - driver_bug_workarounds |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT; if (workarounds().remove_invariant_and_centroid_for_essl3) driver_bug_workarounds |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3; if (workarounds().rewrite_float_unary_minus_operator) @@ -5705,7 +5708,7 @@ void GLES2DecoderImpl::CreateBackTexture() { } ++create_back_texture_count_for_test_; - offscreen_saved_color_texture_.reset(new BackTexture(this)); + offscreen_saved_color_texture_ = std::make_unique<BackTexture>(this); offscreen_saved_color_texture_->Create(); offscreen_saved_color_texture_->AllocateStorage( offscreen_size_, offscreen_saved_color_format_, false); @@ -9334,8 +9337,7 @@ bool GLES2DecoderImpl::InitializeSRGBConverter( const char* function_name) { if (!srgb_converter_.get()) { LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); - srgb_converter_.reset( - new SRGBConverter(feature_info_.get())); + srgb_converter_ = std::make_unique<SRGBConverter>(feature_info_.get()); srgb_converter_->InitializeSRGBConverter(this); if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) { return false; @@ -13755,7 +13757,7 @@ error::Error GLES2DecoderImpl::HandleScheduleCALayerSharedStateCHROMIUM( gfx::Transform transform(mem[9], mem[13], mem[17], mem[21], mem[10], mem[14], mem[18], mem[22], mem[11], mem[15], mem[19], mem[23], mem[12], mem[16], mem[20], mem[24]); - ca_layer_shared_state_.reset(new CALayerSharedState); + ca_layer_shared_state_ = std::make_unique<CALayerSharedState>(); ca_layer_shared_state_->opacity = c.opacity; ca_layer_shared_state_->is_clipped = c.is_clipped ? true : false; ca_layer_shared_state_->clip_rect = gfx::ToEnclosingRect(clip_rect); @@ -18509,8 +18511,8 @@ bool GLES2DecoderImpl::InitializeCopyTexImageBlitter( const char* function_name) { if (!copy_tex_image_blit_.get()) { LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); - copy_tex_image_blit_.reset( - new CopyTexImageResourceManager(feature_info_.get())); + copy_tex_image_blit_ = + std::make_unique<CopyTexImageResourceManager>(feature_info_.get()); copy_tex_image_blit_->Initialize(this); if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) return false; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index 87eb49671c2..971f4d77ef0 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc @@ -4,6 +4,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h" +#include <memory> #include <string> #include <utility> @@ -580,7 +581,7 @@ GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer:: GL_RENDERBUFFER, color_buffer_service_id); } else { - color_texture.reset(new EmulatedColorBuffer(api, format)); + color_texture = std::make_unique<EmulatedColorBuffer>(api, format); api->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture->texture->service_id(), 0); @@ -924,12 +925,12 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize( this); // Create GPU Tracer for timing values. - gpu_tracer_.reset(new GPUTracer(this)); + gpu_tracer_ = std::make_unique<GPUTracer>(this); - gpu_fence_manager_.reset(new GpuFenceManager()); + gpu_fence_manager_ = std::make_unique<GpuFenceManager>(); - multi_draw_manager_.reset( - new MultiDrawManager(MultiDrawManager::IndexStorageType::Pointer)); + multi_draw_manager_ = std::make_unique<MultiDrawManager>( + MultiDrawManager::IndexStorageType::Pointer); auto result = group_->Initialize(this, attrib_helper.context_type, disallowed_features); @@ -1575,7 +1576,9 @@ gpu::Capabilities GLES2DecoderPassthroughImpl::GetCapabilities() { feature_info_->feature_flags().ext_texture_format_dxt5; caps.texture_format_etc1 = feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; - caps.texture_format_etc1_npot = caps.texture_format_etc1; + caps.texture_format_etc1_npot = + caps.texture_format_etc1 && + !feature_info_->workarounds().etc1_power_of_two_only; caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle; caps.texture_usage = feature_info_->feature_flags().angle_texture_usage; caps.texture_storage = feature_info_->feature_flags().ext_texture_storage; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index abd7a835a7f..c3cbc3409ef 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h @@ -1084,29 +1084,7 @@ error::Error DoSetDrawRectangleCHROMIUM(GLint x, GLint width, GLint height); error::Error DoSetEnableDCLayersCHROMIUM(GLboolean enable); -error::Error DoBeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type); -error::Error DoRasterCHROMIUM(GLuint raster_shm_id, - GLuint raster_shm_offset, - GLsizeiptr raster_shm_size, - GLuint font_shm_id, - GLuint font_shm_offset, - GLsizeiptr font_shm_size); -error::Error DoEndRasterCHROMIUM(); -error::Error DoCreateTransferCacheEntryINTERNAL(GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size); -error::Error DoUnlockTransferCacheEntryINTERNAL(GLuint entry_type, - GLuint entry_id); -error::Error DoDeleteTransferCacheEntryINTERNAL(GLuint entry_type, - GLuint entry_id); + error::Error DoWindowRectanglesEXT(GLenum mode, GLsizei n, const volatile GLint* box); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 87a32de016e..d60b346d30d 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc @@ -4,6 +4,8 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h" +#include <memory> + #include "base/callback_helpers.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/ranges.h" @@ -4865,7 +4867,7 @@ error::Error GLES2DecoderPassthroughImpl::DoScheduleCALayerSharedStateCHROMIUM( GLint sorting_context_id, const GLfloat* transform) { if (!ca_layer_shared_state_) { - ca_layer_shared_state_.reset(new CALayerSharedState); + ca_layer_shared_state_ = std::make_unique<CALayerSharedState>(); } ca_layer_shared_state_->opacity = opacity; @@ -5205,60 +5207,6 @@ error::Error GLES2DecoderPassthroughImpl::DoSetEnableDCLayersCHROMIUM( return error::kNoError; } -error::Error GLES2DecoderPassthroughImpl::DoBeginRasterCHROMIUM( - GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type) { - NOTIMPLEMENTED(); - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::DoRasterCHROMIUM( - GLuint raster_shm_id, - GLuint raster_shm_offset, - GLsizeiptr raster_shm_size, - GLuint font_shm_id, - GLuint font_shm_offset, - GLsizeiptr font_shm_size) { - // TODO(enne): Add CHROMIUM_raster_transport extension support to the - // passthrough command buffer. - NOTIMPLEMENTED(); - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::DoEndRasterCHROMIUM() { - NOTIMPLEMENTED(); - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::DoCreateTransferCacheEntryINTERNAL( - GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size) { - NOTIMPLEMENTED(); - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::DoUnlockTransferCacheEntryINTERNAL( - GLuint entry_type, - GLuint entry_id) { - NOTIMPLEMENTED(); - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::DoDeleteTransferCacheEntryINTERNAL( - GLuint entry_type, - GLuint entry_id) { - NOTIMPLEMENTED(); - return error::kNoError; -} - error::Error GLES2DecoderPassthroughImpl::DoWindowRectanglesEXT( GLenum mode, GLsizei n, diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 7047ac40e00..906f0624703 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -198,7 +198,7 @@ ContextResult GLES2DecoderTestBase::MaybeInitDecoderWithWorkarounds( gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress); gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings(); - gl_.reset(new StrictMock<MockGLInterface>()); + gl_ = std::make_unique<StrictMock<MockGLInterface>>(); ::gl::MockGLInterface::SetGLInterface(gl_.get()); SetupMockGLBehaviors(); @@ -243,9 +243,9 @@ ContextResult GLES2DecoderTestBase::MaybeInitDecoderWithWorkarounds( // We initialize the ContextGroup with a MockGLES2Decoder so that // we can use the ContextGroup to figure out how the real GLES2Decoder // will initialize itself. - command_buffer_service_.reset(new FakeCommandBufferServiceBase()); - mock_decoder_.reset( - new MockGLES2Decoder(this, command_buffer_service_.get(), &outputter_)); + command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>(); + mock_decoder_ = std::make_unique<MockGLES2Decoder>( + this, command_buffer_service_.get(), &outputter_); EXPECT_EQ(group_->Initialize(mock_decoder_.get(), init.context_type, DisallowedFeatures()), @@ -2434,7 +2434,7 @@ void GLES2DecoderPassthroughTestBase::SetUp() { context_creation_attribs_.bind_generates_resource = true; gl::init::InitializeStaticGLBindingsImplementation( - gl::kGLImplementationEGLANGLE, false); + gl::GLImplementationParts(gl::kGLImplementationEGLANGLE), false); gl::init::InitializeGLOneOffPlatformImplementation(false, false, true); scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo(); @@ -2453,10 +2453,10 @@ void GLES2DecoderPassthroughTestBase::SetUp() { GenerateGLContextAttribs(context_creation_attribs_, group_.get())); context_->MakeCurrent(surface_.get()); - command_buffer_service_.reset(new FakeCommandBufferServiceBase()); + command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>(); - decoder_.reset(new GLES2DecoderPassthroughImpl( - this, command_buffer_service_.get(), &outputter_, group_.get())); + decoder_ = std::make_unique<GLES2DecoderPassthroughImpl>( + this, command_buffer_service_.get(), &outputter_, group_.get()); // Don't request any optional extensions at startup, individual tests will // request what they need. diff --git a/chromium/gpu/command_buffer/service/gpu_service_test.cc b/chromium/gpu/command_buffer/service/gpu_service_test.cc index 18a4347c6a2..85cd16cf492 100644 --- a/chromium/gpu/command_buffer/service/gpu_service_test.cc +++ b/chromium/gpu/command_buffer/service/gpu_service_test.cc @@ -4,6 +4,8 @@ #include "gpu/command_buffer/service/gpu_service_test.h" +#include <memory> + #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_context_stub.h" @@ -28,7 +30,7 @@ void GpuServiceTest::SetUpWithGLVersion(const char* gl_version, gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress); gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings(); - gl_.reset(new ::testing::StrictMock<::gl::MockGLInterface>()); + gl_ = std::make_unique<::testing::StrictMock<::gl::MockGLInterface>>(); ::gl::MockGLInterface::SetGLInterface(gl_.get()); context_ = new gl::GLContextStub; diff --git a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc index f53aebe21a5..67e8e654bf3 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc +++ b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc @@ -4,6 +4,8 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" @@ -712,12 +714,12 @@ class GPUTracerTest : public GpuServiceTest { void SetUp() override { g_fakeCPUTime = 0; GpuServiceTest::SetUpWithGLVersion("3.2", ""); - decoder_.reset( - new MockGLES2Decoder(&client_, &command_buffer_service_, &outputter_)); + decoder_ = std::make_unique<MockGLES2Decoder>( + &client_, &command_buffer_service_, &outputter_); EXPECT_CALL(*decoder_, GetGLContext()) .Times(AtMost(1)) .WillRepeatedly(Return(GetGLContext())); - tracer_tester_.reset(new GPUTracerTester(decoder_.get())); + tracer_tester_ = std::make_unique<GPUTracerTester>(decoder_.get()); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/service/gr_cache_controller_unittest.cc b/chromium/gpu/command_buffer/service/gr_cache_controller_unittest.cc index 2c6a8a0146f..b098f44a4bb 100644 --- a/chromium/gpu/command_buffer/service/gr_cache_controller_unittest.cc +++ b/chromium/gpu/command_buffer/service/gr_cache_controller_unittest.cc @@ -26,7 +26,7 @@ namespace raster { class GrCacheControllerTest : public testing::Test { public: void SetUp() override { - gl::GLSurfaceTestSupport::InitializeOneOff(); + gl::GLSurfaceTestSupport::InitializeOneOffWithStubBindings(); gpu::GpuDriverBugWorkarounds workarounds; scoped_refptr<gl::GLShareGroup> share_group = new gl::GLShareGroup(); diff --git a/chromium/gpu/command_buffer/service/gr_shader_cache.cc b/chromium/gpu/command_buffer/service/gr_shader_cache.cc index ec87bb27059..d305bfce53a 100644 --- a/chromium/gpu/command_buffer/service/gr_shader_cache.cc +++ b/chromium/gpu/command_buffer/service/gr_shader_cache.cc @@ -8,6 +8,7 @@ #include "base/auto_reset.h" #include "base/base64.h" +#include "base/callback_helpers.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" diff --git a/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc b/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc index 03eec0d32f2..0d0bd5d1211 100644 --- a/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc +++ b/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc @@ -272,7 +272,7 @@ void ImageReaderGLOwner::UpdateTexImage() { AImage* image = nullptr; int acquire_fence_fd = -1; media_status_t return_code = AMEDIA_OK; - DCHECK_GT(max_images_, static_cast<int32_t>(image_refs_.size())); + if (max_images_ - image_refs_.size() < 2) { // acquireNextImageAsync is required here since as per the spec calling // AImageReader_acquireLatestImage with less than two images of margin, that @@ -346,6 +346,11 @@ ImageReaderGLOwner::GetAHardwareBuffer() { if (!buffer) return nullptr; + // TODO(1179206): We suspect that buffer is already freed here and it causes + // crash later. Trying to crash earlier. + base::AndroidHardwareBufferCompat::GetInstance().Acquire(buffer); + base::AndroidHardwareBufferCompat::GetInstance().Release(buffer); + return std::make_unique<ScopedHardwareBufferImpl>( weak_factory_.GetWeakPtr(), current_image_ref_->image(), base::android::ScopedHardwareBufferHandle::Create(buffer), diff --git a/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc b/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc index f3de9651ce7..a91e64065e3 100644 --- a/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc +++ b/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc @@ -33,7 +33,7 @@ class ImageReaderGLOwnerTest : public testing::Test { return; gl::init::InitializeStaticGLBindingsImplementation( - gl::kGLImplementationEGLGLES2, false); + gl::GLImplementationParts(gl::kGLImplementationEGLGLES2), false); gl::init::InitializeGLOneOffPlatformImplementation(false, false, true); surface_ = new gl::PbufferGLSurfaceEGL(gfx::Size(320, 240)); diff --git a/chromium/gpu/command_buffer/service/mailbox_manager.h b/chromium/gpu/command_buffer/service/mailbox_manager.h index fa6895db254..38328a3e9d4 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager.h +++ b/chromium/gpu/command_buffer/service/mailbox_manager.h @@ -13,7 +13,6 @@ namespace gpu { -struct SyncToken; class TextureBase; // Manages resources scoped beyond the context or context group level. @@ -27,13 +26,6 @@ class GPU_EXPORT MailboxManager { // Put the texture into the named mailbox. virtual void ProduceTexture(const Mailbox& mailbox, TextureBase* texture) = 0; - // If |true| then Pull/PushTextureUpdates() needs to be called. - virtual bool UsesSync() = 0; - - // Used to synchronize texture state across share groups. - virtual void PushTextureUpdates(const SyncToken& token) = 0; - virtual void PullTextureUpdates(const SyncToken& token) = 0; - // Destroy any mailbox that reference the given texture. virtual void TextureDeleted(TextureBase* texture) = 0; }; diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_dummy.cc b/chromium/gpu/command_buffer/service/mailbox_manager_dummy.cc index 0c56d52a90b..755d333d671 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_dummy.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_dummy.cc @@ -14,10 +14,6 @@ MailboxManagerDummy::MailboxManagerDummy() = default; MailboxManagerDummy::~MailboxManagerDummy() = default; -bool MailboxManagerDummy::UsesSync() { - return false; -} - TextureBase* MailboxManagerDummy::ConsumeTexture(const Mailbox& mailbox) { NOTREACHED(); return nullptr; diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_dummy.h b/chromium/gpu/command_buffer/service/mailbox_manager_dummy.h index 32fc1722dc8..7bce5010f24 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_dummy.h +++ b/chromium/gpu/command_buffer/service/mailbox_manager_dummy.h @@ -23,9 +23,6 @@ class GPU_GLES2_EXPORT MailboxManagerDummy : public MailboxManager { // MailboxManager implementation: TextureBase* ConsumeTexture(const Mailbox& mailbox) override; void ProduceTexture(const Mailbox& mailbox, TextureBase* texture) override {} - bool UsesSync() override; - void PushTextureUpdates(const SyncToken& token) override {} - void PullTextureUpdates(const SyncToken& token) override {} void TextureDeleted(TextureBase* texture) override {} private: diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_factory.cc b/chromium/gpu/command_buffer/service/mailbox_manager_factory.cc index 8075a0c36e2..4cd01bedebf 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_factory.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_factory.cc @@ -8,7 +8,6 @@ #include "base/feature_list.h" #include "gpu/command_buffer/service/mailbox_manager_dummy.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" -#include "gpu/command_buffer/service/mailbox_manager_sync.h" #include "gpu/config/gpu_finch_features.h" #include "gpu/config/gpu_preferences.h" @@ -20,11 +19,7 @@ std::unique_ptr<MailboxManager> CreateMailboxManager( // TODO(vikassoni):Once shared images have been completely tested and stable // on webview, remove MailboxManagerSync and MailboxManagerSyncDummy. if (gpu_preferences.enable_threaded_texture_mailboxes) { - if (base::FeatureList::IsEnabled(features::kEnableSharedImageForWebview)) { - return std::make_unique<MailboxManagerDummy>(); - } else { - return std::make_unique<MailboxManagerSync>(); - } + return std::make_unique<MailboxManagerDummy>(); } return std::make_unique<MailboxManagerImpl>(); } diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_impl.cc b/chromium/gpu/command_buffer/service/mailbox_manager_impl.cc index 78be97bf3ce..4a5afaec1f2 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_impl.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_impl.cc @@ -21,10 +21,6 @@ MailboxManagerImpl::~MailboxManagerImpl() { DCHECK(textures_to_mailboxes_.empty()); } -bool MailboxManagerImpl::UsesSync() { - return false; -} - TextureBase* MailboxManagerImpl::ConsumeTexture(const Mailbox& mailbox) { MailboxToTextureMap::iterator it = mailbox_to_textures_.find(mailbox); diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_impl.h b/chromium/gpu/command_buffer/service/mailbox_manager_impl.h index 5651fcd6f97..a4fea4bbe9e 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_impl.h +++ b/chromium/gpu/command_buffer/service/mailbox_manager_impl.h @@ -27,9 +27,6 @@ class GPU_GLES2_EXPORT MailboxManagerImpl : public MailboxManager { // MailboxManager implementation: TextureBase* ConsumeTexture(const Mailbox& mailbox) override; void ProduceTexture(const Mailbox& mailbox, TextureBase* texture) override; - bool UsesSync() override; - void PushTextureUpdates(const SyncToken& token) override {} - void PullTextureUpdates(const SyncToken& token) override {} void TextureDeleted(TextureBase* texture) override; private: diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc b/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc deleted file mode 100644 index fdeb05dfe1f..00000000000 --- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/command_buffer/service/mailbox_manager_sync.h" - -#include <stddef.h> - -#include <algorithm> - -#include "base/containers/queue.h" -#include "base/synchronization/lock.h" -#include "gpu/command_buffer/common/sync_token.h" -#include "gpu/command_buffer/service/texture_manager.h" -#include "ui/gl/gl_fence.h" -#include "ui/gl/gl_implementation.h" - -#if !defined(OS_MAC) -#include "ui/gl/gl_fence_egl.h" -#endif - -namespace gpu { -namespace gles2 { - -namespace { - -base::LazyInstance<base::Lock>::DestructorAtExit g_lock = - LAZY_INSTANCE_INITIALIZER; - -#if !defined(OS_MAC) -typedef std::map<SyncToken, std::unique_ptr<gl::GLFence>> SyncTokenToFenceMap; -base::LazyInstance<SyncTokenToFenceMap>::DestructorAtExit - g_sync_point_to_fence = LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<base::queue<SyncTokenToFenceMap::iterator>>::DestructorAtExit - g_sync_points = LAZY_INSTANCE_INITIALIZER; -#endif - -void CreateFenceLocked(const SyncToken& sync_token) { -#if !defined(OS_MAC) - g_lock.Get().AssertAcquired(); - if (gl::GetGLImplementation() == gl::kGLImplementationMockGL || - gl::GetGLImplementation() == gl::kGLImplementationStubGL) - return; - - base::queue<SyncTokenToFenceMap::iterator>& sync_points = g_sync_points.Get(); - SyncTokenToFenceMap& sync_point_to_fence = g_sync_point_to_fence.Get(); - if (sync_token.release_count()) { - while (!sync_points.empty() && - sync_points.front()->second->HasCompleted()) { - sync_point_to_fence.erase(sync_points.front()); - sync_points.pop(); - } - // Need to use EGL fences since we are likely not in a single share group. - std::unique_ptr<gl::GLFence> fence = gl::GLFenceEGL::Create(); - if (!fence) { - // Fall back to glFinish instead crashing such as in crbug.com/995376. - LOG(ERROR) << "eglCreateSyncKHR failed"; - glFinish(); - return; - } - std::pair<SyncTokenToFenceMap::iterator, bool> result = - sync_point_to_fence.insert( - std::make_pair(sync_token, std::move(fence))); - DCHECK(result.second); - sync_points.push(result.first); - DCHECK(sync_points.size() == sync_point_to_fence.size()); - } -#endif -} - -void AcquireFenceLocked(const SyncToken& sync_token) { -#if !defined(OS_MAC) - g_lock.Get().AssertAcquired(); - SyncTokenToFenceMap::iterator fence_it = - g_sync_point_to_fence.Get().find(sync_token); - if (fence_it != g_sync_point_to_fence.Get().end()) { - fence_it->second->ServerWait(); - } -#endif -} - -static const unsigned kNewTextureVersion = 1; - -} // anonymous namespace - -base::LazyInstance<MailboxManagerSync::TextureGroup::MailboxToGroupMap>:: - DestructorAtExit MailboxManagerSync::TextureGroup::mailbox_to_group_ = - LAZY_INSTANCE_INITIALIZER; - -// static -MailboxManagerSync::TextureGroup* MailboxManagerSync::TextureGroup::FromName( - const Mailbox& name) { - MailboxToGroupMap::iterator it = mailbox_to_group_.Get().find(name); - if (it == mailbox_to_group_.Get().end()) - return nullptr; - - return it->second.get(); -} - -MailboxManagerSync::TextureGroup::TextureGroup( - const TextureDefinition& definition) - : definition_(definition) { -} - -MailboxManagerSync::TextureGroup::~TextureGroup() = default; - -void MailboxManagerSync::TextureGroup::AddName(const Mailbox& name) { - g_lock.Get().AssertAcquired(); - DCHECK(std::find(names_.begin(), names_.end(), name) == names_.end()); - names_.push_back(name); - DCHECK(mailbox_to_group_.Get().find(name) == mailbox_to_group_.Get().end()); - mailbox_to_group_.Get()[name] = this; -} - -void MailboxManagerSync::TextureGroup::RemoveName(const Mailbox& name) { - g_lock.Get().AssertAcquired(); - std::vector<Mailbox>::iterator names_it = - std::find(names_.begin(), names_.end(), name); - DCHECK(names_it != names_.end()); - names_.erase(names_it); - MailboxToGroupMap::iterator it = mailbox_to_group_.Get().find(name); - DCHECK(it != mailbox_to_group_.Get().end()); - mailbox_to_group_.Get().erase(it); -} - -void MailboxManagerSync::TextureGroup::AddTexture(MailboxManagerSync* manager, - Texture* texture) { - g_lock.Get().AssertAcquired(); - DCHECK(std::find(textures_.begin(), textures_.end(), - std::make_pair(manager, texture)) == textures_.end()); - textures_.push_back(std::make_pair(manager, texture)); -} - -bool MailboxManagerSync::TextureGroup::RemoveTexture( - MailboxManagerSync* manager, - Texture* texture) { - g_lock.Get().AssertAcquired(); - TextureGroup::TextureList::iterator tex_list_it = std::find( - textures_.begin(), textures_.end(), std::make_pair(manager, texture)); - DCHECK(tex_list_it != textures_.end()); - if (textures_.size() == 1) { - // This is the last texture so the group is going away. - for (size_t n = 0; n < names_.size(); n++) { - const Mailbox& name = names_[n]; - MailboxToGroupMap::iterator mbox_it = - mailbox_to_group_.Get().find(name); - DCHECK(mbox_it != mailbox_to_group_.Get().end()); - DCHECK(mbox_it->second.get() == this); - mailbox_to_group_.Get().erase(mbox_it); - } - return false; - } else { - textures_.erase(tex_list_it); - return true; - } -} - -Texture* MailboxManagerSync::TextureGroup::FindTexture( - MailboxManagerSync* manager) { - g_lock.Get().AssertAcquired(); - for (TextureGroup::TextureList::iterator it = textures_.begin(); - it != textures_.end(); it++) { - if (it->first == manager) - return it->second; - } - return nullptr; -} - -MailboxManagerSync::TextureGroupRef::TextureGroupRef(unsigned version, - TextureGroup* group) - : version(version), group(group) { -} - -MailboxManagerSync::TextureGroupRef::TextureGroupRef( - const TextureGroupRef& other) = default; - -MailboxManagerSync::TextureGroupRef::~TextureGroupRef() = default; - -MailboxManagerSync::MailboxManagerSync() = default; - -MailboxManagerSync::~MailboxManagerSync() { - DCHECK_EQ(0U, texture_to_group_.size()); -} - -// static -bool MailboxManagerSync::SkipTextureWorkarounds(const Texture* texture) { - // Cannot support mips due to support mismatch between - // EGL_KHR_gl_texture_2D_image and glEGLImageTargetTexture2DOES for - // texture levels. - bool has_mips = texture->NeedsMips() && texture->texture_complete(); - return texture->target() != GL_TEXTURE_2D || has_mips; -} - -bool MailboxManagerSync::UsesSync() { - return true; -} - -Texture* MailboxManagerSync::ConsumeTexture(const Mailbox& mailbox) { - base::AutoLock lock(g_lock.Get()); - // Relax the cross-thread access restriction to non-thread-safe RefCount. - // The lock above protects non-thread-safe RefCount in TextureGroup. - base::ScopedAllowCrossThreadRefCountAccess - scoped_allow_cross_thread_ref_count_access; - TextureGroup* group = TextureGroup::FromName(mailbox); - if (!group) - return nullptr; - - // Check if a texture already exists in this share group. - Texture* texture = group->FindTexture(this); - if (texture) - return texture; - - // Otherwise create a new texture. - texture = group->GetDefinition().CreateTexture(); - if (texture) { - DCHECK(!SkipTextureWorkarounds(texture)); - texture->SetMailboxManager(this); - group->AddTexture(this, texture); - - TextureGroupRef new_ref = - TextureGroupRef(group->GetDefinition().version(), group); - texture_to_group_.insert(std::make_pair(texture, new_ref)); - } - - return texture; -} - -void MailboxManagerSync::ProduceTexture(const Mailbox& mailbox, - TextureBase* texture_base) { - DCHECK(texture_base); - base::AutoLock lock(g_lock.Get()); - // Relax the cross-thread access restriction to non-thread-safe RefCount. - // The lock above protects non-thread-safe RefCount in TextureGroup. - base::ScopedAllowCrossThreadRefCountAccess - scoped_allow_cross_thread_ref_count_access; - if (TextureGroup::FromName(mailbox)) { - DLOG(ERROR) << "Ignored attempt to reassign a mailbox"; - return; - } - - Texture* texture = Texture::CheckedCast(texture_base); - - TextureToGroupMap::iterator tex_it = texture_to_group_.find(texture); - TextureGroup* group_for_texture = nullptr; - - if (tex_it != texture_to_group_.end()) { - group_for_texture = tex_it->second.group.get(); - DCHECK(group_for_texture); - } else { - // This is a new texture, so create a new group. - texture->SetMailboxManager(this); - TextureDefinition definition; - if (!SkipTextureWorkarounds(texture)) { - base::AutoUnlock unlock(g_lock.Get()); - definition = TextureDefinition(texture, kNewTextureVersion, nullptr); - } - group_for_texture = new TextureGroup(definition); - group_for_texture->AddTexture(this, texture); - texture_to_group_.insert(std::make_pair( - texture, TextureGroupRef(kNewTextureVersion, group_for_texture))); - } - group_for_texture->AddName(mailbox); - - DCHECK(texture->mailbox_manager() == this); -} - -void MailboxManagerSync::TextureDeleted(TextureBase* texture_base) { - base::AutoLock lock(g_lock.Get()); - // Relax the cross-thread access restriction to non-thread-safe RefCount. - // The lock above protects non-thread-safe RefCount in TextureGroup. - base::ScopedAllowCrossThreadRefCountAccess - scoped_allow_cross_thread_ref_count_access; - - Texture* texture = Texture::CheckedCast(texture_base); - DCHECK(texture != nullptr); - - TextureToGroupMap::iterator tex_it = texture_to_group_.find(texture); - DCHECK(tex_it != texture_to_group_.end()); - TextureGroup* group_for_texture = tex_it->second.group.get(); - if (group_for_texture->RemoveTexture(this, texture)) - UpdateDefinitionLocked(texture, &tex_it->second); - texture_to_group_.erase(tex_it); -} - -void MailboxManagerSync::UpdateDefinitionLocked(TextureBase* texture_base, - TextureGroupRef* group_ref) { - g_lock.Get().AssertAcquired(); - - Texture* texture = Texture::CheckedCast(texture_base); - DCHECK(texture != nullptr); - - if (SkipTextureWorkarounds(texture)) - return; - - gl::GLImage* image = texture->GetLevelImage(texture->target(), 0); - TextureGroup* group = group_ref->group.get(); - const TextureDefinition& definition = group->GetDefinition(); - scoped_refptr<NativeImageBuffer> image_buffer = definition.image(); - - // Make sure we don't clobber with an older version - if (!definition.IsOlderThan(group_ref->version)) - return; - - // Also don't push redundant updates. Note that it would break the - // versioning. - if (definition.Matches(texture)) - return; - - // Don't try to push updates to texture that have a bound image (not created - // by the MailboxManagerSync), as they were never shared to begin with. - if (image && (!image_buffer || !image_buffer->IsClient(image))) - return; - - group->SetDefinition(TextureDefinition(texture, ++group_ref->version, - image ? image_buffer : nullptr)); -} - -void MailboxManagerSync::PushTextureUpdates(const SyncToken& token) { - base::AutoLock lock(g_lock.Get()); - // Relax the cross-thread access restriction to non-thread-safe RefCount. - // The lock above protects non-thread-safe RefCount in TextureGroup. - base::ScopedAllowCrossThreadRefCountAccess - scoped_allow_cross_thread_ref_count_access; - - for (TextureToGroupMap::iterator it = texture_to_group_.begin(); - it != texture_to_group_.end(); it++) { - UpdateDefinitionLocked(it->first, &it->second); - } - CreateFenceLocked(token); -} - -void MailboxManagerSync::PullTextureUpdates(const SyncToken& token) { - using TextureUpdatePair = std::pair<Texture*, TextureDefinition>; - std::vector<TextureUpdatePair> needs_update; - { - base::AutoLock lock(g_lock.Get()); - // Relax the cross-thread access restriction to non-thread-safe RefCount. - // The lock above protects non-thread-safe RefCount in TextureGroup. - base::ScopedAllowCrossThreadRefCountAccess - scoped_allow_cross_thread_ref_count_access; - AcquireFenceLocked(token); - - for (TextureToGroupMap::iterator it = texture_to_group_.begin(); - it != texture_to_group_.end(); it++) { - const TextureDefinition& definition = it->second.group->GetDefinition(); - Texture* texture = it->first; - unsigned& texture_version = it->second.version; - if (texture_version == definition.version() || - definition.IsOlderThan(texture_version)) - continue; - texture_version = definition.version(); - needs_update.push_back(TextureUpdatePair(texture, definition)); - } - } - - if (!needs_update.empty()) { - for (const TextureUpdatePair& pair : needs_update) { - pair.second.UpdateTexture(pair.first); - } - } -} - -} // namespace gles2 -} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h b/chromium/gpu/command_buffer/service/mailbox_manager_sync.h deleted file mode 100644 index 48275fa619f..00000000000 --- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_SYNC_H_ -#define GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_SYNC_H_ - -#include <map> -#include <utility> - -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/mailbox.h" -#include "gpu/command_buffer/service/mailbox_manager.h" -#include "gpu/command_buffer/service/texture_definition.h" -#include "gpu/command_buffer/service/texture_manager.h" -#include "gpu/gpu_gles2_export.h" - -namespace gpu { -namespace gles2 { - -// Manages resources scoped beyond the context or context group level -// and across threads and driver level share groups by synchronizing -// texture state. -class GPU_GLES2_EXPORT MailboxManagerSync : public MailboxManager { - public: - MailboxManagerSync(); - ~MailboxManagerSync() override; - - // MailboxManager implementation: - Texture* ConsumeTexture(const Mailbox& mailbox) override; - void ProduceTexture(const Mailbox& mailbox, TextureBase* texture) override; - bool UsesSync() override; - void PushTextureUpdates(const SyncToken& token) override; - void PullTextureUpdates(const SyncToken& token) override; - void TextureDeleted(TextureBase* texture) override; - - private: - static bool SkipTextureWorkarounds(const Texture* texture); - - class TextureGroup : public base::RefCounted<TextureGroup> { - public: - explicit TextureGroup(const TextureDefinition& definition); - static TextureGroup* FromName(const Mailbox& name); - - void AddName(const Mailbox& name); - void RemoveName(const Mailbox& name); - - void AddTexture(MailboxManagerSync* manager, Texture* texture); - // Returns true if there are other textures left in the group after removal. - bool RemoveTexture(MailboxManagerSync* manager, Texture* texture); - Texture* FindTexture(MailboxManagerSync* manager); - - const TextureDefinition& GetDefinition() { return definition_; } - void SetDefinition(TextureDefinition definition) { - definition_ = definition; - } - - private: - friend class base::RefCounted<TextureGroup>; - ~TextureGroup(); - - typedef std::vector<std::pair<MailboxManagerSync*, Texture*>> TextureList; - std::vector<Mailbox> names_; - TextureList textures_; - TextureDefinition definition_; - - typedef std::map<Mailbox, scoped_refptr<TextureGroup>> - MailboxToGroupMap; - static base::LazyInstance<MailboxToGroupMap>::DestructorAtExit - mailbox_to_group_; - }; - - struct TextureGroupRef { - TextureGroupRef(unsigned version, TextureGroup* group); - TextureGroupRef(const TextureGroupRef& other); - ~TextureGroupRef(); - unsigned version; - scoped_refptr<TextureGroup> group; - }; - static void UpdateDefinitionLocked(TextureBase* texture, - TextureGroupRef* group_ref); - - typedef std::map<Texture*, TextureGroupRef> TextureToGroupMap; - TextureToGroupMap texture_to_group_; - - DISALLOW_COPY_AND_ASSIGN(MailboxManagerSync); -}; - -} // namespage gles2 -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_SYNC_H_ diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc b/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc index 79053f13840..0a89fe901aa 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc @@ -7,7 +7,6 @@ #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" -#include "gpu/command_buffer/service/mailbox_manager_sync.h" #include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_context_stub.h" @@ -31,14 +30,6 @@ class MailboxManagerTest : public GpuServiceTest { GpuServiceTest::SetUp(); feature_info_ = new FeatureInfo; manager_ = std::make_unique<MailboxManagerImpl>(); - DCHECK(!manager_->UsesSync()); - } - - virtual void SetUpWithSynchronizer() { - GpuServiceTest::SetUp(); - feature_info_ = new FeatureInfo; - manager_ = std::make_unique<MailboxManagerSync>(); - DCHECK(manager_->UsesSync()); } Texture* CreateTexture() { @@ -152,587 +143,5 @@ TEST_F(MailboxManagerTest, ProduceMultipleTexture) { EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); } -const GLsizei kMaxTextureWidth = 64; -const GLsizei kMaxTextureHeight = 64; -const GLsizei kMaxTextureDepth = 1; - -class MailboxManagerSyncTest : public MailboxManagerTest { - public: - MailboxManagerSyncTest() = default; - ~MailboxManagerSyncTest() override = default; - - protected: - void SetUp() override { - MailboxManagerTest::SetUpWithSynchronizer(); - manager2_ = std::make_unique<MailboxManagerSync>(); - context_ = new gl::GLContextStub(); - surface_ = new gl::GLSurfaceStub(); - context_->MakeCurrent(surface_.get()); - } - - Texture* DefineTexture() { - Texture* texture = CreateTexture(); - const GLsizei levels_needed = TextureManager::ComputeMipMapCount( - GL_TEXTURE_2D, kMaxTextureWidth, kMaxTextureHeight, kMaxTextureDepth); - SetTarget(texture, GL_TEXTURE_2D, levels_needed); - SetLevelInfo(texture, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(1, 1)); - SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - return texture; - } - - void SetupUpdateTexParamExpectations(GLuint texture_id, - GLenum min, - GLenum mag, - GLenum wrap_s, - GLenum wrap_t) { - DCHECK(texture_id); - const GLuint kCurrentTexture = 0; - EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_2D, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kCurrentTexture)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, texture_id)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kCurrentTexture)) - .Times(1) - .RetiresOnSaturation(); - } - - void TearDown() override { - context_->ReleaseCurrent(nullptr); - MailboxManagerTest::TearDown(); - } - - std::unique_ptr<MailboxManager> manager2_; - scoped_refptr<gl::GLContext> context_; - scoped_refptr<gl::GLSurface> surface_; - - private: - DISALLOW_COPY_AND_ASSIGN(MailboxManagerSyncTest); -}; - -TEST_F(MailboxManagerSyncTest, ProduceDestroy) { - Texture* texture = DefineTexture(); - Mailbox name = Mailbox::Generate(); - - testing::InSequence sequence; - manager_->ProduceTexture(name, texture); - EXPECT_EQ(texture, manager_->ConsumeTexture(name)); - - DestroyTexture(texture); - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -TEST_F(MailboxManagerSyncTest, ProduceSyncDestroy) { - testing::InSequence sequence; - - Texture* texture = DefineTexture(); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - EXPECT_EQ(texture, manager_->ConsumeTexture(name)); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture); - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -TEST_F(MailboxManagerSyncTest, ProduceSyncMultipleMailbox) { - testing::InSequence sequence; - - Texture* texture = DefineTexture(); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - manager_->PushTextureUpdates(g_sync_token); - - // Producing a second time with the same mailbox is ignored. - Texture* old_texture = texture; - texture = DefineTexture(); - manager_->ProduceTexture(name, texture); - EXPECT_EQ(old_texture, manager_->ConsumeTexture(name)); - - DestroyTexture(old_texture); - DestroyTexture(texture); - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -// Duplicates a texture into a second manager instance, and then -// makes sure a redefinition becomes visible there too. -TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture = DefineTexture(); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - EXPECT_EQ(texture, manager_->ConsumeTexture(name)); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - Texture* new_texture = Texture::CheckedCast(manager2_->ConsumeTexture(name)); - EXPECT_NE(nullptr, new_texture); - EXPECT_NE(texture, new_texture); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - // Resize original texture - SetLevelInfo(texture, GL_TEXTURE_2D, 0, GL_RGBA, 16, 32, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(16, 32)); - // Should have been orphaned - EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == nullptr); - - // Synchronize again - manager_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(g_sync_token); - GLsizei width, height; - new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); - EXPECT_EQ(16, width); - EXPECT_EQ(32, height); - - // Should have gotten a new attachment - EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) != nullptr); - // Resize original texture again.... - SetLevelInfo(texture, GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(64, 64)); - // ...and immediately delete the texture which should save the changes. - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - DestroyTexture(texture); - - // Should be still around since there is a ref from manager2 - EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name)); - - // The last change to the texture should be visible without a sync point (i.e. - // push). - manager2_->PullTextureUpdates(g_sync_token); - new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); - EXPECT_EQ(64, width); - EXPECT_EQ(64, height); - - DestroyTexture(new_texture); - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -// Makes sure changes are correctly published even when updates are -// pushed in both directions, i.e. makes sure we don't clobber a shared -// texture definition with an older version. -TEST_F(MailboxManagerSyncTest, ProduceConsumeBidirectional) { - const GLuint kNewTextureId1 = 1234; - const GLuint kNewTextureId2 = 4321; - - Texture* texture1 = DefineTexture(); - Mailbox name1 = Mailbox::Generate(); - Texture* texture2 = DefineTexture(); - Mailbox name2 = Mailbox::Generate(); - TextureBase* new_texture1 = nullptr; - TextureBase* new_texture2 = nullptr; - - manager_->ProduceTexture(name1, texture1); - manager2_->ProduceTexture(name2, texture2); - - // Make visible. - manager_->PushTextureUpdates(g_sync_token); - manager2_->PushTextureUpdates(g_sync_token); - - // Create textures in the other manager instances for texture1 and texture2, - // respectively to create a real sharing scenario. Otherwise, there would - // never be conflicting updates/pushes. - { - testing::InSequence sequence; - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId1)); - SetupUpdateTexParamExpectations( - kNewTextureId1, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - new_texture1 = manager2_->ConsumeTexture(name1); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId2)); - SetupUpdateTexParamExpectations( - kNewTextureId2, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - new_texture2 = manager_->ConsumeTexture(name2); - } - EXPECT_EQ(kNewTextureId1, new_texture1->service_id()); - EXPECT_EQ(kNewTextureId2, new_texture2->service_id()); - - // Make a change to texture1 - DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), texture1->min_filter()); - EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), - SetParameter(texture1, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - - // Make sure this does not clobber it with the previous version we pushed. - manager_->PullTextureUpdates(g_sync_token); - - // Make a change to texture2 - DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), texture2->mag_filter()); - EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), - SetParameter(texture2, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - - testing::Mock::VerifyAndClearExpectations(gl_.get()); - - // Synchronize in both directions - manager_->PushTextureUpdates(g_sync_token); - manager2_->PushTextureUpdates(g_sync_token); - // manager1 should see the change to texture2 mag_filter being applied. - SetupUpdateTexParamExpectations( - new_texture2->service_id(), GL_LINEAR, GL_NEAREST, GL_REPEAT, GL_REPEAT); - manager_->PullTextureUpdates(g_sync_token); - // manager2 should see the change to texture1 min_filter being applied. - SetupUpdateTexParamExpectations( - new_texture1->service_id(), GL_NEAREST, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture1); - DestroyTexture(texture2); - DestroyTexture(new_texture1); - DestroyTexture(new_texture2); -} - -TEST_F(MailboxManagerSyncTest, ClearedStateSynced) { - const GLuint kNewTextureId = 1234; - - Texture* texture = DefineTexture(); - EXPECT_TRUE(texture->SafeToRenderFrom()); - - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - EXPECT_EQ(texture, manager_->ConsumeTexture(name)); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - Texture* new_texture = Texture::CheckedCast(manager2_->ConsumeTexture(name)); - EXPECT_NE(nullptr, new_texture); - EXPECT_NE(texture, new_texture); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - EXPECT_TRUE(texture->SafeToRenderFrom()); - - // Change cleared to false. - SetLevelCleared(texture, texture->target(), 0, false); - EXPECT_FALSE(texture->SafeToRenderFrom()); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(g_sync_token); - - // Cleared state should be synced. - EXPECT_FALSE(new_texture->SafeToRenderFrom()); - - DestroyTexture(texture); - DestroyTexture(new_texture); - - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -TEST_F(MailboxManagerSyncTest, SyncIncompleteTexture) { - const GLuint kNewTextureId = 1234; - - // Create but not define texture. - Texture* texture = CreateTexture(); - SetTarget(texture, GL_TEXTURE_2D, 1); - EXPECT_FALSE(texture->IsDefined()); - - Mailbox name = Mailbox::Generate(); - manager_->ProduceTexture(name, texture); - EXPECT_EQ(texture, manager_->ConsumeTexture(name)); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - // Should sync to new texture which is not defined. - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations(kNewTextureId, texture->min_filter(), - texture->mag_filter(), texture->wrap_s(), - texture->wrap_t()); - Texture* new_texture = Texture::CheckedCast(manager2_->ConsumeTexture(name)); - EXPECT_NE(nullptr, new_texture); - EXPECT_NE(texture, new_texture); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - EXPECT_FALSE(new_texture->IsDefined()); - - // Change cleared to false. - SetLevelInfo(texture, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(1, 1)); - SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - EXPECT_TRUE(texture->IsDefined()); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(g_sync_token); - - // Cleared state should be synced. - EXPECT_TRUE(new_texture->IsDefined()); - - DestroyTexture(texture); - DestroyTexture(new_texture); - - EXPECT_EQ(nullptr, manager_->ConsumeTexture(name)); - EXPECT_EQ(nullptr, manager2_->ConsumeTexture(name)); -} - -// Putting the same texture into multiple mailboxes should result in sharing -// only a single texture also within a synchronized manager instance. -TEST_F(MailboxManagerSyncTest, SharedThroughMultipleMailboxes) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture = DefineTexture(); - Mailbox name1 = Mailbox::Generate(); - Mailbox name2 = Mailbox::Generate(); - - manager_->ProduceTexture(name1, texture); - - // Share - manager_->PushTextureUpdates(g_sync_token); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - manager2_->PullTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - TextureBase* new_texture = manager2_->ConsumeTexture(name1); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - manager_->ProduceTexture(name2, texture); - - // Synchronize - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - // name2 should return the same texture - EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name2)); - - // Even after destroying the source texture, the original mailbox should - // still exist. - DestroyTexture(texture); - EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name1)); - DestroyTexture(new_texture); -} - -// A: produce texture1 into M, B: consume into new_texture -// B: produce texture2 into M, A: produce texture1 into M -// B: consume M should return new_texture -TEST_F(MailboxManagerSyncTest, ProduceBothWays) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture1 = DefineTexture(); - Texture* texture2 = DefineTexture(); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture1); - - // Share - manager_->PushTextureUpdates(g_sync_token); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations( - kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - TextureBase* new_texture = manager2_->ConsumeTexture(name); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - // Clobber - manager2_->ProduceTexture(name, texture2); - manager_->ProduceTexture(name, texture1); - - // Synchronize manager -> manager2 - manager_->PushTextureUpdates(g_sync_token); - manager2_->PullTextureUpdates(g_sync_token); - - // name should return the original texture, and not texture2 or a new one. - EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name)); - - DestroyTexture(texture1); - DestroyTexture(texture2); - DestroyTexture(new_texture); -} - -// Test for crbug.com/816693 -// A: produce texture (without images) into M, B: consume into new_texture -// B: push updates -TEST_F(MailboxManagerSyncTest, ProduceTextureNotDefined) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture = CreateTexture(); - const GLsizei levels_needed = TextureManager::ComputeMipMapCount( - GL_TEXTURE_2D, kMaxTextureWidth, kMaxTextureHeight, kMaxTextureDepth); - SetTarget(texture, GL_TEXTURE_2D, levels_needed); - SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - - // Share - manager_->PushTextureUpdates(g_sync_token); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations(kNewTextureId, GL_LINEAR, GL_LINEAR, - GL_REPEAT, GL_REPEAT); - TextureBase* new_texture = manager2_->ConsumeTexture(name); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - // Change something so that the push recreates the TextureDefinition. - SetParameter(Texture::CheckedCast(new_texture), GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - - // Synchronize manager2 -> manager - manager2_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations(1, GL_NEAREST, GL_LINEAR, GL_REPEAT, - GL_REPEAT); - manager_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture); - DestroyTexture(new_texture); -} - -TEST_F(MailboxManagerSyncTest, ProduceTextureDefinedNotLevel0) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture = CreateTexture(); - const GLsizei levels_needed = TextureManager::ComputeMipMapCount( - GL_TEXTURE_2D, kMaxTextureWidth, kMaxTextureHeight, kMaxTextureDepth); - SetTarget(texture, GL_TEXTURE_2D, levels_needed); - SetLevelInfo(texture, GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 1, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(1, 1)); - SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - - // Share - manager_->PushTextureUpdates(g_sync_token); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations(kNewTextureId, GL_LINEAR, GL_LINEAR, - GL_REPEAT, GL_REPEAT); - TextureBase* new_texture = manager2_->ConsumeTexture(name); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - // Change something so that the push recreates the TextureDefinition. - SetParameter(Texture::CheckedCast(new_texture), GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - - // Synchronize manager2 -> manager - manager2_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations(1, GL_NEAREST, GL_LINEAR, GL_REPEAT, - GL_REPEAT); - manager_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture); - DestroyTexture(new_texture); -} - -TEST_F(MailboxManagerSyncTest, ProduceTextureDefined0Size) { - const GLuint kNewTextureId = 1234; - testing::InSequence sequence; - - Texture* texture = CreateTexture(); - const GLsizei levels_needed = TextureManager::ComputeMipMapCount( - GL_TEXTURE_2D, kMaxTextureWidth, kMaxTextureHeight, kMaxTextureDepth); - SetTarget(texture, GL_TEXTURE_2D, levels_needed); - SetLevelInfo(texture, GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, - GL_UNSIGNED_BYTE, gfx::Rect(0, 0)); - SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - - // Share - manager_->PushTextureUpdates(g_sync_token); - EXPECT_CALL(*gl_, GenTextures(1, testing::_)) - .WillOnce(testing::SetArgPointee<1>(kNewTextureId)); - SetupUpdateTexParamExpectations(kNewTextureId, GL_LINEAR, GL_LINEAR, - GL_REPEAT, GL_REPEAT); - TextureBase* new_texture = manager2_->ConsumeTexture(name); - EXPECT_EQ(kNewTextureId, new_texture->service_id()); - - // Change something so that the push recreates the TextureDefinition. - SetParameter(Texture::CheckedCast(new_texture), GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - - // Synchronize manager2 -> manager - manager2_->PushTextureUpdates(g_sync_token); - SetupUpdateTexParamExpectations(1, GL_NEAREST, GL_LINEAR, GL_REPEAT, - GL_REPEAT); - manager_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture); - DestroyTexture(new_texture); -} - -TEST_F(MailboxManagerSyncTest, ProduceTextureNotBound) { - testing::InSequence sequence; - - Texture* texture = CreateTexture(); - Mailbox name = Mailbox::Generate(); - - manager_->ProduceTexture(name, texture); - - // Share - manager_->PushTextureUpdates(g_sync_token); - - // Consume should fail. - TextureBase* new_texture = manager2_->ConsumeTexture(name); - EXPECT_EQ(nullptr, new_texture); - - // Synchronize manager2 -> manager - manager2_->PushTextureUpdates(g_sync_token); - manager_->PullTextureUpdates(g_sync_token); - - DestroyTexture(texture); -} - -// TODO: Texture::level_infos_[][].size() - -// TODO: unsupported targets and formats - } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/program_manager_unittest.cc b/chromium/gpu/command_buffer/service/program_manager_unittest.cc index a3476cb36a3..f627ad85ba0 100644 --- a/chromium/gpu/command_buffer/service/program_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/program_manager_unittest.cc @@ -60,9 +60,9 @@ uint32_t ComputeOffset(const void* start, const void* position) { class ProgramManagerTestBase : public GpuServiceTest, public DecoderClient { protected: virtual void SetupProgramManager() { - manager_.reset(new ProgramManager( + manager_ = std::make_unique<ProgramManager>( nullptr, kMaxVaryingVectors, kMaxDrawBuffers, kMaxDualSourceDrawBuffers, - kMaxVertexAttribs, gpu_preferences_, feature_info_.get(), nullptr)); + kMaxVertexAttribs, gpu_preferences_, feature_info_.get(), nullptr); } void SetUpBase(const char* gl_version, const char* gl_extensions, @@ -2172,10 +2172,10 @@ class ProgramManagerWithCacheTest : public ProgramManagerTestBase { protected: void SetupProgramManager() override { - manager_.reset( - new ProgramManager(cache_.get(), kMaxVaryingVectors, kMaxDrawBuffers, - kMaxDualSourceDrawBuffers, kMaxVertexAttribs, - gpu_preferences_, feature_info_.get(), nullptr)); + manager_ = std::make_unique<ProgramManager>( + cache_.get(), kMaxVaryingVectors, kMaxDrawBuffers, + kMaxDualSourceDrawBuffers, kMaxVertexAttribs, gpu_preferences_, + feature_info_.get(), nullptr); } void SetUp() override { diff --git a/chromium/gpu/command_buffer/service/query_manager_unittest.cc b/chromium/gpu/command_buffer/service/query_manager_unittest.cc index 5fdd7f3c095..959c8d646cf 100644 --- a/chromium/gpu/command_buffer/service/query_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/query_manager_unittest.cc @@ -62,7 +62,7 @@ class QueryManagerTest : public GpuServiceTest { } void SetUpMockGL(const char* extension_expectations) { - command_buffer_service_.reset(new FakeCommandBufferServiceBase()); + command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>(); scoped_refptr<gpu::Buffer> buffer = command_buffer_service_->CreateTransferBufferHelper(kSharedBufferSize, &shared_memory_id_); @@ -70,15 +70,16 @@ class QueryManagerTest : public GpuServiceTest { buffer = command_buffer_service_->CreateTransferBufferHelper( kSharedBufferSize, &shared_memory2_id_); memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize); - decoder_.reset(new MockGLES2Decoder(&client_, command_buffer_service_.get(), - &outputter_)); + decoder_ = std::make_unique<MockGLES2Decoder>( + &client_, command_buffer_service_.get(), &outputter_); TestHelper::SetupFeatureInfoInitExpectations( gl_.get(), extension_expectations); EXPECT_CALL(*decoder_.get(), GetGLContext()) .WillRepeatedly(Return(GetGLContext())); scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); feature_info->InitializeForTesting(); - manager_.reset(new GLES2QueryManager(decoder_.get(), feature_info.get())); + manager_ = + std::make_unique<GLES2QueryManager>(decoder_.get(), feature_info.get()); } QueryManager::Query* CreateQuery(GLenum target, diff --git a/chromium/gpu/command_buffer/service/raster_decoder.cc b/chromium/gpu/command_buffer/service/raster_decoder.cc index 16c9facc40a..4426208d82f 100644 --- a/chromium/gpu/command_buffer/service/raster_decoder.cc +++ b/chromium/gpu/command_buffer/service/raster_decoder.cc @@ -623,6 +623,7 @@ class RasterDecoderImpl final : public RasterDecoder, void DoLoseContextCHROMIUM(GLenum current, GLenum other); void DoBeginRasterCHROMIUM(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const volatile GLbyte* key); @@ -965,8 +966,8 @@ ContextResult RasterDecoderImpl::Initialize( DCHECK_EQ(context.get(), shared_context_state_->context()); // Create GPU Tracer for timing values. - gpu_tracer_.reset( - new gles2::GPUTracer(this, shared_context_state_->GrContextIsGL())); + gpu_tracer_ = std::make_unique<gles2::GPUTracer>( + this, shared_context_state_->GrContextIsGL()); // Save the loseContextWhenOutOfMemory context creation attribute. lose_context_when_out_of_memory_ = @@ -1895,8 +1896,8 @@ error::Error RasterDecoderImpl::HandleSetActiveURLCHROMIUM( bool RasterDecoderImpl::InitializeCopyTexImageBlitter() { if (!copy_tex_image_blit_.get()) { LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTexture"); - copy_tex_image_blit_.reset( - new gles2::CopyTexImageResourceManager(feature_info())); + copy_tex_image_blit_ = + std::make_unique<gles2::CopyTexImageResourceManager>(feature_info()); copy_tex_image_blit_->Initialize(this); if (LOCAL_PEEK_GL_ERROR("glCopySubTexture") != GL_NO_ERROR) return false; @@ -2247,6 +2248,9 @@ void RasterDecoderImpl::DoCopySubTextureINTERNALGL( false /* unpack_unmultiply_alpha */, false /* dither */, method, copy_tex_image_blit_.get()); dest_texture->SetLevelClearedRect(dest_target, dest_level, new_cleared_rect); + if (!dest_shared_image->IsCleared()) { + dest_shared_image->SetClearedRect(new_cleared_rect); + } in_copy_sub_texture_ = false; if (reset_texture_state_) { reset_texture_state_ = false; @@ -2970,6 +2974,7 @@ void RasterDecoderImpl::DoClearPaintCacheINTERNAL() { } void RasterDecoderImpl::DoBeginRasterCHROMIUM(GLuint sk_color, + GLboolean needs_clear, GLuint msaa_sample_count, GLboolean can_use_lcd_text, const volatile GLbyte* key) { @@ -3062,15 +3067,18 @@ void RasterDecoderImpl::DoBeginRasterCHROMIUM(GLuint sk_color, &end_semaphores_, error_state_.get()); // All or nothing clearing, as no way to validate the client's input on what - // is the "used" part of the texture. - // TODO(enne): This doesn't handle the case where the background color - // changes and so any extra pixels outside the raster area that get - // sampled may be incorrect. - if (shared_image_->IsCleared()) - return; - - raster_canvas_->drawColor(sk_color); - shared_image_->SetCleared(); + // is the "used" part of the texture. A separate |needs_clear| flag is needed + // because clear tracking on the shared image cannot be used for this purpose + // with passthrough decoder shared images which are always considered cleared. + // + // TODO(enne): This doesn't handle the case where the background color changes + // and so any extra pixels outside the raster area that get sampled may be + // incorrect. + if (needs_clear) { + raster_canvas_->drawColor(sk_color, SkBlendMode::kSrc); + shared_image_->SetCleared(); + } + DCHECK(shared_image_->IsCleared()); } scoped_refptr<Buffer> RasterDecoderImpl::GetShmBuffer(uint32_t shm_id) { diff --git a/chromium/gpu/command_buffer/service/raster_decoder_autogen.h b/chromium/gpu/command_buffer/service/raster_decoder_autogen.h index 50f8e95bb58..7813f03a1e2 100644 --- a/chromium/gpu/command_buffer/service/raster_decoder_autogen.h +++ b/chromium/gpu/command_buffer/service/raster_decoder_autogen.h @@ -112,6 +112,7 @@ error::Error RasterDecoderImpl::HandleBeginRasterCHROMIUMImmediate( *static_cast<const volatile raster::cmds::BeginRasterCHROMIUMImmediate*>( cmd_data); GLuint sk_color = static_cast<GLuint>(c.sk_color); + GLboolean needs_clear = static_cast<GLboolean>(c.needs_clear); GLuint msaa_sample_count = static_cast<GLuint>(c.msaa_sample_count); GLboolean can_use_lcd_text = static_cast<GLboolean>(c.can_use_lcd_text); uint32_t mailbox_size; @@ -127,7 +128,8 @@ error::Error RasterDecoderImpl::HandleBeginRasterCHROMIUMImmediate( if (mailbox == nullptr) { return error::kOutOfBounds; } - DoBeginRasterCHROMIUM(sk_color, msaa_sample_count, can_use_lcd_text, mailbox); + DoBeginRasterCHROMIUM(sk_color, needs_clear, msaa_sample_count, + can_use_lcd_text, mailbox); return error::kNoError; } diff --git a/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc index 6c73190fce4..c356cfcf379 100644 --- a/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc +++ b/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc @@ -147,7 +147,7 @@ void RasterDecoderTestBase::InitDecoder(const InitState& init) { gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress); gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings(); - gl_.reset(new StrictMock<MockGLInterface>()); + gl_ = std::make_unique<StrictMock<MockGLInterface>>(); ::gl::MockGLInterface::SetGLInterface(gl_.get()); InSequence sequence; @@ -196,7 +196,7 @@ void RasterDecoderTestBase::InitDecoder(const InitState& init) { shared_context_state_->disable_check_reset_status_throttling_for_test_ = true; shared_context_state_->InitializeGL(GpuPreferences(), feature_info_); - command_buffer_service_.reset(new FakeCommandBufferServiceBase()); + command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>(); decoder_.reset(RasterDecoder::Create( this, command_buffer_service_.get(), &outputter_, gpu_feature_info, diff --git a/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc index de693bb47a5..9120d188476 100644 --- a/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc @@ -6,7 +6,9 @@ #include <stdint.h> +#include <memory> #include <set> + #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gpu_service_test.h" @@ -39,8 +41,8 @@ class RenderbufferManagerTestBase : public GpuServiceTest { use_gles ? "OpenGL ES 2.0" : "2.1", feature_info_->context_type()); feature_info_->InitializeForTesting(); - manager_.reset(new RenderbufferManager( - memory_tracker, kMaxSize, kMaxSamples, feature_info_.get())); + manager_ = std::make_unique<RenderbufferManager>( + memory_tracker, kMaxSize, kMaxSamples, feature_info_.get()); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/service/scheduler.cc b/chromium/gpu/command_buffer/service/scheduler.cc index d50013680c4..dbe7b863cfe 100644 --- a/chromium/gpu/command_buffer/service/scheduler.cc +++ b/chromium/gpu/command_buffer/service/scheduler.cc @@ -5,6 +5,8 @@ #include "gpu/command_buffer/service/scheduler.h" #include <algorithm> +#include <cstddef> +#include <vector> #include "base/bind.h" #include "base/callback.h" @@ -13,6 +15,7 @@ #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" +#include "base/time/time.h" #include "base/timer/elapsed_timer.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" @@ -34,10 +37,12 @@ uint64_t GetTaskFlowId(uint32_t sequence_id, uint32_t order_num) { Scheduler::Task::Task(SequenceId sequence_id, base::OnceClosure closure, - std::vector<SyncToken> sync_token_fences) + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback) : sequence_id(sequence_id), closure(std::move(closure)), - sync_token_fences(std::move(sync_token_fences)) {} + sync_token_fences(std::move(sync_token_fences)), + report_callback(std::move(report_callback)) {} Scheduler::Task::Task(Task&& other) = default; Scheduler::Task::~Task() = default; Scheduler::Task& Scheduler::Task::operator=(Task&& other) = default; @@ -57,10 +62,18 @@ Scheduler::SchedulingState::AsValue() const { return std::move(state); } -Scheduler::Sequence::Task::Task(base::OnceClosure closure, uint32_t order_num) - : closure(std::move(closure)), order_num(order_num) {} +Scheduler::Sequence::Task::Task(base::OnceClosure closure, + uint32_t order_num, + ReportingCallback report_callback) + : closure(std::move(closure)), + order_num(order_num), + report_callback(std::move(report_callback)) {} + Scheduler::Sequence::Task::Task(Task&& other) = default; -Scheduler::Sequence::Task::~Task() = default; +Scheduler::Sequence::Task::~Task() { + DCHECK(report_callback.is_null()); +} + Scheduler::Sequence::Task& Scheduler::Sequence::Task::operator=(Task&& other) = default; @@ -172,19 +185,35 @@ void Scheduler::Sequence::UpdateRunningPriority() { void Scheduler::Sequence::ContinueTask(base::OnceClosure closure) { DCHECK_EQ(running_state_, RUNNING); uint32_t order_num = order_data_->current_order_num(); - tasks_.push_front({std::move(closure), order_num}); + + tasks_.push_front({std::move(closure), order_num, ReportingCallback()}); order_data_->PauseProcessingOrderNumber(order_num); } -uint32_t Scheduler::Sequence::ScheduleTask(base::OnceClosure closure) { +uint32_t Scheduler::Sequence::ScheduleTask(base::OnceClosure closure, + ReportingCallback report_callback) { uint32_t order_num = order_data_->GenerateUnprocessedOrderNumber(); TRACE_EVENT_WITH_FLOW0("gpu,toplevel.flow", "Scheduler::ScheduleTask", GetTaskFlowId(sequence_id_.value(), order_num), TRACE_EVENT_FLAG_FLOW_OUT); - tasks_.push_back({std::move(closure), order_num}); + tasks_.push_back({std::move(closure), order_num, std::move(report_callback)}); return order_num; } +base::TimeDelta Scheduler::Sequence::FrontTaskWaitingDependencyDelta() { + DCHECK(!tasks_.empty()); + if (tasks_.front().first_dependency_added.is_null()) { + // didn't wait for dependencies. + return base::TimeDelta(); + } + return tasks_.front().running_ready - tasks_.front().first_dependency_added; +} + +base::TimeDelta Scheduler::Sequence::FrontTaskSchedulingDelay() { + DCHECK(!tasks_.empty()); + return base::TimeTicks::Now() - tasks_.front().running_ready; +} + uint32_t Scheduler::Sequence::BeginTask(base::OnceClosure* closure) { DCHECK(closure); DCHECK(!tasks_.empty()); @@ -194,6 +223,9 @@ uint32_t Scheduler::Sequence::BeginTask(base::OnceClosure* closure) { *closure = std::move(tasks_.front().closure); uint32_t order_num = tasks_.front().order_num; + if (!tasks_.front().report_callback.is_null()) { + std::move(tasks_.front().report_callback).Run(tasks_.front().running_ready); + } tasks_.pop_front(); return order_num; @@ -204,6 +236,14 @@ void Scheduler::Sequence::FinishTask() { running_state_ = IDLE; } +void Scheduler::Sequence::SetLastTaskFirstDependencyTimeIfNeeded() { + DCHECK(!tasks_.empty()); + if (tasks_.back().first_dependency_added.is_null()) { + // Fence are always added for the last task (which should always exists). + tasks_.back().first_dependency_added = base::TimeTicks::Now(); + } +} + void Scheduler::Sequence::AddWaitFence(const SyncToken& sync_token, uint32_t order_num, SequenceId release_sequence_id) { @@ -233,6 +273,17 @@ void Scheduler::Sequence::RemoveWaitFence(const SyncToken& sync_token, SchedulingPriority wait_priority = it->second; wait_fences_.erase(it); + for (auto& task : tasks_) { + if (order_num == task.order_num) { + // The fence applies to this task, bump the readiness timestamp + task.running_ready = base::TimeTicks::Now(); + break; + } else if (order_num < task.order_num) { + // Updated all task related to this fence. + break; + } + } + Sequence* release_sequence = scheduler_->GetSequence(release_sequence_id); if (release_sequence) release_sequence->RemoveWaitingPriority(wait_priority); @@ -413,7 +464,8 @@ void Scheduler::ScheduleTaskHelper(Task task) { Sequence* sequence = GetSequence(sequence_id); DCHECK(sequence); - uint32_t order_num = sequence->ScheduleTask(std::move(task.closure)); + uint32_t order_num = sequence->ScheduleTask(std::move(task.closure), + std::move(task.report_callback)); for (const SyncToken& sync_token : task.sync_token_fences) { SequenceId release_sequence_id = @@ -424,6 +476,7 @@ void Scheduler::ScheduleTaskHelper(Task task) { sync_token, order_num, release_sequence_id, sequence_id))) { sequence->AddWaitFence(sync_token, order_num, release_sequence_id); + sequence->SetLastTaskFirstDependencyTimeIfNeeded(); } } @@ -495,6 +548,7 @@ void Scheduler::TryScheduleSequence(Sequence* sequence) { if (!running_) { TRACE_EVENT_ASYNC_BEGIN0("gpu", "Scheduler::Running", this); running_ = true; + run_next_task_scheduled_ = base::TimeTicks::Now(); task_runner_->PostTask( FROM_HERE, base::BindOnce(&Scheduler::RunNextTask, weak_ptr_)); } @@ -525,6 +579,11 @@ void Scheduler::RebuildSchedulingQueue() { void Scheduler::RunNextTask() { DCHECK(thread_checker_.CalledOnValidThread()); base::AutoLock auto_lock(lock_); + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "GPU.Scheduler.ThreadSuspendedTime", + base::TimeTicks::Now() - run_next_task_scheduled_, + base::TimeDelta::FromMicroseconds(10), base::TimeDelta::FromSeconds(30), + 100); RebuildSchedulingQueue(); @@ -544,6 +603,18 @@ void Scheduler::RunNextTask() { Sequence* sequence = GetSequence(state.sequence_id); DCHECK(sequence); + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "GPU.Scheduler.TaskDependencyTime", + sequence->FrontTaskWaitingDependencyDelta(), + base::TimeDelta::FromMicroseconds(10), base::TimeDelta::FromSeconds(30), + 100); + + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "GPU.Scheduler.TaskSchedulingDelayTime", + sequence->FrontTaskSchedulingDelay(), + base::TimeDelta::FromMicroseconds(10), base::TimeDelta::FromSeconds(30), + 100); + base::OnceClosure closure; uint32_t order_num = sequence->BeginTask(&closure); DCHECK_EQ(order_num, state.order_num); @@ -598,6 +669,7 @@ void Scheduler::RunNextTask() { base::TimeDelta::FromMicroseconds(10), base::TimeDelta::FromSeconds(30), 100); + run_next_task_scheduled_ = base::TimeTicks::Now(); task_runner_->PostTask(FROM_HERE, base::BindOnce(&Scheduler::RunNextTask, weak_ptr_)); } diff --git a/chromium/gpu/command_buffer/service/scheduler.h b/chromium/gpu/command_buffer/service/scheduler.h index c47f6f56ea0..427dce82ad4 100644 --- a/chromium/gpu/command_buffer/service/scheduler.h +++ b/chromium/gpu/command_buffer/service/scheduler.h @@ -17,6 +17,7 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "gpu/command_buffer/common/command_buffer_id.h" #include "gpu/command_buffer/common/scheduling_priority.h" #include "gpu/command_buffer/common/sync_token.h" @@ -35,11 +36,17 @@ class SyncPointManager; struct GpuPreferences; class GPU_EXPORT Scheduler { + // A callback to be used for reporting when the task is ready to run (when the + // dependencies have been solved). + using ReportingCallback = + base::OnceCallback<void(base::TimeTicks task_ready)>; + public: struct GPU_EXPORT Task { Task(SequenceId sequence_id, base::OnceClosure closure, - std::vector<SyncToken> sync_token_fences); + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback = ReportingCallback()); Task(Task&& other); ~Task(); Task& operator=(Task&& other); @@ -47,6 +54,7 @@ class GPU_EXPORT Scheduler { SequenceId sequence_id; base::OnceClosure closure; std::vector<SyncToken> sync_token_fences; + ReportingCallback report_callback; }; Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner, @@ -169,6 +177,14 @@ class GPU_EXPORT Scheduler { // Update cached scheduling priority while running. void UpdateRunningPriority(); + // The time delta it took for the front task's dependencies to be completed. + base::TimeDelta FrontTaskWaitingDependencyDelta(); + + // The delay between when the front task was ready to run (no more + // dependencies) and now. This is used when the task is actually started to + // check for low scheduling delays. + base::TimeDelta FrontTaskSchedulingDelay(); + // Returns the next order number and closure. Sets running state to RUNNING. uint32_t BeginTask(base::OnceClosure* closure); @@ -177,12 +193,17 @@ class GPU_EXPORT Scheduler { void FinishTask(); // Enqueues a task in the sequence and returns the generated order number. - uint32_t ScheduleTask(base::OnceClosure closure); + uint32_t ScheduleTask(base::OnceClosure closure, + ReportingCallback report_callback); // Continue running the current task with the given closure. Must be called // in between |BeginTask| and |FinishTask|. void ContinueTask(base::OnceClosure closure); + // Sets the first dependency added time on the last task if it wasn't + // already set, no-op otherwise. + void SetLastTaskFirstDependencyTimeIfNeeded(); + // Add a sync token fence that this sequence should wait on. void AddWaitFence(const SyncToken& sync_token, uint32_t order_num, @@ -229,12 +250,20 @@ class GPU_EXPORT Scheduler { struct Task { Task(Task&& other); - Task(base::OnceClosure closure, uint32_t order_num); + Task(base::OnceClosure closure, + uint32_t order_num, + ReportingCallback report_callback); ~Task(); Task& operator=(Task&& other); base::OnceClosure closure; uint32_t order_num; + + ReportingCallback report_callback; + // Note: this time is only correct once the last fence has been removed, + // as it is updated for all fences. + base::TimeTicks running_ready = base::TimeTicks::Now(); + base::TimeTicks first_dependency_added; }; // Description of Stream priority propagation: Each Stream has an initial @@ -349,6 +378,9 @@ class GPU_EXPORT Scheduler { base::ThreadChecker thread_checker_; + // Indicate when the next task run was scheduled + base::TimeTicks run_next_task_scheduled_; + // Invalidated on main thread. base::WeakPtr<Scheduler> weak_ptr_; base::WeakPtrFactory<Scheduler> weak_factory_{this}; diff --git a/chromium/gpu/command_buffer/service/scheduler_unittest.cc b/chromium/gpu/command_buffer/service/scheduler_unittest.cc index 7202a8a3290..ec1d82e6e35 100644 --- a/chromium/gpu/command_buffer/service/scheduler_unittest.cc +++ b/chromium/gpu/command_buffer/service/scheduler_unittest.cc @@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/test/test_simple_task_runner.h" +#include "base/time/time.h" #include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/config/gpu_preferences.h" #include "testing/gmock/include/gmock/gmock.h" @@ -68,6 +69,28 @@ TEST_F(SchedulerTest, ScheduledTasksRunInOrder) { EXPECT_TRUE(ran2); } +TEST_F(SchedulerTest, ScheduledTasksRunAfterReporting) { + SequenceId sequence_id = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + bool ran = false; + bool reported = false; + scheduler()->ScheduleTask( + Scheduler::Task(sequence_id, GetClosure([&] { + EXPECT_TRUE(reported); + ran = true; + }), + std::vector<SyncToken>(), + base::Bind( + [&](bool& ran, bool& reported, base::TimeTicks t) { + EXPECT_FALSE(ran); + reported = true; + }, + std::ref(ran), std::ref(reported)))); + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran); +} + TEST_F(SchedulerTest, ContinuedTasksRunFirst) { SequenceId sequence_id = scheduler()->CreateSequence(SchedulingPriority::kNormal); diff --git a/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc index 6d1aa65cbe1..95039ac8b5a 100644 --- a/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc @@ -4,6 +4,8 @@ #include "gpu/command_buffer/service/service_discardable_manager.h" +#include <memory> + #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_service_test.h" @@ -41,8 +43,8 @@ void CreateLockedHandlesForTesting( scoped_refptr<gpu::Buffer> buffer = MakeBufferFromSharedMemory( std::move(shared_mem), std::move(shared_mem_mapping)); - client_handle->reset(new ClientDiscardableHandle(buffer, 0, 0)); - service_handle->reset(new ServiceDiscardableHandle(buffer, 0, 0)); + *client_handle = std::make_unique<ClientDiscardableHandle>(buffer, 0, 0); + *service_handle = std::make_unique<ServiceDiscardableHandle>(buffer, 0, 0); } ServiceDiscardableHandle CreateLockedServiceHandleForTesting() { @@ -72,8 +74,8 @@ class ServiceDiscardableManagerTest : public GpuServiceTest { protected: void SetUp() override { GpuServiceTest::SetUp(); - decoder_.reset( - new MockGLES2Decoder(&client_, &command_buffer_service_, &outputter_)); + decoder_ = std::make_unique<MockGLES2Decoder>( + &client_, &command_buffer_service_, &outputter_); feature_info_ = new FeatureInfo(); context_group_ = scoped_refptr<ContextGroup>(new ContextGroup( gpu_preferences_, false, &mailbox_manager_, nullptr, nullptr, nullptr, diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc index 05748005ef1..893f4d19b6f 100644 --- a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc +++ b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc @@ -8,6 +8,7 @@ #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "gpu/command_buffer/common/shared_image_trace_utils.h" +#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/shared_image_representation_d3d.h" #include "gpu/command_buffer/service/shared_image_representation_skia_gl.h" #include "ui/gl/trace_util.h" @@ -80,6 +81,10 @@ SharedImageBackingD3D::~SharedImageBackingD3D() { keyed_mutex_acquire_key_ = 0; keyed_mutex_acquired_ = false; shared_handle_.Close(); + +#if BUILDFLAG(USE_DAWN) + external_image_ = nullptr; +#endif // BUILDFLAG(USE_DAWN) } void SharedImageBackingD3D::Update(std::unique_ptr<gfx::GpuFence> in_fence) { @@ -93,13 +98,57 @@ bool SharedImageBackingD3D::ProduceLegacyMailbox( return true; } +uint32_t SharedImageBackingD3D::GetAllowedDawnUsages() const { + // TODO(crbug.com/2709243): Figure out other SI flags, if any. + DCHECK(usage() & gpu::SHARED_IMAGE_USAGE_WEBGPU); + return static_cast<uint32_t>( + WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | + WGPUTextureUsage_Sampled | WGPUTextureUsage_OutputAttachment); +} + std::unique_ptr<SharedImageRepresentationDawn> SharedImageBackingD3D::ProduceDawn(SharedImageManager* manager, MemoryTypeTracker* tracker, WGPUDevice device) { #if BUILDFLAG(USE_DAWN) - return std::make_unique<SharedImageRepresentationDawnD3D>(manager, this, - tracker, device); + + // Persistently open the shared handle by caching it on this backing. + if (!external_image_) { + DCHECK(shared_handle_.IsValid()); + + const viz::ResourceFormat viz_resource_format = format(); + const WGPUTextureFormat wgpu_format = + viz::ToWGPUFormat(viz_resource_format); + if (wgpu_format == WGPUTextureFormat_Undefined) { + DLOG(ERROR) << "Unsupported viz format found: " << viz_resource_format; + return nullptr; + } + + WGPUTextureDescriptor texture_descriptor = {}; + texture_descriptor.nextInChain = nullptr; + texture_descriptor.format = wgpu_format; + texture_descriptor.usage = GetAllowedDawnUsages(); + texture_descriptor.dimension = WGPUTextureDimension_2D; + texture_descriptor.size = {size().width(), size().height(), 1}; + texture_descriptor.mipLevelCount = 1; + texture_descriptor.sampleCount = 1; + + dawn_native::d3d12::ExternalImageDescriptorDXGISharedHandle + externalImageDesc; + externalImageDesc.cTextureDescriptor = &texture_descriptor; + externalImageDesc.sharedHandle = shared_handle_.Get(); + + external_image_ = dawn_native::d3d12::ExternalImageDXGI::Create( + device, &externalImageDesc); + + if (!external_image_) { + DLOG(ERROR) << "Failed to create external image"; + return nullptr; + } + } + + return std::make_unique<SharedImageRepresentationDawnD3D>( + manager, this, tracker, device, external_image_.get()); #else return nullptr; #endif // BUILDFLAG(USE_DAWN) diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h index 50e0645458c..b6bdb0742de 100644 --- a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h +++ b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h @@ -18,8 +18,15 @@ #include "gpu/command_buffer/service/shared_image_manager.h" #include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "ui/gl/buildflags.h" #include "ui/gl/gl_image_d3d.h" +// Usage of BUILDFLAG(USE_DAWN) needs to be after the include for +// ui/gl/buildflags.h +#if BUILDFLAG(USE_DAWN) +#include <dawn_native/D3D12Backend.h> +#endif // BUILDFLAG(USE_DAWN) + namespace gfx { class Size; class ColorSpace; @@ -93,6 +100,8 @@ class GPU_GLES2_EXPORT SharedImageBackingD3D scoped_refptr<SharedContextState> context_state) override; private: + uint32_t GetAllowedDawnUsages() const; + Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_; scoped_refptr<gles2::TexturePassthrough> texture_; scoped_refptr<gl::GLImage> image_; @@ -115,6 +124,12 @@ class GPU_GLES2_EXPORT SharedImageBackingD3D uint64_t keyed_mutex_acquire_key_ = 0; bool keyed_mutex_acquired_ = false; + // If external_image_ exists, it means Dawn produced the D3D12 side of the + // D3D11 texture created by ID3D12Device::OpenSharedHandle. +#if BUILDFLAG(USE_DAWN) + std::unique_ptr<dawn_native::d3d12::ExternalImageDXGI> external_image_; +#endif // BUILDFLAG(USE_DAWN) + DISALLOW_COPY_AND_ASSIGN(SharedImageBackingD3D); }; diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index dc051ffee60..4643405502c 100644 --- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc @@ -584,7 +584,8 @@ bool SharedImageBackingFactoryAHB::ValidateUsage( if (size.width() < 1 || size.height() < 1 || size.width() > max_gl_texture_size_ || size.height() > max_gl_texture_size_) { - LOG(ERROR) << "CreateSharedImage: invalid size"; + LOG(ERROR) << "CreateSharedImage: invalid size=" << size.ToString() + << " max_gl_texture_size=" << max_gl_texture_size_; return false; } diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc index 54682c56be9..dbd59f909df 100644 --- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc +++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc @@ -913,5 +913,129 @@ TEST_F(SharedImageBackingFactoryD3DTest, CreateSharedImageFromHandle) { EXPECT_EQ(backing_d3d->GetSharedHandle(), shared_handle); } +#if BUILDFLAG(USE_DAWN) +// Test to check external image stored in the backing can be reused +TEST_F(SharedImageBackingFactoryD3DTest, Dawn_ReuseExternalImage) { + if (!IsD3DSharedImageSupported()) + return; + + // Create a backing using mailbox. + auto mailbox = Mailbox::GenerateForSharedImage(); + const auto format = viz::ResourceFormat::RGBA_8888; + const gfx::Size size(1, 1); + const auto color_space = gfx::ColorSpace::CreateSRGB(); + const uint32_t usage = SHARED_IMAGE_USAGE_GLES2 | SHARED_IMAGE_USAGE_DISPLAY | + SHARED_IMAGE_USAGE_WEBGPU; + const gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; + auto backing = shared_image_factory_->CreateSharedImage( + mailbox, format, surface_handle, size, color_space, + kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage, + false /* is_thread_safe */); + ASSERT_NE(backing, nullptr); + + std::unique_ptr<SharedImageRepresentationFactoryRef> factory_ref = + shared_image_manager_.Register(std::move(backing), + memory_type_tracker_.get()); + + // Create a Dawn D3D12 device + dawn_native::Instance instance; + instance.DiscoverDefaultAdapters(); + + std::vector<dawn_native::Adapter> adapters = instance.GetAdapters(); + auto adapter_it = std::find_if( + adapters.begin(), adapters.end(), [](dawn_native::Adapter adapter) { + return adapter.GetBackendType() == dawn_native::BackendType::D3D12; + }); + ASSERT_NE(adapter_it, adapters.end()); + + wgpu::Device device = wgpu::Device::Acquire(adapter_it->CreateDevice()); + DawnProcTable procs = dawn_native::GetProcs(); + dawnProcSetProcs(&procs); + + const WGPUTextureUsage texture_usage = WGPUTextureUsage_OutputAttachment; + + // Create the first Dawn texture then clear it to green. + { + auto dawn_representation = + shared_image_representation_factory_->ProduceDawn(mailbox, + device.Get()); + ASSERT_TRUE(dawn_representation); + + auto scoped_access = dawn_representation->BeginScopedAccess( + texture_usage, SharedImageRepresentation::AllowUnclearedAccess::kYes); + ASSERT_TRUE(scoped_access); + + wgpu::Texture texture(scoped_access->texture()); + + wgpu::RenderPassColorAttachmentDescriptor color_desc; + color_desc.attachment = texture.CreateView(); + color_desc.resolveTarget = nullptr; + color_desc.loadOp = wgpu::LoadOp::Clear; + color_desc.storeOp = wgpu::StoreOp::Store; + color_desc.clearColor = {0, 255, 0, 255}; + + wgpu::RenderPassDescriptor renderPassDesc = {}; + renderPassDesc.colorAttachmentCount = 1; + renderPassDesc.colorAttachments = &color_desc; + renderPassDesc.depthStencilAttachment = nullptr; + + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc); + pass.EndPass(); + wgpu::CommandBuffer commands = encoder.Finish(); + + wgpu::Queue queue = device.GetDefaultQueue(); + queue.Submit(1, &commands); + } + + CheckSkiaPixels(mailbox, size, {0, 255, 0, 255}); + + // Create another Dawn texture then clear it with another color. + { + auto dawn_representation = + shared_image_representation_factory_->ProduceDawn(mailbox, + device.Get()); + ASSERT_TRUE(dawn_representation); + + // Check again that the texture is still green + CheckSkiaPixels(mailbox, size, {0, 255, 0, 255}); + + auto scoped_access = dawn_representation->BeginScopedAccess( + texture_usage, SharedImageRepresentation::AllowUnclearedAccess::kYes); + ASSERT_TRUE(scoped_access); + + wgpu::Texture texture(scoped_access->texture()); + + wgpu::RenderPassColorAttachmentDescriptor color_desc; + color_desc.attachment = texture.CreateView(); + color_desc.resolveTarget = nullptr; + color_desc.loadOp = wgpu::LoadOp::Clear; + color_desc.storeOp = wgpu::StoreOp::Store; + color_desc.clearColor = {255, 0, 0, 255}; + + wgpu::RenderPassDescriptor renderPassDesc = {}; + renderPassDesc.colorAttachmentCount = 1; + renderPassDesc.colorAttachments = &color_desc; + renderPassDesc.depthStencilAttachment = nullptr; + + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc); + pass.EndPass(); + wgpu::CommandBuffer commands = encoder.Finish(); + + wgpu::Queue queue = device.GetDefaultQueue(); + queue.Submit(1, &commands); + } + + CheckSkiaPixels(mailbox, size, {255, 0, 0, 255}); + + // Shut down Dawn + device = wgpu::Device(); + dawnProcSetProcs(nullptr); + + factory_ref.reset(); +} +#endif // BUILDFLAG(USE_DAWN) + } // anonymous namespace } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/shared_image_manager.h b/chromium/gpu/command_buffer/service/shared_image_manager.h index f7c5249def7..2d3d151962f 100644 --- a/chromium/gpu/command_buffer/service/shared_image_manager.h +++ b/chromium/gpu/command_buffer/service/shared_image_manager.h @@ -57,6 +57,13 @@ class GPU_GLES2_EXPORT SharedImageManager { const Mailbox& mailbox, MemoryTypeTracker* ref, scoped_refptr<SharedContextState> context_state); + + // ProduceDawn must also be called using same |device| if + // using the same |mailbox|. This is because the underlying shared image + // compatibility also depends on the WGPUAdapter which ProduceDawn does not + // associate with the representation. + // TODO(crbug.com/1147184): Revisit this in the future for WebGPU + // multi-adapter support. std::unique_ptr<SharedImageRepresentationDawn> ProduceDawn( const Mailbox& mailbox, MemoryTypeTracker* ref, diff --git a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc index 6fa591c9e8e..1b5937a8b34 100644 --- a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc +++ b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc @@ -45,11 +45,14 @@ SharedImageRepresentationDawnD3D::SharedImageRepresentationDawnD3D( SharedImageManager* manager, SharedImageBacking* backing, MemoryTypeTracker* tracker, - WGPUDevice device) + WGPUDevice device, + dawn_native::d3d12::ExternalImageDXGI* external_image) : SharedImageRepresentationDawn(manager, backing, tracker), device_(device), + external_image_(external_image), dawn_procs_(dawn_native::GetProcs()) { DCHECK(device_); + DCHECK(external_image_); // Keep a reference to the device so that it stays valid (it might become // lost in which case operations will be noops). @@ -66,38 +69,21 @@ WGPUTexture SharedImageRepresentationDawnD3D::BeginAccess( SharedImageBackingD3D* d3d_image_backing = static_cast<SharedImageBackingD3D*>(backing()); - const HANDLE shared_handle = d3d_image_backing->GetSharedHandle(); - const viz::ResourceFormat viz_resource_format = d3d_image_backing->format(); - WGPUTextureFormat wgpu_format = viz::ToWGPUFormat(viz_resource_format); - if (wgpu_format == WGPUTextureFormat_Undefined) { - DLOG(ERROR) << "Unsupported viz format found: " << viz_resource_format; - return nullptr; - } - uint64_t shared_mutex_acquire_key; if (!d3d_image_backing->BeginAccessD3D12(&shared_mutex_acquire_key)) { return nullptr; } - WGPUTextureDescriptor texture_descriptor = {}; - texture_descriptor.nextInChain = nullptr; - texture_descriptor.format = wgpu_format; - texture_descriptor.usage = usage; - texture_descriptor.dimension = WGPUTextureDimension_2D; - texture_descriptor.size = {size().width(), size().height(), 1}; - texture_descriptor.mipLevelCount = 1; - texture_descriptor.sampleCount = 1; - - dawn_native::d3d12::ExternalImageDescriptorDXGISharedHandle descriptor; - descriptor.cTextureDescriptor = &texture_descriptor; + dawn_native::d3d12::ExternalImageAccessDescriptorDXGIKeyedMutex descriptor; descriptor.isInitialized = IsCleared(); - descriptor.sharedHandle = shared_handle; descriptor.acquireMutexKey = shared_mutex_acquire_key; descriptor.isSwapChainTexture = (d3d_image_backing->usage() & SHARED_IMAGE_USAGE_WEBGPU_SWAP_CHAIN_TEXTURE); + descriptor.usage = usage; - texture_ = dawn_native::d3d12::WrapSharedHandle(device_, &descriptor); + DCHECK(external_image_); + texture_ = external_image_->ProduceTexture(device_, &descriptor); if (!texture_) { d3d_image_backing->EndAccessD3D12(); } @@ -123,6 +109,7 @@ void SharedImageRepresentationDawnD3D::EndAccess() { dawn_procs_.textureRelease(texture_); texture_ = nullptr; + external_image_ = nullptr; d3d_image_backing->EndAccessD3D12(); } diff --git a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h index 9d3cca28ab1..634858837cd 100644 --- a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h +++ b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h @@ -47,10 +47,12 @@ class SharedImageRepresentationGLTexturePassthroughD3D #if BUILDFLAG(USE_DAWN) class SharedImageRepresentationDawnD3D : public SharedImageRepresentationDawn { public: - SharedImageRepresentationDawnD3D(SharedImageManager* manager, - SharedImageBacking* backing, - MemoryTypeTracker* tracker, - WGPUDevice device); + SharedImageRepresentationDawnD3D( + SharedImageManager* manager, + SharedImageBacking* backing, + MemoryTypeTracker* tracker, + WGPUDevice device, + dawn_native::d3d12::ExternalImageDXGI* external_image); ~SharedImageRepresentationDawnD3D() override; @@ -60,6 +62,7 @@ class SharedImageRepresentationDawnD3D : public SharedImageRepresentationDawn { private: WGPUDevice device_; WGPUTexture texture_ = nullptr; + dawn_native::d3d12::ExternalImageDXGI* external_image_ = nullptr; // TODO(cwallez@chromium.org): Load procs only once when the factory is // created and pass a pointer to them around? diff --git a/chromium/gpu/command_buffer/service/shared_image_representation_skia_gl.cc b/chromium/gpu/command_buffer/service/shared_image_representation_skia_gl.cc index 5ab1f28ff50..53b43c09278 100644 --- a/chromium/gpu/command_buffer/service/shared_image_representation_skia_gl.cc +++ b/chromium/gpu/command_buffer/service/shared_image_representation_skia_gl.cc @@ -74,6 +74,8 @@ SharedImageRepresentationSkiaGL::SharedImageRepresentationSkiaGL( SharedImageRepresentationSkiaGL::~SharedImageRepresentationSkiaGL() { DCHECK_EQ(RepresentationAccessMode::kNone, mode_); surface_.reset(); + if (!has_context()) + gl_representation_->OnContextLost(); } sk_sp<SkSurface> SharedImageRepresentationSkiaGL::BeginWriteAccess( diff --git a/chromium/gpu/command_buffer/service/surface_texture_gl_owner_unittest.cc b/chromium/gpu/command_buffer/service/surface_texture_gl_owner_unittest.cc index 4ef50c95ecf..2afd4c1fa44 100644 --- a/chromium/gpu/command_buffer/service/surface_texture_gl_owner_unittest.cc +++ b/chromium/gpu/command_buffer/service/surface_texture_gl_owner_unittest.cc @@ -34,7 +34,7 @@ class SurfaceTextureGLOwnerTest : public testing::Test { protected: void SetUp() override { gl::init::InitializeStaticGLBindingsImplementation( - gl::kGLImplementationEGLGLES2, false); + gl::GLImplementationParts(gl::kGLImplementationEGLGLES2), false); gl::init::InitializeGLOneOffPlatformImplementation(false, false, true); surface_ = new gl::PbufferGLSurfaceEGL(gfx::Size(320, 240)); diff --git a/chromium/gpu/command_buffer/service/texture_manager.h b/chromium/gpu/command_buffer/service/texture_manager.h index 498a81708dd..cb079bf5348 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.h +++ b/chromium/gpu/command_buffer/service/texture_manager.h @@ -473,7 +473,6 @@ class GPU_GLES2_EXPORT Texture final : public TextureBase { } private: - friend class MailboxManagerSync; friend class MailboxManagerTest; friend class TextureDefinition; friend class TextureManager; diff --git a/chromium/gpu/command_buffer/service/transform_feedback_manager_unittest.cc b/chromium/gpu/command_buffer/service/transform_feedback_manager_unittest.cc index 4aefb8464d4..96f9d4b6489 100644 --- a/chromium/gpu/command_buffer/service/transform_feedback_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/transform_feedback_manager_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/transform_feedback_manager.h" @@ -28,8 +30,8 @@ class TransformFeedbackManagerTest : public GpuServiceTest { void SetUp() override { const GLuint kMaxTransformFeedbackSeparateAttribs = 16; GpuServiceTest::SetUpWithGLVersion("4.1", ""); - manager_.reset(new TransformFeedbackManager( - kMaxTransformFeedbackSeparateAttribs, true)); + manager_ = std::make_unique<TransformFeedbackManager>( + kMaxTransformFeedbackSeparateAttribs, true); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc b/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc index 4dc5cbb3701..3985fc3fdad 100644 --- a/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc @@ -32,7 +32,7 @@ class VertexArrayManagerTest : public GpuServiceTest { protected: void SetUp() override { GpuServiceTest::SetUpWithGLVersion("2.1", "GL_ARB_vertex_array_object"); - manager_.reset(new VertexArrayManager()); + manager_ = std::make_unique<VertexArrayManager>(); } void TearDown() override { diff --git a/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc b/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc index 4b033949c11..c1cf5e93b94 100644 --- a/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc @@ -539,6 +539,9 @@ error::Error WebGPUDecoderImpl::InitDawnDevice( if (request_device_properties.timestampQuery) { device_descriptor.requiredExtensions.push_back("timestamp_query"); } + if (request_device_properties.depthClamping) { + device_descriptor.requiredExtensions.push_back("depth_clamping"); + } for (const std::string& toggles : force_enabled_toggles_) { device_descriptor.forceEnabledToggles.push_back(toggles.c_str()); diff --git a/chromium/gpu/command_buffer/service/webgpu_decoder_unittest.cc b/chromium/gpu/command_buffer/service/webgpu_decoder_unittest.cc index aebc03bcc5c..3effe36c329 100644 --- a/chromium/gpu/command_buffer/service/webgpu_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/webgpu_decoder_unittest.cc @@ -4,6 +4,8 @@ #include "gpu/command_buffer/service/webgpu_decoder.h" +#include <memory> + #include "build/build_config.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/common/webgpu_cmd_format.h" @@ -29,8 +31,8 @@ class WebGPUDecoderTest : public ::testing::Test { if (!WebGPUSupported()) { return; } - decoder_client_.reset(new FakeDecoderClient()); - command_buffer_service_.reset(new FakeCommandBufferServiceBase()); + decoder_client_ = std::make_unique<FakeDecoderClient>(); + command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>(); decoder_.reset(WebGPUDecoder::Create( decoder_client_.get(), command_buffer_service_.get(), nullptr, nullptr, &outputter_, GpuPreferences())); diff --git a/chromium/gpu/config/gpu_driver_bug_list.json b/chromium/gpu/config/gpu_driver_bug_list.json index 868d35b95b2..01060f55749 100644 --- a/chromium/gpu/config/gpu_driver_bug_list.json +++ b/chromium/gpu/config/gpu_driver_bug_list.json @@ -523,8 +523,8 @@ "os": { "type": "android" }, - "gl_vendor": "Imagination.*", - "gl_renderer": "PowerVR SGX 5.*", + "gl_vendor": ".*Imagination.*", + "gl_renderer": ".*PowerVR SGX 5.*", "features": [ "etc1_power_of_two_only" ] @@ -862,23 +862,6 @@ ] }, { - "id": 118, - "cr_bugs": [477306], - "description": "NVIDIA 331 series drivers shader compiler may crash when attempting to optimize pow()", - "os": { - "type": "linux" - }, - "driver_version": { - "op": "<=", - "value": "331" - }, - "vendor_id": "0x10de", - "gl_vendor": "NVIDIA.*", - "features": [ - "remove_pow_with_constant_exponent" - ] - }, - { "id": 119, "description": "Context lost recovery often fails on Mali-400/450 on Android.", "cr_bugs": [496438], @@ -1712,19 +1695,6 @@ ] }, { - "id": 201, - "cr_bugs": [659326,639760], - "description": "AMD drivers in Linux require invariant qualifier to match between vertex and fragment shaders", - "os": { - "type": "linux" - }, - "vendor_id": "0x1002", - "features": [ - "dont_remove_invariant_for_fragment_input", - "remove_invariant_and_centroid_for_essl3" - ] - }, - { "id": 202, "cr_bugs": [639760,641129], "description": "Mac driver GL 4.1 requires invariant and centroid to match between shaders", @@ -3655,19 +3625,6 @@ ] }, { - "id": 366, - "cr_bugs": [1179557], - "description": "The hardware video encoder on the SC7180 SoC has poor quality.", - "os": { - "type": "chromeos" - }, - "gl_vendor": "freedreno", - "features": [ - "disable_accelerated_h264_encode", - "disable_accelerated_vp8_encode" - ] - }, - { "id": 367, "cr_bugs": [1180962], "description": "ANGLE cannot recover from context lost", @@ -3728,6 +3685,22 @@ "features": [ "disable_direct_composition_sw_video_overlays" ] + }, + { + "id": 372, + "cr_bugs": [1103852], + "description": "Check YCbCr_Studio_G22_Left_P709 color space for NV12 overlay support on Intel", + "os": { + "type": "win" + }, + "vendor_id": "0x8086", + "intel_gpu_generation": { + "op": "=", + "value": "9" + }, + "features": [ + "check_ycbcr_studio_g22_left_p709_for_nv12_support" + ] } ] } diff --git a/chromium/gpu/config/gpu_finch_features.cc b/chromium/gpu/config/gpu_finch_features.cc index 388fc5dd548..df72207fd3c 100644 --- a/chromium/gpu/config/gpu_finch_features.cc +++ b/chromium/gpu/config/gpu_finch_features.cc @@ -123,11 +123,6 @@ const base::Feature kCanvasOopRasterization{"CanvasOopRasterization", // Use a high priority for GPU process on Windows. const base::Feature kGpuProcessHighPriorityWin{ "GpuProcessHighPriorityWin", base::FEATURE_ENABLED_BY_DEFAULT}; - -// Compute the root damage rect from the surface damage list for overlays on -// Windows. -const base::Feature kDirectCompositionUseOverlayDamageList{ - "DirectCompositionUseOverlayDamageList", base::FEATURE_ENABLED_BY_DEFAULT}; #endif // Use ThreadPriority::DISPLAY for GPU main, viz compositor and IO threads. @@ -211,11 +206,6 @@ const base::FeatureParam<std::string> kVulkanBlockListByAndroidBuildFP{ // and on Linux this will use Vulkan. const base::Feature kSkiaDawn{"SkiaDawn", base::FEATURE_DISABLED_BY_DEFAULT}; -// Used to enable shared image mailbox and disable legacy texture mailbox on -// webview. -const base::Feature kEnableSharedImageForWebview{ - "EnableSharedImageForWebview", base::FEATURE_ENABLED_BY_DEFAULT}; - // Enable GrShaderCache to use with Vulkan backend. const base::Feature kEnableGrShaderCacheForVulkan{ "EnableGrShaderCacheForVulkan", base::FEATURE_ENABLED_BY_DEFAULT}; diff --git a/chromium/gpu/config/gpu_finch_features.h b/chromium/gpu/config/gpu_finch_features.h index 39f2e447fff..45997f037d4 100644 --- a/chromium/gpu/config/gpu_finch_features.h +++ b/chromium/gpu/config/gpu_finch_features.h @@ -34,8 +34,6 @@ GPU_EXPORT extern const base::Feature kCanvasOopRasterization; #if defined(OS_WIN) GPU_EXPORT extern const base::Feature kGpuProcessHighPriorityWin; - -GPU_EXPORT extern const base::Feature kDirectCompositionUseOverlayDamageList; #endif GPU_EXPORT extern const base::Feature kGpuUseDisplayThreadPriority; @@ -56,8 +54,6 @@ GPU_EXPORT extern const base::Feature kVulkan; GPU_EXPORT extern const base::Feature kSkiaDawn; -GPU_EXPORT extern const base::Feature kEnableSharedImageForWebview; - GPU_EXPORT extern const base::Feature kEnableGrShaderCacheForVulkan; GPU_EXPORT extern const base::Feature kEnableVkPipelineCache; diff --git a/chromium/gpu/config/gpu_info_collector.cc b/chromium/gpu/config/gpu_info_collector.cc index b8ec898b25a..cc7b26f5d50 100644 --- a/chromium/gpu/config/gpu_info_collector.cc +++ b/chromium/gpu/config/gpu_info_collector.cc @@ -234,10 +234,16 @@ bool CollectBasicGraphicsInfo(const base::CommandLine* command_line, return true; } + gl::GLImplementationParts implementation = + gl::GetNamedGLImplementation(use_gl, use_angle); + + bool useSoftwareGLForTests = + command_line->HasSwitch(switches::kOverrideUseSoftwareGLForTests); base::StringPiece software_gl_impl_name = - gl::GetGLImplementationName(gl::GetSoftwareGLImplementation()); - if (use_gl == software_gl_impl_name || - command_line->HasSwitch(switches::kOverrideUseSoftwareGLForTests)) { + gl::GetGLImplementationGLName(gl::GetLegacySoftwareGLImplementation()); + if ((implementation == gl::GetLegacySoftwareGLImplementation()) || + (useSoftwareGLForTests && (gl::GetLegacySoftwareGLImplementation() == + gl::GetSoftwareGLForTestsImplementation()))) { // If using the software GL implementation, use fake vendor and // device ids to make sure it never gets blocklisted. It allows us // to proceed with loading the blocklist which may have non-device @@ -252,8 +258,10 @@ bool CollectBasicGraphicsInfo(const base::CommandLine* command_line, gpu_info->gpu.driver_vendor = software_gl_impl_name.as_string(); return true; - } else if (use_gl == gl::kGLImplementationANGLEName && - use_angle == gl::kANGLEImplementationSwiftShaderName) { + } else if ((implementation == gl::GetSoftwareGLImplementation()) || + (useSoftwareGLForTests && + (gl::GetSoftwareGLImplementation() == + gl::GetSoftwareGLForTestsImplementation()))) { // Similarly to the above, use fake vendor and device ids // to make sure they never gets blocklisted for SwANGLE as well. gpu_info->gpu.vendor_id = 0xffff; diff --git a/chromium/gpu/config/gpu_info_collector_unittest.cc b/chromium/gpu/config/gpu_info_collector_unittest.cc index 885062edd8b..4102071648c 100644 --- a/chromium/gpu/config/gpu_info_collector_unittest.cc +++ b/chromium/gpu/config/gpu_info_collector_unittest.cc @@ -58,7 +58,7 @@ class GPUInfoCollectorTest testing::Test::SetUp(); gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress); gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings(); - gl_.reset(new ::testing::StrictMock<::gl::MockGLInterface>()); + gl_ = std::make_unique<::testing::StrictMock<::gl::MockGLInterface>>(); ::gl::MockGLInterface::SetGLInterface(gl_.get()); switch (GetParam()) { case kMockedAndroid: { diff --git a/chromium/gpu/config/gpu_lists_version.h b/chromium/gpu/config/gpu_lists_version.h index 32592ddb244..3dee57b4bec 100644 --- a/chromium/gpu/config/gpu_lists_version.h +++ b/chromium/gpu/config/gpu_lists_version.h @@ -3,6 +3,6 @@ #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_ #define GPU_CONFIG_GPU_LISTS_VERSION_H_ -#define GPU_LISTS_VERSION "4be5e4894f1d31a23e5471b56014aa5a20dc70bb" +#define GPU_LISTS_VERSION "7d823479a5f90086f54d88e6b43f1c31702fc984" #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_ diff --git a/chromium/gpu/config/gpu_preferences.h b/chromium/gpu/config/gpu_preferences.h index f4077c21d7d..b8834a16026 100644 --- a/chromium/gpu/config/gpu_preferences.h +++ b/chromium/gpu/config/gpu_preferences.h @@ -279,7 +279,7 @@ struct GPU_EXPORT GpuPreferences { // =================================== // Settings from //media/base/media_switches.h -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) // Enable the hardware-accelerated direct video decoder on ChromeOS. bool enable_chromeos_direct_video_decoder = false; #endif diff --git a/chromium/gpu/config/gpu_preferences_unittest.cc b/chromium/gpu/config/gpu_preferences_unittest.cc index 83abd28f9e7..2c1e6d3d279 100644 --- a/chromium/gpu/config/gpu_preferences_unittest.cc +++ b/chromium/gpu/config/gpu_preferences_unittest.cc @@ -97,7 +97,7 @@ void CheckGpuPreferencesEqual(GpuPreferences left, GpuPreferences right) { #endif EXPECT_EQ(left.enable_native_gpu_memory_buffers, right.enable_native_gpu_memory_buffers); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) EXPECT_EQ(left.enable_chromeos_direct_video_decoder, right.enable_chromeos_direct_video_decoder); #endif @@ -189,7 +189,7 @@ TEST(GpuPreferencesTest, EncodeDecode) { base::MessagePumpType::UI) #endif GPU_PREFERENCES_FIELD(enable_native_gpu_memory_buffers, true); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) GPU_PREFERENCES_FIELD(enable_chromeos_direct_video_decoder, true); #endif @@ -284,7 +284,7 @@ TEST(GpuPreferencesTest, DISABLED_DecodePreferences) { PRINT_INT(message_pump_type); #endif PRINT_BOOL(enable_native_gpu_memory_buffers); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) PRINT_BOOL(enable_chromeos_direct_video_decoder); #endif printf("}\n"); diff --git a/chromium/gpu/config/gpu_test_config.cc b/chromium/gpu/config/gpu_test_config.cc index cc4f0b8fe78..592f71243e5 100644 --- a/chromium/gpu/config/gpu_test_config.cc +++ b/chromium/gpu/config/gpu_test_config.cc @@ -82,11 +82,7 @@ GPUTestConfig::OS GetCurrentOS() { } break; case 11: - switch (minor_version) { - case 0: - return GPUTestConfig::kOsMacBigSur; - } - break; + return GPUTestConfig::kOsMacBigSur; } return GPUTestConfig::kOsUnknown; #elif defined(OS_ANDROID) diff --git a/chromium/gpu/config/gpu_workaround_list.txt b/chromium/gpu/config/gpu_workaround_list.txt index 5913f2adbc4..bf373727f22 100644 --- a/chromium/gpu/config/gpu_workaround_list.txt +++ b/chromium/gpu/config/gpu_workaround_list.txt @@ -4,6 +4,7 @@ avoid_egl_image_target_texture_reuse avoid_one_component_egl_images avoid_stencil_buffers broken_egl_image_ref_counting +check_ycbcr_studio_g22_left_p709_for_nv12_support clamp_texture_base_level_and_max_level clear_pixel_unpack_buffer_before_copyteximage clear_to_zero_or_one_broken @@ -59,7 +60,6 @@ disallow_large_instanced_draw dont_delete_source_texture_for_egl_image dont_disable_webgl_when_compositor_context_lost dont_initialize_uninitialized_locals -dont_remove_invariant_for_fragment_input dont_use_eglclientwaitsync_with_timeout dont_use_loops_to_initialize_variables emulate_abs_int_function @@ -102,7 +102,6 @@ regenerate_struct_names rely_on_implicit_sync_for_swap_buffers remove_dynamic_indexing_of_swizzled_vector remove_invariant_and_centroid_for_essl3 -remove_pow_with_constant_exponent reset_base_mipmap_level_before_texstorage reset_teximage2d_base_level restore_scissor_on_fbo_change diff --git a/chromium/gpu/gles2_conform_support/egl/display.cc b/chromium/gpu/gles2_conform_support/egl/display.cc index 64e65bbbcbf..62ab1bef88e 100644 --- a/chromium/gpu/gles2_conform_support/egl/display.cc +++ b/chromium/gpu/gles2_conform_support/egl/display.cc @@ -4,6 +4,8 @@ #include "gpu/gles2_conform_support/egl/display.h" +#include <memory> + #include "base/stl_util.h" #include "build/build_config.h" #include "gpu/gles2_conform_support/egl/config.h" @@ -364,8 +366,8 @@ void Display::InitializeConfigsIfNeeded() { // This way we can record the client intention at context creation time. // The GL implementation (gl::GLContext and gl::GLSurface) needs this // distinction when creating a context. - configs_[0].reset(new Config(EGL_WINDOW_BIT)); - configs_[1].reset(new Config(EGL_PBUFFER_BIT)); + configs_[0] = std::make_unique<Config>(EGL_WINDOW_BIT); + configs_[1] = std::make_unique<Config>(EGL_PBUFFER_BIT); } } diff --git a/chromium/gpu/gles2_conform_support/egl/thread_state.cc b/chromium/gpu/gles2_conform_support/egl/thread_state.cc index 556bf900fc2..cf1ac72180e 100644 --- a/chromium/gpu/gles2_conform_support/egl/thread_state.cc +++ b/chromium/gpu/gles2_conform_support/egl/thread_state.cc @@ -65,10 +65,10 @@ egl::ThreadState* ThreadState::Get() { std::string env_string; env->GetVar("CHROME_COMMAND_BUFFER_GLES2_ARGS", &env_string); #if defined(OS_WIN) - argv = base::SplitString(base::UTF8ToUTF16(env_string), - base::kWhitespaceUTF16, base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); - argv.insert(argv.begin(), base::UTF8ToUTF16("dummy")); + argv = + base::SplitString(base::UTF8ToWide(env_string), base::kWhitespaceWide, + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + argv.insert(argv.begin(), base::UTF8ToWide("dummy")); #else argv = base::SplitString(env_string, base::kWhitespaceASCII, @@ -205,4 +205,4 @@ void ThreadState::AutoCurrentContextRestore::SetCurrent(Surface* surface, } } // namespace egl -} // namespace gles2_conform_support
\ No newline at end of file +} // namespace gles2_conform_support diff --git a/chromium/gpu/gles2_conform_support/generate_gles2_conform_tests.py b/chromium/gpu/gles2_conform_support/generate_gles2_conform_tests.py index b6b49a128c3..c29407cd461 100755 --- a/chromium/gpu/gles2_conform_support/generate_gles2_conform_tests.py +++ b/chromium/gpu/gles2_conform_support/generate_gles2_conform_tests.py @@ -30,17 +30,17 @@ def GenerateTests(out_file): out_file.write(""" #include "gpu/gles2_conform_support/gles2_conform_test.h" #include "testing/gtest/include/gtest/gtest.h" -""") +""".encode("utf8")) for test in tests: - out_file.write(""" + out_file.write((""" TEST(GLES2ConformTest, %(name)s) { EXPECT_TRUE(RunGLES2ConformTest("%(path)s")); } """ % { "name": re.sub(r'[^A-Za-z0-9]', '_', test), "path": test, - }) + }).encode("utf8")) def main(argv): diff --git a/chromium/gpu/gles2_conform_support/generate_gles2_embedded_data.py b/chromium/gpu/gles2_conform_support/generate_gles2_embedded_data.py index 809b24a57bf..d8eb08f8ac2 100755 --- a/chromium/gpu/gles2_conform_support/generate_gles2_embedded_data.py +++ b/chromium/gpu/gles2_conform_support/generate_gles2_embedded_data.py @@ -5,6 +5,8 @@ """generates files to embed the gles2 conformance test data in executable.""" +from __future__ import print_function + import os import sys @@ -35,23 +37,23 @@ class GenerateEmbeddedFiles(object): self.files_data_c = open(os.path.join(base_dir, "FilesDATA.c"), "wb") self.files_toc_c = open(os.path.join(base_dir, "FilesTOC.c"), "wb") - self.files_data_h.write("#ifndef FilesDATA_h\n\n") - self.files_data_h.write("#define FilesDATA_h\n\n"); + self.files_data_h.write(b"#ifndef FilesDATA_h\n\n") + self.files_data_h.write(b"#define FilesDATA_h\n\n"); - self.files_data_c.write("#include \"FilesDATA.h\"\n\n") + self.files_data_c.write(b"#include \"FilesDATA.h\"\n\n") - self.files_toc_c.write("#include \"FilesTOC.h\"\n\n"); - self.files_toc_c.write("struct GTFVectorFileEntry tempFiles;\n\n"); - self.files_toc_c.write("struct FileEntry files[] = {\n"); + self.files_toc_c.write(b"#include \"FilesTOC.h\"\n\n"); + self.files_toc_c.write(b"struct GTFVectorFileEntry tempFiles;\n\n"); + self.files_toc_c.write(b"struct FileEntry files[] = {\n"); self.AddFiles(scan_dir) if self.base_dir != None: - self.files_toc_c.write("\n};\n\n"); + self.files_toc_c.write(b"\n};\n\n"); self.files_toc_c.write( - "int numFileEntrys = sizeof(files) / sizeof(struct FileEntry);\n"); + b"int numFileEntrys = sizeof(files) / sizeof(struct FileEntry);\n"); - self.files_data_h.write("\n\n#endif // FilesDATA_h\n"); + self.files_data_h.write(b"\n\n#endif // FilesDATA_h\n"); self.files_data_c.close() self.files_data_h.close() @@ -70,14 +72,16 @@ class GenerateEmbeddedFiles(object): sub_dirs.append(full_path) elif ext in GenerateEmbeddedFiles.extensions_to_include: if self.base_dir == None: - print full_path.replace("\\", "/") + print(full_path.replace("\\", "/")) else: self.count += 1 name = "_FILE_%s_%d" % (ext.upper(), self.count) name = name.replace(".", "_") - self.files_data_h.write("extern const char %s[];\n" % name) - self.files_data_c.write("const char %s[] = \n" % name) + self.files_data_h.write( + ("extern const char %s[];\n" % name).encode("utf8")) + self.files_data_c.write( + ("const char %s[] = \n" % name).encode("utf8")) data = open(full_path, "r") lines = data.readlines(); @@ -89,11 +93,11 @@ class GenerateEmbeddedFiles(object): line = line.replace("\\", "\\\\") line = line.replace("\"", "\\\"") - self.files_data_c.write('"%s\\n"\n' % line) + self.files_data_c.write(('"%s\\n"\n' % line).encode("utf8")) - self.files_data_c.write(";\n") - self.files_toc_c.write("\t{ \"%s\", %s, 0 },\n" % ( - base_path.replace("\\", "/"), name)) + self.files_data_c.write(b";\n") + self.files_toc_c.write(("\t{ \"%s\", %s, 0 },\n" % ( + base_path.replace("\\", "/"), name)).encode("utf8")) for sub_dir in sub_dirs: self.AddFiles(sub_dir) diff --git a/chromium/gpu/gles2_conform_support/native/main.cc b/chromium/gpu/gles2_conform_support/native/main.cc index 0d169a65c54..5a41a914f95 100644 --- a/chromium/gpu/gles2_conform_support/native/main.cc +++ b/chromium/gpu/gles2_conform_support/native/main.cc @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { #if defined(OS_WIN) std::vector<std::string> argsNonWide(args.size()); for (size_t index = 0; index < args.size(); ++index) { - argsNonWide[index] = base::UTF16ToASCII(args[index]); + argsNonWide[index] = base::WideToASCII(args[index]); argsArray[index+1] = argsNonWide[index].c_str(); } #else diff --git a/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc b/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc index 4feee7262b2..a05633700c2 100644 --- a/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc @@ -11,9 +11,11 @@ #include "base/command_line.h" #include "base/location.h" #include "base/logging.h" +#include "base/metrics/histogram.h" #include "base/optional.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/timer/elapsed_timer.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "gpu/command_buffer/client/gpu_control_client.h" @@ -196,7 +198,7 @@ void CommandBufferProxyImpl::OnGpuSwitched( void CommandBufferProxyImpl::AddDeletionObserver(DeletionObserver* observer) { std::unique_ptr<base::AutoLock> lock; if (lock_) - lock.reset(new base::AutoLock(*lock_)); + lock = std::make_unique<base::AutoLock>(*lock_); deletion_observers_.AddObserver(observer); } @@ -204,7 +206,7 @@ void CommandBufferProxyImpl::RemoveDeletionObserver( DeletionObserver* observer) { std::unique_ptr<base::AutoLock> lock; if (lock_) - lock.reset(new base::AutoLock(*lock_)); + lock = std::make_unique<base::AutoLock>(*lock_); deletion_observers_.RemoveObserver(observer); } @@ -484,8 +486,13 @@ void CommandBufferProxyImpl::SetLock(base::Lock* lock) { void CommandBufferProxyImpl::EnsureWorkVisible() { // Don't send messages once disconnected. - if (!disconnected_) - channel_->VerifyFlush(UINT32_MAX); + if (disconnected_) + return; + + const base::ElapsedTimer elapsed_timer; + channel_->VerifyFlush(UINT32_MAX); + GetUMAHistogramEnsureWorkVisibleDuration()->Add( + elapsed_timer.Elapsed().InMicroseconds()); } gpu::CommandBufferNamespace CommandBufferProxyImpl::GetNamespaceID() const { @@ -754,6 +761,63 @@ gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const { shared_state_mapping_.memory()); } +base::HistogramBase* +CommandBufferProxyImpl::GetUMAHistogramEnsureWorkVisibleDuration() { + if (!uma_histogram_ensure_work_visible_duration_) { + // Combine two linear histograms: + // 1/4 ms buckets in 0..15ms = 60 buckets + // 1/4 s buckets in 25ms .. 30s = 120 buckets + // This gives good cardinality for both VSYNC intervals and 30s watchdog: + // 0.00 ms + // 0.25 ms + // 0.50 ms + // 0.75 ms + // 1.00 ms + // 1.25 ms + // 1.50 ms + // ... + // 14.00 ms + // 14.25 ms + // 14.50 ms + // 14.75 ms + // 15.00 ms + // 0.25 s + // 0.50 s + // 0.75 s + // 1.00 s + // 1.25 s + // 1.50 s + // ... + // 29.00 s + // 29.25 s + // 29.50 s + // 29.75 s + // + // Histogram values are in microseconds. + + std::vector<base::HistogramBase::Sample> intervals; + constexpr base::HistogramBase::Sample k15Milliseconds = 15 * 1000; + constexpr base::HistogramBase::Sample k30Seconds = 30 * 1000 * 1000; + constexpr int kFirstPartCount = 60; + constexpr int kSecondPartCount = 120; + intervals.reserve(kFirstPartCount + kSecondPartCount); + for (int i = 0; i <= kFirstPartCount; ++i) { + intervals.push_back(k15Milliseconds / + static_cast<float>(kFirstPartCount) * i); + } + // 0 index was already populated by the first part. + for (int i = 1; i < kSecondPartCount; ++i) { + intervals.push_back(k30Seconds / static_cast<float>(kSecondPartCount) * + i); + } + uma_histogram_ensure_work_visible_duration_ = + base::CustomHistogram::FactoryGet( + "GPU.EnsureWorkVisibleDuration", intervals, + base::HistogramBase::kUmaTargetedHistogramFlag); + } + return uma_histogram_ensure_work_visible_duration_; +} + void CommandBufferProxyImpl::OnSwapBuffersCompleted( const SwapBuffersCompleteParams& params) { if (gpu_control_client_) diff --git a/chromium/gpu/ipc/client/command_buffer_proxy_impl.h b/chromium/gpu/ipc/client/command_buffer_proxy_impl.h index 224439738b4..3a541f708a3 100644 --- a/chromium/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/chromium/gpu/ipc/client/command_buffer_proxy_impl.h @@ -43,6 +43,10 @@ struct GPUCommandBufferConsoleMessage; class GURL; +namespace base { +class HistogramBase; +} + namespace gfx { struct GpuFenceHandle; struct PresentationFeedback; @@ -231,6 +235,8 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, // The shared memory area used to update state. gpu::CommandBufferSharedState* shared_state() const; + base::HistogramBase* GetUMAHistogramEnsureWorkVisibleDuration(); + // The shared memory region used to update state. base::UnsafeSharedMemoryRegion shared_state_shm_; base::WritableSharedMemoryMapping shared_state_mapping_; @@ -279,6 +285,9 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, UpdateVSyncParametersCallback update_vsync_parameters_completion_callback_; + // Cache pointer to EnsureWorkVisibleDuration custom UMA histogram. + base::HistogramBase* uma_histogram_ensure_work_visible_duration_ = nullptr; + using GetGpuFenceTaskMap = base::flat_map<uint32_t, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>>; diff --git a/chromium/gpu/ipc/client/gpu_channel_host.cc b/chromium/gpu/ipc/client/gpu_channel_host.cc index d4c969c636d..026dc503d77 100644 --- a/chromium/gpu/ipc/client/gpu_channel_host.cc +++ b/chromium/gpu/ipc/client/gpu_channel_host.cc @@ -31,16 +31,18 @@ using base::AutoLock; namespace gpu { -GpuChannelHost::GpuChannelHost(int channel_id, - const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info, - mojo::ScopedMessagePipeHandle handle) - : io_thread_(base::ThreadTaskRunnerHandle::Get()), +GpuChannelHost::GpuChannelHost( + int channel_id, + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info, + mojo::ScopedMessagePipeHandle handle, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) + : io_thread_(io_task_runner ? io_task_runner + : base::ThreadTaskRunnerHandle::Get()), channel_id_(channel_id), gpu_info_(gpu_info), gpu_feature_info_(gpu_feature_info), - listener_(new Listener(std::move(handle), io_thread_), - base::OnTaskRunnerDeleter(io_thread_)), + listener_(new Listener(), base::OnTaskRunnerDeleter(io_thread_)), shared_image_interface_( this, static_cast<int32_t>( @@ -49,6 +51,16 @@ GpuChannelHost::GpuChannelHost(int channel_id, this, static_cast<int32_t>( GpuChannelReservedRoutes::kImageDecodeAccelerator)) { + if (io_thread_->BelongsToCurrentThread()) { + listener_->Initialize(std::move(handle), io_thread_); + DCHECK(io_thread_->BelongsToCurrentThread()); + } else { + io_thread_->PostTask( + FROM_HERE, + base::BindOnce(&Listener::Initialize, base::Unretained(listener_.get()), + std::move(handle), io_thread_)); + } + next_image_id_.GetNext(); for (int32_t i = 0; i <= static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue); ++i) @@ -270,18 +282,16 @@ GpuChannelHost::OrderingBarrierInfo::OrderingBarrierInfo( GpuChannelHost::OrderingBarrierInfo& GpuChannelHost::OrderingBarrierInfo:: operator=(OrderingBarrierInfo&&) = default; -GpuChannelHost::Listener::Listener( +GpuChannelHost::Listener::Listener() = default; + +void GpuChannelHost::Listener::Initialize( mojo::ScopedMessagePipeHandle handle, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) - : channel_(IPC::ChannelMojo::Create( - std::move(handle), - IPC::Channel::MODE_CLIENT, - this, - io_task_runner, - base::ThreadTaskRunnerHandle::Get(), - mojo::internal::MessageQuotaChecker::MaybeCreate())) { + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) { + channel_ = IPC::ChannelMojo::Create( + std::move(handle), IPC::Channel::MODE_CLIENT, this, io_task_runner, + base::ThreadTaskRunnerHandle::Get(), + mojo::internal::MessageQuotaChecker::MaybeCreate()); DCHECK(channel_); - DCHECK(io_task_runner->BelongsToCurrentThread()); bool result = channel_->Connect(); DCHECK(result); } diff --git a/chromium/gpu/ipc/client/gpu_channel_host.h b/chromium/gpu/ipc/client/gpu_channel_host.h index fb96db908da..371ec1ce96c 100644 --- a/chromium/gpu/ipc/client/gpu_channel_host.h +++ b/chromium/gpu/ipc/client/gpu_channel_host.h @@ -63,10 +63,12 @@ class GPU_EXPORT GpuChannelHost : public IPC::Sender, public base::RefCountedThreadSafe<GpuChannelHost> { public: - GpuChannelHost(int channel_id, - const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info, - mojo::ScopedMessagePipeHandle handle); + GpuChannelHost( + int channel_id, + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info, + mojo::ScopedMessagePipeHandle handle, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr); bool IsLost() const { DCHECK(listener_.get()); @@ -157,12 +159,15 @@ class GPU_EXPORT GpuChannelHost // all the contexts. class GPU_EXPORT Listener : public IPC::Listener { public: - Listener(mojo::ScopedMessagePipeHandle handle, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + Listener(); ~Listener() override; // Called on the IO thread. + void Initialize(mojo::ScopedMessagePipeHandle handle, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + + // Called on the IO thread. void Close(); // Called on the IO thread. diff --git a/chromium/gpu/ipc/client/raster_in_process_context_tests.cc b/chromium/gpu/ipc/client/raster_in_process_context_tests.cc index def3e61c9ec..d8ad7b20aa2 100644 --- a/chromium/gpu/ipc/client/raster_in_process_context_tests.cc +++ b/chromium/gpu/ipc/client/raster_in_process_context_tests.cc @@ -105,9 +105,9 @@ TEST_F(RasterInProcessCommandBufferTest, AllowedBetweenBeginEndRasterCHROMIUM) { ri_->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData()); // Call BeginRasterCHROMIUM. - ri_->BeginRasterCHROMIUM(/*sk_color=*/0, /*msaa_sample_count=*/0, - /*can_use_lcd_text=*/false, color_space, - mailbox.name); + ri_->BeginRasterCHROMIUM( + /*sk_color=*/0, /*needs_clear=*/true, /*msaa_sample_count=*/0, + /*can_use_lcd_text=*/false, color_space, mailbox.name); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError()); // Should flag an error this command is not allowed between a Begin and diff --git a/chromium/gpu/ipc/common/BUILD.gn b/chromium/gpu/ipc/common/BUILD.gn index 7a4f18e8718..f66e5bedec6 100644 --- a/chromium/gpu/ipc/common/BUILD.gn +++ b/chromium/gpu/ipc/common/BUILD.gn @@ -86,9 +86,12 @@ source_set("ipc_common_sources") { if (is_win) { sources += [ + "dxgi_helpers.cc", + "dxgi_helpers.h", "gpu_memory_buffer_impl_dxgi.cc", "gpu_memory_buffer_impl_dxgi.h", ] + libs = [ "d3d11.lib" ] } if (is_linux || is_chromeos || use_ozone) { sources += [ @@ -120,8 +123,10 @@ source_set("ipc_common_sources") { deps = [ "//base", "//components/viz/common:resource_format", + "//gpu/command_buffer/client:client_sources", "//gpu/command_buffer/common:common_sources", "//gpu/config:config_sources", + "//third_party/libyuv", "//ui/base", "//ui/gfx:color_space", "//ui/gfx/geometry", @@ -483,6 +488,9 @@ mojom("gpu_preferences_interface") { if (use_ozone) { enabled_features += [ "use_ozone" ] } + if (is_chromeos_ash || is_chromeos_lacros) { + enabled_features += [ "is_chromeos_device" ] + } cpp_typemaps = [ { diff --git a/chromium/gpu/ipc/common/DEPS b/chromium/gpu/ipc/common/DEPS index 1b22eccf17e..04393481d72 100644 --- a/chromium/gpu/ipc/common/DEPS +++ b/chromium/gpu/ipc/common/DEPS @@ -12,4 +12,7 @@ specific_include_rules = { "+third_party/skia/include/gpu/GrTypes.h", "+third_party/skia/include/core/SkImageInfo.h", ], + "dxgi_helpers.cc": [ + "+third_party/libyuv/include/libyuv/planar_functions.h", + ] } diff --git a/chromium/gpu/ipc/common/dxgi_helpers.cc b/chromium/gpu/ipc/common/dxgi_helpers.cc new file mode 100644 index 00000000000..066d205418f --- /dev/null +++ b/chromium/gpu/ipc/common/dxgi_helpers.cc @@ -0,0 +1,170 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/ipc/common/dxgi_helpers.h" + +#include "base/check.h" +#include "base/logging.h" +#include "base/time/time.h" +#include "third_party/libyuv/include/libyuv/planar_functions.h" + +namespace { + +constexpr char kStagingTextureLabel[] = "DxgiGmb_Map_StagingTexture"; + +Microsoft::WRL::ComPtr<ID3D11Texture2D> CreateStagingTexture( + ID3D11Device* d3d11_device, + D3D11_TEXTURE2D_DESC input_desc) { + D3D11_TEXTURE2D_DESC staging_desc = {}; + staging_desc.Width = input_desc.Width; + staging_desc.Height = input_desc.Height; + staging_desc.Format = input_desc.Format; + staging_desc.MipLevels = 1; + staging_desc.ArraySize = 1; + staging_desc.SampleDesc.Count = 1; + staging_desc.Usage = D3D11_USAGE_STAGING; + staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + + Microsoft::WRL::ComPtr<ID3D11Texture2D> staging_texture; + HRESULT hr = + d3d11_device->CreateTexture2D(&staging_desc, nullptr, &staging_texture); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to create staging texture. hr=" << std::hex << hr; + return nullptr; + } + // Add debug label to the long lived texture. + staging_texture->SetPrivateData(WKPDID_D3DDebugObjectName, + strlen(kStagingTextureLabel), + kStagingTextureLabel); + + return staging_texture; +} + +} // namespace + +namespace gpu { + +D3D11ScopedTextureUnmap::D3D11ScopedTextureUnmap( + Microsoft::WRL::ComPtr<ID3D11DeviceContext> context, + Microsoft::WRL::ComPtr<ID3D11Texture2D> texture) + : context_(std::move(context)), texture_(std::move(texture)) {} + +D3D11ScopedTextureUnmap::~D3D11ScopedTextureUnmap() { + context_->Unmap(texture_.Get(), 0); +} + +DXGIScopedReleaseKeyedMutex::DXGIScopedReleaseKeyedMutex( + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex, + UINT64 key) + : keyed_mutex_(std::move(keyed_mutex)), key_(key) { + DCHECK(keyed_mutex_); +} + +DXGIScopedReleaseKeyedMutex::~DXGIScopedReleaseKeyedMutex() { + HRESULT hr = keyed_mutex_->ReleaseSync(key_); + DCHECK(SUCCEEDED(hr)); +} + +bool CopyDXGIBufferToShMem( + HANDLE dxgi_handle, + base::UnsafeSharedMemoryRegion shared_memory, + ID3D11Device* d3d11_device, + Microsoft::WRL::ComPtr<ID3D11Texture2D>* staging_texture) { + DCHECK(d3d11_device); + DCHECK(staging_texture); + + Microsoft::WRL::ComPtr<ID3D11Device1> device1; + HRESULT hr = d3d11_device->QueryInterface(IID_PPV_ARGS(&device1)); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to open D3D11_1 device. hr=" << std::hex << hr; + return false; + } + + Microsoft::WRL::ComPtr<ID3D11Texture2D> texture; + + // Open texture on device using shared handle + hr = device1->OpenSharedResource1(dxgi_handle, IID_PPV_ARGS(&texture)); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to open shared texture. hr=" << std::hex << hr; + return false; + } + + D3D11_TEXTURE2D_DESC texture_desc = {}; + texture->GetDesc(&texture_desc); + + if (texture_desc.Format != DXGI_FORMAT_NV12) { + DLOG(ERROR) << "Can't copy non-NV12 texture. format=" + << static_cast<int>(texture_desc.Format); + return false; + } + + // The texture isn't accessible for CPU reads, thus a staging texture is used. + bool create_staging_texture = !*staging_texture; + if (*staging_texture) { + D3D11_TEXTURE2D_DESC staging_texture_desc; + (*staging_texture)->GetDesc(&staging_texture_desc); + create_staging_texture = + (staging_texture_desc.Width != texture_desc.Width || + staging_texture_desc.Height != texture_desc.Height || + staging_texture_desc.Format != texture_desc.Format); + } + if (create_staging_texture) { + *staging_texture = CreateStagingTexture(d3d11_device, texture_desc); + if (!*staging_texture) + return false; + } + + Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context; + d3d11_device->GetImmediateContext(&device_context); + + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex; + hr = texture.As(&keyed_mutex); + + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to get keyed mutex. hr=" << std::hex << hr; + return false; + } + + // Key equal to 0 is also used by the producer. Therefore, this keyed mutex + // acts purely as a regular mutex. + hr = keyed_mutex->AcquireSync(0, INFINITE); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to acquire keyed mutex. hr=" << std::hex << hr; + return false; + } + DXGIScopedReleaseKeyedMutex release_keyed_mutex(keyed_mutex, 0); + + device_context->CopySubresourceRegion(staging_texture->Get(), 0, 0, 0, 0, + texture.Get(), 0, nullptr); + + D3D11_MAPPED_SUBRESOURCE mapped_resource = {}; + hr = device_context->Map(staging_texture->Get(), 0, D3D11_MAP_READ, 0, + &mapped_resource); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to map texture for read. hr=" << std::hex << hr; + return false; + } + D3D11ScopedTextureUnmap scoped_unmap(device_context, *staging_texture); + + // Copy mapped texture to shared memory region for client + size_t buffer_size = texture_desc.Height * texture_desc.Width * 3 / 2; + if (shared_memory.GetSize() < buffer_size) + return false; + + base::WritableSharedMemoryMapping mapping = shared_memory.Map(); + const uint8_t* source_buffer = static_cast<uint8_t*>(mapped_resource.pData); + uint8_t* dest_buffer = mapping.GetMemoryAsSpan<uint8_t>().data(); + + const uint32_t source_stride = mapped_resource.RowPitch; + const uint32_t dest_stride = texture_desc.Width; + + return libyuv::NV12Copy(source_buffer, source_stride, + source_buffer + texture_desc.Height * source_stride, + source_stride, dest_buffer, dest_stride, + dest_buffer + texture_desc.Height * dest_stride, + dest_stride, texture_desc.Width, + texture_desc.Height) == 0; +} + +} // namespace gpu
\ No newline at end of file diff --git a/chromium/gpu/ipc/common/dxgi_helpers.h b/chromium/gpu/ipc/common/dxgi_helpers.h new file mode 100644 index 00000000000..e2797e2a950 --- /dev/null +++ b/chromium/gpu/ipc/common/dxgi_helpers.h @@ -0,0 +1,69 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_IPC_COMMON_DXGI_HELPERS_H_ +#define GPU_IPC_COMMON_DXGI_HELPERS_H_ + +#include <d3d11_1.h> +#include <dxgi.h> +#include <wrl/client.h> + +#include "base/memory/unsafe_shared_memory_region.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +// This helper class can be used to securely unmap texture. +// Create one after successful ID3D11DeviceContext::Map() with the +// mapped texture and device context. +// Upon destruction the texture will be automatically unmapped. +class GPU_EXPORT D3D11ScopedTextureUnmap { + public: + D3D11ScopedTextureUnmap(Microsoft::WRL::ComPtr<ID3D11DeviceContext> context, + Microsoft::WRL::ComPtr<ID3D11Texture2D> texture); + + D3D11ScopedTextureUnmap(const D3D11ScopedTextureUnmap&) = delete; + + D3D11ScopedTextureUnmap& operator=(const D3D11ScopedTextureUnmap&) = delete; + + ~D3D11ScopedTextureUnmap(); + + private: + Microsoft::WRL::ComPtr<ID3D11DeviceContext> context_; + Microsoft::WRL::ComPtr<ID3D11Texture2D> texture_; +}; + +// This helper class can be used to securely release KeyedMutex. +// Create one after successful acquisition of the keyed mutex. +// Upon destruction the mutex would be automatically released. +class GPU_EXPORT DXGIScopedReleaseKeyedMutex { + public: + DXGIScopedReleaseKeyedMutex( + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex, + UINT64 key); + + DXGIScopedReleaseKeyedMutex(const DXGIScopedReleaseKeyedMutex&) = delete; + + DXGIScopedReleaseKeyedMutex& operator=(const DXGIScopedReleaseKeyedMutex&) = + delete; + + ~DXGIScopedReleaseKeyedMutex(); + + private: + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex_; + UINT64 key_ = 0; +}; + +// Copies |dxgi_handle| data to |shared_memory| using provided D3D11 device, and +// a staging texture. The texture may be recreated if it has wrong size or +// format. Returns true if succeeded. +GPU_EXPORT bool CopyDXGIBufferToShMem( + HANDLE dxgi_handle, + base::UnsafeSharedMemoryRegion shared_memory, + ID3D11Device* d3d11_device, + Microsoft::WRL::ComPtr<ID3D11Texture2D>* staging_texture); + +} // namespace gpu + +#endif // GPU_IPC_COMMON_DXGI_HELPERS_H_ diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.cc b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.cc index af73c5761cb..532bc38d474 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.cc +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "ui/gfx/buffer_format_util.h" @@ -20,15 +21,19 @@ namespace gpu { GpuMemoryBufferImplDXGI::~GpuMemoryBufferImplDXGI() {} std::unique_ptr<GpuMemoryBufferImplDXGI> -GpuMemoryBufferImplDXGI::CreateFromHandle(gfx::GpuMemoryBufferHandle handle, - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - DestructionCallback callback) { +GpuMemoryBufferImplDXGI::CreateFromHandle( + gfx::GpuMemoryBufferHandle handle, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + DestructionCallback callback, + GpuMemoryBufferManager* gpu_memory_buffer_manager, + scoped_refptr<base::UnsafeSharedMemoryPool> pool) { DCHECK(handle.dxgi_handle.IsValid()); - return base::WrapUnique( - new GpuMemoryBufferImplDXGI(handle.id, size, format, std::move(callback), - std::move(handle.dxgi_handle))); + return base::WrapUnique(new GpuMemoryBufferImplDXGI( + handle.id, size, format, std::move(callback), + std::move(handle.dxgi_handle), gpu_memory_buffer_manager, std::move(pool), + std::move(handle.region))); } base::OnceClosure GpuMemoryBufferImplDXGI::AllocateForTesting( @@ -84,14 +89,72 @@ base::OnceClosure GpuMemoryBufferImplDXGI::AllocateForTesting( } bool GpuMemoryBufferImplDXGI::Map() { - return false; // The current implementation doesn't support mapping. + base::AutoLock auto_lock(map_lock_); + if (map_count_++) + return true; + + if (unowned_region_.IsValid()) { + unowned_mapping_ = unowned_region_.Map(); + if (unowned_mapping_.IsValid()) { + return true; + } + // If failed to map unowned region - try to do manual copy as if the region + // was not provided. + } + + DCHECK(!shared_memory_handle_); + DCHECK(gpu_memory_buffer_manager_); + DCHECK(shared_memory_pool_); + + shared_memory_handle_ = shared_memory_pool_->MaybeAllocateBuffer( + gfx::BufferSizeForBufferFormat(size_, format_)); + if (!shared_memory_handle_) { + --map_count_; + return false; + } + + // Need to perform mapping in GPU process + if (!gpu_memory_buffer_manager_->CopyGpuMemoryBufferSync( + CloneHandle(), shared_memory_handle_->GetRegion().Duplicate())) { + shared_memory_handle_.reset(); + --map_count_; + return false; + } + + return true; } void* GpuMemoryBufferImplDXGI::memory(size_t plane) { - return nullptr; // The current implementation doesn't support mapping. + AssertMapped(); + + if (plane > gfx::NumberOfPlanesForLinearBufferFormat(format_) || + (!shared_memory_handle_ && !unowned_mapping_.IsValid())) { + return nullptr; + } + + uint8_t* plane_addr = + (shared_memory_handle_ ? shared_memory_handle_->GetMapping() + : unowned_mapping_) + .GetMemoryAsSpan<uint8_t>() + .data(); + // This is safe, since we already checked that the requested plane is + // valid for current buffer format. + plane_addr += gfx::BufferOffsetForBufferFormat(size_, format_, plane); + return plane_addr; } -void GpuMemoryBufferImplDXGI::Unmap() {} +void GpuMemoryBufferImplDXGI::Unmap() { + base::AutoLock al(map_lock_); + DCHECK_GT(map_count_, 0u); + if (--map_count_) + return; + + if (shared_memory_handle_) { + shared_memory_handle_.reset(); + } else { + unowned_mapping_ = base::WritableSharedMemoryMapping(); + } +} int GpuMemoryBufferImplDXGI::stride(size_t plane) const { return gfx::RowSizeForBufferFormat(size_.width(), format_, plane); @@ -115,16 +178,28 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferImplDXGI::CloneHandle() const { if (!result) DPLOG(ERROR) << "Failed to duplicate DXGI resource handle."; handle.dxgi_handle.Set(duplicated_handle); + if (unowned_region_.IsValid()) { + handle.region = unowned_region_.Duplicate(); + } return handle; } +HANDLE GpuMemoryBufferImplDXGI::GetHandle() const { + return dxgi_handle_.Get(); +} + GpuMemoryBufferImplDXGI::GpuMemoryBufferImplDXGI( gfx::GpuMemoryBufferId id, const gfx::Size& size, gfx::BufferFormat format, DestructionCallback callback, - base::win::ScopedHandle dxgi_handle) + base::win::ScopedHandle dxgi_handle, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + scoped_refptr<base::UnsafeSharedMemoryPool> pool, + base::UnsafeSharedMemoryRegion region) : GpuMemoryBufferImpl(id, size, format, std::move(callback)), - dxgi_handle_(std::move(dxgi_handle)) {} - + dxgi_handle_(std::move(dxgi_handle)), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), + shared_memory_pool_(std::move(pool)), + unowned_region_(std::move(region)) {} } // namespace gpu diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h index 21895c4af99..4b1c371b99e 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h @@ -10,6 +10,8 @@ #include <memory> #include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/unsafe_shared_memory_pool.h" #include "base/win/scoped_handle.h" #include "gpu/gpu_export.h" #include "gpu/ipc/common/gpu_memory_buffer_impl.h" @@ -17,6 +19,8 @@ namespace gpu { +class GpuMemoryBufferManager; + // Implementation of GPU memory buffer based on dxgi textures. class GPU_EXPORT GpuMemoryBufferImplDXGI : public GpuMemoryBufferImpl { public: @@ -30,7 +34,9 @@ class GPU_EXPORT GpuMemoryBufferImplDXGI : public GpuMemoryBufferImpl { const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - DestructionCallback callback); + DestructionCallback callback, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + scoped_refptr<base::UnsafeSharedMemoryPool> pool); static base::OnceClosure AllocateForTesting( const gfx::Size& size, @@ -45,14 +51,29 @@ class GPU_EXPORT GpuMemoryBufferImplDXGI : public GpuMemoryBufferImpl { gfx::GpuMemoryBufferType GetType() const override; gfx::GpuMemoryBufferHandle CloneHandle() const override; + HANDLE GetHandle() const; + private: GpuMemoryBufferImplDXGI(gfx::GpuMemoryBufferId id, const gfx::Size& size, gfx::BufferFormat format, DestructionCallback callback, - base::win::ScopedHandle dxgi_handle); + base::win::ScopedHandle dxgi_handle, + GpuMemoryBufferManager* gpu_memory_buffer_manager, + scoped_refptr<base::UnsafeSharedMemoryPool> pool, + base::UnsafeSharedMemoryRegion region); base::win::ScopedHandle dxgi_handle_; + GpuMemoryBufferManager* gpu_memory_buffer_manager_; + + // Used to create and store shared memory for data, copied via request to + // gpu process. + scoped_refptr<base::UnsafeSharedMemoryPool> shared_memory_pool_; + std::unique_ptr<base::UnsafeSharedMemoryPool::Handle> shared_memory_handle_; + + // Used to store shared memory passed from the capturer. + base::UnsafeSharedMemoryRegion unowned_region_; + base::WritableSharedMemoryMapping unowned_mapping_; DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplDXGI); }; diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc index d5053168890..d14c28379e7 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc @@ -43,6 +43,7 @@ uint32_t LockFlags(gfx::BufferUsage usage) { case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_VDA_WRITE: case gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE: + case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: return 0; } NOTREACHED(); diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc index 870afaa163c..e20d1ceca9a 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc @@ -158,6 +158,7 @@ bool GpuMemoryBufferImplSharedMemory::IsUsageSupported(gfx::BufferUsage usage) { case gfx::BufferUsage::GPU_READ: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: + case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: return true; case gfx::BufferUsage::SCANOUT: case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc b/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc index 374281fb13d..7f849a553b1 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc @@ -7,6 +7,7 @@ #include "base/check_op.h" #include "base/notreached.h" #include "build/build_config.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.h" #include "ui/base/ui_base_features.h" #include "ui/gfx/buffer_format_util.h" @@ -86,6 +87,7 @@ bool GpuMemoryBufferSupport::IsNativeGpuMemoryBufferConfigurationSupported( case gfx::BufferUsage::SCANOUT: case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: + case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: return format == gfx::BufferFormat::BGRA_8888 || format == gfx::BufferFormat::RGBA_8888 || format == gfx::BufferFormat::BGRX_8888 || @@ -122,6 +124,7 @@ bool GpuMemoryBufferSupport::IsNativeGpuMemoryBufferConfigurationSupported( case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_VEA_CPU_READ: case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE: + case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: return false; } NOTREACHED(); @@ -153,6 +156,7 @@ bool GpuMemoryBufferSupport::IsNativeGpuMemoryBufferConfigurationSupported( case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_VEA_CPU_READ: case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE: + case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: return false; } NOTREACHED(); @@ -191,7 +195,9 @@ GpuMemoryBufferSupport::CreateGpuMemoryBufferImplFromHandle( const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - GpuMemoryBufferImpl::DestructionCallback callback) { + GpuMemoryBufferImpl::DestructionCallback callback, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + scoped_refptr<base::UnsafeSharedMemoryPool> pool) { switch (handle.type) { case gfx::SHARED_MEMORY_BUFFER: return GpuMemoryBufferImplSharedMemory::CreateFromHandle( @@ -210,7 +216,8 @@ GpuMemoryBufferSupport::CreateGpuMemoryBufferImplFromHandle( #if defined(OS_WIN) case gfx::DXGI_SHARED_HANDLE: return GpuMemoryBufferImplDXGI::CreateFromHandle( - std::move(handle), size, format, usage, std::move(callback)); + std::move(handle), size, format, usage, std::move(callback), + gpu_memory_buffer_manager, std::move(pool)); #endif #if defined(OS_ANDROID) case gfx::ANDROID_HARDWARE_BUFFER: diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_support.h b/chromium/gpu/ipc/common/gpu_memory_buffer_support.h index 29419a24f5e..32428cc4f90 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_support.h +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_support.h @@ -9,6 +9,8 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/unsafe_shared_memory_pool.h" #include "build/build_config.h" #include "gpu/gpu_export.h" #include "gpu/ipc/common/gpu_memory_buffer_impl.h" @@ -24,6 +26,8 @@ class ClientNativePixmapFactory; namespace gpu { +class GpuMemoryBufferManager; + // Provides a common factory for GPU memory buffer implementations. class GPU_EXPORT GpuMemoryBufferSupport { public: @@ -53,13 +57,17 @@ class GPU_EXPORT GpuMemoryBufferSupport { // should match what was used to allocate the |handle|. |callback|, if // non-null, is called when instance is deleted, which is not necessarily on // the same thread as this function was called on and instance was created on. + // |gpu_memory_buffer_manager| and |pool| are only needed if the created + // buffer is a windows DXGI buffer and it needs to be mapped at the consumer. virtual std::unique_ptr<GpuMemoryBufferImpl> CreateGpuMemoryBufferImplFromHandle( gfx::GpuMemoryBufferHandle handle, const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - GpuMemoryBufferImpl::DestructionCallback callback); + GpuMemoryBufferImpl::DestructionCallback callback, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = nullptr, + scoped_refptr<base::UnsafeSharedMemoryPool> pool = nullptr); private: #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(USE_OZONE) diff --git a/chromium/gpu/ipc/common/gpu_preferences.mojom b/chromium/gpu/ipc/common/gpu_preferences.mojom index da1202da560..927b091e8d5 100644 --- a/chromium/gpu/ipc/common/gpu_preferences.mojom +++ b/chromium/gpu/ipc/common/gpu_preferences.mojom @@ -97,6 +97,6 @@ struct GpuPreferences { bool enable_native_gpu_memory_buffers; - [EnableIf=is_chromeos] + [EnableIf=is_chromeos_device] bool enable_chromeos_direct_video_decoder; }; diff --git a/chromium/gpu/ipc/common/gpu_preferences_mojom_traits.h b/chromium/gpu/ipc/common/gpu_preferences_mojom_traits.h index 681d05679df..c4f7eabe0f6 100644 --- a/chromium/gpu/ipc/common/gpu_preferences_mojom_traits.h +++ b/chromium/gpu/ipc/common/gpu_preferences_mojom_traits.h @@ -195,7 +195,7 @@ struct StructTraits<gpu::mojom::GpuPreferencesDataView, gpu::GpuPreferences> { out->enable_native_gpu_memory_buffers = prefs.enable_native_gpu_memory_buffers(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) out->enable_chromeos_direct_video_decoder = prefs.enable_chromeos_direct_video_decoder(); #endif @@ -397,7 +397,7 @@ struct StructTraits<gpu::mojom::GpuPreferencesDataView, gpu::GpuPreferences> { const gpu::GpuPreferences& prefs) { return prefs.enable_native_gpu_memory_buffers; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) static bool enable_chromeos_direct_video_decoder( const gpu::GpuPreferences& prefs) { return prefs.enable_chromeos_direct_video_decoder; diff --git a/chromium/gpu/ipc/common/gpu_watchdog_timeout.h b/chromium/gpu/ipc/common/gpu_watchdog_timeout.h index 53b41c19897..be43d877c0d 100644 --- a/chromium/gpu/ipc/common/gpu_watchdog_timeout.h +++ b/chromium/gpu/ipc/common/gpu_watchdog_timeout.h @@ -23,6 +23,11 @@ constexpr base::TimeDelta kGpuWatchdogTimeout = #elif defined(OS_WIN) constexpr base::TimeDelta kGpuWatchdogTimeout = base::TimeDelta::FromSeconds(30); +#elif defined(OS_FUCHSIA) +// Increased temporarily to investigate if this helps https://crbug.com/1185119 +// (GPU process hangs when running blink web tests on Fuchsia). +constexpr base::TimeDelta kGpuWatchdogTimeout = + base::TimeDelta::FromSeconds(30); #else constexpr base::TimeDelta kGpuWatchdogTimeout = base::TimeDelta::FromSeconds(15); diff --git a/chromium/gpu/ipc/gpu_task_scheduler_helper.cc b/chromium/gpu/ipc/gpu_task_scheduler_helper.cc index cf4fbc4a78a..32e4f62f358 100644 --- a/chromium/gpu/ipc/gpu_task_scheduler_helper.cc +++ b/chromium/gpu/ipc/gpu_task_scheduler_helper.cc @@ -36,7 +36,8 @@ void GpuTaskSchedulerHelper::Initialize( void GpuTaskSchedulerHelper::ScheduleGpuTask( base::OnceClosure callback, - std::vector<gpu::SyncToken> sync_tokens) { + std::vector<gpu::SyncToken> sync_tokens, + SingleTaskSequence::ReportingCallback report_callback) { // There are two places where this function is called: inside // SkiaOutputSurface, where |using_command_buffer_| is false, or by other // users when sharing with command buffer, where we should ahve @@ -46,7 +47,8 @@ void GpuTaskSchedulerHelper::ScheduleGpuTask( if (command_buffer_helper_) command_buffer_helper_->Flush(); - task_sequence_->ScheduleTask(std::move(callback), std::move(sync_tokens)); + task_sequence_->ScheduleTask(std::move(callback), std::move(sync_tokens), + std::move(report_callback)); } void GpuTaskSchedulerHelper::ScheduleOrRetainGpuTask( diff --git a/chromium/gpu/ipc/gpu_task_scheduler_helper.h b/chromium/gpu/ipc/gpu_task_scheduler_helper.h index b12c77965f6..abe5f7687b3 100644 --- a/chromium/gpu/ipc/gpu_task_scheduler_helper.h +++ b/chromium/gpu/ipc/gpu_task_scheduler_helper.h @@ -49,12 +49,16 @@ class GL_IN_PROCESS_CONTEXT_EXPORT GpuTaskSchedulerHelper { // buffer, thus no need to be called when using SkiaRenderer. void Initialize(CommandBufferHelper* command_buffer_helper); + using ReportingCallback = + base::OnceCallback<void(base::TimeTicks task_ready)>; + // This is called outside of CommandBuffer and would need to flush the command // buffer if the CommandBufferHelper is present. CommandBuffer is a friend of // this class and gets a direct pointer to the internal // |gpu::SingleTaskSequence|. void ScheduleGpuTask(base::OnceClosure task, - std::vector<SyncToken> sync_tokens); + std::vector<SyncToken> sync_tokens, + ReportingCallback report_callback = ReportingCallback()); // This is only called with SkiaOutputSurface, no need to flush command buffer // here. diff --git a/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc b/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc index 9e10a095cdc..2ee6c023378 100644 --- a/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc +++ b/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc @@ -43,6 +43,7 @@ GpuMemoryBufferConfigurationSet GetNativeGpuMemoryBufferConfigurations( gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::BufferUsage::SCANOUT_VEA_CPU_READ, gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_FRONT_RENDERING, }; for (auto format : kBufferFormats) { diff --git a/chromium/gpu/ipc/in_process_command_buffer.cc b/chromium/gpu/ipc/in_process_command_buffer.cc index 8c52faf21a1..ac4941b98da 100644 --- a/chromium/gpu/ipc/in_process_command_buffer.cc +++ b/chromium/gpu/ipc/in_process_command_buffer.cc @@ -23,6 +23,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" @@ -384,10 +385,6 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread( use_virtualized_gl_context_ |= task_executor_->ForceVirtualizedGLContexts(); - // MailboxManagerSync synchronization correctness currently depends on having - // only a single context. See https://crbug.com/510243 for details. - use_virtualized_gl_context_ |= task_executor_->mailbox_manager()->UsesSync(); - use_virtualized_gl_context_ |= context_group_->feature_info()->workarounds().use_virtualized_gl_contexts; @@ -814,12 +811,14 @@ void InProcessCommandBuffer::RunTaskOnGpuThread(base::OnceClosure task) { void InProcessCommandBuffer::ScheduleGpuTask( base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) { + std::vector<SyncToken> sync_token_fences, + SingleTaskSequence::ReportingCallback report_callback) { base::OnceClosure gpu_task = base::BindOnce( &InProcessCommandBuffer::RunTaskOnGpuThread, gpu_thread_weak_ptr_factory_.GetWeakPtr(), std::move(task)); task_sequence_->ScheduleTask(std::move(gpu_task), - std::move(sync_token_fences)); + std::move(sync_token_fences), + std::move(report_callback)); } void InProcessCommandBuffer::ContinueGpuTask(base::OnceClosure task) { @@ -854,6 +853,10 @@ bool InProcessCommandBuffer::HasUnprocessedCommandsOnGpuThread() { return false; } +void InProcessCommandBuffer::ReportTaskReady(base::TimeTicks task_ready) { + gpu_task_ready_ = task_ready; +} + void InProcessCommandBuffer::FlushOnGpuThread( int32_t put_offset, const std::vector<SyncToken>& sync_token_fences, @@ -878,12 +881,6 @@ void InProcessCommandBuffer::FlushOnGpuThread( return; auto cache_use = CreateCacheUse(); - MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync()) { - for (const auto& sync_token : sync_token_fences) - mailbox_manager->PullTextureUpdates(sync_token); - } - { base::Optional<raster::GrShaderCache::ScopedCacheUse> gr_cache_use; if (gr_shader_cache_) @@ -952,9 +949,13 @@ void InProcessCommandBuffer::Flush(int32_t put_offset) { next_flush_sync_token_fences_.swap(sync_token_fences); base::TimeTicks flush_timestamp; + SingleTaskSequence::ReportingCallback reporting_callback; if (should_measure_next_flush_) { should_measure_next_flush_ = false; flush_timestamp = base::TimeTicks::Now(); + reporting_callback = + base::BindOnce(&InProcessCommandBuffer::ReportTaskReady, + gpu_thread_weak_ptr_factory_.GetWeakPtr()); } // Don't use std::move() for |sync_token_fences| because evaluation order for @@ -963,7 +964,7 @@ void InProcessCommandBuffer::Flush(int32_t put_offset) { base::BindOnce(&InProcessCommandBuffer::FlushOnGpuThread, gpu_thread_weak_ptr_factory_.GetWeakPtr(), put_offset, sync_token_fences, flush_timestamp), - sync_token_fences); + sync_token_fences, std::move(reporting_callback)); } void InProcessCommandBuffer::OrderingBarrier(int32_t put_offset) { @@ -1198,10 +1199,6 @@ void InProcessCommandBuffer::OnFenceSyncRelease(uint64_t release) { SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), release); - MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync()) - mailbox_manager->PushTextureUpdates(sync_token); - command_buffer_->SetReleaseCount(release); sync_point_client_state_->ReleaseFenceSync(release); } @@ -1216,11 +1213,13 @@ void InProcessCommandBuffer::OnRescheduleAfterFinished() { void InProcessCommandBuffer::OnSwapBuffers(uint64_t swap_id, uint32_t flags) { DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); - pending_swap_completed_params_.push_back( - {swap_id, flags, viz_scheduled_draw_, gpu_started_draw_}); + pending_swap_completed_params_.push_back({swap_id, flags, viz_scheduled_draw_, + gpu_started_draw_, + gpu_task_ready_}); pending_presented_params_.push_back({swap_id, flags}); viz_scheduled_draw_ = base::TimeTicks(); gpu_started_draw_ = base::TimeTicks(); + gpu_task_ready_ = base::TimeTicks(); } void InProcessCommandBuffer::ScheduleGrContextCleanup() { @@ -1454,6 +1453,7 @@ void InProcessCommandBuffer::DidSwapBuffersComplete( pending_swap.viz_scheduled_draw; params.swap_response.timings.gpu_started_draw = pending_swap.gpu_started_draw; params.swap_response.swap_id = pending_swap.swap_id; + params.swap_response.timings.gpu_task_ready = pending_swap.gpu_task_ready; pending_swap_completed_params_.pop_front(); PostOrRunClientCallback(base::BindOnce( diff --git a/chromium/gpu/ipc/in_process_command_buffer.h b/chromium/gpu/ipc/in_process_command_buffer.h index 82d4dc1c726..83f5d653a54 100644 --- a/chromium/gpu/ipc/in_process_command_buffer.h +++ b/chromium/gpu/ipc/in_process_command_buffer.h @@ -281,6 +281,8 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer void Destroy(); bool DestroyOnGpuThread(); + void ReportTaskReady(base::TimeTicks task_ready); + // Flush up to put_offset. If execution is deferred either by yielding, or due // to a sync token wait, HasUnprocessedCommandsOnGpuThread() returns true. void FlushOnGpuThread(int32_t put_offset, @@ -301,9 +303,13 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer base::OnceClosure WrapClientCallback(base::OnceClosure callback); void RunTaskOnGpuThread(base::OnceClosure task); + + using ReportingCallback = + base::OnceCallback<void(base::TimeTicks task_ready)>; void ScheduleGpuTask( base::OnceClosure task, - std::vector<SyncToken> sync_token_fences = std::vector<SyncToken>()); + std::vector<SyncToken> sync_token_fences = std::vector<SyncToken>(), + ReportingCallback report_callback = ReportingCallback()); void ContinueGpuTask(base::OnceClosure task); void SignalSyncTokenOnGpuThread(const SyncToken& sync_token, @@ -425,12 +431,14 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer uint32_t flags; base::TimeTicks viz_scheduled_draw; base::TimeTicks gpu_started_draw; + base::TimeTicks gpu_task_ready; }; base::circular_deque<SwapBufferParams> pending_presented_params_; base::circular_deque<SwapBufferParams> pending_swap_completed_params_; bool should_measure_next_flush_ = false; base::TimeTicks viz_scheduled_draw_; base::TimeTicks gpu_started_draw_; + base::TimeTicks gpu_task_ready_; scoped_refptr<SharedContextState> context_state_; diff --git a/chromium/gpu/ipc/scheduler_sequence.cc b/chromium/gpu/ipc/scheduler_sequence.cc index 20ed7fd2e9a..16dbb856a81 100644 --- a/chromium/gpu/ipc/scheduler_sequence.cc +++ b/chromium/gpu/ipc/scheduler_sequence.cc @@ -64,7 +64,8 @@ bool SchedulerSequence::ShouldYield() { } void SchedulerSequence::ScheduleTask(base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) { + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback) { // If your CL is failing this DCHECK, then that means you are probably calling // ScheduleGpuTask at a point that cannot be supported by Android Webview. // Consider using ScheduleOrRetainGpuTask which will delay (not reorder) the @@ -77,14 +78,17 @@ void SchedulerSequence::ScheduleTask(base::OnceClosure task, "delay (not reorder) the task in Android Webview until the next " "DrawAndSwap."; #endif - ScheduleOrRetainTask(std::move(task), std::move(sync_token_fences)); + ScheduleOrRetainTask(std::move(task), std::move(sync_token_fences), + std::move(report_callback)); } void SchedulerSequence::ScheduleOrRetainTask( base::OnceClosure task, - std::vector<gpu::SyncToken> sync_token_fences) { + std::vector<gpu::SyncToken> sync_token_fences, + ReportingCallback report_callback) { scheduler_->ScheduleTask(Scheduler::Task(sequence_id_, std::move(task), - std::move(sync_token_fences))); + std::move(sync_token_fences), + std::move(report_callback))); } void SchedulerSequence::ContinueTask(base::OnceClosure task) { diff --git a/chromium/gpu/ipc/scheduler_sequence.h b/chromium/gpu/ipc/scheduler_sequence.h index b8f56251eb9..6745c9c1ff8 100644 --- a/chromium/gpu/ipc/scheduler_sequence.h +++ b/chromium/gpu/ipc/scheduler_sequence.h @@ -70,10 +70,14 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SchedulerSequence // SingleTaskSequence implementation. SequenceId GetSequenceId() override; bool ShouldYield() override; - void ScheduleTask(base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) override; - void ScheduleOrRetainTask(base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) override; + void ScheduleTask( + base::OnceClosure task, + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback = ReportingCallback()) override; + void ScheduleOrRetainTask( + base::OnceClosure task, + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback = ReportingCallback()) override; void ContinueTask(base::OnceClosure task) override; private: diff --git a/chromium/gpu/ipc/service/command_buffer_stub.cc b/chromium/gpu/ipc/service/command_buffer_stub.cc index 323f9a7cd41..8448fcb165b 100644 --- a/chromium/gpu/ipc/service/command_buffer_stub.cc +++ b/chromium/gpu/ipc/service/command_buffer_stub.cc @@ -502,13 +502,6 @@ void CommandBufferStub::OnAsyncFlush( CommandBuffer::State pre_state = command_buffer_->GetState(); UpdateActiveUrl(); - MailboxManager* mailbox_manager = - channel_->gpu_channel_manager()->mailbox_manager(); - if (mailbox_manager->UsesSync()) { - for (const auto& sync_token : sync_token_fences) - mailbox_manager->PullTextureUpdates(sync_token); - } - { auto* gr_shader_cache = channel_->gpu_channel_manager()->gr_shader_cache(); base::Optional<raster::GrShaderCache::ScopedCacheUse> cache_use; @@ -589,11 +582,6 @@ void CommandBufferStub::OnSignalQuery(uint32_t query_id, uint32_t id) { void CommandBufferStub::OnFenceSyncRelease(uint64_t release) { SyncToken sync_token(CommandBufferNamespace::GPU_IO, command_buffer_id_, release); - MailboxManager* mailbox_manager = - channel_->gpu_channel_manager()->mailbox_manager(); - if (mailbox_manager->UsesSync() && MakeCurrent()) - mailbox_manager->PushTextureUpdates(sync_token); - command_buffer_->SetReleaseCount(release); sync_point_client_state_->ReleaseFenceSync(release); } diff --git a/chromium/gpu/ipc/service/gles2_command_buffer_stub.cc b/chromium/gpu/ipc/service/gles2_command_buffer_stub.cc index 025815ab5d1..9d4a5828261 100644 --- a/chromium/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/chromium/gpu/ipc/service/gles2_command_buffer_stub.cc @@ -130,10 +130,6 @@ gpu::ContextResult GLES2CommandBufferStub::Initialize( use_virtualized_gl_context_ |= context_group_->feature_info()->workarounds().use_virtualized_gl_contexts; - // MailboxManagerSync synchronization correctness currently depends on having - // only a single context. See crbug.com/510243 for details. - use_virtualized_gl_context_ |= manager->mailbox_manager()->UsesSync(); - bool offscreen = (surface_handle_ == kNullSurfaceHandle); gl::GLSurface* default_surface = manager->default_offscreen_surface(); // On low-spec Android devices, the default offscreen surface is @@ -468,7 +464,6 @@ void GLES2CommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) { void GLES2CommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) { // No need to pull texture updates. - DCHECK(!context_group_->mailbox_manager()->UsesSync()); gles2_decoder_->ReturnFrontBuffer(mailbox, is_lost); } diff --git a/chromium/gpu/ipc/service/gpu_channel_manager.cc b/chromium/gpu/ipc/service/gpu_channel_manager.cc index c2a3d747ae5..90ac53b9414 100644 --- a/chromium/gpu/ipc/service/gpu_channel_manager.cc +++ b/chromium/gpu/ipc/service/gpu_channel_manager.cc @@ -5,6 +5,7 @@ #include "gpu/ipc/service/gpu_channel_manager.h" #include <algorithm> +#include <memory> #include <utility> #include "base/bind.h" @@ -44,6 +45,7 @@ #endif #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_share_group.h" +#include "ui/gl/gl_surface_egl.h" #include "ui/gl/gl_version_info.h" #include "ui/gl/init/gl_factory.h" @@ -360,8 +362,10 @@ GpuChannelManager::~GpuChannelManager() { gles2::Outputter* GpuChannelManager::outputter() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!outputter_) - outputter_.reset(new gles2::TraceOutputter("GpuChannelManager Trace")); + if (!outputter_) { + outputter_ = + std::make_unique<gles2::TraceOutputter>("GpuChannelManager Trace"); + } return outputter_.get(); } @@ -377,13 +381,13 @@ gles2::ProgramCache* GpuChannelManager::program_cache() { // Use the EGL blob cache extension for the passthrough decoder. if (gpu_preferences_.use_passthrough_cmd_decoder && gles2::PassthroughCommandDecoderSupported()) { - program_cache_.reset(new gles2::PassthroughProgramCache( - gpu_preferences_.gpu_program_cache_size, disable_disk_cache)); + program_cache_ = std::make_unique<gles2::PassthroughProgramCache>( + gpu_preferences_.gpu_program_cache_size, disable_disk_cache); } else { - program_cache_.reset(new gles2::MemoryProgramCache( + program_cache_ = std::make_unique<gles2::MemoryProgramCache>( gpu_preferences_.gpu_program_cache_size, disable_disk_cache, workarounds.disable_program_caching_for_transform_feedback, - &activity_flags_)); + &activity_flags_); } } return program_cache_.get(); @@ -655,52 +659,22 @@ void GpuChannelManager::HandleMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "TotalDuration"); - - if (program_cache_) { - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "ProgramCacheHandleMemoryPressureDuration"); + if (program_cache_) program_cache_->HandleMemoryPressure(memory_pressure_level); - } // These caches require a current context for cleanup. if (shared_context_state_ && shared_context_state_->MakeCurrent(nullptr, true /* needs_gl */)) { - { - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "DiscardableManagerHandleMemoryPressureDuration"); discardable_manager_.HandleMemoryPressure(memory_pressure_level); - } - { - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "PasshtroughDiscardableManagerHandleMemoryPressureDuration"); passthrough_discardable_manager_.HandleMemoryPressure( memory_pressure_level); - } - - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "SharedContextStatePurgeMemoryDuration"); shared_context_state_->PurgeMemory(memory_pressure_level); } - if (gr_shader_cache_) { - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "GrShaderCachePurgeMemoryDuration"); + + if (gr_shader_cache_) gr_shader_cache_->PurgeMemory(memory_pressure_level); - } #if defined(OS_WIN) - { - SCOPED_UMA_HISTOGRAM_TIMER( - "Memory.Experimental.GpuChannelManagerPressureHandlerDuration." - "TrimD3DResourcesDuration"); - TrimD3DResources(); - } + TrimD3DResources(); #endif } @@ -723,9 +697,6 @@ scoped_refptr<SharedContextState> GpuChannelManager::GetSharedContextState( #endif use_virtualized_gl_contexts |= gpu_driver_bug_workarounds_.use_virtualized_gl_contexts; - // MailboxManagerSync synchronization correctness currently depends on having - // only a single context. See crbug.com/510243 for details. - use_virtualized_gl_contexts |= mailbox_manager_->UsesSync(); const bool use_passthrough_decoder = gles2::PassthroughCommandDecoderSupported() && @@ -750,6 +721,14 @@ scoped_refptr<SharedContextState> GpuChannelManager::GetSharedContextState( gl::GLContextAttribs attribs = gles2::GenerateGLContextAttribs( ContextCreationAttribs(), use_passthrough_decoder); + // Disable robust resource initialization for raster decoder and compositor. + // TODO(crbug.com/1192632): disable robust_resource_initialization for + // SwANGLE. + if (gl::GLSurfaceEGL::GetDisplayType() != gl::ANGLE_SWIFTSHADER && + features::IsUsingSkiaRenderer()) { + attribs.robust_resource_initialization = false; + } + // Only skip validation if the GLContext will be used exclusively by the // SharedContextState and dcheck is off. #if DCHECK_IS_ON() diff --git a/chromium/gpu/ipc/service/gpu_channel_test_common.cc b/chromium/gpu/ipc/service/gpu_channel_test_common.cc index c2822672d90..7364038f7a0 100644 --- a/chromium/gpu/ipc/service/gpu_channel_test_common.cc +++ b/chromium/gpu/ipc/service/gpu_channel_test_common.cc @@ -4,6 +4,8 @@ #include "gpu/ipc/service/gpu_channel_test_common.h" +#include <memory> + #include "base/memory/unsafe_shared_memory_region.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -88,14 +90,14 @@ GpuChannelTestCommon::GpuChannelTestCommon( feature_info.enabled_gpu_driver_bug_workarounds = std::move(enabled_workarounds); - channel_manager_.reset(new GpuChannelManager( + channel_manager_ = std::make_unique<GpuChannelManager>( GpuPreferences(), channel_manager_delegate_.get(), nullptr, /* watchdog */ task_runner_.get(), io_task_runner_.get(), scheduler_.get(), sync_point_manager_.get(), shared_image_manager_.get(), nullptr, /* gpu_memory_buffer_factory */ std::move(feature_info), GpuProcessActivityFlags(), gl::init::CreateOffscreenGLSurface(gfx::Size()), - nullptr /* image_decode_accelerator_worker */)); + nullptr /* image_decode_accelerator_worker */); } GpuChannelTestCommon::~GpuChannelTestCommon() { diff --git a/chromium/gpu/ipc/service/gpu_init.cc b/chromium/gpu/ipc/service/gpu_init.cc index a82fc34973b..ac8fe31cf17 100644 --- a/chromium/gpu/ipc/service/gpu_init.cc +++ b/chromium/gpu/ipc/service/gpu_init.cc @@ -99,6 +99,16 @@ void InitializePlatformOverlaySettings(GPUInfo* gpu_info, if (gpu_feature_info.IsWorkaroundEnabled(gpu::FORCE_NV12_OVERLAY_SUPPORT)) { gl::DirectCompositionSurfaceWin::ForceNV12OverlaySupport(); } + if (gpu_feature_info.IsWorkaroundEnabled( + gpu::FORCE_RGB10A2_OVERLAY_SUPPORT_FLAGS)) { + gl::DirectCompositionSurfaceWin::ForceRgb10a2OverlaySupport(); + } + if (gpu_feature_info.IsWorkaroundEnabled( + gpu::CHECK_YCBCR_STUDIO_G22_LEFT_P709_FOR_NV12_SUPPORT)) { + gl::DirectCompositionSurfaceWin:: + SetCheckYCbCrStudioG22LeftP709ForNv12Support(); + } + DCHECK(gpu_info); CollectHardwareOverlayInfo(&gpu_info->overlay_info); #elif defined(OS_ANDROID) @@ -320,6 +330,10 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, params.single_process = false; params.enable_native_gpu_memory_buffers = gpu_preferences.enable_native_gpu_memory_buffers; + + // Page flip testing will only happen in ash-chrome, not in lacros-chrome. + // Therefore, we only allow or disallow sync and real buffer page flip + // testing for ash-chrome. #if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) params.allow_sync_and_real_buffer_page_flip_testing = @@ -426,7 +440,7 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, LOG_IF(ERROR, !gpu_info_.passthrough_cmd_decoder) #endif << "Passthrough is not supported, GL is " - << gl::GetGLImplementationName(gl::GetGLImplementation()); + << gl::GetGLImplementationGLName(gl::GetGLImplementationParts()); } else { gpu_info_.passthrough_cmd_decoder = false; } @@ -582,7 +596,7 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, } } if (gl_use_swiftshader_ || - gl::GetGLImplementation() == gl::GetSoftwareGLImplementation()) { + gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts())) { gpu_info_.software_rendering = true; watchdog_thread_ = nullptr; watchdog_init.SetGpuWatchdogPtr(nullptr); @@ -661,6 +675,10 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line, if (features::IsUsingOzonePlatform()) { ui::OzonePlatform::InitParams params; params.single_process = true; + + // Page flip testing will only happen in ash-chrome, not in lacros-chrome. + // Therefore, we only allow or disallow sync and real buffer page flip + // testing for ash-chrome. #if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) params.allow_sync_and_real_buffer_page_flip_testing = diff --git a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc index a70371408bf..a5802db7e38 100644 --- a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc +++ b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc @@ -3,81 +3,17 @@ // found in the LICENSE file. #include "gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h" + #include <vector> + #include "base/memory/unsafe_shared_memory_region.h" #include "base/trace_event/trace_event.h" +#include "gpu/ipc/common/dxgi_helpers.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gl/gl_angle_util_win.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image_dxgi.h" -namespace { - -class ScopedTextureUnmap { - public: - ScopedTextureUnmap(Microsoft::WRL::ComPtr<ID3D11DeviceContext> context, - Microsoft::WRL::ComPtr<ID3D11Texture2D> texture) - : context_(context), texture_(texture) {} - - ScopedTextureUnmap(const ScopedTextureUnmap&) = delete; - - ScopedTextureUnmap& operator=(const ScopedTextureUnmap&) = delete; - - ~ScopedTextureUnmap() { context_->Unmap(texture_.Get(), 0); } - - private: - Microsoft::WRL::ComPtr<ID3D11DeviceContext> context_; - Microsoft::WRL::ComPtr<ID3D11Texture2D> texture_; -}; - -class ScopedReleaseKeyedMutex { - public: - ScopedReleaseKeyedMutex(Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex, - UINT64 key) - : keyed_mutex_(keyed_mutex), key_(key) { - DCHECK(keyed_mutex); - } - - ScopedReleaseKeyedMutex(const ScopedReleaseKeyedMutex&) = delete; - - ScopedReleaseKeyedMutex& operator=(const ScopedReleaseKeyedMutex&) = delete; - - ~ScopedReleaseKeyedMutex() { - HRESULT hr = keyed_mutex_->ReleaseSync(key_); - DCHECK(SUCCEEDED(hr)); - } - - private: - Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex_; - UINT64 key_ = 0; -}; - -Microsoft::WRL::ComPtr<ID3D11Texture2D> CreateStagingTexture( - ID3D11Device* d3d11_device, - D3D11_TEXTURE2D_DESC input_desc) { - D3D11_TEXTURE2D_DESC staging_desc = {}; - staging_desc.Width = input_desc.Width; - staging_desc.Height = input_desc.Height; - staging_desc.Format = input_desc.Format; - staging_desc.MipLevels = 1; - staging_desc.ArraySize = 1; - staging_desc.SampleDesc.Count = 1; - staging_desc.Usage = D3D11_USAGE_STAGING; - staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - - Microsoft::WRL::ComPtr<ID3D11Texture2D> staging_texture; - HRESULT hr = - d3d11_device->CreateTexture2D(&staging_desc, nullptr, &staging_texture); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to create staging texture. hr=" << std::hex << hr; - return nullptr; - } - - return staging_texture; -} - -} // namespace - namespace gpu { GpuMemoryBufferFactoryDXGI::GpuMemoryBufferFactoryDXGI() {} @@ -171,103 +107,9 @@ bool GpuMemoryBufferFactoryDXGI::FillSharedMemoryRegionWithBufferContents( if (!d3d11_device) return false; - Microsoft::WRL::ComPtr<ID3D11Device1> device1; - HRESULT hr = d3d11_device.As(&device1); - CHECK(SUCCEEDED(hr)); - - Microsoft::WRL::ComPtr<ID3D11Texture2D> texture; - - // Open texture on device using shared handle - hr = device1->OpenSharedResource1(buffer_handle.dxgi_handle.Get(), - IID_PPV_ARGS(&texture)); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to open shared texture. hr=" << std::hex << hr; - return false; - } - - // If texture isn't accessible for CPU reads, create a staging texture - D3D11_TEXTURE2D_DESC texture_desc = {}; - texture->GetDesc(&texture_desc); - - if (texture_desc.Format != DXGI_FORMAT_NV12) { - DLOG(ERROR) << "Can't copy non-NV12 texture. format=" - << static_cast<int>(texture_desc.Format); - return false; - } - - bool create_staging_texture = !staging_texture_; - if (staging_texture_) { - D3D11_TEXTURE2D_DESC staging_texture_desc; - staging_texture_->GetDesc(&staging_texture_desc); - create_staging_texture = - (staging_texture_desc.Width != texture_desc.Width || - staging_texture_desc.Height != texture_desc.Height || - staging_texture_desc.Format != texture_desc.Format); - } - if (create_staging_texture) { - staging_texture_ = CreateStagingTexture(d3d11_device.Get(), texture_desc); - if (!staging_texture_) - return false; - } - - Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context; - d3d11_device->GetImmediateContext(&device_context); - - Microsoft::WRL::ComPtr<IDXGIKeyedMutex> keyed_mutex; - texture.As(&keyed_mutex); - - // A keyed mutex will only exist for shared textures - base::Optional<ScopedReleaseKeyedMutex> release_keyed_mutex; - if (keyed_mutex) { - const int kAcquireKeyedMutexTimeout = 1000; - // Key equal to 0 is also used by the producer. Therefore, this keyed mutex - // acts purely as a regular mutex. - // TODO: Add a constant for the key value and use it both here and at the - // producer. - hr = keyed_mutex->AcquireSync(0, kAcquireKeyedMutexTimeout); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to acquire keyed mutex. hr=" << std::hex << hr; - return false; - } - release_keyed_mutex.emplace(keyed_mutex, 0); - } - - device_context->CopySubresourceRegion(staging_texture_.Get(), 0, 0, 0, 0, - texture.Get(), 0, nullptr); - - D3D11_MAPPED_SUBRESOURCE mapped_resource = {}; - hr = device_context->Map(staging_texture_.Get(), 0, D3D11_MAP_READ, 0, - &mapped_resource); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to map texture for read. hr=" << std::hex << hr; - return false; - } - ScopedTextureUnmap scoped_unmap(device_context, staging_texture_); - - // Copy mapped texture to shared memory region for client - size_t buffer_size = texture_desc.Height * texture_desc.Width * 3 / 2; - if (shared_memory.GetSize() < buffer_size) - return false; - - base::WritableSharedMemoryMapping mapping = shared_memory.Map(); - const uint8_t* source_buffer = - reinterpret_cast<uint8_t*>(mapped_resource.pData); - uint8_t* dest_buffer = reinterpret_cast<uint8_t*>(mapping.memory()); - - // Direct copy if rows don't have extra padding - if (texture_desc.Width == mapped_resource.RowPitch) { - std::copy(source_buffer, source_buffer + buffer_size, dest_buffer); - } else { - const uint32_t source_stride = mapped_resource.RowPitch; - const uint32_t dest_stride = texture_desc.Width; - for (size_t i = 0; i < texture_desc.Height * 3 / 2; i++) { - std::copy(source_buffer, source_buffer + dest_stride, dest_buffer); - source_buffer += source_stride; - dest_buffer += dest_stride; - } - } - - return true; + return CopyDXGIBufferToShMem(buffer_handle.dxgi_handle.Get(), + std::move(shared_memory), d3d11_device.Get(), + &staging_texture_); } ImageFactory* GpuMemoryBufferFactoryDXGI::AsImageFactory() { diff --git a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc index 8af3ce42507..eb099a02b60 100644 --- a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc +++ b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc @@ -12,7 +12,9 @@ namespace { // On Fuchsia NativePixmap depends on Vulkan, which is not initialized in tests. // See crbug.com/957700 -#if !defined(OS_FUCHSIA) +#if defined(OS_FUCHSIA) +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GpuMemoryBufferFactoryTest); +#else INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryNativePixmap, GpuMemoryBufferFactoryTest, GpuMemoryBufferFactoryNativePixmap); diff --git a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h index 9c1fce9b325..eaa521b2b5d 100644 --- a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h +++ b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h @@ -72,6 +72,7 @@ TYPED_TEST_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer) { gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::BufferUsage::SCANOUT_VEA_CPU_READ, gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_FRONT_RENDERING, }; for (auto usage : usages) { #if defined(USE_X11) diff --git a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc index 5c059d06b2a..ff971e478f3 100644 --- a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc +++ b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc @@ -94,7 +94,7 @@ GpuWatchdogThread::~GpuWatchdogThread() { Stop(); // stop the watchdog thread base::CurrentThread::Get()->RemoveTaskObserver(this); - base::PowerMonitor::RemoveObserver(this); + base::PowerMonitor::RemovePowerSuspendObserver(this); GpuWatchdogHistogram(GpuWatchdogThreadEvent::kGpuWatchdogEnd); #if defined(OS_WIN) if (watched_thread_handle_) @@ -285,7 +285,7 @@ void GpuWatchdogThread::OnAddPowerObserver() { DCHECK(watchdog_thread_task_runner_->BelongsToCurrentThread()); DCHECK(base::PowerMonitor::IsInitialized()); - base::PowerMonitor::AddObserver(this); + base::PowerMonitor::AddPowerSuspendObserver(this); is_power_observer_added_ = true; } diff --git a/chromium/gpu/ipc/service/gpu_watchdog_thread.h b/chromium/gpu/ipc/service/gpu_watchdog_thread.h index f0dbe28edcb..ad714a7b9d8 100644 --- a/chromium/gpu/ipc/service/gpu_watchdog_thread.h +++ b/chromium/gpu/ipc/service/gpu_watchdog_thread.h @@ -76,10 +76,11 @@ constexpr int kMaxExtraCyclesBeforeKill = 0; // A thread that intermitently sends tasks to a group of watched message loops // and deliberately crashes if one of them does not respond after a timeout. -class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread : public base::Thread, - public base::PowerObserver, - public base::TaskObserver, - public gl::ProgressReporter { +class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread + : public base::Thread, + public base::PowerSuspendObserver, + public base::TaskObserver, + public gl::ProgressReporter { public: static std::unique_ptr<GpuWatchdogThread> Create(bool start_backgrounded); @@ -135,7 +136,7 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread : public base::Thread, bool was_blocked_or_low_priority) override; void DidProcessTask(const base::PendingTask& pending_task) override; - // Implements base::PowerObserver. + // Implements base::PowerSuspendObserver. void OnSuspend() override; void OnResume() override; diff --git a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm index cd73f9e5669..957b3d4028b 100644 --- a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm +++ b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm @@ -4,6 +4,7 @@ #include "gpu/ipc/service/image_transport_surface_overlay_mac.h" +#include <memory> #include <sstream> #include "base/bind.h" @@ -49,8 +50,8 @@ ImageTransportSurfaceOverlayMacBase<BaseClass>:: ->workarounds() .disable_av_sample_buffer_display_layer; - ca_layer_tree_coordinator_.reset(new ui::CALayerTreeCoordinator( - use_remote_layer_api_, allow_av_sample_buffer_display_layer)); + ca_layer_tree_coordinator_ = std::make_unique<ui::CALayerTreeCoordinator>( + use_remote_layer_api_, allow_av_sample_buffer_display_layer); // Create the CAContext to send this to the GPU process, and the layer for // the context. diff --git a/chromium/gpu/ipc/service/shared_image_stub.cc b/chromium/gpu/ipc/service/shared_image_stub.cc index 5cfe3135f89..91ba6f01157 100644 --- a/chromium/gpu/ipc/service/shared_image_stub.cc +++ b/chromium/gpu/ipc/service/shared_image_stub.cc @@ -206,8 +206,6 @@ void SharedImageStub::OnCreateSharedImage( SyncToken sync_token(sync_point_client_state_->namespace_id(), sync_point_client_state_->command_buffer_id(), params.release_id); - auto* mailbox_manager = channel_->gpu_channel_manager()->mailbox_manager(); - mailbox_manager->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(params.release_id); } @@ -265,8 +263,6 @@ void SharedImageStub::OnCreateSharedImageWithData( SyncToken sync_token(sync_point_client_state_->namespace_id(), sync_point_client_state_->command_buffer_id(), params.release_id); - auto* mailbox_manager = channel_->gpu_channel_manager()->mailbox_manager(); - mailbox_manager->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(params.release_id); } @@ -286,8 +282,6 @@ void SharedImageStub::OnCreateGMBSharedImage( SyncToken sync_token(sync_point_client_state_->namespace_id(), sync_point_client_state_->command_buffer_id(), params.release_id); - auto* mailbox_manager = channel_->gpu_channel_manager()->mailbox_manager(); - mailbox_manager->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(params.release_id); } @@ -302,8 +296,6 @@ void SharedImageStub::OnUpdateSharedImage(const Mailbox& mailbox, SyncToken sync_token(sync_point_client_state_->namespace_id(), sync_point_client_state_->command_buffer_id(), release_id); - auto* mailbox_manager = channel_->gpu_channel_manager()->mailbox_manager(); - mailbox_manager->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(release_id); } @@ -320,8 +312,6 @@ void SharedImageStub::OnCreateSharedImageWithAHB(const Mailbox& out_mailbox, SyncToken sync_token(sync_point_client_state_->namespace_id(), sync_point_client_state_->command_buffer_id(), release_id); - auto* mailbox_manager = channel_->gpu_channel_manager()->mailbox_manager(); - mailbox_manager->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(release_id); } #endif diff --git a/chromium/gpu/ipc/shared_image_interface_in_process.cc b/chromium/gpu/ipc/shared_image_interface_in_process.cc index 54f97772018..04b96e99968 100644 --- a/chromium/gpu/ipc/shared_image_interface_in_process.cc +++ b/chromium/gpu/ipc/shared_image_interface_in_process.cc @@ -173,7 +173,6 @@ void SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread( command_buffer_helper_->SetError(); return; } - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } @@ -228,7 +227,6 @@ void SharedImageInterfaceInProcess::CreateSharedImageWithDataOnGpuThread( command_buffer_helper_->SetError(); return; } - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } @@ -301,7 +299,6 @@ void SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread( command_buffer_helper_->SetError(); return; } - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } @@ -343,7 +340,6 @@ void SharedImageInterfaceInProcess::CreateSharedImageWithAHBOnGpuThread( command_buffer_helper_->SetError(); return; } - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } #endif @@ -418,7 +414,6 @@ void SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread( command_buffer_helper_->SetError(); return; } - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } @@ -453,7 +448,6 @@ void SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread( if (!MakeContextCurrent()) return; - mailbox_manager_->PushTextureUpdates(sync_token); sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); } diff --git a/chromium/gpu/ipc/shared_image_interface_in_process.h b/chromium/gpu/ipc/shared_image_interface_in_process.h index 8d74513f041..0a2246fcfde 100644 --- a/chromium/gpu/ipc/shared_image_interface_in_process.h +++ b/chromium/gpu/ipc/shared_image_interface_in_process.h @@ -227,7 +227,6 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SharedImageInterfaceInProcess SharedImageManager* shared_image_manager_; // Accessed on GPU thread. - // TODO(weiliangc): Check whether can be removed when !UsesSync(). MailboxManager* mailbox_manager_; // Used to check if context is lost at destruction time. // TODO(weiliangc): SharedImageInterface should become active observer of diff --git a/chromium/gpu/ipc/single_task_sequence.h b/chromium/gpu/ipc/single_task_sequence.h index 61db1a2dff6..1026939cd94 100644 --- a/chromium/gpu/ipc/single_task_sequence.h +++ b/chromium/gpu/ipc/single_task_sequence.h @@ -30,14 +30,21 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SingleTaskSequence { // Returns true if sequence should yield while running its current task. virtual bool ShouldYield() = 0; + // A callback to measure when a given task was ready to be scheduled. + using ReportingCallback = + base::OnceCallback<void(base::TimeTicks task_ready)>; + // Schedule a task with provided sync token dependencies. The dependencies // are hints for sync token waits within the task, and can be ignored by the // implementation. // For scheduling from viz thread, due to limitations in Android WebView, // ScheduleTask is only available to be called inside initialization, // teardown, and DrawAndSwap. - virtual void ScheduleTask(base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) = 0; + // |report_callback| will be called on the same thread and before |task| runs. + virtual void ScheduleTask( + base::OnceClosure task, + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback = ReportingCallback()) = 0; // If |ScheduleGpuTask| is available, then this is equivalent to // ScheduleGpuTask. Otherwise, the |task| and |sync_tokens| are retained @@ -45,9 +52,11 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SingleTaskSequence { // |ScheduleTask| and |ScheduleOrRetainTask| are sequenced by the call order; // calling this instead of |ScheduleTask| can only delay but not reorder // tasks. + // |report_callback| will be called on the same thread and before |task| runs. virtual void ScheduleOrRetainTask( base::OnceClosure task, - std::vector<SyncToken> sync_token_fences) = 0; + std::vector<SyncToken> sync_token_fences, + ReportingCallback report_callback = ReportingCallback()) = 0; // Continue running the current task after yielding execution. virtual void ContinueTask(base::OnceClosure task) = 0; diff --git a/chromium/gpu/vulkan/demo/main.cc b/chromium/gpu/vulkan/demo/main.cc index 3aeb5583979..ad3832d9180 100644 --- a/chromium/gpu/vulkan/demo/main.cc +++ b/chromium/gpu/vulkan/demo/main.cc @@ -7,6 +7,7 @@ #include "base/at_exit.h" #include "base/command_line.h" #include "base/debug/stack_trace.h" +#include "base/logging.h" #include "base/message_loop/message_pump_type.h" #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool/thread_pool_instance.h" diff --git a/chromium/gpu/vulkan/demo/vulkan_demo.cc b/chromium/gpu/vulkan/demo/vulkan_demo.cc index 2ebd3807382..b4c0fb9c987 100644 --- a/chromium/gpu/vulkan/demo/vulkan_demo.cc +++ b/chromium/gpu/vulkan/demo/vulkan_demo.cc @@ -76,11 +76,11 @@ void VulkanDemo::Run() { run_loop_ = nullptr; } -void VulkanDemo::OnBoundsChanged(const gfx::Rect& new_bounds) { - if (vulkan_surface_->image_size() == new_bounds.size()) +void VulkanDemo::OnBoundsChanged(const BoundsChange& change) { + if (vulkan_surface_->image_size() == change.bounds.size()) return; auto generation = vulkan_surface_->swap_chain_generation(); - vulkan_surface_->Reshape(new_bounds.size(), gfx::OVERLAY_TRANSFORM_NONE); + vulkan_surface_->Reshape(change.bounds.size(), gfx::OVERLAY_TRANSFORM_NONE); if (vulkan_surface_->swap_chain_generation() != generation) { // Size has been changed, we need to clear all surfaces which will be // recreated later. diff --git a/chromium/gpu/vulkan/demo/vulkan_demo.h b/chromium/gpu/vulkan/demo/vulkan_demo.h index 84473fac91c..7d83039ac57 100644 --- a/chromium/gpu/vulkan/demo/vulkan_demo.h +++ b/chromium/gpu/vulkan/demo/vulkan_demo.h @@ -46,7 +46,7 @@ class VulkanDemo : public ui::PlatformWindowDelegate { private: // ui::PlatformWindowDelegate: - void OnBoundsChanged(const gfx::Rect& new_bounds) override; + void OnBoundsChanged(const BoundsChange& change) override; void OnDamageRect(const gfx::Rect& damaged_region) override {} void DispatchEvent(ui::Event* event) override {} void OnCloseRequest() override; diff --git a/chromium/gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h b/chromium/gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h index b5c7d82d30f..47bb657671e 100644 --- a/chromium/gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h +++ b/chromium/gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h @@ -54,6 +54,9 @@ const VkExternalSemaphoreHandleTypeFlagBits const VkObjectType VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = static_cast<VkObjectType>(1001004002); +// TODO(crbug.com/1191605): Remove definitions below after updating +// vulkan headers to a version that includes this extension. +#ifndef VK_FUCHSIA_external_memory #define VK_FUCHSIA_external_memory 1 #define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1 #define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory" @@ -100,7 +103,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( zx_handle_t ZirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); #endif +#endif +// TODO(crbug.com/1191605): Remove definitions below after updating +// vulkan headers to a version that includes this extension. +#ifndef VK_FUCHSIA_external_semaphore #define VK_FUCHSIA_external_semaphore 1 #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME \ @@ -112,7 +119,7 @@ typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA { VkSemaphore semaphore; VkSemaphoreImportFlags flags; VkExternalSemaphoreHandleTypeFlagBits handleType; - zx_handle_t handle; + zx_handle_t zirconHandle; } VkImportSemaphoreZirconHandleInfoFUCHSIA; typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA { @@ -142,6 +149,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA( const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); #endif +#endif #define VK_FUCHSIA_buffer_collection 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA) diff --git a/chromium/gpu/vulkan/generate_bindings.py b/chromium/gpu/vulkan/generate_bindings.py index 71e67a00e6d..f6d1c901c83 100755 --- a/chromium/gpu/vulkan/generate_bindings.py +++ b/chromium/gpu/vulkan/generate_bindings.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""code generator for Vulkan function pointers.""" +"""Code generator for Vulkan function pointers.""" import filecmp import optparse diff --git a/chromium/gpu/vulkan/vulkan_device_queue.cc b/chromium/gpu/vulkan/vulkan_device_queue.cc index 5d172abe685..f095cb6eaaa 100644 --- a/chromium/gpu/vulkan/vulkan_device_queue.cc +++ b/chromium/gpu/vulkan/vulkan_device_queue.cc @@ -188,8 +188,23 @@ bool VulkanDeviceQueue::Initialize( crash_keys::vulkan_device_api_version.Set( VkVersionToString(vk_physical_device_properties_.apiVersion)); - crash_keys::vulkan_device_driver_version.Set(base::StringPrintf( - "0x%08x", vk_physical_device_properties_.driverVersion)); + if (vk_physical_device_properties_.vendorID == 0x10DE) { + // NVIDIA + // 10 bits = major version (up to r1023) + // 8 bits = minor version (up to 255) + // 8 bits = secondary branch version/build version (up to 255) + // 6 bits = tertiary branch/build version (up to 63) + auto version = vk_physical_device_properties_.driverVersion; + uint32_t major = (version >> 22) & 0x3ff; + uint32_t minor = (version >> 14) & 0x0ff; + uint32_t secondary_branch = (version >> 6) & 0x0ff; + uint32_t tertiary_branch = version & 0x003f; + crash_keys::vulkan_device_driver_version.Set(base::StringPrintf( + "%d.%d.%d.%d", major, minor, secondary_branch, tertiary_branch)); + } else { + crash_keys::vulkan_device_driver_version.Set( + VkVersionToString(vk_physical_device_properties_.driverVersion)); + } crash_keys::vulkan_device_vendor_id.Set( base::StringPrintf("0x%04x", vk_physical_device_properties_.vendorID)); crash_keys::vulkan_device_id.Set( diff --git a/chromium/gpu/vulkan/vulkan_function_pointers.h b/chromium/gpu/vulkan/vulkan_function_pointers.h index 1ec6898e827..8f072570900 100644 --- a/chromium/gpu/vulkan/vulkan_function_pointers.h +++ b/chromium/gpu/vulkan/vulkan_function_pointers.h @@ -1066,15 +1066,30 @@ ALWAYS_INLINE VkResult vkGetMemoryWin32HandlePropertiesKHR( #endif // defined(OS_WIN) #if defined(OS_FUCHSIA) -#define vkImportSemaphoreZirconHandleFUCHSIA \ - gpu::GetVulkanFunctionPointers()->vkImportSemaphoreZirconHandleFUCHSIA -#define vkGetSemaphoreZirconHandleFUCHSIA \ - gpu::GetVulkanFunctionPointers()->vkGetSemaphoreZirconHandleFUCHSIA +ALWAYS_INLINE VkResult vkImportSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkImportSemaphoreZirconHandleInfoFUCHSIA* + pImportSemaphoreZirconHandleInfo) { + return gpu::GetVulkanFunctionPointers()->vkImportSemaphoreZirconHandleFUCHSIA( + device, pImportSemaphoreZirconHandleInfo); +} +ALWAYS_INLINE VkResult vkGetSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle) { + return gpu::GetVulkanFunctionPointers()->vkGetSemaphoreZirconHandleFUCHSIA( + device, pGetZirconHandleInfo, pZirconHandle); +} #endif // defined(OS_FUCHSIA) #if defined(OS_FUCHSIA) -#define vkGetMemoryZirconHandleFUCHSIA \ - gpu::GetVulkanFunctionPointers()->vkGetMemoryZirconHandleFUCHSIA +ALWAYS_INLINE VkResult vkGetMemoryZirconHandleFUCHSIA( + VkDevice device, + const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle) { + return gpu::GetVulkanFunctionPointers()->vkGetMemoryZirconHandleFUCHSIA( + device, pGetZirconHandleInfo, pZirconHandle); +} #endif // defined(OS_FUCHSIA) #if defined(OS_FUCHSIA) diff --git a/chromium/gpu/vulkan/vulkan_image_android.cc b/chromium/gpu/vulkan/vulkan_image_android.cc index 2939879a34c..9748cb327d0 100644 --- a/chromium/gpu/vulkan/vulkan_image_android.cc +++ b/chromium/gpu/vulkan/vulkan_image_android.cc @@ -5,6 +5,7 @@ #include "gpu/vulkan/vulkan_image.h" #include "base/android/android_hardware_buffer_compat.h" +#include "base/debug/crash_logging.h" #include "base/logging.h" #include "gpu/vulkan/vulkan_device_queue.h" #include "gpu/vulkan/vulkan_function_pointers.h" @@ -24,6 +25,8 @@ bool VulkanImage::InitializeFromGpuMemoryBufferHandle( return false; } DCHECK(gmb_handle.android_hardware_buffer.is_valid()); + SCOPED_CRASH_KEY_BOOL("vulkan", "gmb_buffer.is_valid", + gmb_handle.android_hardware_buffer.is_valid()); auto& ahb_handle = gmb_handle.android_hardware_buffer; // To obtain format properties of an Android hardware buffer, include an diff --git a/chromium/gpu/vulkan/vulkan_swap_chain.cc b/chromium/gpu/vulkan/vulkan_swap_chain.cc index cd1de474c48..68ed4cf8f40 100644 --- a/chromium/gpu/vulkan/vulkan_swap_chain.cc +++ b/chromium/gpu/vulkan/vulkan_swap_chain.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" +#include "base/debug/crash_logging.h" #include "base/logging.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -503,6 +504,12 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() { FenceAndSemaphores fence_and_semaphores; do { #if !defined(OS_FUCHSIA) + // This crash key is for diagnosing OOM crash. + // TODO(penghuang): remove it when OOM crash is fixed, or find out it is not + // related. + SCOPED_CRASH_KEY_NUMBER("VulkanSwapChian", "queue_.size()", + fence_and_semaphores_queue_.size()); + if (LIKELY(!fence_and_semaphores_queue_.empty())) { fence_and_semaphores = fence_and_semaphores_queue_.front(); auto result = vkGetFenceStatus(device, fence_and_semaphores.fence); diff --git a/chromium/gpu/vulkan/vulkan_util.cc b/chromium/gpu/vulkan/vulkan_util.cc index 9f6c9d73cf4..9e6f19e982f 100644 --- a/chromium/gpu/vulkan/vulkan_util.cc +++ b/chromium/gpu/vulkan/vulkan_util.cc @@ -16,10 +16,33 @@ #include "gpu/config/vulkan_info.h" #include "gpu/vulkan/vulkan_function_pointers.h" +#if defined(OS_ANDROID) +#include "base/android/build_info.h" +#endif + namespace gpu { namespace { uint64_t g_submit_count = 0u; uint64_t g_import_semaphore_into_gl_count = 0u; + +#if defined(OS_ANDROID) +int GetEMUIVersion() { + const auto* build_info = base::android::BuildInfo::GetInstance(); + base::StringPiece manufacturer(build_info->manufacturer()); + + // TODO(crbug.com/1096222): check Honor devices as well. + if (manufacturer != "HUAWEI") + return -1; + + // Huawei puts EMUI version in the build version incremental. + // Example: 11.0.0.130C00 + int version = 0; + if (sscanf(build_info->version_incremental(), "%d.", &version) != 1) + return -1; + + return version; +} +#endif } bool SubmitSignalVkSemaphores(VkQueue vk_queue, @@ -189,10 +212,13 @@ bool CheckVulkanCompabilities(const VulkanInfo& vulkan_info, } if (device_info.properties.vendorID == kVendorARM) { - // https://crbug.com/1096222: Display problem with Huawei and Honor devices - // with Mali GPU. The Mali driver version is < 19.0.0. - if (device_info.properties.driverVersion < VK_MAKE_VERSION(19, 0, 0)) + int emui_version = GetEMUIVersion(); + // TODO(crbug.com/1096222) Display problem with Huawei EMUI < 11 and Honor + // devices with Mali GPU. The Mali driver version is < 19.0.0. + if (device_info.properties.driverVersion < VK_MAKE_VERSION(19, 0, 0) && + emui_version < 11) { return false; + } // Remove "Mali-" prefix. base::StringPiece device_name(device_info.properties.deviceName); |