1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h"
6 #include <wrl.h>
7 #include <vector>
8 #include "base/trace_event/trace_event.h"
9 #include "ui/gfx/buffer_format_util.h"
10 #include "ui/gl/gl_angle_util_win.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_image_dxgi.h"
13
14 namespace gpu {
15
GpuMemoryBufferFactoryDXGI()16 GpuMemoryBufferFactoryDXGI::GpuMemoryBufferFactoryDXGI() {}
17
~GpuMemoryBufferFactoryDXGI()18 GpuMemoryBufferFactoryDXGI::~GpuMemoryBufferFactoryDXGI() {}
19
CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,int client_id,SurfaceHandle surface_handle)20 gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer(
21 gfx::GpuMemoryBufferId id,
22 const gfx::Size& size,
23 gfx::BufferFormat format,
24 gfx::BufferUsage usage,
25 int client_id,
26 SurfaceHandle surface_handle) {
27 TRACE_EVENT0("gpu", "GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer");
28
29 gfx::GpuMemoryBufferHandle handle;
30
31 Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
32 gl::QueryD3D11DeviceObjectFromANGLE();
33 if (!d3d11_device)
34 return handle;
35
36 DXGI_FORMAT dxgi_format;
37 switch (format) {
38 case gfx::BufferFormat::RGBA_8888:
39 case gfx::BufferFormat::RGBX_8888:
40 dxgi_format = DXGI_FORMAT_R8G8B8A8_UNORM;
41 break;
42 default:
43 NOTREACHED();
44 return handle;
45 }
46
47 // We are binding as a shader resource and render target regardless of usage,
48 // so make sure that the usage is one that we support.
49 DCHECK(usage == gfx::BufferUsage::GPU_READ ||
50 usage == gfx::BufferUsage::SCANOUT);
51
52 D3D11_TEXTURE2D_DESC desc = {
53 size.width(),
54 size.height(),
55 1,
56 1,
57 dxgi_format,
58 {1, 0},
59 D3D11_USAGE_DEFAULT,
60 D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
61 0,
62 D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
63 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
64
65 Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
66
67 if (FAILED(d3d11_device->CreateTexture2D(&desc, nullptr,
68 d3d11_texture.GetAddressOf())))
69 return handle;
70
71 Microsoft::WRL::ComPtr<IDXGIResource1> dxgi_resource;
72 if (FAILED(d3d11_texture.CopyTo(dxgi_resource.GetAddressOf())))
73 return handle;
74
75 HANDLE texture_handle;
76 if (FAILED(dxgi_resource->CreateSharedHandle(
77 nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
78 nullptr, &texture_handle)))
79 return handle;
80
81 size_t buffer_size;
82 if (!BufferSizeForBufferFormatChecked(size, format, &buffer_size))
83 return handle;
84
85 handle.dxgi_handle.Set(texture_handle);
86 handle.type = gfx::DXGI_SHARED_HANDLE;
87 handle.id = id;
88
89 return handle;
90 }
91
DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,int client_id)92 void GpuMemoryBufferFactoryDXGI::DestroyGpuMemoryBuffer(
93 gfx::GpuMemoryBufferId id,
94 int client_id) {}
95
AsImageFactory()96 ImageFactory* GpuMemoryBufferFactoryDXGI::AsImageFactory() {
97 return this;
98 }
99
100 scoped_refptr<gl::GLImage>
CreateImageForGpuMemoryBuffer(gfx::GpuMemoryBufferHandle handle,const gfx::Size & size,gfx::BufferFormat format,int client_id,SurfaceHandle surface_handle)101 GpuMemoryBufferFactoryDXGI::CreateImageForGpuMemoryBuffer(
102 gfx::GpuMemoryBufferHandle handle,
103 const gfx::Size& size,
104 gfx::BufferFormat format,
105 int client_id,
106 SurfaceHandle surface_handle) {
107 if (handle.type != gfx::DXGI_SHARED_HANDLE)
108 return nullptr;
109 // Transfer ownership of handle to GLImageDXGI.
110 auto image = base::MakeRefCounted<gl::GLImageDXGI>(size, nullptr);
111 if (!image->InitializeHandle(std::move(handle.dxgi_handle), 0, format))
112 return nullptr;
113 return image;
114 }
115
RequiredTextureType()116 unsigned GpuMemoryBufferFactoryDXGI::RequiredTextureType() {
117 return GL_TEXTURE_2D;
118 }
119
SupportsFormatRGB()120 bool GpuMemoryBufferFactoryDXGI::SupportsFormatRGB() {
121 return true;
122 }
123 } // namespace gpu
124