• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)22 PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance)
23     : Resource(ppapi::OBJECT_IS_IMPL, instance), size_(0), map_count_(0) {}
24 
~PPB_Buffer_Impl()25 PPB_Buffer_Impl::~PPB_Buffer_Impl() {}
26 
27 // static
Create(PP_Instance instance,uint32_t size)28 PP_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)36 scoped_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()45 PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { return this; }
46 
AsPPB_Buffer_API()47 PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { return this; }
48 
Init(uint32_t size)49 bool 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)58 PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) {
59   *size_in_bytes = size_;
60   return PP_TRUE;
61 }
62 
IsMapped()63 PP_Bool PPB_Buffer_Impl::IsMapped() {
64   return PP_FromBool(!!shared_memory_->memory());
65 }
66 
Map()67 void* 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()75 void PPB_Buffer_Impl::Unmap() {
76   if (--map_count_ == 0)
77     shared_memory_->Unmap();
78 }
79 
GetSharedMemory(int * shm_handle)80 int32_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)91 BufferAutoMapper::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()97 BufferAutoMapper::~BufferAutoMapper() {
98   if (needs_unmap_)
99     api_->Unmap();
100 }
101 
102 }  // namespace content
103