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