Chromium Code Reviews| 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 eeec46039404502fccf79b4e59ea3d3154d6dc90..b8732788b0e69126be955fb29818ce5d2e76ac48 100644 |
| --- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
| +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc |
| @@ -9,7 +9,9 @@ |
| #include <vector> |
| #include "base/logging.h" |
| +#include "content/common/gpu/client/gpu_memory_buffer_impl.h" |
| #include "content/common/mac/io_surface_manager.h" |
| +#include "ui/gfx/buffer_format_util.h" |
| #include "ui/gl/gl_image_io_surface.h" |
| namespace content { |
| @@ -26,6 +28,7 @@ void AddIntegerValue(CFMutableDictionaryRef dictionary, |
| int32 BytesPerPixel(gfx::BufferFormat format) { |
| switch (format) { |
| case gfx::BufferFormat::R_8: |
| + case gfx::BufferFormat::YUV_420_BIPLANAR: |
| return 1; |
| case gfx::BufferFormat::BGRA_8888: |
| return 4; |
| @@ -52,6 +55,8 @@ int32 PixelFormat(gfx::BufferFormat format) { |
| return 'L008'; |
| case gfx::BufferFormat::BGRA_8888: |
| return 'BGRA'; |
| + case gfx::BufferFormat::YUV_420_BIPLANAR: |
| + return '420v'; |
| case gfx::BufferFormat::ATC: |
| case gfx::BufferFormat::ATCIA: |
| case gfx::BufferFormat::DXT1: |
| @@ -74,7 +79,10 @@ 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}, |
| +}; |
| } // namespace |
| @@ -111,16 +119,46 @@ 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)); |
| + size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); |
| + DCHECK_GT(num_planes, 0u); |
| + if (num_planes == 1) { |
|
reveman
2015/08/11 08:20:08
This is unfortunate. What happens if we remove thi
Andre
2015/08/11 18:15:44
Done.
I removed the if statement, and it seems to
|
| + AddIntegerValue( |
| + properties, kIOSurfaceBytesPerElement, BytesPerPixel(format)); |
| + } else { |
| + base::ScopedCFTypeRef<CFMutableArrayRef> planes(CFArrayCreateMutable( |
| + kCFAllocatorDefault, num_planes, &kCFTypeArrayCallBacks)); |
| + |
| + for (size_t plane = 0; plane < num_planes; ++plane) { |
| + size_t factor = GpuMemoryBufferImpl::SubsamplingFactor(format, plane); |
| + gfx::Size plane_size(size.width() / factor, size.height() / factor); |
| + size_t row_size; |
| + bool valid_row_size = GpuMemoryBufferImpl::RowSizeInBytes( |
| + size.width(), format, plane, &row_size); |
| + DCHECK(valid_row_size); |
| + |
| + base::ScopedCFTypeRef<CFMutableDictionaryRef> plane_info( |
| + CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
| + &kCFTypeDictionaryKeyCallBacks, |
| + &kCFTypeDictionaryValueCallBacks)); |
| + AddIntegerValue(plane_info, kIOSurfacePlaneWidth, plane_size.width()); |
| + AddIntegerValue(plane_info, kIOSurfacePlaneHeight, plane_size.height()); |
| + AddIntegerValue(plane_info, kIOSurfacePlaneBytesPerElement, |
| + row_size / plane_size.width()); |
|
reveman
2015/08/11 08:20:08
Instead of using RowSizeInBytes here, can we repla
Andre
2015/08/11 18:15:44
Great idea, done.
|
| + |
| + CFArrayAppendValue(planes, plane_info); |
| + } |
| + |
| + CFDictionaryAddValue(properties, kIOSurfacePlaneInfo, planes); |
| + } |
| + |
| base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceCreate(properties)); |
| if (!io_surface) |
| return gfx::GpuMemoryBufferHandle(); |