| 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() {
|
|
|