15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/numerics/safe_math.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/gl/gl_bindings.h" 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content { 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Noop() { 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory( 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Size& size, 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DestructionCallback& callback, 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::SharedMemory> shared_memory) 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : GpuMemoryBufferImpl(size, internalformat, callback), 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci shared_memory_(shared_memory.Pass()) { 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GpuMemoryBufferImplSharedMemory::~GpuMemoryBufferImplSharedMemory() { 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferImplSharedMemory::Create(const gfx::Size& size, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned usage, 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const CreationCallback& callback) { 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, internalformat, usage)); 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!shared_memory->CreateAnonymous(size.GetArea() * 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BytesPerPixel(internalformat))) { 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(scoped_ptr<GpuMemoryBufferImpl>()); 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run( 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_scoped_ptr<GpuMemoryBufferImpl>(new GpuMemoryBufferImplSharedMemory( 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, internalformat, base::Bind(&Noop), shared_memory.Pass()))); 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Size& size, 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unsigned internalformat, 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::ProcessHandle child_process, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AllocationCallback& callback) { 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsLayoutSupported(size, internalformat)); 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::SharedMemory shared_memory; 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!shared_memory.CreateAnonymous(size.GetArea() * 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BytesPerPixel(internalformat))) { 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(gfx::GpuMemoryBufferHandle()); 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::GpuMemoryBufferHandle handle; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) handle.type = gfx::SHARED_MEMORY_BUFFER; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shared_memory.GiveToProcess(child_process, &handle.handle); 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(handle); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<GpuMemoryBufferImpl> 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGpuMemoryBufferImplSharedMemory::CreateFromHandle( 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::GpuMemoryBufferHandle& handle, 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Size& size, 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DestructionCallback& callback) { 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(IsLayoutSupported(size, internalformat)); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!base::SharedMemory::IsHandleValid(handle.handle)) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return scoped_ptr<GpuMemoryBufferImpl>(); 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return make_scoped_ptr<GpuMemoryBufferImpl>( 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new GpuMemoryBufferImplSharedMemory( 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci internalformat, 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_scoped_ptr(new base::SharedMemory(handle.handle, false)))); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GpuMemoryBufferImplSharedMemory::IsLayoutSupported( 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Size& size, 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned internalformat) { 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::CheckedNumeric<int> buffer_size = size.width(); 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) buffer_size *= size.height(); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) buffer_size *= BytesPerPixel(internalformat); 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return buffer_size.IsValid(); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GpuMemoryBufferImplSharedMemory::IsUsageSupported(unsigned usage) { 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (usage) { 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case GL_IMAGE_MAP_CHROMIUM: 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) default: 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Size& size, 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned internalformat, 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned usage) { 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return IsLayoutSupported(size, internalformat) && IsUsageSupported(usage); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void* GpuMemoryBufferImplSharedMemory::Map() { 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!mapped_); 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(internalformat_))) 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return NULL; 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mapped_ = true; 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return shared_memory_->memory(); 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GpuMemoryBufferImplSharedMemory::Unmap() { 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(mapped_); 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) shared_memory_->Unmap(); 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mapped_ = false; 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)uint32 GpuMemoryBufferImplSharedMemory::GetStride() const { 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return size_.width() * BytesPerPixel(internalformat_); 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSharedMemory::GetHandle() const { 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle; 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) handle.type = gfx::SHARED_MEMORY_BUFFER; 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) handle.handle = shared_memory_->handle(); 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return handle; 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace content 144