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"
15 void AddBooleanValue(CFMutableDictionaryRef dictionary
,
16 const CFStringRef key
,
19 dictionary
, key
, value
? kCFBooleanTrue
: kCFBooleanFalse
);
22 void AddIntegerValue(CFMutableDictionaryRef dictionary
,
23 const CFStringRef key
,
25 base::ScopedCFTypeRef
<CFNumberRef
> number(
26 CFNumberCreate(NULL
, kCFNumberSInt32Type
, &value
));
27 CFDictionaryAddValue(dictionary
, key
, number
.get());
30 int32
BytesPerPixel(gfx::GpuMemoryBuffer::Format format
) {
32 case gfx::GpuMemoryBuffer::BGRA_8888
:
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
:
50 int32
PixelFormat(gfx::GpuMemoryBuffer::Format format
) {
52 case gfx::GpuMemoryBuffer::BGRA_8888
:
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
:
70 const GpuMemoryBufferFactory::Configuration kSupportedConfigurations
[] = {
71 { gfx::GpuMemoryBuffer::BGRA_8888
, gfx::GpuMemoryBuffer::MAP
}
76 GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() {
79 GpuMemoryBufferFactoryIOSurface::~GpuMemoryBufferFactoryIOSurface() {
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
)
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
,
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
));
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
;
137 handle
.io_surface_id
= IOSurfaceGetID(io_surface
);
141 void GpuMemoryBufferFactoryIOSurface::DestroyGpuMemoryBuffer(
142 gfx::GpuMemoryBufferId 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() {
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
,
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
>();
178 } // namespace content