1 // Copyright 2014 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_shared_memory.h" 6 7 #include "base/bind.h" 8 #include "base/numerics/safe_math.h" 9 #include "ui/gl/gl_bindings.h" 10 11 namespace content { 12 namespace { 13 14 void Noop() { 15 } 16 17 } // namespace 18 19 GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory( 20 const gfx::Size& size, 21 unsigned internalformat, 22 const DestructionCallback& callback, 23 scoped_ptr<base::SharedMemory> shared_memory) 24 : GpuMemoryBufferImpl(size, internalformat, callback), 25 shared_memory_(shared_memory.Pass()) { 26 } 27 28 GpuMemoryBufferImplSharedMemory::~GpuMemoryBufferImplSharedMemory() { 29 } 30 31 // static 32 void GpuMemoryBufferImplSharedMemory::Create(const gfx::Size& size, 33 unsigned internalformat, 34 unsigned usage, 35 const CreationCallback& callback) { 36 DCHECK(GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( 37 size, internalformat, usage)); 38 39 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 40 if (!shared_memory->CreateAnonymous(size.GetArea() * 41 BytesPerPixel(internalformat))) { 42 callback.Run(scoped_ptr<GpuMemoryBufferImpl>()); 43 return; 44 } 45 46 callback.Run( 47 make_scoped_ptr<GpuMemoryBufferImpl>(new GpuMemoryBufferImplSharedMemory( 48 size, internalformat, base::Bind(&Noop), shared_memory.Pass()))); 49 } 50 51 // static 52 void GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 53 const gfx::Size& size, 54 unsigned internalformat, 55 base::ProcessHandle child_process, 56 const AllocationCallback& callback) { 57 DCHECK(IsLayoutSupported(size, internalformat)); 58 base::SharedMemory shared_memory; 59 if (!shared_memory.CreateAnonymous(size.GetArea() * 60 BytesPerPixel(internalformat))) { 61 callback.Run(gfx::GpuMemoryBufferHandle()); 62 return; 63 } 64 gfx::GpuMemoryBufferHandle handle; 65 handle.type = gfx::SHARED_MEMORY_BUFFER; 66 shared_memory.GiveToProcess(child_process, &handle.handle); 67 callback.Run(handle); 68 } 69 70 // static 71 scoped_ptr<GpuMemoryBufferImpl> 72 GpuMemoryBufferImplSharedMemory::CreateFromHandle( 73 const gfx::GpuMemoryBufferHandle& handle, 74 const gfx::Size& size, 75 unsigned internalformat, 76 const DestructionCallback& callback) { 77 DCHECK(IsLayoutSupported(size, internalformat)); 78 79 if (!base::SharedMemory::IsHandleValid(handle.handle)) 80 return scoped_ptr<GpuMemoryBufferImpl>(); 81 82 return make_scoped_ptr<GpuMemoryBufferImpl>( 83 new GpuMemoryBufferImplSharedMemory( 84 size, 85 internalformat, 86 callback, 87 make_scoped_ptr(new base::SharedMemory(handle.handle, false)))); 88 } 89 90 // static 91 bool GpuMemoryBufferImplSharedMemory::IsLayoutSupported( 92 const gfx::Size& size, 93 unsigned internalformat) { 94 base::CheckedNumeric<int> buffer_size = size.width(); 95 buffer_size *= size.height(); 96 buffer_size *= BytesPerPixel(internalformat); 97 return buffer_size.IsValid(); 98 } 99 100 // static 101 bool GpuMemoryBufferImplSharedMemory::IsUsageSupported(unsigned usage) { 102 switch (usage) { 103 case GL_IMAGE_MAP_CHROMIUM: 104 return true; 105 default: 106 return false; 107 } 108 } 109 110 // static 111 bool GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( 112 const gfx::Size& size, 113 unsigned internalformat, 114 unsigned usage) { 115 return IsLayoutSupported(size, internalformat) && IsUsageSupported(usage); 116 } 117 118 void* GpuMemoryBufferImplSharedMemory::Map() { 119 DCHECK(!mapped_); 120 if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(internalformat_))) 121 return NULL; 122 mapped_ = true; 123 return shared_memory_->memory(); 124 } 125 126 void GpuMemoryBufferImplSharedMemory::Unmap() { 127 DCHECK(mapped_); 128 shared_memory_->Unmap(); 129 mapped_ = false; 130 } 131 132 uint32 GpuMemoryBufferImplSharedMemory::GetStride() const { 133 return size_.width() * BytesPerPixel(internalformat_); 134 } 135 136 gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSharedMemory::GetHandle() const { 137 gfx::GpuMemoryBufferHandle handle; 138 handle.type = gfx::SHARED_MEMORY_BUFFER; 139 handle.handle = shared_memory_->handle(); 140 return handle; 141 } 142 143 } // namespace content 144