Index: content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
index 327d4bc8796d05087886fa1619a6a01e39a2e47f..0bb014523685bf756b10ccdae19806b3c085fcf9 100644 |
--- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
+++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
@@ -77,7 +77,11 @@ const GpuMemoryBufferFactory::Configuration kSupportedConfigurations[] = { |
{gfx::BufferFormat::R_8, gfx::BufferUsage::PERSISTENT_MAP}, |
{gfx::BufferFormat::R_8, gfx::BufferUsage::MAP}, |
{gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP}, |
- {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}}; |
+ {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}, |
+ {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::MAP}, |
+ {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::PERSISTENT_MAP}, |
+ {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::SCANOUT}, |
+}; |
} // namespace |
@@ -114,16 +118,42 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( |
gfx::BufferUsage usage, |
int client_id, |
gfx::PluginWindowHandle surface_handle) { |
- base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; |
- properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, |
- 0, |
- &kCFTypeDictionaryKeyCallBacks, |
- &kCFTypeDictionaryValueCallBacks)); |
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> properties( |
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
+ &kCFTypeDictionaryKeyCallBacks, |
+ &kCFTypeDictionaryValueCallBacks)); |
AddIntegerValue(properties, kIOSurfaceWidth, size.width()); |
AddIntegerValue(properties, kIOSurfaceHeight, size.height()); |
- AddIntegerValue(properties, kIOSurfaceBytesPerElement, BytesPerPixel(format)); |
AddIntegerValue(properties, kIOSurfacePixelFormat, PixelFormat(format)); |
+ if (format == gfx::BufferFormat::YUV_420_BIPLANAR) { |
+ // This format has 2 planes, Y and interleaved UV. |
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> y_plane( |
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
+ &kCFTypeDictionaryKeyCallBacks, |
+ &kCFTypeDictionaryValueCallBacks)); |
+ AddIntegerValue(y_plane, kIOSurfacePlaneWidth, size.width()); |
+ AddIntegerValue(y_plane, kIOSurfacePlaneHeight, size.height()); |
+ AddIntegerValue(y_plane, kIOSurfacePlaneBytesPerElement, 1); |
+ |
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> uv_plane( |
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
+ &kCFTypeDictionaryKeyCallBacks, |
+ &kCFTypeDictionaryValueCallBacks)); |
+ AddIntegerValue(uv_plane, kIOSurfacePlaneWidth, size.width() / 2); |
+ AddIntegerValue(uv_plane, kIOSurfacePlaneHeight, size.height() / 2); |
+ AddIntegerValue(uv_plane, kIOSurfacePlaneBytesPerElement, 2); |
+ |
+ base::ScopedCFTypeRef<CFMutableArrayRef> planes( |
+ CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks)); |
+ CFArrayAppendValue(planes, y_plane); |
+ CFArrayAppendValue(planes, uv_plane); |
+ CFDictionaryAddValue(properties, kIOSurfacePlaneInfo, planes); |
+ } else { |
+ AddIntegerValue( |
+ properties, kIOSurfaceBytesPerElement, BytesPerPixel(format)); |
+ } |
+ |
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceCreate(properties)); |
if (!io_surface) |
return gfx::GpuMemoryBufferHandle(); |