We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / content / common / gpu / gpu_memory_buffer_factory_io_surface.cc
blob2737a4d53aef9654cb274a3d8f00194940069266
1 // Copyright 2014 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.
5 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
7 #include <CoreFoundation/CoreFoundation.h>
9 #include "base/logging.h"
10 #include "ui/gl/gl_image_io_surface.h"
12 namespace content {
13 namespace {
15 void AddBooleanValue(CFMutableDictionaryRef dictionary,
16 const CFStringRef key,
17 bool value) {
18 CFDictionaryAddValue(
19 dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
22 void AddIntegerValue(CFMutableDictionaryRef dictionary,
23 const CFStringRef key,
24 int32 value) {
25 base::ScopedCFTypeRef<CFNumberRef> number(
26 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
27 CFDictionaryAddValue(dictionary, key, number.get());
30 int32 BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
31 switch (format) {
32 case gfx::GpuMemoryBuffer::BGRA_8888:
33 return 4;
34 case gfx::GpuMemoryBuffer::ATC:
35 case gfx::GpuMemoryBuffer::ATCIA:
36 case gfx::GpuMemoryBuffer::DXT1:
37 case gfx::GpuMemoryBuffer::DXT5:
38 case gfx::GpuMemoryBuffer::ETC1:
39 case gfx::GpuMemoryBuffer::RGBA_8888:
40 case gfx::GpuMemoryBuffer::RGBX_8888:
41 case gfx::GpuMemoryBuffer::YUV_420:
42 NOTREACHED();
43 return 0;
46 NOTREACHED();
47 return 0;
50 int32 PixelFormat(gfx::GpuMemoryBuffer::Format format) {
51 switch (format) {
52 case gfx::GpuMemoryBuffer::BGRA_8888:
53 return 'BGRA';
54 case gfx::GpuMemoryBuffer::ATC:
55 case gfx::GpuMemoryBuffer::ATCIA:
56 case gfx::GpuMemoryBuffer::DXT1:
57 case gfx::GpuMemoryBuffer::DXT5:
58 case gfx::GpuMemoryBuffer::ETC1:
59 case gfx::GpuMemoryBuffer::RGBA_8888:
60 case gfx::GpuMemoryBuffer::RGBX_8888:
61 case gfx::GpuMemoryBuffer::YUV_420:
62 NOTREACHED();
63 return 0;
66 NOTREACHED();
67 return 0;
70 const GpuMemoryBufferFactory::Configuration kSupportedConfigurations[] = {
71 { gfx::GpuMemoryBuffer::BGRA_8888, gfx::GpuMemoryBuffer::MAP }
74 } // namespace
76 GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() {
79 GpuMemoryBufferFactoryIOSurface::~GpuMemoryBufferFactoryIOSurface() {
82 // static
83 bool GpuMemoryBufferFactoryIOSurface::IsGpuMemoryBufferConfigurationSupported(
84 gfx::GpuMemoryBuffer::Format format,
85 gfx::GpuMemoryBuffer::Usage usage) {
86 for (auto& configuration : kSupportedConfigurations) {
87 if (configuration.format == format && configuration.usage == usage)
88 return true;
91 return false;
94 void GpuMemoryBufferFactoryIOSurface::GetSupportedGpuMemoryBufferConfigurations(
95 std::vector<Configuration>* configurations) {
96 configurations->assign(
97 kSupportedConfigurations,
98 kSupportedConfigurations + arraysize(kSupportedConfigurations));
101 gfx::GpuMemoryBufferHandle
102 GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
103 gfx::GpuMemoryBufferId id,
104 const gfx::Size& size,
105 gfx::GpuMemoryBuffer::Format format,
106 gfx::GpuMemoryBuffer::Usage usage,
107 int client_id,
108 gfx::PluginWindowHandle surface_handle) {
109 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
110 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
112 &kCFTypeDictionaryKeyCallBacks,
113 &kCFTypeDictionaryValueCallBacks));
114 AddIntegerValue(properties, kIOSurfaceWidth, size.width());
115 AddIntegerValue(properties, kIOSurfaceHeight, size.height());
116 AddIntegerValue(properties, kIOSurfaceBytesPerElement, BytesPerPixel(format));
117 AddIntegerValue(properties, kIOSurfacePixelFormat, PixelFormat(format));
118 // TODO(reveman): Remove this when using a mach_port_t to transfer
119 // IOSurface to browser and renderer process. crbug.com/323304
120 AddBooleanValue(properties, kIOSurfaceIsGlobal, true);
122 base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceCreate(properties));
123 if (!io_surface)
124 return gfx::GpuMemoryBufferHandle();
127 base::AutoLock lock(io_surfaces_lock_);
129 IOSurfaceMapKey key(id, client_id);
130 DCHECK(io_surfaces_.find(key) == io_surfaces_.end());
131 io_surfaces_[key] = io_surface;
134 gfx::GpuMemoryBufferHandle handle;
135 handle.type = gfx::IO_SURFACE_BUFFER;
136 handle.id = id;
137 handle.io_surface_id = IOSurfaceGetID(io_surface);
138 return handle;
141 void GpuMemoryBufferFactoryIOSurface::DestroyGpuMemoryBuffer(
142 gfx::GpuMemoryBufferId id,
143 int client_id) {
144 base::AutoLock lock(io_surfaces_lock_);
146 IOSurfaceMapKey key(id, client_id);
147 IOSurfaceMap::iterator it = io_surfaces_.find(key);
148 if (it != io_surfaces_.end())
149 io_surfaces_.erase(it);
152 gpu::ImageFactory* GpuMemoryBufferFactoryIOSurface::AsImageFactory() {
153 return this;
156 scoped_refptr<gfx::GLImage>
157 GpuMemoryBufferFactoryIOSurface::CreateImageForGpuMemoryBuffer(
158 const gfx::GpuMemoryBufferHandle& handle,
159 const gfx::Size& size,
160 gfx::GpuMemoryBuffer::Format format,
161 unsigned internalformat,
162 int client_id) {
163 base::AutoLock lock(io_surfaces_lock_);
165 DCHECK_EQ(handle.type, gfx::IO_SURFACE_BUFFER);
166 IOSurfaceMapKey key(handle.id, client_id);
167 IOSurfaceMap::iterator it = io_surfaces_.find(key);
168 if (it == io_surfaces_.end())
169 return scoped_refptr<gfx::GLImage>();
171 scoped_refptr<gfx::GLImageIOSurface> image(new gfx::GLImageIOSurface(size));
172 if (!image->Initialize(it->second.get()))
173 return scoped_refptr<gfx::GLImage>();
175 return image;
178 } // namespace content