1// Copyright 2013 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. 4 5#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" 6 7#include "base/atomic_sequence_num.h" 8#include "base/bind.h" 9#include "base/logging.h" 10#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" 11#include "ui/gl/gl_bindings.h" 12 13namespace content { 14namespace { 15 16base::StaticAtomicSequenceNumber g_next_buffer_id; 17 18void Noop() { 19} 20 21void GpuMemoryBufferCreated( 22 const gfx::Size& size, 23 unsigned internalformat, 24 const GpuMemoryBufferImpl::CreationCallback& callback, 25 const gfx::GpuMemoryBufferHandle& handle) { 26 DCHECK_EQ(gfx::IO_SURFACE_BUFFER, handle.type); 27 28 callback.Run(GpuMemoryBufferImplIOSurface::CreateFromHandle( 29 handle, size, internalformat, base::Bind(&Noop))); 30} 31 32void GpuMemoryBufferCreatedForChildProcess( 33 const GpuMemoryBufferImpl::AllocationCallback& callback, 34 const gfx::GpuMemoryBufferHandle& handle) { 35 DCHECK_EQ(gfx::IO_SURFACE_BUFFER, handle.type); 36 37 callback.Run(handle); 38} 39 40} // namespace 41 42GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface( 43 const gfx::Size& size, 44 unsigned internalformat, 45 const DestructionCallback& callback, 46 IOSurfaceRef io_surface) 47 : GpuMemoryBufferImpl(size, internalformat, callback), 48 io_surface_(io_surface) { 49} 50 51GpuMemoryBufferImplIOSurface::~GpuMemoryBufferImplIOSurface() { 52} 53 54// static 55void GpuMemoryBufferImplIOSurface::Create(const gfx::Size& size, 56 unsigned internalformat, 57 unsigned usage, 58 int client_id, 59 const CreationCallback& callback) { 60 gfx::GpuMemoryBufferHandle handle; 61 handle.type = gfx::IO_SURFACE_BUFFER; 62 handle.global_id.primary_id = g_next_buffer_id.GetNext(); 63 handle.global_id.secondary_id = client_id; 64 GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer( 65 handle, 66 size, 67 internalformat, 68 usage, 69 base::Bind(&GpuMemoryBufferCreated, size, internalformat, callback)); 70} 71 72// static 73void GpuMemoryBufferImplIOSurface::AllocateForChildProcess( 74 const gfx::Size& size, 75 unsigned internalformat, 76 unsigned usage, 77 int child_client_id, 78 const AllocationCallback& callback) { 79 gfx::GpuMemoryBufferHandle handle; 80 handle.type = gfx::IO_SURFACE_BUFFER; 81 handle.global_id.primary_id = g_next_buffer_id.GetNext(); 82 handle.global_id.secondary_id = child_client_id; 83 GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer( 84 handle, 85 size, 86 internalformat, 87 usage, 88 base::Bind(&GpuMemoryBufferCreatedForChildProcess, callback)); 89} 90 91// static 92scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImplIOSurface::CreateFromHandle( 93 const gfx::GpuMemoryBufferHandle& handle, 94 const gfx::Size& size, 95 unsigned internalformat, 96 const DestructionCallback& callback) { 97 DCHECK(IsFormatSupported(internalformat)); 98 99 base::ScopedCFTypeRef<IOSurfaceRef> io_surface( 100 IOSurfaceLookup(handle.io_surface_id)); 101 if (!io_surface) 102 return scoped_ptr<GpuMemoryBufferImpl>(); 103 104 return make_scoped_ptr<GpuMemoryBufferImpl>(new GpuMemoryBufferImplIOSurface( 105 size, internalformat, callback, io_surface.get())); 106} 107 108// static 109bool GpuMemoryBufferImplIOSurface::IsFormatSupported(unsigned internalformat) { 110 switch (internalformat) { 111 case GL_BGRA8_EXT: 112 return true; 113 default: 114 return false; 115 } 116} 117 118// static 119bool GpuMemoryBufferImplIOSurface::IsUsageSupported(unsigned usage) { 120 switch (usage) { 121 case GL_IMAGE_MAP_CHROMIUM: 122 return true; 123 default: 124 return false; 125 } 126} 127 128// static 129bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported( 130 unsigned internalformat, 131 unsigned usage) { 132 return IsFormatSupported(internalformat) && IsUsageSupported(usage); 133} 134 135// static 136uint32 GpuMemoryBufferImplIOSurface::PixelFormat(unsigned internalformat) { 137 switch (internalformat) { 138 case GL_BGRA8_EXT: 139 return 'BGRA'; 140 default: 141 NOTREACHED(); 142 return 0; 143 } 144} 145 146void* GpuMemoryBufferImplIOSurface::Map() { 147 DCHECK(!mapped_); 148 IOSurfaceLock(io_surface_, 0, NULL); 149 mapped_ = true; 150 return IOSurfaceGetBaseAddress(io_surface_); 151} 152 153void GpuMemoryBufferImplIOSurface::Unmap() { 154 DCHECK(mapped_); 155 IOSurfaceUnlock(io_surface_, 0, NULL); 156 mapped_ = false; 157} 158 159uint32 GpuMemoryBufferImplIOSurface::GetStride() const { 160 return IOSurfaceGetBytesPerRow(io_surface_); 161} 162 163gfx::GpuMemoryBufferHandle GpuMemoryBufferImplIOSurface::GetHandle() const { 164 gfx::GpuMemoryBufferHandle handle; 165 handle.type = gfx::IO_SURFACE_BUFFER; 166 handle.io_surface_id = IOSurfaceGetID(io_surface_); 167 return handle; 168} 169 170} // namespace content 171