Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 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/renderer/pepper/ppb_buffer_impl.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/logging.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "content/renderer/pepper/common.h"
     12 #include "content/renderer/render_thread_impl.h"
     13 #include "ppapi/c/dev/ppb_buffer_dev.h"
     14 #include "ppapi/c/pp_errors.h"
     15 #include "ppapi/c/pp_instance.h"
     16 #include "ppapi/c/pp_resource.h"
     17 
     18 using ppapi::thunk::PPB_Buffer_API;
     19 
     20 namespace content {
     21 
     22 PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance)
     23     : Resource(ppapi::OBJECT_IS_IMPL, instance),
     24       size_(0),
     25       map_count_(0) {
     26 }
     27 
     28 PPB_Buffer_Impl::~PPB_Buffer_Impl() {
     29 }
     30 
     31 // static
     32 PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) {
     33   scoped_refptr<PPB_Buffer_Impl> new_resource(CreateResource(instance, size));
     34   if (new_resource.get())
     35     return new_resource->GetReference();
     36   return 0;
     37 }
     38 
     39 // static
     40 scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource(
     41     PP_Instance instance,
     42     uint32_t size) {
     43   scoped_refptr<PPB_Buffer_Impl> buffer(new PPB_Buffer_Impl(instance));
     44   if (!buffer->Init(size))
     45     return scoped_refptr<PPB_Buffer_Impl>();
     46   return buffer;
     47 }
     48 
     49 PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() {
     50   return this;
     51 }
     52 
     53 PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() {
     54   return this;
     55 }
     56 
     57 bool PPB_Buffer_Impl::Init(uint32_t size) {
     58   if (size == 0)
     59     return false;
     60   size_ = size;
     61   shared_memory_.reset(
     62       RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release());
     63   return shared_memory_.get() != NULL;
     64 }
     65 
     66 PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) {
     67   *size_in_bytes = size_;
     68   return PP_TRUE;
     69 }
     70 
     71 PP_Bool PPB_Buffer_Impl::IsMapped() {
     72   return PP_FromBool(!!shared_memory_->memory());
     73 }
     74 
     75 void* PPB_Buffer_Impl::Map() {
     76   DCHECK(size_);
     77   DCHECK(shared_memory_.get());
     78   if (map_count_++ == 0)
     79     shared_memory_->Map(size_);
     80   return shared_memory_->memory();
     81 }
     82 
     83 void PPB_Buffer_Impl::Unmap() {
     84   if (--map_count_ == 0)
     85     shared_memory_->Unmap();
     86 }
     87 
     88 int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) {
     89 #if defined(OS_POSIX)
     90   *shm_handle = shared_memory_->handle().fd;
     91 #elif defined(OS_WIN)
     92   *shm_handle = reinterpret_cast<int>(
     93       shared_memory_->handle());
     94 #else
     95 #error "Platform not supported."
     96 #endif
     97   return PP_OK;
     98 }
     99 
    100 BufferAutoMapper::BufferAutoMapper(PPB_Buffer_API* api) : api_(api) {
    101   needs_unmap_ = !PP_ToBool(api->IsMapped());
    102   data_ = api->Map();
    103   api->Describe(&size_);
    104 }
    105 
    106 BufferAutoMapper::~BufferAutoMapper() {
    107   if (needs_unmap_)
    108     api_->Unmap();
    109 }
    110 
    111 }  // namespace content
    112