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 13 namespace content { 14 namespace { 15 16 base::StaticAtomicSequenceNumber g_next_buffer_id; 17 18 void Noop() { 19 } 20 21 void 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 32 void 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 42 GpuMemoryBufferImplIOSurface::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 51 GpuMemoryBufferImplIOSurface::~GpuMemoryBufferImplIOSurface() { 52 } 53 54 // static 55 void 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 73 void 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 92 scoped_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 109 bool 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 119 bool 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 129 bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported( 130 unsigned internalformat, 131 unsigned usage) { 132 return IsFormatSupported(internalformat) && IsUsageSupported(usage); 133 } 134 135 // static 136 uint32 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 146 void* GpuMemoryBufferImplIOSurface::Map() { 147 DCHECK(!mapped_); 148 IOSurfaceLock(io_surface_, 0, NULL); 149 mapped_ = true; 150 return IOSurfaceGetBaseAddress(io_surface_); 151 } 152 153 void GpuMemoryBufferImplIOSurface::Unmap() { 154 DCHECK(mapped_); 155 IOSurfaceUnlock(io_surface_, 0, NULL); 156 mapped_ = false; 157 } 158 159 uint32 GpuMemoryBufferImplIOSurface::GetStride() const { 160 return IOSurfaceGetBytesPerRow(io_surface_); 161 } 162 163 gfx::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