OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/ppb_image_data_impl.h" | 5 #include "content/renderer/pepper/ppb_image_data_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "content/common/view_messages.h" | 12 #include "content/common/view_messages.h" |
13 #include "content/renderer/pepper/common.h" | 13 #include "content/renderer/pepper/common.h" |
14 #include "content/renderer/render_thread_impl.h" | 14 #include "content/renderer/render_thread_impl.h" |
15 #include "ppapi/c/pp_errors.h" | 15 #include "ppapi/c/pp_errors.h" |
16 #include "ppapi/c/pp_instance.h" | 16 #include "ppapi/c/pp_instance.h" |
17 #include "ppapi/c/pp_resource.h" | 17 #include "ppapi/c/pp_resource.h" |
18 #include "ppapi/c/ppb_image_data.h" | 18 #include "ppapi/c/ppb_image_data.h" |
19 #include "ppapi/thunk/thunk.h" | 19 #include "ppapi/thunk/thunk.h" |
20 #include "skia/ext/platform_canvas.h" | 20 #include "skia/ext/platform_canvas.h" |
21 #include "third_party/skia/include/core/SkColorPriv.h" | 21 #include "third_party/skia/include/core/SkColorPriv.h" |
22 #include "ui/surface/transport_dib.h" | 22 #include "ui/surface/transport_dib.h" |
23 | 23 |
24 using ppapi::thunk::PPB_ImageData_API; | 24 using ppapi::thunk::PPB_ImageData_API; |
25 | 25 |
26 namespace content { | 26 namespace content { |
27 | 27 |
28 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, | 28 PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, |
29 PPB_ImageData_Shared::ImageDataType type) | 29 PPB_ImageData_Shared::ImageDataType type, |
30 bool is_browser_allocated) | |
bbudge
2013/11/11 12:24:06
Couldn't we just call IsBrowserAllocated on the ty
bbudge
2013/11/11 19:09:15
Never mind, I realized this is the whole point of
| |
30 : Resource(ppapi::OBJECT_IS_IMPL, instance), | 31 : Resource(ppapi::OBJECT_IS_IMPL, instance), |
31 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), | 32 format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), |
32 width_(0), | 33 width_(0), |
33 height_(0) { | 34 height_(0) { |
34 switch (type) { | 35 switch (type) { |
35 case PPB_ImageData_Shared::PLATFORM: | 36 case PPB_ImageData_Shared::PLATFORM: |
36 backend_.reset(new ImageDataPlatformBackend); | 37 backend_.reset(new ImageDataPlatformBackend(is_browser_allocated)); |
37 return; | 38 return; |
38 case PPB_ImageData_Shared::SIMPLE: | 39 case PPB_ImageData_Shared::SIMPLE: |
40 DCHECK(!is_browser_allocated) << | |
41 "PPB_ImageData_Shared::SIMPLE is always allocated in the renderer."; | |
39 backend_.reset(new ImageDataSimpleBackend); | 42 backend_.reset(new ImageDataSimpleBackend); |
40 return; | 43 return; |
41 // No default: so that we get a compiler warning if any types are added. | 44 // No default: so that we get a compiler warning if any types are added. |
42 } | 45 } |
43 NOTREACHED(); | 46 NOTREACHED(); |
44 } | 47 } |
45 | 48 |
46 PPB_ImageData_Impl::~PPB_ImageData_Impl() { | 49 PPB_ImageData_Impl::~PPB_ImageData_Impl() { |
47 } | 50 } |
48 | 51 |
52 // static | |
53 bool PPB_ImageData_Impl::IsBrowserAllocated(ImageDataType format) { | |
54 if (format == PPB_ImageData_Shared::SIMPLE) | |
55 return false; | |
56 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | |
57 // On the Mac, shared memory has to be created in the browser in order to | |
58 // work in the sandbox. | |
59 return true; | |
60 #endif | |
61 return false; | |
62 } | |
63 | |
49 bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, | 64 bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, |
50 int width, int height, | 65 int width, int height, |
51 bool init_to_zero) { | 66 bool init_to_zero) { |
52 // TODO(brettw) this should be called only on the main thread! | 67 // TODO(brettw) this should be called only on the main thread! |
53 if (!IsImageDataFormatSupported(format)) | 68 if (!IsImageDataFormatSupported(format)) |
54 return false; // Only support this one format for now. | 69 return false; // Only support this one format for now. |
55 if (width <= 0 || height <= 0) | 70 if (width <= 0 || height <= 0) |
56 return false; | 71 return false; |
57 if (static_cast<int64>(width) * static_cast<int64>(height) >= | 72 if (static_cast<int64>(width) * static_cast<int64>(height) >= |
58 std::numeric_limits<int32>::max() / 4) | 73 std::numeric_limits<int32>::max() / 4) |
59 return false; // Prevent overflow of signed 32-bit ints. | 74 return false; // Prevent overflow of signed 32-bit ints. |
60 | 75 |
61 format_ = format; | 76 format_ = format; |
62 width_ = width; | 77 width_ = width; |
63 height_ = height; | 78 height_ = height; |
64 return backend_->Init(this, format, width, height, init_to_zero); | 79 return backend_->Init(this, format, width, height, init_to_zero); |
65 } | 80 } |
66 | 81 |
67 // static | 82 // static |
68 PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance, | 83 PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance, |
69 PPB_ImageData_Shared::ImageDataType type, | 84 PPB_ImageData_Shared::ImageDataType type, |
70 PP_ImageDataFormat format, | 85 PP_ImageDataFormat format, |
71 const PP_Size& size, | 86 const PP_Size& size, |
72 PP_Bool init_to_zero) { | 87 PP_Bool init_to_zero) { |
73 scoped_refptr<PPB_ImageData_Impl> | 88 scoped_refptr<PPB_ImageData_Impl> |
74 data(new PPB_ImageData_Impl(instance, type)); | 89 data(new PPB_ImageData_Impl(instance, type, IsBrowserAllocated(type))); |
75 if (!data->Init(format, size.width, size.height, !!init_to_zero)) | 90 if (!data->Init(format, size.width, size.height, !!init_to_zero)) |
76 return 0; | 91 return 0; |
77 return data->GetReference(); | 92 return data->GetReference(); |
78 } | 93 } |
79 | 94 |
80 PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { | 95 PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { |
81 return this; | 96 return this; |
82 } | 97 } |
83 | 98 |
84 bool PPB_ImageData_Impl::IsMapped() const { | 99 bool PPB_ImageData_Impl::IsMapped() const { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 void PPB_ImageData_Impl::SetIsCandidateForReuse() { | 135 void PPB_ImageData_Impl::SetIsCandidateForReuse() { |
121 // Nothing to do since we don't support image data re-use in-process. | 136 // Nothing to do since we don't support image data re-use in-process. |
122 } | 137 } |
123 | 138 |
124 const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { | 139 const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { |
125 return backend_->GetMappedBitmap(); | 140 return backend_->GetMappedBitmap(); |
126 } | 141 } |
127 | 142 |
128 // ImageDataPlatformBackend ---------------------------------------------------- | 143 // ImageDataPlatformBackend ---------------------------------------------------- |
129 | 144 |
130 ImageDataPlatformBackend::ImageDataPlatformBackend() | 145 ImageDataPlatformBackend::ImageDataPlatformBackend(bool is_browser_allocated) |
131 : width_(0), | 146 : width_(0), |
132 height_(0) { | 147 height_(0), |
148 is_browser_allocated_(is_browser_allocated) { | |
133 } | 149 } |
134 | 150 |
135 // On POSIX, we have to tell the browser to free the transport DIB. | 151 // On POSIX, we have to tell the browser to free the transport DIB. |
136 ImageDataPlatformBackend::~ImageDataPlatformBackend() { | 152 ImageDataPlatformBackend::~ImageDataPlatformBackend() { |
137 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | 153 if (is_browser_allocated_) { |
138 if (dib_) { | 154 if (dib_) { |
139 RenderThreadImpl::current()->Send( | 155 RenderThreadImpl::current()->Send( |
140 new ViewHostMsg_FreeTransportDIB(dib_->id())); | 156 new ViewHostMsg_FreeTransportDIB(dib_->id())); |
157 } | |
141 } | 158 } |
142 #endif | |
143 } | 159 } |
144 | 160 |
145 bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, | 161 bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, |
146 PP_ImageDataFormat format, | 162 PP_ImageDataFormat format, |
147 int width, int height, | 163 int width, int height, |
148 bool init_to_zero) { | 164 bool init_to_zero) { |
149 // TODO(brettw) use init_to_zero when we implement caching. | 165 // TODO(brettw) use init_to_zero when we implement caching. |
150 width_ = width; | 166 width_ = width; |
151 height_ = height; | 167 height_ = height; |
152 uint32 buffer_size = width_ * height_ * 4; | 168 uint32 buffer_size = width_ * height_ * 4; |
153 | 169 |
154 // Allocate the transport DIB and the PlatformCanvas pointing to it. | 170 // Allocate the transport DIB and the PlatformCanvas pointing to it. |
155 #if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) | 171 TransportDIB* dib = NULL; |
156 // On the Mac, shared memory has to be created in the browser in order to | 172 if (is_browser_allocated_) { |
157 // work in the sandbox. Do this by sending a message to the browser | 173 // Allocate the image data by sending a message to the browser requesting a |
158 // requesting a TransportDIB (see also | 174 // TransportDIB (see also chrome/renderer/webplugin_delegate_proxy.cc, |
159 // chrome/renderer/webplugin_delegate_proxy.cc, method | 175 // method WebPluginDelegateProxy::CreateBitmap() for similar code). The |
160 // WebPluginDelegateProxy::CreateBitmap() for similar code). The TransportDIB | 176 // TransportDIB is cached in the browser, and is freed (in typical cases) by |
161 // is cached in the browser, and is freed (in typical cases) by the | 177 // the TransportDIB's destructor. |
162 // TransportDIB's destructor. | 178 TransportDIB::Handle dib_handle; |
163 TransportDIB::Handle dib_handle; | 179 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size, |
164 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size, | 180 true, |
165 true, | 181 &dib_handle); |
166 &dib_handle); | 182 if (!RenderThreadImpl::current()->Send(msg)) |
167 if (!RenderThreadImpl::current()->Send(msg)) | 183 return false; |
168 return false; | 184 if (!TransportDIB::is_valid_handle(dib_handle)) |
169 if (!TransportDIB::is_valid_handle(dib_handle)) | 185 return false; |
170 return false; | |
171 | 186 |
172 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle); | 187 dib = TransportDIB::CreateWithHandle(dib_handle); |
173 #else | 188 } else { |
174 static int next_dib_id = 0; | 189 static int next_dib_id = 0; |
175 TransportDIB* dib = TransportDIB::Create(buffer_size, next_dib_id++); | 190 dib = TransportDIB::Create(buffer_size, next_dib_id++); |
176 if (!dib) | 191 if (!dib) |
177 return false; | 192 return false; |
178 #endif | 193 } |
179 dib_.reset(dib); | 194 dib_.reset(dib); |
180 return true; | 195 return true; |
181 } | 196 } |
182 | 197 |
183 bool ImageDataPlatformBackend::IsMapped() const { | 198 bool ImageDataPlatformBackend::IsMapped() const { |
184 return !!mapped_canvas_.get(); | 199 return !!mapped_canvas_.get(); |
185 } | 200 } |
186 | 201 |
187 TransportDIB* ImageDataPlatformBackend::GetTransportDIB() const { | 202 TransportDIB* ImageDataPlatformBackend::GetTransportDIB() const { |
188 return dib_.get(); | 203 return dib_.get(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 return skia_canvas_.get(); | 323 return skia_canvas_.get(); |
309 } | 324 } |
310 | 325 |
311 const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const { | 326 const SkBitmap* ImageDataSimpleBackend::GetMappedBitmap() const { |
312 if (!IsMapped()) | 327 if (!IsMapped()) |
313 return NULL; | 328 return NULL; |
314 return &skia_bitmap_; | 329 return &skia_bitmap_; |
315 } | 330 } |
316 | 331 |
317 } // namespace content | 332 } // namespace content |
OLD | NEW |