diff options
author | alexst <alexst@chromium.org> | 2014-12-08 12:19:08 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-08 20:19:46 +0000 |
commit | 6934562f7d5890a16186810dd1d89712fe88b135 (patch) | |
tree | c0aa724a94c757baf8a4a0dd8107fae5a064184b | |
parent | f271a6c0399df3f40c761c3481f9887257a46dea (diff) | |
download | chromium_src-6934562f7d5890a16186810dd1d89712fe88b135.zip chromium_src-6934562f7d5890a16186810dd1d89712fe88b135.tar.gz chromium_src-6934562f7d5890a16186810dd1d89712fe88b135.tar.bz2 |
Plumb surface id to GpuMemoryBuffer allocation.
We need to know which display controller to use for allocation of scanout buffers in situations where an external USB monitor is connected.
BUG=432550
Review URL: https://codereview.chromium.org/725723002
Cr-Commit-Position: refs/heads/master@{#307317}
28 files changed, 222 insertions, 99 deletions
diff --git a/content/browser/compositor/buffer_queue.cc b/content/browser/compositor/buffer_queue.cc index ebb0165..c58e6bc 100644 --- a/content/browser/compositor/buffer_queue.cc +++ b/content/browser/compositor/buffer_queue.cc @@ -5,23 +5,31 @@ #include "content/browser/compositor/buffer_queue.h" #include "content/browser/compositor/image_transport_factory.h" +#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/common/gpu/client/gl_helper.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/service/image_factory.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRegion.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace content { -BufferQueue::BufferQueue(scoped_refptr<cc::ContextProvider> context_provider, - unsigned int internalformat, - GLHelper* gl_helper) +BufferQueue::BufferQueue( + scoped_refptr<cc::ContextProvider> context_provider, + unsigned int internalformat, + GLHelper* gl_helper, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager, + int surface_id) : context_provider_(context_provider), fbo_(0), allocated_count_(0), internalformat_(internalformat), - gl_helper_(gl_helper) { + gl_helper_(gl_helper), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), + surface_id_(surface_id) { } BufferQueue::~BufferQueue() { @@ -157,11 +165,15 @@ BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() { // We don't want to allow anything more than triple buffering. DCHECK_LT(allocated_count_, 4U); - unsigned int id = - gl->CreateGpuMemoryBufferImageCHROMIUM(size_.width(), - size_.height(), - internalformat_, - GL_SCANOUT_CHROMIUM); + scoped_ptr<gfx::GpuMemoryBuffer> buffer( + gpu_memory_buffer_manager_->AllocateGpuMemoryBufferForScanout( + size_, gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat( + internalformat_), + surface_id_)); + + unsigned int id = gl->CreateImageCHROMIUM( + buffer->AsClientBuffer(), size_.width(), size_.height(), internalformat_); + if (!id) { LOG(ERROR) << "Failed to allocate backing image surface"; gl->DeleteTextures(1, &texture); diff --git a/content/browser/compositor/buffer_queue.h b/content/browser/compositor/buffer_queue.h index dca9c38..3e6727e 100644 --- a/content/browser/compositor/buffer_queue.h +++ b/content/browser/compositor/buffer_queue.h @@ -20,6 +20,7 @@ class ContextProvider; namespace content { +class BrowserGpuMemoryBufferManager; class GLHelper; // Provides a surface that manages its own buffers, backed by GpuMemoryBuffers @@ -30,7 +31,9 @@ class CONTENT_EXPORT BufferQueue { public: BufferQueue(scoped_refptr<cc::ContextProvider> context_provider, unsigned int internalformat, - GLHelper* gl_helper); + GLHelper* gl_helper, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager, + int surface_id); virtual ~BufferQueue(); bool Initialize(); @@ -81,6 +84,8 @@ class CONTENT_EXPORT BufferQueue { std::vector<AllocatedSurface> available_surfaces_; // These are free for use. std::deque<AllocatedSurface> in_flight_surfaces_; GLHelper* gl_helper_; + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager_; + int surface_id_; DISALLOW_COPY_AND_ASSIGN(BufferQueue); }; diff --git a/content/browser/compositor/buffer_queue_unittest.cc b/content/browser/compositor/buffer_queue_unittest.cc index 1a2c4fe..8506b58 100644 --- a/content/browser/compositor/buffer_queue_unittest.cc +++ b/content/browser/compositor/buffer_queue_unittest.cc @@ -8,6 +8,7 @@ #include "cc/test/test_web_graphics_context_3d.h" #include "content/browser/compositor/buffer_queue.h" #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h" +#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,11 +20,48 @@ using ::testing::Ne; using ::testing::Return; namespace content { + +class StubGpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { + public: + StubGpuMemoryBufferImpl() {} + + // Overridden from gfx::GpuMemoryBuffer: + void* Map() override { return nullptr; } + void Unmap() override {} + bool IsMapped() const override { return false; } + Format GetFormat() const override { return gfx::GpuMemoryBuffer::RGBX_8888; } + uint32 GetStride() const override { return 0; } + gfx::GpuMemoryBufferHandle GetHandle() const override { + return gfx::GpuMemoryBufferHandle(); + } + ClientBuffer AsClientBuffer() override { + return reinterpret_cast<ClientBuffer>(this); + } +}; + +class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager { + public: + StubBrowserGpuMemoryBufferManager() + : BrowserGpuMemoryBufferManager(nullptr, 1) {} + + scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + int32 surface_id) override { + return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl); + } +}; + class MockBufferQueue : public BufferQueue { public: MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager, unsigned int internalformat) - : BufferQueue(context_provider, internalformat, nullptr) {} + : BufferQueue(context_provider, + internalformat, + nullptr, + gpu_memory_buffer_manager, + 1) {} MOCK_METHOD4(CopyBufferDamage, void(int, int, const gfx::Rect&, const gfx::Rect&)); }; @@ -36,7 +74,9 @@ class BufferQueueTest : public ::testing::Test { scoped_refptr<cc::TestContextProvider> context_provider = cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create()); context_provider->BindToCurrentThread(); - output_surface_.reset(new MockBufferQueue(context_provider, GL_RGBA)); + gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager); + output_surface_.reset(new MockBufferQueue( + context_provider, gpu_memory_buffer_manager_.get(), GL_RGBA)); output_surface_->Initialize(); } @@ -102,6 +142,7 @@ class BufferQueueTest : public ::testing::Test { return true; } + scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_; scoped_ptr<MockBufferQueue> output_surface_; bool doublebuffering_; bool first_frame_; @@ -119,29 +160,33 @@ class MockedContext : public cc::TestWebGraphicsContext3D { MOCK_METHOD2(bindFramebuffer, void(GLenum, GLuint)); MOCK_METHOD2(bindTexture, void(GLenum, GLuint)); MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint)); - MOCK_METHOD4(createGpuMemoryBufferImageCHROMIUM, - GLuint(GLsizei, GLsizei, GLenum, GLenum)); + MOCK_METHOD4(createImageCHROMIUM, + GLuint(ClientBuffer, GLsizei, GLsizei, GLenum)); MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint)); MOCK_METHOD5(framebufferTexture2D, void(GLenum, GLenum, GLenum, GLuint, GLint)); }; -scoped_ptr<BufferQueue> CreateOutputSurfaceWithMock(MockedContext** context) { +scoped_ptr<BufferQueue> CreateOutputSurfaceWithMock( + MockedContext** context, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) { *context = new MockedContext(); scoped_refptr<cc::TestContextProvider> context_provider = cc::TestContextProvider::Create( scoped_ptr<cc::TestWebGraphicsContext3D>(*context)); context_provider->BindToCurrentThread(); - scoped_ptr<BufferQueue> buffer_queue( - new BufferQueue(context_provider, GL_RGBA, nullptr)); + scoped_ptr<BufferQueue> buffer_queue(new BufferQueue( + context_provider, GL_RGBA, nullptr, gpu_memory_buffer_manager, 1)); buffer_queue->Initialize(); return buffer_queue.Pass(); } TEST(BufferQueueStandaloneTest, FboInitialization) { MockedContext* context; + scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( + new StubBrowserGpuMemoryBufferManager); scoped_ptr<BufferQueue> output_surface = - CreateOutputSurfaceWithMock(&context); + CreateOutputSurfaceWithMock(&context, gpu_memory_buffer_manager.get()); EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); ON_CALL(*context, framebufferTexture2D(_, _, _, _, _)) @@ -152,14 +197,15 @@ TEST(BufferQueueStandaloneTest, FboInitialization) { TEST(BufferQueueStandaloneTest, FboBinding) { MockedContext* context; + scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( + new StubBrowserGpuMemoryBufferManager); scoped_ptr<BufferQueue> output_surface = - CreateOutputSurfaceWithMock(&context); + CreateOutputSurfaceWithMock(&context, gpu_memory_buffer_manager.get()); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, Ne(0U))); EXPECT_CALL(*context, destroyImageCHROMIUM(1)); Expectation image = - EXPECT_CALL(*context, - createGpuMemoryBufferImageCHROMIUM( - 0, 0, GL_RGBA, GL_SCANOUT_CHROMIUM)).WillOnce(Return(1)); + EXPECT_CALL(*context, createImageCHROMIUM(_, 0, 0, GL_RGBA)) + .WillOnce(Return(1)); Expectation fb = EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); Expectation tex = EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, Ne(0U))); diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 9f56909..33b3aa0 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc @@ -265,13 +265,11 @@ void GpuProcessTransportFactory::EstablishedGpuChannel( #if defined(USE_OZONE) if (ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { surface.reset(new GpuSurfacelessBrowserCompositorOutputSurface( - context_provider, - data->surface_id, - &output_surface_map_, + context_provider, data->surface_id, &output_surface_map_, compositor->vsync_manager(), - CreateOverlayCandidateValidator(compositor->widget()), - GL_RGB, - compositor_thread_ != nullptr)); + CreateOverlayCandidateValidator(compositor->widget()), GL_RGB, + compositor_thread_ != nullptr, + BrowserGpuMemoryBufferManager::current())); } #endif if (!surface) diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc index 0245aae..2852ba7 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc @@ -23,14 +23,16 @@ GpuSurfacelessBrowserCompositorOutputSurface:: const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager, scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator, unsigned internalformat, - bool use_own_gl_helper) + bool use_own_gl_helper, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) : GpuBrowserCompositorOutputSurface(context, surface_id, output_surface_map, vsync_manager, overlay_candidate_validator.Pass()), internalformat_(internalformat), - use_own_gl_helper_(use_own_gl_helper) { + use_own_gl_helper_(use_own_gl_helper), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { capabilities_.uses_default_gl_framebuffer = false; capabilities_.flipped_output_surface = true; } @@ -95,8 +97,9 @@ bool GpuSurfacelessBrowserCompositorOutputSurface::BindToClient( if (!helper) return false; - output_surface_.reset( - new BufferQueue(context_provider_, internalformat_, helper)); + output_surface_.reset(new BufferQueue(context_provider_, internalformat_, + helper, gpu_memory_buffer_manager_, + surface_id_)); return output_surface_->Initialize(); } diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h index e95ab7a..2c98a56 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h @@ -9,6 +9,7 @@ namespace content { +class BrowserGpuMemoryBufferManager; class BufferQueue; class GLHelper; @@ -22,7 +23,8 @@ class GpuSurfacelessBrowserCompositorOutputSurface const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager, scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator, unsigned internalformat, - bool use_own_gl_helper); + bool use_own_gl_helper, + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager); ~GpuSurfacelessBrowserCompositorOutputSurface() override; private: @@ -37,6 +39,7 @@ class GpuSurfacelessBrowserCompositorOutputSurface bool use_own_gl_helper_; scoped_ptr<GLHelper> gl_helper_; scoped_ptr<BufferQueue> output_surface_; + BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager_; }; } // namespace content diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 99f9948..851e9e5 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc @@ -486,6 +486,7 @@ void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, int client_id, + int32 surface_id, const CreateGpuMemoryBufferCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -499,14 +500,9 @@ void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( create_gpu_memory_buffer_requests_[request_id] = callback; host->CreateGpuMemoryBuffer( - id, - size, - format, - usage, - client_id, + id, size, format, usage, client_id, surface_id, base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, - base::Unretained(this), - request_id)); + base::Unretained(this), request_id)); } void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h index 84ad1ff..b482b35 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.h +++ b/content/browser/gpu/browser_gpu_channel_host_factory.h @@ -50,6 +50,7 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, int client_id, + int32 surface_id, const CreateGpuMemoryBufferCallback& callback) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id, diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc index 11af884..2cfb9c8 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc @@ -29,18 +29,21 @@ struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { AllocateGpuMemoryBufferRequest(const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) + int client_id, + int surface_id) : event(true, false), size(size), format(format), usage(usage), - client_id(client_id) {} + client_id(client_id), + surface_id(surface_id) {} ~AllocateGpuMemoryBufferRequest() {} base::WaitableEvent event; gfx::Size size; gfx::GpuMemoryBuffer::Format format; gfx::GpuMemoryBuffer::Usage usage; int client_id; + int surface_id; scoped_ptr<gfx::GpuMemoryBuffer> result; }; @@ -68,6 +71,25 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage) { + return AllocateGpuMemoryBufferCommon(size, format, usage, 0); +} + +scoped_ptr<gfx::GpuMemoryBuffer> +BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + int32 surface_id) { + DCHECK_GT(surface_id, 0); + return AllocateGpuMemoryBufferCommon( + size, format, gfx::GpuMemoryBuffer::SCANOUT, surface_id); +} + +scoped_ptr<gfx::GpuMemoryBuffer> +BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferCommon( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + gfx::GpuMemoryBuffer::Usage usage, + int32 surface_id) { DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); // Fallback to shared memory buffer if |format| and |usage| are not supported @@ -80,7 +102,8 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer( g_next_gpu_memory_buffer_id.GetNext(), size, format); } - AllocateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_); + AllocateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_, + surface_id); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -134,16 +157,10 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess( buffers[new_id] = gfx::EMPTY_BUFFER; gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer( - new_id, - size, - format, - usage, - child_client_id, + new_id, size, format, usage, child_client_id, 0, base::Bind(&BrowserGpuMemoryBufferManager:: GpuMemoryBufferAllocatedForChildProcess, - weak_ptr_factory_.GetWeakPtr(), - child_client_id, - callback)); + weak_ptr_factory_.GetWeakPtr(), child_client_id, callback)); } gfx::GpuMemoryBuffer* @@ -226,14 +243,10 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO( // Note: Unretained is safe as this is only used for synchronous allocation // from a non-IO thread. gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer( - g_next_gpu_memory_buffer_id.GetNext(), - request->size, - request->format, - request->usage, - request->client_id, + g_next_gpu_memory_buffer_id.GetNext(), request->size, request->format, + request->usage, request->client_id, request->surface_id, base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO, - base::Unretained(this), - base::Unretained(request))); + base::Unretained(this), base::Unretained(request))); } void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO( diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/content/browser/gpu/browser_gpu_memory_buffer_manager.h index 08ab881..60815de 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.h +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.h @@ -37,6 +37,11 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer, uint32 sync_point) override; + // Virtual for testing. + virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + int32 surface_id); void AllocateGpuMemoryBufferForChildProcess( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, @@ -54,6 +59,11 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager private: struct AllocateGpuMemoryBufferRequest; + scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferCommon( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + gfx::GpuMemoryBuffer::Usage usage, + int32 surface_id); void AllocateGpuMemoryBufferOnIO(AllocateGpuMemoryBufferRequest* request); void GpuMemoryBufferAllocatedOnIO(AllocateGpuMemoryBufferRequest* request, const gfx::GpuMemoryBufferHandle& handle); diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 2d04cb9..2f90e67 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -657,14 +657,28 @@ void GpuProcessHost::CreateGpuMemoryBuffer( gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, int client_id, + int32 surface_id, const CreateGpuMemoryBufferCallback& callback) { TRACE_EVENT0("gpu", "GpuProcessHost::CreateGpuMemoryBuffer"); DCHECK(CalledOnValidThread()); - if (Send(new GpuMsg_CreateGpuMemoryBuffer( - id, size, format, usage, client_id))) { + GpuMsg_CreateGpuMemoryBuffer_Params params; + params.id = id; + params.size = size; + params.format = format; + params.usage = usage; + params.client_id = client_id; + params.surface_handle = + GpuSurfaceTracker::GetInstance()->GetSurfaceHandle(surface_id).handle; + if (Send(new GpuMsg_CreateGpuMemoryBuffer(params))) { create_gpu_memory_buffer_requests_.push(callback); + create_gpu_memory_buffer_surface_refs_.push(surface_id); + if (surface_id) { + surface_refs_.insert(std::make_pair( + surface_id, GpuSurfaceTracker::GetInstance()->GetSurfaceRefForSurface( + surface_id))); + } } else { callback.Run(gfx::GpuMemoryBufferHandle()); } @@ -753,6 +767,13 @@ void GpuProcessHost::OnGpuMemoryBufferCreated( create_gpu_memory_buffer_requests_.front(); create_gpu_memory_buffer_requests_.pop(); callback.Run(handle); + + int32 surface_id = create_gpu_memory_buffer_surface_refs_.front(); + create_gpu_memory_buffer_surface_refs_.pop(); + SurfaceRefMap::iterator it = surface_refs_.find(surface_id); + if (it != surface_refs_.end()) { + surface_refs_.erase(it); + } } void GpuProcessHost::OnDidCreateOffscreenContext(const GURL& url) { diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 145cdcc..1a79b0b 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -124,6 +124,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, int client_id, + int32 surface_id, const CreateGpuMemoryBufferCallback& callback); // Tells the GPU process to destroy GPU memory buffer. @@ -204,6 +205,9 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate, // The pending create gpu memory buffer requests we need to reply to. std::queue<CreateGpuMemoryBufferCallback> create_gpu_memory_buffer_requests_; + // Surface ids for pending gpu memory buffer request refs. + std::queue<int32> create_gpu_memory_buffer_surface_refs_; + // Qeueud messages to send when the process launches. std::queue<IPC::Message*> queued_messages_; diff --git a/content/common/gpu/client/gpu_memory_buffer_factory_host.h b/content/common/gpu/client/gpu_memory_buffer_factory_host.h index c206911..fc42b18 100644 --- a/content/common/gpu/client/gpu_memory_buffer_factory_host.h +++ b/content/common/gpu/client/gpu_memory_buffer_factory_host.h @@ -29,6 +29,7 @@ class CONTENT_EXPORT GpuMemoryBufferFactoryHost { gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, int client_id, + int32 surface_id, const CreateGpuMemoryBufferCallback& callback) = 0; virtual void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id, diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc index 615cc93..3ac1b83 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc @@ -12,6 +12,7 @@ namespace content { namespace { const int kClientId = 1; +const int kSurfaceId = 0; class GpuMemoryBufferImplTest : public testing::TestWithParam<gfx::GpuMemoryBufferType> { @@ -32,7 +33,8 @@ class GpuMemoryBufferImplTest gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage) { ++buffer_count_; - return factory_->CreateGpuMemoryBuffer(id, size, format, usage, kClientId); + return factory_->CreateGpuMemoryBuffer(id, size, format, usage, kClientId, + kSurfaceId); } void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32 sync_point) { diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc index 9e5fee4..131c7b5 100644 --- a/content/common/gpu/gpu_channel_manager.cc +++ b/content/common/gpu/gpu_channel_manager.cc @@ -59,23 +59,15 @@ class GpuChannelManagerMessageFilter : public IPC::MessageFilter { protected: ~GpuChannelManagerMessageFilter() override {} - void OnCreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::GpuMemoryBuffer::Format format, - gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + void OnCreateGpuMemoryBuffer( + const GpuMsg_CreateGpuMemoryBuffer_Params& params) { TRACE_EVENT2("gpu", "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer", - "id", - id, - "client_id", - client_id); + "id", params.id, "client_id", params.client_id); sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated( - gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(id, - size, - format, - usage, - client_id))); + gpu_memory_buffer_factory_->CreateGpuMemoryBuffer( + params.id, params.size, params.format, params.usage, + params.client_id, params.surface_handle))); } IPC::Sender* sender_; diff --git a/content/common/gpu/gpu_memory_buffer_factory.h b/content/common/gpu/gpu_memory_buffer_factory.h index 7df2773..467944b 100644 --- a/content/common/gpu/gpu_memory_buffer_factory.h +++ b/content/common/gpu/gpu_memory_buffer_factory.h @@ -12,6 +12,7 @@ #include "content/common/content_export.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" +#include "ui/gfx/native_widget_types.h" namespace gfx { class GLImage; @@ -52,7 +53,8 @@ class CONTENT_EXPORT GpuMemoryBufferFactory { const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) = 0; + int client_id, + gfx::PluginWindowHandle surface_handle) = 0; // Destroys GPU memory buffer identified by |id|. virtual void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc index e6954bf..ba00ea2 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc @@ -92,7 +92,8 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + int client_id, + gfx::PluginWindowHandle surface_handle) { base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.h b/content/common/gpu/gpu_memory_buffer_factory_io_surface.h index e636bbd..0fe8681 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.h +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.h @@ -40,7 +40,8 @@ class GpuMemoryBufferFactoryIOSurface : public GpuMemoryBufferFactory, const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) override; + int client_id, + gfx::PluginWindowHandle surface_handle) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id) override; gpu::ImageFactory* AsImageFactory() override; diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc index c4f8e82..6185150 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc @@ -56,9 +56,10 @@ GpuMemoryBufferFactoryOzoneNativeBuffer::CreateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + int client_id, + gfx::PluginWindowHandle surface_handle) { if (!ozone_native_buffer_factory_.CreateGpuMemoryBuffer( - id, size, format, usage, client_id)) { + id, size, format, usage, client_id, surface_handle)) { return gfx::GpuMemoryBufferHandle(); } gfx::GpuMemoryBufferHandle handle; diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h index 9b311de..5cdce58 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h @@ -36,7 +36,8 @@ class GpuMemoryBufferFactoryOzoneNativeBuffer : public GpuMemoryBufferFactory, const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) override; + int client_id, + gfx::PluginWindowHandle surface_handle) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id) override; gpu::ImageFactory* AsImageFactory() override; diff --git a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc index 3a65c7c..9a4bdcf 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc @@ -35,7 +35,8 @@ GpuMemoryBufferFactorySharedMemory::CreateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + int client_id, + gfx::PluginWindowHandle surface_handle) { base::SharedMemory shared_memory; if (!shared_memory.CreateAnonymous( size.GetArea() * GpuMemoryBufferImpl::BytesPerPixel(format))) diff --git a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h index 521021c..b2a9c70 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h +++ b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h @@ -31,7 +31,8 @@ class GpuMemoryBufferFactorySharedMemory : public GpuMemoryBufferFactory, const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) override; + int client_id, + gfx::PluginWindowHandle surface_handle) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id) override; gpu::ImageFactory* AsImageFactory() override; diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc index 2410e61..1b2c881 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc @@ -49,7 +49,8 @@ GpuMemoryBufferFactorySurfaceTexture::CreateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + int client_id, + gfx::PluginWindowHandle surface_handle) { // Note: this needs to be 0 as the surface texture implemenation will take // ownership of the texture and call glDeleteTextures when the GPU service // attaches the surface texture to a real texture id. glDeleteTextures diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h index 57dfc94..fe47f69 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h @@ -38,7 +38,8 @@ class GpuMemoryBufferFactorySurfaceTexture : public GpuMemoryBufferFactory, const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) override; + int client_id, + gfx::PluginWindowHandle surface_handle) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id) override; gpu::ImageFactory* AsImageFactory() override; diff --git a/content/common/gpu/gpu_memory_buffer_factory_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_unittest.cc index 174c36c..39186f1 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_unittest.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_unittest.cc @@ -30,16 +30,14 @@ class GpuMemoryBufferFactoryTest TEST_P(GpuMemoryBufferFactoryTest, CreateAndDestroy) { const int kBufferId = 1; const int kClientId = 1; + const int kSurfaceId = 0; gfx::Size buffer_size(1, 1); for (auto configuration : supported_configurations_) { gfx::GpuMemoryBufferHandle handle = factory_->CreateGpuMemoryBuffer( - kBufferId, - buffer_size, - configuration.format, - configuration.usage, - kClientId); + kBufferId, buffer_size, configuration.format, configuration.usage, + kClientId, kSurfaceId); EXPECT_EQ(handle.type, GetParam()); factory_->DestroyGpuMemoryBuffer(kBufferId, kClientId); } diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 3f373bb..b860c56 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -77,6 +77,15 @@ IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig) IPC_STRUCT_MEMBER(gfx::GpuPreference, gpu_preference) IPC_STRUCT_END() +IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBuffer_Params) +IPC_STRUCT_MEMBER(int32, id) +IPC_STRUCT_MEMBER(gfx::Size, size) +IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Format, format) +IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Usage, usage) +IPC_STRUCT_MEMBER(int32, client_id) +IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, surface_handle) +IPC_STRUCT_END() + IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params) IPC_STRUCT_MEMBER(int32, surface_id) IPC_STRUCT_MEMBER(uint64, surface_handle) @@ -252,12 +261,8 @@ IPC_MESSAGE_CONTROL5(GpuMsg_CreateViewCommandBuffer, int32 /* route_id */) // Tells the GPU process to create a new gpu memory buffer. -IPC_MESSAGE_CONTROL5(GpuMsg_CreateGpuMemoryBuffer, - gfx::GpuMemoryBufferId, /* id */ - gfx::Size, /* size */ - gfx::GpuMemoryBuffer::Format, /* format */ - gfx::GpuMemoryBuffer::Usage, /* usage */ - int32 /* client_id */) +IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBuffer, + GpuMsg_CreateGpuMemoryBuffer_Params) // Tells the GPU process to destroy buffer. IPC_MESSAGE_CONTROL3(GpuMsg_DestroyGpuMemoryBuffer, diff --git a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc index f2a5371..ef58da2 100644 --- a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc +++ b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc @@ -121,10 +121,11 @@ bool GpuMemoryBufferFactoryOzoneNativeBuffer::CreateGpuMemoryBuffer( const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id) { + int client_id, + gfx::PluginWindowHandle surface_handle) { scoped_refptr<NativePixmap> pixmap = SurfaceFactoryOzone::GetInstance()->CreateNativePixmap( - gfx::kNullAcceleratedWidget, size, GetOzoneFormatFor(format), + surface_handle, size, GetOzoneFormatFor(format), GetOzoneUsageFor(usage)); if (!pixmap.get()) { LOG(ERROR) << "Failed to create pixmap " << size.width() << "x" diff --git a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h index c7bdd2e..bf98786 100644 --- a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h +++ b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h @@ -11,6 +11,7 @@ #include "base/synchronization/lock.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" +#include "ui/gfx/native_widget_types.h" #include "ui/ozone/gpu/ozone_gpu_export.h" namespace gfx { @@ -33,7 +34,8 @@ class OZONE_GPU_EXPORT GpuMemoryBufferFactoryOzoneNativeBuffer { const gfx::Size& size, gfx::GpuMemoryBuffer::Format format, gfx::GpuMemoryBuffer::Usage usage, - int client_id); + int client_id, + gfx::PluginWindowHandle surface_handle); // Destroys GPU memory buffer identified by |id|. void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id); |