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