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 "ppapi/proxy/ppb_image_data_proxy.h" | 5 #include "ppapi/proxy/ppb_image_data_proxy.h" |
6 | 6 |
7 #include <string.h> // For memcpy | 7 #include <string.h> // For memcpy |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <vector> | 10 #include <vector> |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 }; | 113 }; |
114 | 114 |
115 // ImageDataInstanceCache ------------------------------------------------------ | 115 // ImageDataInstanceCache ------------------------------------------------------ |
116 | 116 |
117 // Per-instance cache of image datas. | 117 // Per-instance cache of image datas. |
118 class ImageDataInstanceCache { | 118 class ImageDataInstanceCache { |
119 public: | 119 public: |
120 ImageDataInstanceCache() : next_insertion_point_(0) {} | 120 ImageDataInstanceCache() : next_insertion_point_(0) {} |
121 | 121 |
122 // These functions have the same spec as the ones in ImageDataCache. | 122 // These functions have the same spec as the ones in ImageDataCache. |
123 scoped_refptr<ImageData> Get(int width, int height, | 123 scoped_refptr<ImageData> Get(PPB_ImageData_Shared::ImageDataType type, |
124 int width, int height, | |
124 PP_ImageDataFormat format); | 125 PP_ImageDataFormat format); |
125 void Add(ImageData* image_data); | 126 void Add(ImageData* image_data); |
126 void ImageDataUsable(ImageData* image_data); | 127 void ImageDataUsable(ImageData* image_data); |
127 | 128 |
128 // Expires old entries. Returns true if there are still entries in the list, | 129 // Expires old entries. Returns true if there are still entries in the list, |
129 // false if this instance cache is now empty. | 130 // false if this instance cache is now empty. |
130 bool ExpireEntries(); | 131 bool ExpireEntries(); |
131 | 132 |
132 private: | 133 private: |
133 void IncrementInsertionPoint(); | 134 void IncrementInsertionPoint(); |
134 | 135 |
135 // We'll store this many ImageDatas per instance. | 136 // We'll store this many ImageDatas per instance. |
136 const static int kCacheSize = 2; | 137 const static int kCacheSize = 2; |
137 | 138 |
138 ImageDataCacheEntry images_[kCacheSize]; | 139 ImageDataCacheEntry images_[kCacheSize]; |
139 | 140 |
140 // Index into cache where the next item will go. | 141 // Index into cache where the next item will go. |
141 int next_insertion_point_; | 142 int next_insertion_point_; |
142 }; | 143 }; |
143 | 144 |
144 scoped_refptr<ImageData> ImageDataInstanceCache::Get( | 145 scoped_refptr<ImageData> ImageDataInstanceCache::Get( |
146 ppapi::PPB_ImageData_Shared::ImageDataType type, | |
145 int width, int height, | 147 int width, int height, |
146 PP_ImageDataFormat format) { | 148 PP_ImageDataFormat format) { |
147 // Just do a brute-force search since the cache is so small. | 149 // Just do a brute-force search since the cache is so small. |
148 for (int i = 0; i < kCacheSize; i++) { | 150 for (int i = 0; i < kCacheSize; i++) { |
149 if (!images_[i].usable) | 151 if (!images_[i].usable) |
150 continue; | 152 continue; |
153 if (!images_[i].image->type() == type) | |
154 continue; | |
151 const PP_ImageDataDesc& desc = images_[i].image->desc(); | 155 const PP_ImageDataDesc& desc = images_[i].image->desc(); |
152 if (desc.format == format && | 156 if (desc.format == format && |
153 desc.size.width == width && desc.size.height == height) { | 157 desc.size.width == width && desc.size.height == height) { |
154 scoped_refptr<ImageData> ret(images_[i].image); | 158 scoped_refptr<ImageData> ret(images_[i].image); |
155 images_[i] = ImageDataCacheEntry(); | 159 images_[i] = ImageDataCacheEntry(); |
156 | 160 |
157 // Since we just removed an item, this entry is the best place to insert | 161 // Since we just removed an item, this entry is the best place to insert |
158 // a subsequent one. | 162 // a subsequent one. |
159 next_insertion_point_ = i; | 163 next_insertion_point_ = i; |
160 return ret; | 164 return ret; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 | 220 |
217 // ImageDataCache -------------------------------------------------------------- | 221 // ImageDataCache -------------------------------------------------------------- |
218 | 222 |
219 class ImageDataCache { | 223 class ImageDataCache { |
220 public: | 224 public: |
221 ImageDataCache() : weak_factory_(this) {} | 225 ImageDataCache() : weak_factory_(this) {} |
222 ~ImageDataCache() {} | 226 ~ImageDataCache() {} |
223 | 227 |
224 static ImageDataCache* GetInstance(); | 228 static ImageDataCache* GetInstance(); |
225 | 229 |
226 // Retrieves an image data from the cache of the specified size and format if | 230 // Retrieves an image data from the cache of the specified type, size and |
227 // one exists. If one doesn't exist, this will return a null refptr. | 231 // format if one exists. If one doesn't exist, this will return a null refptr. |
228 scoped_refptr<ImageData> Get(PP_Instance instance, | 232 scoped_refptr<ImageData> Get(PP_Instance instance, |
233 PPB_ImageData_Shared::ImageDataType type, | |
229 int width, int height, | 234 int width, int height, |
230 PP_ImageDataFormat format); | 235 PP_ImageDataFormat format); |
231 | 236 |
232 // Adds the given image data to the cache. There should be no plugin | 237 // Adds the given image data to the cache. There should be no plugin |
233 // references to it. This may delete an older item from the cache. | 238 // references to it. This may delete an older item from the cache. |
234 void Add(ImageData* image_data); | 239 void Add(ImageData* image_data); |
235 | 240 |
236 // Notification from the renderer that the given image data is usable. | 241 // Notification from the renderer that the given image data is usable. |
237 void ImageDataUsable(ImageData* image_data); | 242 void ImageDataUsable(ImageData* image_data); |
238 | 243 |
(...skipping 16 matching lines...) Expand all Loading... | |
255 | 260 |
256 DISALLOW_COPY_AND_ASSIGN(ImageDataCache); | 261 DISALLOW_COPY_AND_ASSIGN(ImageDataCache); |
257 }; | 262 }; |
258 | 263 |
259 // static | 264 // static |
260 ImageDataCache* ImageDataCache::GetInstance() { | 265 ImageDataCache* ImageDataCache::GetInstance() { |
261 return Singleton<ImageDataCache, | 266 return Singleton<ImageDataCache, |
262 LeakySingletonTraits<ImageDataCache> >::get(); | 267 LeakySingletonTraits<ImageDataCache> >::get(); |
263 } | 268 } |
264 | 269 |
265 scoped_refptr<ImageData> ImageDataCache::Get(PP_Instance instance, | 270 scoped_refptr<ImageData> ImageDataCache::Get( |
266 int width, int height, | 271 PP_Instance instance, |
267 PP_ImageDataFormat format) { | 272 PPB_ImageData_Shared::ImageDataType type, |
273 int width, int height, | |
274 PP_ImageDataFormat format) { | |
268 CacheMap::iterator found = cache_.find(instance); | 275 CacheMap::iterator found = cache_.find(instance); |
269 if (found == cache_.end()) | 276 if (found == cache_.end()) |
270 return scoped_refptr<ImageData>(); | 277 return scoped_refptr<ImageData>(); |
271 return found->second.Get(width, height, format); | 278 return found->second.Get(type, width, height, format); |
272 } | 279 } |
273 | 280 |
274 void ImageDataCache::Add(ImageData* image_data) { | 281 void ImageDataCache::Add(ImageData* image_data) { |
275 cache_[image_data->pp_instance()].Add(image_data); | 282 cache_[image_data->pp_instance()].Add(image_data); |
276 | 283 |
277 // Schedule a timer to invalidate this entry. | 284 // Schedule a timer to invalidate this entry. |
278 base::MessageLoop::current()->PostDelayedTask( | 285 base::MessageLoop::current()->PostDelayedTask( |
279 FROM_HERE, | 286 FROM_HERE, |
280 RunWhileLocked(base::Bind(&ImageDataCache::OnTimer, | 287 RunWhileLocked(base::Bind(&ImageDataCache::OnTimer, |
281 weak_factory_.GetWeakPtr(), | 288 weak_factory_.GetWeakPtr(), |
(...skipping 18 matching lines...) Expand all Loading... | |
300 if (!found->second.ExpireEntries()) { | 307 if (!found->second.ExpireEntries()) { |
301 // There are no more entries for this instance, remove it from the cache. | 308 // There are no more entries for this instance, remove it from the cache. |
302 cache_.erase(found); | 309 cache_.erase(found); |
303 } | 310 } |
304 } | 311 } |
305 | 312 |
306 } // namespace | 313 } // namespace |
307 | 314 |
308 // ImageData ------------------------------------------------------------------- | 315 // ImageData ------------------------------------------------------------------- |
309 | 316 |
310 #if !defined(OS_NACL) | |
311 ImageData::ImageData(const HostResource& resource, | 317 ImageData::ImageData(const HostResource& resource, |
312 const PP_ImageDataDesc& desc, | 318 PPB_ImageData_Shared::ImageDataType type, |
313 ImageHandle handle) | 319 const PP_ImageDataDesc& desc) |
314 : Resource(OBJECT_IS_PROXY, resource), | 320 : Resource(OBJECT_IS_PROXY, resource), |
321 type_(type), | |
315 desc_(desc), | 322 desc_(desc), |
316 is_candidate_for_reuse_(false) { | 323 is_candidate_for_reuse_(false) { |
317 #if defined(OS_WIN) | |
318 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); | |
319 #else | |
320 transport_dib_.reset(TransportDIB::Map(handle)); | |
321 #endif // defined(OS_WIN) | |
322 } | 324 } |
323 #else // !defined(OS_NACL) | |
324 | |
325 ImageData::ImageData(const HostResource& resource, | |
326 const PP_ImageDataDesc& desc, | |
327 const base::SharedMemoryHandle& handle) | |
328 : Resource(OBJECT_IS_PROXY, resource), | |
329 desc_(desc), | |
330 shm_(handle, false /* read_only */), | |
331 size_(desc.size.width * desc.size.height * 4), | |
332 map_count_(0), | |
333 is_candidate_for_reuse_(false) { | |
334 } | |
335 #endif // else, !defined(OS_NACL) | |
336 | 325 |
337 ImageData::~ImageData() { | 326 ImageData::~ImageData() { |
338 } | 327 } |
339 | 328 |
340 PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { | 329 PPB_ImageData_API* ImageData::AsPPB_ImageData_API() { |
341 return this; | 330 return this; |
342 } | 331 } |
343 | 332 |
344 void ImageData::LastPluginRefWasDeleted() { | 333 void ImageData::LastPluginRefWasDeleted() { |
345 // The plugin no longer needs this ImageData, add it to our cache if it's | 334 // The plugin no longer needs this ImageData, add it to our cache if it's |
346 // been used in a ReplaceContents. These are the ImageDatas that the renderer | 335 // been used in a ReplaceContents. These are the ImageDatas that the renderer |
347 // will send back ImageDataUsable messages for. | 336 // will send back ImageDataUsable messages for. |
348 if (is_candidate_for_reuse_) | 337 if (is_candidate_for_reuse_) |
349 ImageDataCache::GetInstance()->Add(this); | 338 ImageDataCache::GetInstance()->Add(this); |
350 } | 339 } |
351 | 340 |
352 void ImageData::InstanceWasDeleted() { | 341 void ImageData::InstanceWasDeleted() { |
353 ImageDataCache::GetInstance()->DidDeleteInstance(pp_instance()); | 342 ImageDataCache::GetInstance()->DidDeleteInstance(pp_instance()); |
354 } | 343 } |
355 | 344 |
356 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { | 345 PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { |
357 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); | 346 memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); |
358 return PP_TRUE; | 347 return PP_TRUE; |
359 } | 348 } |
360 | 349 |
361 void* ImageData::Map() { | 350 int32_t ImageData::GetSharedMemory(int* /* handle */, |
362 #if defined(OS_NACL) | 351 uint32_t* /* byte_count */) { |
363 if (map_count_++ == 0) | 352 // Not supported in the proxy (this method is for actually implementing the |
364 shm_.Map(size_); | 353 // proxy in the host). |
365 return shm_.memory(); | 354 return PP_ERROR_NOACCESS; |
355 } | |
356 | |
357 void ImageData::SetIsCandidateForReuse() { | |
358 is_candidate_for_reuse_ = true; | |
359 } | |
360 | |
361 void ImageData::RecycleToPlugin(bool zero_contents) { | |
362 is_candidate_for_reuse_ = false; | |
363 if (zero_contents) { | |
364 void* data = Map(); | |
365 memset(data, 0, desc_.stride * desc_.size.height); | |
366 Unmap(); | |
367 } | |
368 } | |
369 | |
370 // PlatformImageData ----------------------------------------------------------- | |
371 | |
372 #if !defined(OS_NACL) | |
373 PlatformImageData::PlatformImageData(const HostResource& resource, | |
374 const PP_ImageDataDesc& desc, | |
375 ImageHandle handle) | |
376 : ImageData(resource, PPB_ImageData_Shared::PLATFORM, desc) { | |
377 #if defined(OS_WIN) | |
378 transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); | |
366 #else | 379 #else |
380 transport_dib_.reset(TransportDIB::Map(handle)); | |
381 #endif // defined(OS_WIN) | |
382 } | |
383 | |
384 PlatformImageData::~PlatformImageData() { | |
385 } | |
386 | |
387 void* PlatformImageData::Map() { | |
367 if (!mapped_canvas_.get()) { | 388 if (!mapped_canvas_.get()) { |
368 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, | 389 mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, |
369 desc_.size.height)); | 390 desc_.size.height)); |
370 if (!mapped_canvas_.get()) | 391 if (!mapped_canvas_.get()) |
371 return NULL; | 392 return NULL; |
372 } | 393 } |
373 const SkBitmap& bitmap = | 394 const SkBitmap& bitmap = |
374 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); | 395 skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true); |
375 | 396 |
376 bitmap.lockPixels(); | 397 bitmap.lockPixels(); |
377 return bitmap.getAddr(0, 0); | 398 return bitmap.getAddr(0, 0); |
378 #endif | |
379 } | 399 } |
380 | 400 |
381 void ImageData::Unmap() { | 401 void PlatformImageData::Unmap() { |
382 #if defined(OS_NACL) | |
383 if (--map_count_ == 0) | |
384 shm_.Unmap(); | |
385 #else | |
386 // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't | 402 // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't |
387 // possible since deleting the TransportDIB also frees all the handles. | 403 // possible since deleting the TransportDIB also frees all the handles. |
388 // We need to add a method to TransportDIB to release the handles. | 404 // We need to add a method to TransportDIB to release the handles. |
389 #endif | |
390 } | 405 } |
391 | 406 |
392 int32_t ImageData::GetSharedMemory(int* /* handle */, | 407 SkCanvas* PlatformImageData::GetPlatformCanvas() { |
393 uint32_t* /* byte_count */) { | 408 return mapped_canvas_.get(); |
394 // Not supported in the proxy (this method is for actually implementing the | |
395 // proxy in the host). | |
396 return PP_ERROR_NOACCESS; | |
397 } | 409 } |
398 | 410 |
399 SkCanvas* ImageData::GetPlatformCanvas() { | 411 SkCanvas* PlatformImageData::GetCanvas() { |
400 #if defined(OS_NACL) | |
401 return NULL; // No canvas in NaCl. | |
402 #else | |
403 return mapped_canvas_.get(); | 412 return mapped_canvas_.get(); |
404 #endif | |
405 } | 413 } |
406 | 414 |
407 SkCanvas* ImageData::GetCanvas() { | |
408 #if defined(OS_NACL) | |
409 return NULL; // No canvas in NaCl. | |
410 #else | |
411 return mapped_canvas_.get(); | |
412 #endif | |
413 } | |
414 | |
415 void ImageData::SetIsCandidateForReuse() { | |
416 is_candidate_for_reuse_ = true; | |
417 } | |
418 | |
419 void ImageData::RecycleToPlugin(bool zero_contents) { | |
420 is_candidate_for_reuse_ = false; | |
421 if (zero_contents) { | |
422 void* data = Map(); | |
423 memset(data, 0, desc_.stride * desc_.size.height); | |
424 Unmap(); | |
425 } | |
426 } | |
427 | |
428 #if !defined(OS_NACL) | |
429 // static | 415 // static |
430 ImageHandle ImageData::NullHandle() { | 416 ImageHandle PlatformImageData::NullHandle() { |
431 #if defined(OS_WIN) | 417 #if defined(OS_WIN) |
432 return NULL; | 418 return NULL; |
433 #elif defined(TOOLKIT_GTK) | 419 #elif defined(TOOLKIT_GTK) |
434 return 0; | 420 return 0; |
435 #else | 421 #else |
436 return ImageHandle(); | 422 return ImageHandle(); |
437 #endif | 423 #endif |
438 } | 424 } |
439 | 425 |
440 ImageHandle ImageData::HandleFromInt(int32_t i) { | 426 ImageHandle PlatformImageData::HandleFromInt(int32_t i) { |
441 #if defined(OS_WIN) | 427 #if defined(OS_WIN) |
442 return reinterpret_cast<ImageHandle>(i); | 428 return reinterpret_cast<ImageHandle>(i); |
443 #elif defined(TOOLKIT_GTK) | 429 #elif defined(TOOLKIT_GTK) |
444 return static_cast<ImageHandle>(i); | 430 return static_cast<ImageHandle>(i); |
445 #else | 431 #else |
446 return ImageHandle(i, false); | 432 return ImageHandle(i, false); |
447 #endif | 433 #endif |
448 } | 434 } |
449 #endif // !defined(OS_NACL) | 435 #endif // !defined(OS_NACL) |
450 | 436 |
437 // SimpleImageData ------------------------------------------------------------- | |
438 | |
439 SimpleImageData::SimpleImageData(const HostResource& resource, | |
440 const PP_ImageDataDesc& desc, | |
441 const base::SharedMemoryHandle& handle) | |
442 : ImageData(resource, PPB_ImageData_Shared::SIMPLE, desc), | |
443 shm_(handle, false /* read_only */), | |
444 size_(desc.size.width * desc.size.height * 4), | |
445 map_count_(0) { | |
446 } | |
447 | |
448 SimpleImageData::~SimpleImageData() { | |
449 } | |
450 | |
451 void* SimpleImageData::Map() { | |
452 if (map_count_++ == 0) | |
453 shm_.Map(size_); | |
454 return shm_.memory(); | |
455 } | |
456 | |
457 void SimpleImageData::Unmap() { | |
458 if (--map_count_ == 0) | |
459 shm_.Unmap(); | |
460 } | |
461 | |
462 SkCanvas* SimpleImageData::GetPlatformCanvas() { | |
463 return NULL; // No canvas available. | |
464 } | |
465 | |
466 SkCanvas* SimpleImageData::GetCanvas() { | |
467 return NULL; // No canvas available. | |
468 } | |
469 | |
451 // PPB_ImageData_Proxy --------------------------------------------------------- | 470 // PPB_ImageData_Proxy --------------------------------------------------------- |
452 | 471 |
453 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) | 472 PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher) |
454 : InterfaceProxy(dispatcher) { | 473 : InterfaceProxy(dispatcher) { |
455 } | 474 } |
456 | 475 |
457 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { | 476 PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { |
458 } | 477 } |
459 | 478 |
460 // static | 479 // static |
461 PP_Resource PPB_ImageData_Proxy::CreateProxyResource(PP_Instance instance, | 480 PP_Resource PPB_ImageData_Proxy::CreateProxyResource( |
462 PP_ImageDataFormat format, | 481 PP_Instance instance, |
463 const PP_Size& size, | 482 PPB_ImageData_Shared::ImageDataType type, |
464 PP_Bool init_to_zero) { | 483 PP_ImageDataFormat format, |
484 const PP_Size& size, | |
485 PP_Bool init_to_zero) { | |
465 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 486 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
466 if (!dispatcher) | 487 if (!dispatcher) |
467 return 0; | 488 return 0; |
468 | 489 |
469 // Check the cache. | 490 // Check the cache. |
470 scoped_refptr<ImageData> cached_image_data = | 491 scoped_refptr<ImageData> cached_image_data = |
471 ImageDataCache::GetInstance()->Get(instance, size.width, size.height, | 492 ImageDataCache::GetInstance()->Get(instance, type, |
472 format); | 493 size.width, size.height, format); |
473 if (cached_image_data.get()) { | 494 if (cached_image_data.get()) { |
474 // We have one we can re-use rather than allocating a new one. | 495 // We have one we can re-use rather than allocating a new one. |
475 cached_image_data->RecycleToPlugin(PP_ToBool(init_to_zero)); | 496 cached_image_data->RecycleToPlugin(PP_ToBool(init_to_zero)); |
476 return cached_image_data->GetReference(); | 497 return cached_image_data->GetReference(); |
477 } | 498 } |
478 | 499 |
479 HostResource result; | 500 HostResource result; |
480 std::string image_data_desc; | 501 PP_ImageDataDesc desc; |
481 #if defined(OS_NACL) | 502 switch (type) { |
482 ppapi::proxy::SerializedHandle image_handle_wrapper; | 503 case PPB_ImageData_Shared::SIMPLE: { |
483 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateNaCl( | 504 ppapi::proxy::SerializedHandle image_handle_wrapper; |
484 kApiID, instance, format, size, init_to_zero, | 505 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreateSimple( |
485 &result, &image_data_desc, &image_handle_wrapper)); | 506 kApiID, instance, format, size, init_to_zero, |
486 if (!image_handle_wrapper.is_shmem()) | 507 &result, &desc, &image_handle_wrapper)); |
487 return 0; | 508 if (image_handle_wrapper.is_shmem()) { |
488 base::SharedMemoryHandle image_handle = image_handle_wrapper.shmem(); | 509 base::SharedMemoryHandle image_handle = image_handle_wrapper.shmem(); |
489 #else | 510 if (!result.is_null()) |
490 ImageHandle image_handle = ImageData::NullHandle(); | 511 return |
491 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( | 512 (new SimpleImageData(result, desc, image_handle))->GetReference(); |
492 kApiID, instance, format, size, init_to_zero, | 513 } |
493 &result, &image_data_desc, &image_handle)); | 514 break; |
515 } | |
516 case PPB_ImageData_Shared::PLATFORM: { | |
517 #if !defined(OS_NACL) | |
518 ImageHandle image_handle = PlatformImageData::NullHandle(); | |
519 dispatcher->Send(new PpapiHostMsg_PPBImageData_CreatePlatform( | |
520 kApiID, instance, format, size, init_to_zero, | |
521 &result, &desc, &image_handle)); | |
522 if (!result.is_null()) | |
523 return | |
524 (new PlatformImageData(result, desc, image_handle))->GetReference(); | |
494 #endif | 525 #endif |
dmichael (off chromium)
2013/06/11 17:55:34
#else
NOTREACHED();
#endif
(or NOTIMPLEMENTED)?
It
bbudge
2013/06/11 18:13:01
I'll go with NOTREACHED since NOTIMPLEMENTED impli
| |
526 break; | |
527 } | |
528 } | |
495 | 529 |
496 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) | 530 return 0; |
497 return 0; | |
498 | |
499 // We serialize the PP_ImageDataDesc just by copying to a string. | |
500 PP_ImageDataDesc desc; | |
501 memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); | |
502 | |
503 return (new ImageData(result, desc, image_handle))->GetReference(); | |
504 } | 531 } |
505 | 532 |
506 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { | 533 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { |
507 bool handled = true; | 534 bool handled = true; |
508 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) | 535 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) |
509 #if !defined(OS_NACL) | 536 #if !defined(OS_NACL) |
510 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnHostMsgCreate) | 537 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreatePlatform, |
511 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateNaCl, | 538 OnHostMsgCreatePlatform) |
512 OnHostMsgCreateNaCl) | 539 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateSimple, |
540 OnHostMsgCreateSimple) | |
513 #endif | 541 #endif |
514 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, | 542 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, |
515 OnPluginMsgNotifyUnusedImageData) | 543 OnPluginMsgNotifyUnusedImageData) |
516 | 544 |
517 IPC_MESSAGE_UNHANDLED(handled = false) | 545 IPC_MESSAGE_UNHANDLED(handled = false) |
518 IPC_END_MESSAGE_MAP() | 546 IPC_END_MESSAGE_MAP() |
519 return handled; | 547 return handled; |
520 } | 548 } |
521 | 549 |
522 #if !defined(OS_NACL) | 550 #if !defined(OS_NACL) |
523 // static | 551 // static |
524 PP_Resource PPB_ImageData_Proxy::CreateImageData( | 552 PP_Resource PPB_ImageData_Proxy::CreateImageData( |
525 PP_Instance instance, | 553 PP_Instance instance, |
554 PPB_ImageData_Shared::ImageDataType type, | |
526 PP_ImageDataFormat format, | 555 PP_ImageDataFormat format, |
527 const PP_Size& size, | 556 const PP_Size& size, |
528 bool init_to_zero, | 557 bool init_to_zero, |
529 bool is_nacl_plugin, | |
530 PP_ImageDataDesc* desc, | 558 PP_ImageDataDesc* desc, |
531 IPC::PlatformFileForTransit* image_handle, | 559 IPC::PlatformFileForTransit* image_handle, |
532 uint32_t* byte_count) { | 560 uint32_t* byte_count) { |
533 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | 561 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
534 if (!dispatcher) | 562 if (!dispatcher) |
535 return 0; | 563 return 0; |
536 | 564 |
537 thunk::EnterResourceCreation enter(instance); | 565 thunk::EnterResourceCreation enter(instance); |
538 if (enter.failed()) | 566 if (enter.failed()) |
539 return 0; | 567 return 0; |
540 | 568 |
541 PP_Bool pp_init_to_zero = init_to_zero ? PP_TRUE : PP_FALSE; | 569 PP_Bool pp_init_to_zero = init_to_zero ? PP_TRUE : PP_FALSE; |
542 ppapi::ScopedPPResource resource( | 570 ppapi::ScopedPPResource resource( |
543 ppapi::ScopedPPResource::PassRef(), | 571 ppapi::ScopedPPResource::PassRef(), |
544 is_nacl_plugin ? | 572 enter.functions()->CreateImageData(instance, type, |
545 enter.functions()->CreateImageDataNaCl(instance, format, &size, | 573 format, &size, pp_init_to_zero)); |
546 pp_init_to_zero) : | |
547 enter.functions()->CreateImageData(instance, format, &size, | |
548 pp_init_to_zero)); | |
549 if (!resource.get()) | 574 if (!resource.get()) |
550 return 0; | 575 return 0; |
551 | 576 |
552 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource.get(), | 577 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource.get(), |
553 false); | 578 false); |
554 if (enter_resource.object()->Describe(desc) != PP_TRUE) { | 579 if (enter_resource.object()->Describe(desc) != PP_TRUE) { |
555 DVLOG(1) << "CreateImageData failed: could not Describe"; | 580 DVLOG(1) << "CreateImageData failed: could not Describe"; |
556 return 0; | 581 return 0; |
557 } | 582 } |
558 | 583 |
559 int local_fd = 0; | 584 int local_fd = 0; |
560 if (enter_resource.object()->GetSharedMemory(&local_fd, | 585 if (enter_resource.object()->GetSharedMemory(&local_fd, |
561 byte_count) != PP_OK) { | 586 byte_count) != PP_OK) { |
562 DVLOG(1) << "CreateImageData failed: could not GetSharedMemory"; | 587 DVLOG(1) << "CreateImageData failed: could not GetSharedMemory"; |
563 return 0; | 588 return 0; |
564 } | 589 } |
565 | 590 |
566 #if defined(OS_WIN) | 591 #if defined(OS_WIN) |
567 *image_handle = dispatcher->ShareHandleWithRemote( | 592 *image_handle = dispatcher->ShareHandleWithRemote( |
568 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); | 593 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); |
569 #elif defined(TOOLKIT_GTK) | 594 #elif defined(TOOLKIT_GTK) |
570 // On X Windows, a non-nacl handle is a SysV shared memory key. | 595 // On X Windows, a PlatformImageData is backed by a SysV shared memory key, |
571 if (is_nacl_plugin) | 596 // so embed that in a fake PlatformFileForTransit and don't share it across |
597 // processes. | |
598 if (type == PPB_ImageData_Shared::PLATFORM) | |
599 *image_handle = IPC::PlatformFileForTransit(local_fd, false); | |
600 else | |
572 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); | 601 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); |
573 else | |
574 *image_handle = IPC::PlatformFileForTransit(local_fd, false); | |
575 #elif defined(OS_POSIX) | 602 #elif defined(OS_POSIX) |
576 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); | 603 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); |
577 #else | 604 #else |
578 #error Not implemented. | 605 #error Not implemented. |
579 #endif | 606 #endif |
580 | 607 |
581 return resource.Release(); | 608 return resource.Release(); |
582 } | 609 } |
583 | 610 |
584 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, | 611 void PPB_ImageData_Proxy::OnHostMsgCreatePlatform( |
585 int32_t format, | 612 PP_Instance instance, |
586 const PP_Size& size, | 613 int32_t format, |
587 PP_Bool init_to_zero, | 614 const PP_Size& size, |
588 HostResource* result, | 615 PP_Bool init_to_zero, |
589 std::string* image_data_desc, | 616 HostResource* result, |
590 ImageHandle* result_image_handle) { | 617 PP_ImageDataDesc* desc, |
591 PP_ImageDataDesc desc; | 618 ImageHandle* result_image_handle) { |
592 IPC::PlatformFileForTransit image_handle; | 619 IPC::PlatformFileForTransit image_handle; |
593 uint32_t byte_count; | 620 uint32_t byte_count; |
594 PP_Resource resource = | 621 PP_Resource resource = |
595 CreateImageData(instance, | 622 CreateImageData(instance, |
623 PPB_ImageData_Shared::PLATFORM, | |
596 static_cast<PP_ImageDataFormat>(format), | 624 static_cast<PP_ImageDataFormat>(format), |
597 size, | 625 size, |
598 true /* init_to_zero */, | 626 true /* init_to_zero */, |
599 false /* is_nacl_plugin */, | 627 desc, &image_handle, &byte_count); |
600 &desc, &image_handle, &byte_count); | |
601 result->SetHostResource(instance, resource); | 628 result->SetHostResource(instance, resource); |
602 if (resource) { | 629 if (resource) { |
603 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | |
604 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | |
605 #if defined(TOOLKIT_GTK) | 630 #if defined(TOOLKIT_GTK) |
606 // On X Windows ImageHandle is a SysV shared memory key. | 631 // On X Windows ImageHandle is a SysV shared memory key. |
607 *result_image_handle = image_handle.fd; | 632 *result_image_handle = image_handle.fd; |
608 #else | 633 #else |
609 *result_image_handle = image_handle; | 634 *result_image_handle = image_handle; |
610 #endif | 635 #endif |
611 } else { | 636 } else { |
612 image_data_desc->clear(); | 637 *result_image_handle = PlatformImageData::NullHandle(); |
613 *result_image_handle = ImageData::NullHandle(); | |
614 } | 638 } |
615 } | 639 } |
616 | 640 |
617 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( | 641 void PPB_ImageData_Proxy::OnHostMsgCreateSimple( |
618 PP_Instance instance, | 642 PP_Instance instance, |
619 int32_t format, | 643 int32_t format, |
620 const PP_Size& size, | 644 const PP_Size& size, |
621 PP_Bool init_to_zero, | 645 PP_Bool init_to_zero, |
622 HostResource* result, | 646 HostResource* result, |
623 std::string* image_data_desc, | 647 PP_ImageDataDesc* desc, |
624 ppapi::proxy::SerializedHandle* result_image_handle) { | 648 ppapi::proxy::SerializedHandle* result_image_handle) { |
625 PP_ImageDataDesc desc; | |
626 IPC::PlatformFileForTransit image_handle; | 649 IPC::PlatformFileForTransit image_handle; |
627 uint32_t byte_count; | 650 uint32_t byte_count; |
628 PP_Resource resource = | 651 PP_Resource resource = |
629 CreateImageData(instance, | 652 CreateImageData(instance, |
653 PPB_ImageData_Shared::SIMPLE, | |
630 static_cast<PP_ImageDataFormat>(format), | 654 static_cast<PP_ImageDataFormat>(format), |
631 size, | 655 size, |
632 true /* init_to_zero */, | 656 true /* init_to_zero */, |
633 true /* is_nacl_plugin */, | 657 desc, &image_handle, &byte_count); |
634 &desc, &image_handle, &byte_count); | |
635 | 658 |
636 result->SetHostResource(instance, resource); | 659 result->SetHostResource(instance, resource); |
637 if (resource) { | 660 if (resource) { |
638 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | |
639 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | |
640 result_image_handle->set_shmem(image_handle, byte_count); | 661 result_image_handle->set_shmem(image_handle, byte_count); |
641 } else { | 662 } else { |
642 image_data_desc->clear(); | |
643 result_image_handle->set_null_shmem(); | 663 result_image_handle->set_null_shmem(); |
644 } | 664 } |
645 } | 665 } |
646 #endif // !defined(OS_NACL) | 666 #endif // !defined(OS_NACL) |
647 | 667 |
648 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( | 668 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( |
649 const HostResource& old_image_data) { | 669 const HostResource& old_image_data) { |
650 PluginGlobals* plugin_globals = PluginGlobals::Get(); | 670 PluginGlobals* plugin_globals = PluginGlobals::Get(); |
651 if (!plugin_globals) | 671 if (!plugin_globals) |
652 return; // This may happen if the plugin is maliciously sending this | 672 return; // This may happen if the plugin is maliciously sending this |
653 // message to the renderer. | 673 // message to the renderer. |
654 | 674 |
655 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); | 675 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); |
656 if (enter.succeeded()) { | 676 if (enter.succeeded()) { |
657 ImageData* image_data = static_cast<ImageData*>(enter.object()); | 677 ImageData* image_data = static_cast<ImageData*>(enter.object()); |
658 ImageDataCache::GetInstance()->ImageDataUsable(image_data); | 678 ImageDataCache::GetInstance()->ImageDataUsable(image_data); |
659 } | 679 } |
660 | 680 |
661 // The renderer sent us a reference with the message. If the image data was | 681 // The renderer sent us a reference with the message. If the image data was |
662 // still cached in our process, the proxy still holds a reference so we can | 682 // still cached in our process, the proxy still holds a reference so we can |
663 // remove the one the renderer just sent is. If the proxy no longer holds a | 683 // remove the one the renderer just sent is. If the proxy no longer holds a |
664 // reference, we released everything and we should also release the one the | 684 // reference, we released everything and we should also release the one the |
665 // renderer just sent us. | 685 // renderer just sent us. |
666 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( | 686 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( |
667 API_ID_PPB_CORE, old_image_data)); | 687 API_ID_PPB_CORE, old_image_data)); |
668 } | 688 } |
669 | 689 |
670 } // namespace proxy | 690 } // namespace proxy |
671 } // namespace ppapi | 691 } // namespace ppapi |
OLD | NEW |