Home | History | Annotate | Download | only in client
      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