From 0dfb4b3339bd94b919f51cf5b1ab35197476bfc4 Mon Sep 17 00:00:00 2001 From: ccameron Date: Mon, 11 Jan 2016 15:41:37 -0800 Subject: GpuMemoryBuffers: Add an IsInUse function Add a function GpuMemoryBuffer::IsInUseByWindowServer to see if a resource is currently in use by the system. This will only return true on Mac, where it returns the result of IOSurfaceIsInUse. Hook this up to cc::ResourceProvider::CanLockForWrite and InUseByConsumer. These fix the bug where tiles would flicker during reuse. BUG=558701 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1527483003 Cr-Commit-Position: refs/heads/master@{#368718} --- cc/resources/resource_provider.cc | 8 ++++++-- cc/resources/resource_provider_unittest.cc | 27 +++++++++++++++++++++++++++ cc/test/test_gpu_memory_buffer_manager.cc | 18 +++++++++++++++++- cc/test/test_gpu_memory_buffer_manager.h | 4 ++++ 4 files changed, 54 insertions(+), 3 deletions(-) (limited to 'cc') diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 3637422..6ef8d59 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -375,7 +375,9 @@ ResourceProvider::~ResourceProvider() { bool ResourceProvider::InUseByConsumer(ResourceId id) { Resource* resource = GetResource(id); return resource->lock_for_read_count > 0 || resource->exported_count > 0 || - resource->lost; + resource->lost || + (resource->gpu_memory_buffer && + resource->gpu_memory_buffer->IsInUseByMacOSWindowServer()); } bool ResourceProvider::IsLost(ResourceId id) { @@ -774,7 +776,9 @@ bool ResourceProvider::CanLockForWrite(ResourceId id) { Resource* resource = GetResource(id); return !resource->locked_for_write && !resource->lock_for_read_count && !resource->exported_count && resource->origin == Resource::INTERNAL && - !resource->lost && ReadLockFenceHasPassed(resource); + !resource->lost && ReadLockFenceHasPassed(resource) && + !(resource->gpu_memory_buffer && + resource->gpu_memory_buffer->IsInUseByMacOSWindowServer()); } bool ResourceProvider::IsOverlayCandidate(ResourceId id) { diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 1a0e685..23a9211 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -3607,5 +3607,32 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) { } } +TEST_P(ResourceProviderTest, GpuMemoryBufferInUse) { + if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) + return; + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + size_t pixel_size = TextureSizeBytes(size, format); + ASSERT_EQ(4U, pixel_size); + + ResourceId id = resource_provider_->CreateResource( + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + + gfx::GpuMemoryBuffer* gpu_memory_buffer = nullptr; + { + ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock( + resource_provider_.get(), id); + gpu_memory_buffer = lock.GetGpuMemoryBuffer(); + EXPECT_TRUE(lock.GetGpuMemoryBuffer()); + } + EXPECT_TRUE(resource_provider_->CanLockForWrite(id)); + EXPECT_FALSE(resource_provider_->InUseByConsumer(id)); + gpu_memory_buffer_manager_->SetGpuMemoryBufferIsInUseByMacOSWindowServer( + gpu_memory_buffer, true); + EXPECT_FALSE(resource_provider_->CanLockForWrite(id)); + EXPECT_TRUE(resource_provider_->InUseByConsumer(id)); +} + } // namespace } // namespace cc diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc index e1e6e89..a540e32 100644 --- a/cc/test/test_gpu_memory_buffer_manager.cc +++ b/cc/test/test_gpu_memory_buffer_manager.cc @@ -27,7 +27,8 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { shared_memory_(std::move(shared_memory)), offset_(offset), stride_(stride), - mapped_(false) {} + mapped_(false), + is_in_use_by_window_server_(false) {} // Overridden from gfx::GpuMemoryBuffer: bool Map() override { @@ -50,6 +51,9 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { shared_memory_->Unmap(); mapped_ = false; } + bool IsInUseByMacOSWindowServer() const override { + return is_in_use_by_window_server_; + } gfx::Size GetSize() const override { return size_; } gfx::BufferFormat GetFormat() const override { return format_; } int stride(size_t plane) const override { @@ -73,6 +77,10 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { return reinterpret_cast(this); } + void SetIsInUseByMacOSWindowServer(bool value) { + is_in_use_by_window_server_ = value; + } + private: const gfx::Size size_; gfx::BufferFormat format_; @@ -80,6 +88,7 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { size_t offset_; size_t stride_; bool mapped_; + bool is_in_use_by_window_server_; }; } // namespace @@ -90,6 +99,13 @@ TestGpuMemoryBufferManager::TestGpuMemoryBufferManager() { TestGpuMemoryBufferManager::~TestGpuMemoryBufferManager() { } +void TestGpuMemoryBufferManager::SetGpuMemoryBufferIsInUseByMacOSWindowServer( + gfx::GpuMemoryBuffer* gpu_memory_buffer, + bool in_use) { + static_cast(gpu_memory_buffer) + ->SetIsInUseByMacOSWindowServer(in_use); +} + scoped_ptr TestGpuMemoryBufferManager::AllocateGpuMemoryBuffer(const gfx::Size& size, gfx::BufferFormat format, diff --git a/cc/test/test_gpu_memory_buffer_manager.h b/cc/test/test_gpu_memory_buffer_manager.h index fcaaa32..5c693cb 100644 --- a/cc/test/test_gpu_memory_buffer_manager.h +++ b/cc/test/test_gpu_memory_buffer_manager.h @@ -15,6 +15,10 @@ class TestGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager { TestGpuMemoryBufferManager(); ~TestGpuMemoryBufferManager() override; + void SetGpuMemoryBufferIsInUseByMacOSWindowServer( + gfx::GpuMemoryBuffer* gpu_memory_buffer, + bool in_use); + // Overridden from gpu::GpuMemoryBufferManager: scoped_ptr AllocateGpuMemoryBuffer( const gfx::Size& size, -- cgit v1.1