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(); |