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