| 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 529ffc49b527ead87ae8106320ae8421d0b6c508..d43f84c0cbe58d729d72dea3a6603b7aba0498f3 100644
|
| --- a/gpu/command_buffer/service/in_process_command_buffer.cc
|
| +++ b/gpu/command_buffer/service/in_process_command_buffer.cc
|
| @@ -43,6 +43,11 @@
|
| #include "ui/gl/android/surface_texture.h"
|
| #endif
|
|
|
| +#if defined(OS_WIN)
|
| +#include <windows.h>
|
| +#include "base/process/process_handle.h"
|
| +#endif
|
| +
|
| namespace gpu {
|
|
|
| namespace {
|
| @@ -180,6 +185,53 @@ void SyncPointManager::WaitSyncPoint(uint32 sync_point) {
|
| base::LazyInstance<SyncPointManager> g_sync_point_manager =
|
| LAZY_INSTANCE_INITIALIZER;
|
|
|
| +base::SharedMemoryHandle ShareToGpuThread(
|
| + base::SharedMemoryHandle source_handle) {
|
| +#if defined(OS_WIN)
|
| + // Windows needs to explicitly duplicate the handle to current process.
|
| + base::SharedMemoryHandle target_handle;
|
| + if (!DuplicateHandle(GetCurrentProcess(),
|
| + source_handle,
|
| + GetCurrentProcess(),
|
| + &target_handle,
|
| + FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
| + FALSE,
|
| + 0)) {
|
| + return base::SharedMemory::NULLHandle();
|
| + }
|
| +
|
| + return target_handle;
|
| +#else
|
| + int duped_handle = HANDLE_EINTR(dup(source_handle.fd));
|
| + if (duped_handle < 0)
|
| + return base::SharedMemory::NULLHandle();
|
| +
|
| + return base::FileDescriptor(duped_handle, true);
|
| +#endif
|
| +}
|
| +
|
| +gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread(
|
| + const gfx::GpuMemoryBufferHandle& source_handle,
|
| + bool* requires_sync_point) {
|
| + switch (source_handle.type) {
|
| + case gfx::SHARED_MEMORY_BUFFER: {
|
| + gfx::GpuMemoryBufferHandle handle;
|
| + handle.type = gfx::SHARED_MEMORY_BUFFER;
|
| + handle.handle = ShareToGpuThread(source_handle.handle);
|
| + *requires_sync_point = false;
|
| + return handle;
|
| + }
|
| + case gfx::IO_SURFACE_BUFFER:
|
| + case gfx::SURFACE_TEXTURE_BUFFER:
|
| + case gfx::OZONE_NATIVE_BUFFER:
|
| + *requires_sync_point = true;
|
| + return source_handle;
|
| + default:
|
| + NOTREACHED();
|
| + return gfx::GpuMemoryBufferHandle();
|
| + }
|
| +}
|
| +
|
| } // anonyous namespace
|
|
|
| InProcessCommandBuffer::Service::Service() {}
|
| @@ -642,13 +694,28 @@ int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer,
|
|
|
| DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
|
| internalformat, gpu_memory_buffer->GetFormat()));
|
| +
|
| + // 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.
|
| + bool requires_sync_point = false;
|
| + gfx::GpuMemoryBufferHandle handle =
|
| + ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(),
|
| + &requires_sync_point);
|
| +
|
| QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread,
|
| base::Unretained(this),
|
| new_id,
|
| - gpu_memory_buffer->GetHandle(),
|
| + handle,
|
| gfx::Size(width, height),
|
| gpu_memory_buffer->GetFormat(),
|
| internalformat));
|
| +
|
| + if (requires_sync_point) {
|
| + gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer,
|
| + InsertSyncPoint());
|
| + }
|
| +
|
| return new_id;
|
| }
|
|
|
|
|