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>
11 #include "base/logging.h"
12 #include "content/common/mac/io_surface_manager.h"
13 #include "ui/gl/gl_image_io_surface.h"
18 void AddIntegerValue(CFMutableDictionaryRef dictionary
,
19 const CFStringRef key
,
21 base::ScopedCFTypeRef
<CFNumberRef
> number(
22 CFNumberCreate(NULL
, kCFNumberSInt32Type
, &value
));
23 CFDictionaryAddValue(dictionary
, key
, number
.get());
26 int32
BytesPerPixel(gfx::GpuMemoryBuffer::Format format
) {
28 case gfx::GpuMemoryBuffer::R_8
:
30 case gfx::GpuMemoryBuffer::BGRA_8888
:
32 case gfx::GpuMemoryBuffer::ATC
:
33 case gfx::GpuMemoryBuffer::ATCIA
:
34 case gfx::GpuMemoryBuffer::DXT1
:
35 case gfx::GpuMemoryBuffer::DXT5
:
36 case gfx::GpuMemoryBuffer::ETC1
:
37 case gfx::GpuMemoryBuffer::RGBA_4444
:
38 case gfx::GpuMemoryBuffer::RGBA_8888
:
39 case gfx::GpuMemoryBuffer::RGBX_8888
:
40 case gfx::GpuMemoryBuffer::YUV_420
:
49 int32
PixelFormat(gfx::GpuMemoryBuffer::Format format
) {
51 case gfx::GpuMemoryBuffer::R_8
:
53 case gfx::GpuMemoryBuffer::BGRA_8888
:
55 case gfx::GpuMemoryBuffer::ATC
:
56 case gfx::GpuMemoryBuffer::ATCIA
:
57 case gfx::GpuMemoryBuffer::DXT1
:
58 case gfx::GpuMemoryBuffer::DXT5
:
59 case gfx::GpuMemoryBuffer::ETC1
:
60 case gfx::GpuMemoryBuffer::RGBA_4444
:
61 case gfx::GpuMemoryBuffer::RGBA_8888
:
62 case gfx::GpuMemoryBuffer::RGBX_8888
:
63 case gfx::GpuMemoryBuffer::YUV_420
:
72 const GpuMemoryBufferFactory::Configuration kSupportedConfigurations
[] = {
73 {gfx::GpuMemoryBuffer::BGRA_8888
, gfx::GpuMemoryBuffer::SCANOUT
},
74 {gfx::GpuMemoryBuffer::R_8
, gfx::GpuMemoryBuffer::PERSISTENT_MAP
},
75 {gfx::GpuMemoryBuffer::R_8
, gfx::GpuMemoryBuffer::MAP
},
76 {gfx::GpuMemoryBuffer::BGRA_8888
, gfx::GpuMemoryBuffer::PERSISTENT_MAP
},
77 {gfx::GpuMemoryBuffer::BGRA_8888
, gfx::GpuMemoryBuffer::MAP
}};
81 GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() {
84 GpuMemoryBufferFactoryIOSurface::~GpuMemoryBufferFactoryIOSurface() {
88 bool GpuMemoryBufferFactoryIOSurface::IsGpuMemoryBufferConfigurationSupported(
89 gfx::GpuMemoryBuffer::Format format
,
90 gfx::GpuMemoryBuffer::Usage usage
) {
91 for (auto& configuration
: kSupportedConfigurations
) {
92 if (configuration
.format
== format
&& configuration
.usage
== usage
)
99 void GpuMemoryBufferFactoryIOSurface::GetSupportedGpuMemoryBufferConfigurations(
100 std::vector
<Configuration
>* configurations
) {
101 configurations
->assign(
102 kSupportedConfigurations
,
103 kSupportedConfigurations
+ arraysize(kSupportedConfigurations
));
106 gfx::GpuMemoryBufferHandle
107 GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
108 gfx::GpuMemoryBufferId id
,
109 const gfx::Size
& size
,
110 gfx::GpuMemoryBuffer::Format format
,
111 gfx::GpuMemoryBuffer::Usage usage
,
113 gfx::PluginWindowHandle surface_handle
) {
114 base::ScopedCFTypeRef
<CFMutableDictionaryRef
> properties
;
115 properties
.reset(CFDictionaryCreateMutable(kCFAllocatorDefault
,
117 &kCFTypeDictionaryKeyCallBacks
,
118 &kCFTypeDictionaryValueCallBacks
));
119 AddIntegerValue(properties
, kIOSurfaceWidth
, size
.width());
120 AddIntegerValue(properties
, kIOSurfaceHeight
, size
.height());
121 AddIntegerValue(properties
, kIOSurfaceBytesPerElement
, BytesPerPixel(format
));
122 AddIntegerValue(properties
, kIOSurfacePixelFormat
, PixelFormat(format
));
124 base::ScopedCFTypeRef
<IOSurfaceRef
> io_surface(IOSurfaceCreate(properties
));
126 return gfx::GpuMemoryBufferHandle();
128 if (!IOSurfaceManager::GetInstance()->RegisterIOSurface(id
, client_id
,
130 return gfx::GpuMemoryBufferHandle();
134 base::AutoLock
lock(io_surfaces_lock_
);
136 IOSurfaceMapKey
key(id
, client_id
);
137 DCHECK(io_surfaces_
.find(key
) == io_surfaces_
.end());
138 io_surfaces_
[key
] = io_surface
;
141 gfx::GpuMemoryBufferHandle handle
;
142 handle
.type
= gfx::IO_SURFACE_BUFFER
;
147 void GpuMemoryBufferFactoryIOSurface::DestroyGpuMemoryBuffer(
148 gfx::GpuMemoryBufferId id
,
151 base::AutoLock
lock(io_surfaces_lock_
);
153 IOSurfaceMapKey
key(id
, client_id
);
154 DCHECK(io_surfaces_
.find(key
) != io_surfaces_
.end());
155 io_surfaces_
.erase(key
);
158 IOSurfaceManager::GetInstance()->UnregisterIOSurface(id
, client_id
);
161 gpu::ImageFactory
* GpuMemoryBufferFactoryIOSurface::AsImageFactory() {
165 scoped_refptr
<gfx::GLImage
>
166 GpuMemoryBufferFactoryIOSurface::CreateImageForGpuMemoryBuffer(
167 const gfx::GpuMemoryBufferHandle
& handle
,
168 const gfx::Size
& size
,
169 gfx::GpuMemoryBuffer::Format format
,
170 unsigned internalformat
,
172 base::AutoLock
lock(io_surfaces_lock_
);
174 DCHECK_EQ(handle
.type
, gfx::IO_SURFACE_BUFFER
);
175 IOSurfaceMapKey
key(handle
.id
, client_id
);
176 IOSurfaceMap::iterator it
= io_surfaces_
.find(key
);
177 if (it
== io_surfaces_
.end())
178 return scoped_refptr
<gfx::GLImage
>();
180 scoped_refptr
<gfx::GLImageIOSurface
> image(
181 new gfx::GLImageIOSurface(size
, internalformat
));
182 if (!image
->Initialize(it
->second
.get(), format
))
183 return scoped_refptr
<gfx::GLImage
>();
188 } // namespace content