Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: ppapi/proxy/ppb_image_data_proxy.cc

Issue 16605006: Clean up Pepper ImageData resource class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add NOTREACHED if creating PlatformImageData in NaCl. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_image_data_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 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
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
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
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();
510 if (!result.is_null())
511 return
512 (new SimpleImageData(result, desc, image_handle))->GetReference();
513 }
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();
489 #else 525 #else
490 ImageHandle image_handle = ImageData::NullHandle(); 526 // PlatformImageData shouldn't be created in untrusted code.
491 dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( 527 NOTREACHED();
492 kApiID, instance, format, size, init_to_zero,
493 &result, &image_data_desc, &image_handle));
494 #endif 528 #endif
529 break;
530 }
531 }
495 532
496 if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) 533 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 } 534 }
505 535
506 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { 536 bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) {
507 bool handled = true; 537 bool handled = true;
508 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) 538 IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg)
509 #if !defined(OS_NACL) 539 #if !defined(OS_NACL)
510 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnHostMsgCreate) 540 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreatePlatform,
511 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateNaCl, 541 OnHostMsgCreatePlatform)
512 OnHostMsgCreateNaCl) 542 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_CreateSimple,
543 OnHostMsgCreateSimple)
513 #endif 544 #endif
514 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, 545 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData,
515 OnPluginMsgNotifyUnusedImageData) 546 OnPluginMsgNotifyUnusedImageData)
516 547
517 IPC_MESSAGE_UNHANDLED(handled = false) 548 IPC_MESSAGE_UNHANDLED(handled = false)
518 IPC_END_MESSAGE_MAP() 549 IPC_END_MESSAGE_MAP()
519 return handled; 550 return handled;
520 } 551 }
521 552
522 #if !defined(OS_NACL) 553 #if !defined(OS_NACL)
523 // static 554 // static
524 PP_Resource PPB_ImageData_Proxy::CreateImageData( 555 PP_Resource PPB_ImageData_Proxy::CreateImageData(
525 PP_Instance instance, 556 PP_Instance instance,
557 PPB_ImageData_Shared::ImageDataType type,
526 PP_ImageDataFormat format, 558 PP_ImageDataFormat format,
527 const PP_Size& size, 559 const PP_Size& size,
528 bool init_to_zero, 560 bool init_to_zero,
529 bool is_nacl_plugin,
530 PP_ImageDataDesc* desc, 561 PP_ImageDataDesc* desc,
531 IPC::PlatformFileForTransit* image_handle, 562 IPC::PlatformFileForTransit* image_handle,
532 uint32_t* byte_count) { 563 uint32_t* byte_count) {
533 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); 564 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
534 if (!dispatcher) 565 if (!dispatcher)
535 return 0; 566 return 0;
536 567
537 thunk::EnterResourceCreation enter(instance); 568 thunk::EnterResourceCreation enter(instance);
538 if (enter.failed()) 569 if (enter.failed())
539 return 0; 570 return 0;
540 571
541 PP_Bool pp_init_to_zero = init_to_zero ? PP_TRUE : PP_FALSE; 572 PP_Bool pp_init_to_zero = init_to_zero ? PP_TRUE : PP_FALSE;
542 ppapi::ScopedPPResource resource( 573 ppapi::ScopedPPResource resource(
543 ppapi::ScopedPPResource::PassRef(), 574 ppapi::ScopedPPResource::PassRef(),
544 is_nacl_plugin ? 575 enter.functions()->CreateImageData(instance, type,
545 enter.functions()->CreateImageDataNaCl(instance, format, &size, 576 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()) 577 if (!resource.get())
550 return 0; 578 return 0;
551 579
552 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource.get(), 580 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource.get(),
553 false); 581 false);
554 if (enter_resource.object()->Describe(desc) != PP_TRUE) { 582 if (enter_resource.object()->Describe(desc) != PP_TRUE) {
555 DVLOG(1) << "CreateImageData failed: could not Describe"; 583 DVLOG(1) << "CreateImageData failed: could not Describe";
556 return 0; 584 return 0;
557 } 585 }
558 586
559 int local_fd = 0; 587 int local_fd = 0;
560 if (enter_resource.object()->GetSharedMemory(&local_fd, 588 if (enter_resource.object()->GetSharedMemory(&local_fd,
561 byte_count) != PP_OK) { 589 byte_count) != PP_OK) {
562 DVLOG(1) << "CreateImageData failed: could not GetSharedMemory"; 590 DVLOG(1) << "CreateImageData failed: could not GetSharedMemory";
563 return 0; 591 return 0;
564 } 592 }
565 593
566 #if defined(OS_WIN) 594 #if defined(OS_WIN)
567 *image_handle = dispatcher->ShareHandleWithRemote( 595 *image_handle = dispatcher->ShareHandleWithRemote(
568 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); 596 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false);
569 #elif defined(TOOLKIT_GTK) 597 #elif defined(TOOLKIT_GTK)
570 // On X Windows, a non-nacl handle is a SysV shared memory key. 598 // On X Windows, a PlatformImageData is backed by a SysV shared memory key,
571 if (is_nacl_plugin) 599 // so embed that in a fake PlatformFileForTransit and don't share it across
600 // processes.
601 if (type == PPB_ImageData_Shared::PLATFORM)
602 *image_handle = IPC::PlatformFileForTransit(local_fd, false);
603 else
572 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); 604 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false);
573 else
574 *image_handle = IPC::PlatformFileForTransit(local_fd, false);
575 #elif defined(OS_POSIX) 605 #elif defined(OS_POSIX)
576 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); 606 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false);
577 #else 607 #else
578 #error Not implemented. 608 #error Not implemented.
579 #endif 609 #endif
580 610
581 return resource.Release(); 611 return resource.Release();
582 } 612 }
583 613
584 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, 614 void PPB_ImageData_Proxy::OnHostMsgCreatePlatform(
585 int32_t format, 615 PP_Instance instance,
586 const PP_Size& size, 616 int32_t format,
587 PP_Bool init_to_zero, 617 const PP_Size& size,
588 HostResource* result, 618 PP_Bool init_to_zero,
589 std::string* image_data_desc, 619 HostResource* result,
590 ImageHandle* result_image_handle) { 620 PP_ImageDataDesc* desc,
591 PP_ImageDataDesc desc; 621 ImageHandle* result_image_handle) {
592 IPC::PlatformFileForTransit image_handle; 622 IPC::PlatformFileForTransit image_handle;
593 uint32_t byte_count; 623 uint32_t byte_count;
594 PP_Resource resource = 624 PP_Resource resource =
595 CreateImageData(instance, 625 CreateImageData(instance,
626 PPB_ImageData_Shared::PLATFORM,
596 static_cast<PP_ImageDataFormat>(format), 627 static_cast<PP_ImageDataFormat>(format),
597 size, 628 size,
598 true /* init_to_zero */, 629 true /* init_to_zero */,
599 false /* is_nacl_plugin */, 630 desc, &image_handle, &byte_count);
600 &desc, &image_handle, &byte_count);
601 result->SetHostResource(instance, resource); 631 result->SetHostResource(instance, resource);
602 if (resource) { 632 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) 633 #if defined(TOOLKIT_GTK)
606 // On X Windows ImageHandle is a SysV shared memory key. 634 // On X Windows ImageHandle is a SysV shared memory key.
607 *result_image_handle = image_handle.fd; 635 *result_image_handle = image_handle.fd;
608 #else 636 #else
609 *result_image_handle = image_handle; 637 *result_image_handle = image_handle;
610 #endif 638 #endif
611 } else { 639 } else {
612 image_data_desc->clear(); 640 *result_image_handle = PlatformImageData::NullHandle();
613 *result_image_handle = ImageData::NullHandle();
614 } 641 }
615 } 642 }
616 643
617 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( 644 void PPB_ImageData_Proxy::OnHostMsgCreateSimple(
618 PP_Instance instance, 645 PP_Instance instance,
619 int32_t format, 646 int32_t format,
620 const PP_Size& size, 647 const PP_Size& size,
621 PP_Bool init_to_zero, 648 PP_Bool init_to_zero,
622 HostResource* result, 649 HostResource* result,
623 std::string* image_data_desc, 650 PP_ImageDataDesc* desc,
624 ppapi::proxy::SerializedHandle* result_image_handle) { 651 ppapi::proxy::SerializedHandle* result_image_handle) {
625 PP_ImageDataDesc desc;
626 IPC::PlatformFileForTransit image_handle; 652 IPC::PlatformFileForTransit image_handle;
627 uint32_t byte_count; 653 uint32_t byte_count;
628 PP_Resource resource = 654 PP_Resource resource =
629 CreateImageData(instance, 655 CreateImageData(instance,
656 PPB_ImageData_Shared::SIMPLE,
630 static_cast<PP_ImageDataFormat>(format), 657 static_cast<PP_ImageDataFormat>(format),
631 size, 658 size,
632 true /* init_to_zero */, 659 true /* init_to_zero */,
633 true /* is_nacl_plugin */, 660 desc, &image_handle, &byte_count);
634 &desc, &image_handle, &byte_count);
635 661
636 result->SetHostResource(instance, resource); 662 result->SetHostResource(instance, resource);
637 if (resource) { 663 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); 664 result_image_handle->set_shmem(image_handle, byte_count);
641 } else { 665 } else {
642 image_data_desc->clear();
643 result_image_handle->set_null_shmem(); 666 result_image_handle->set_null_shmem();
644 } 667 }
645 } 668 }
646 #endif // !defined(OS_NACL) 669 #endif // !defined(OS_NACL)
647 670
648 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( 671 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData(
649 const HostResource& old_image_data) { 672 const HostResource& old_image_data) {
650 PluginGlobals* plugin_globals = PluginGlobals::Get(); 673 PluginGlobals* plugin_globals = PluginGlobals::Get();
651 if (!plugin_globals) 674 if (!plugin_globals)
652 return; // This may happen if the plugin is maliciously sending this 675 return; // This may happen if the plugin is maliciously sending this
653 // message to the renderer. 676 // message to the renderer.
654 677
655 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); 678 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data);
656 if (enter.succeeded()) { 679 if (enter.succeeded()) {
657 ImageData* image_data = static_cast<ImageData*>(enter.object()); 680 ImageData* image_data = static_cast<ImageData*>(enter.object());
658 ImageDataCache::GetInstance()->ImageDataUsable(image_data); 681 ImageDataCache::GetInstance()->ImageDataUsable(image_data);
659 } 682 }
660 683
661 // The renderer sent us a reference with the message. If the image data was 684 // 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 685 // 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 686 // 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 687 // reference, we released everything and we should also release the one the
665 // renderer just sent us. 688 // renderer just sent us.
666 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( 689 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
667 API_ID_PPB_CORE, old_image_data)); 690 API_ID_PPB_CORE, old_image_data));
668 } 691 }
669 692
670 } // namespace proxy 693 } // namespace proxy
671 } // namespace ppapi 694 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_image_data_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698