Index: gpu/command_buffer/service/in_process_command_buffer.cc |
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc |
index c4fa167800478e1887431a4b14524413271e8053..c4725a139a6a70b9bde17a2735cde68cee0f6940 100644 |
--- a/gpu/command_buffer/service/in_process_command_buffer.cc |
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc |
@@ -700,41 +700,69 @@ gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { |
return capabilities_; |
} |
-int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer, |
+int32 InProcessCommandBuffer::CreateImage(ClientBuffer* const buffers, |
size_t width, |
size_t height, |
unsigned internalformat) { |
CheckSequencedThread(); |
DCHECK(gpu_memory_buffer_manager_); |
- gfx::GpuMemoryBuffer* gpu_memory_buffer = |
- gpu_memory_buffer_manager_->GpuMemoryBufferFromClientBuffer(buffer); |
- DCHECK(gpu_memory_buffer); |
- |
int32 new_id = next_image_id_.GetNext(); |
- DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( |
- internalformat, gpu_memory_buffer->GetFormat())); |
+ // Log and return if the |internalformat| isn't supported. |
+ if (!gpu::ImageFactory::IsImageFormatSupported(internalformat)) { |
+ LOG(ERROR) << "Internalformat is not supported."; |
+ return -1; |
+ } |
- // This handle is owned by the GPU thread and must be passed to it or it |
- // will leak. In otherwords, do not early out on error between here and the |
- // queuing of the CreateImage task below. |
+ // Check the buffer count for the given |internalformat| and initialize the |
+ // vectors where data will be passed. |
+ size_t num_buffers = |
+ gpu::ImageFactory::NumberOfPlanesForImageFormat(internalformat); |
+ std::vector<gfx::GpuMemoryBufferHandle> handles; |
+ std::vector<gfx::GpuMemoryBuffer::Format> formats; |
bool requires_sync_point = false; |
- gfx::GpuMemoryBufferHandle handle = |
- ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(), |
- &requires_sync_point); |
+ |
+ for (size_t i = 0; i < num_buffers; ++i) { |
+ gfx::GpuMemoryBuffer* gpu_memory_buffer = |
+ gpu_memory_buffer_manager_->GpuMemoryBufferFromClientBuffer(buffers[i]); |
+ DCHECK(gpu_memory_buffer); |
+ |
+ formats.push_back(gpu_memory_buffer->GetFormat()); |
+ DCHECK(gpu::ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat( |
+ gfx::Size(width, height), formats[i])); |
+ DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( |
+ internalformat, i, formats[i])); |
+ |
+ bool buffer_requires_sync_point = false; |
+ // This handle is owned by the GPU thread and must be passed to it or it |
+ // will leak. In other words, do not early out on error between here and the |
+ // queuing of the CreateImage task below. |
+ handles.push_back(ShareGpuMemoryBufferToGpuThread( |
+ gpu_memory_buffer->GetHandle(), &buffer_requires_sync_point)); |
+ |
+ // We set a destruction sync point on all buffers if one happen to require |
+ // one. |
+ requires_sync_point |= buffer_requires_sync_point; |
+ } |
QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, |
base::Unretained(this), |
new_id, |
- handle, |
+ handles, |
gfx::Size(width, height), |
- gpu_memory_buffer->GetFormat(), |
+ formats, |
internalformat)); |
if (requires_sync_point) { |
- gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer, |
- InsertSyncPoint()); |
+ uint32 sync_point = InsertSyncPoint(); |
+ for (size_t i = 0; i < num_buffers; ++i) { |
+ gfx::GpuMemoryBuffer* gpu_memory_buffer = |
+ gpu_memory_buffer_manager_->GpuMemoryBufferFromClientBuffer( |
+ buffers[i]); |
+ gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer, |
+ sync_point); |
+ } |
} |
return new_id; |
@@ -742,9 +770,9 @@ int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer, |
void InProcessCommandBuffer::CreateImageOnGpuThread( |
int32 id, |
- const gfx::GpuMemoryBufferHandle& handle, |
+ const std::vector<gfx::GpuMemoryBufferHandle>& handles, |
const gfx::Size& size, |
- gfx::GpuMemoryBuffer::Format format, |
+ const std::vector<gfx::GpuMemoryBuffer::Format>& formats, |
uint32 internalformat) { |
if (!decoder_) |
return; |
@@ -761,8 +789,8 @@ void InProcessCommandBuffer::CreateImageOnGpuThread( |
DCHECK(image_factory_); |
scoped_refptr<gfx::GLImage> image = |
- image_factory_->CreateImageForGpuMemoryBuffer( |
- handle, size, format, internalformat, kClientId); |
+ image_factory_->CreateImageForGpuMemoryBuffers(handles, size, formats, |
+ internalformat, kClientId); |
if (!image.get()) |
return; |
@@ -797,17 +825,28 @@ int32 InProcessCommandBuffer::CreateGpuMemoryBufferImage( |
unsigned internalformat, |
unsigned usage) { |
CheckSequencedThread(); |
- |
+ DCHECK(gpu::ImageFactory::IsImageFormatSupported(internalformat)); |
DCHECK(gpu_memory_buffer_manager_); |
- scoped_ptr<gfx::GpuMemoryBuffer> buffer( |
- gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
- gfx::Size(width, height), |
- gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat), |
- gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); |
- if (!buffer) |
- return -1; |
- return CreateImage(buffer->AsClientBuffer(), width, height, internalformat); |
+ size_t num_buffers = |
+ gpu::ImageFactory::NumberOfPlanesForImageFormat(internalformat); |
+ ScopedVector<gfx::GpuMemoryBuffer> buffers; |
+ std::vector<ClientBuffer> client_buffers; |
+ |
+ for (size_t i = 0; i < num_buffers; ++i) { |
+ gfx::GpuMemoryBuffer::Format format = |
+ gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat, |
+ i); |
+ buffers.push_back(gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
+ gfx::Size(width, height), format, |
+ gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); |
+ |
+ if (!buffers[i]) |
+ return -1; |
+ |
+ client_buffers[i] = buffers[i]->AsClientBuffer(); |
+ } |
+ return CreateImage(client_buffers.data(), width, height, internalformat); |
} |
uint32 InProcessCommandBuffer::InsertSyncPoint() { |