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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
512 #endif | 512 #endif |
513 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, | 513 IPC_MESSAGE_HANDLER(PpapiMsg_PPBImageData_NotifyUnusedImageData, |
514 OnPluginMsgNotifyUnusedImageData) | 514 OnPluginMsgNotifyUnusedImageData) |
515 | 515 |
516 IPC_MESSAGE_UNHANDLED(handled = false) | 516 IPC_MESSAGE_UNHANDLED(handled = false) |
517 IPC_END_MESSAGE_MAP() | 517 IPC_END_MESSAGE_MAP() |
518 return handled; | 518 return handled; |
519 } | 519 } |
520 | 520 |
521 #if !defined(OS_NACL) | 521 #if !defined(OS_NACL) |
522 // static | |
523 PP_Resource PPB_ImageData_Proxy::CreateImageData( | |
524 PP_Instance instance, | |
525 PP_ImageDataFormat format, | |
526 const PP_Size& size, | |
527 bool init_to_zero, | |
528 bool is_nacl_plugin, | |
529 PP_ImageDataDesc* desc, | |
530 IPC::PlatformFileForTransit* image_handle, | |
531 uint32_t* byte_count) { | |
532 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | |
533 if (!dispatcher) | |
534 return 0; | |
535 | |
536 thunk::EnterResourceCreation enter(instance); | |
537 if (enter.failed()) | |
538 return 0; | |
539 | |
540 PP_Resource result = 0; | |
541 PP_Bool clear = init_to_zero ? PP_TRUE : PP_FALSE; | |
542 if (is_nacl_plugin) { | |
543 result = enter.functions()->CreateImageDataNaCl( | |
544 instance, static_cast<PP_ImageDataFormat>(format), &size, clear); | |
yzshen1
2013/05/01 23:18:33
the static_cast is not needed. (and line 547)
bbudge
2013/05/02 21:39:06
Done.
| |
545 } else { | |
546 result = enter.functions()->CreateImageData( | |
547 instance, static_cast<PP_ImageDataFormat>(format), &size, clear); | |
548 } | |
549 if (!result) | |
550 return 0; | |
551 | |
552 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(result, false); | |
553 if (enter_resource.object()->Describe(desc) != PP_TRUE) | |
yzshen1
2013/05/01 23:18:33
In this case and line 557, shall we release the PP
bbudge
2013/05/02 21:39:06
Done.
| |
554 DVLOG(1) << "CreateImageData failed: could not Describe"; | |
555 | |
556 int local_fd = 0; | |
557 if (enter_resource.object()->GetSharedMemory(&local_fd, byte_count) != PP_OK) | |
558 DVLOG(1) << "CreateImageData failed: could not GetSharedMemory"; | |
559 | |
560 #if defined(OS_WIN) | |
561 *image_handle = dispatcher->ShareHandleWithRemote( | |
562 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); | |
563 #elif defined(OS_MACOSX) || defined(OS_ANDROID) | |
564 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); | |
565 #elif defined(OS_POSIX) | |
566 // On X Windows, a non-nacl handle is a SysV shared memory key. | |
567 if (is_nacl_plugin) | |
568 *image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); | |
569 else | |
570 *image_handle = IPC::PlatformFileForTransit(local_fd, false); | |
571 #else | |
572 #error Not implemented. | |
573 #endif | |
574 | |
575 return result; | |
576 } | |
577 | |
522 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, | 578 void PPB_ImageData_Proxy::OnHostMsgCreate(PP_Instance instance, |
523 int32_t format, | 579 int32_t format, |
524 const PP_Size& size, | 580 const PP_Size& size, |
525 PP_Bool init_to_zero, | 581 PP_Bool init_to_zero, |
526 HostResource* result, | 582 HostResource* result, |
527 std::string* image_data_desc, | 583 std::string* image_data_desc, |
528 ImageHandle* result_image_handle) { | 584 ImageHandle* result_image_handle) { |
529 *result_image_handle = ImageData::NullHandle(); | 585 PP_ImageDataDesc desc; |
530 | 586 IPC::PlatformFileForTransit image_handle; |
531 thunk::EnterResourceCreation enter(instance); | 587 uint32_t byte_count; |
532 if (enter.failed()) | 588 PP_Resource resource = CreateImageData( |
533 return; | 589 instance, |
yzshen1
2013/05/01 23:18:33
nit: The indent is a little bit unusual.
bbudge
2013/05/02 21:39:06
Done.
| |
534 | 590 static_cast<PP_ImageDataFormat>(format), |
535 PP_Resource resource = enter.functions()->CreateImageData( | 591 size, |
536 instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); | 592 true /* init_to_zero */, |
537 if (!resource) | 593 false /* is_nacl_plugin */, |
538 return; | 594 &desc, &image_handle, &byte_count); |
539 result->SetHostResource(instance, resource); | 595 result->SetHostResource(instance, resource); |
540 | 596 if (resource) { |
541 // Get the description, it's just serialized as a string. | |
542 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource, false); | |
543 PP_ImageDataDesc desc; | |
544 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { | |
545 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | 597 image_data_desc->resize(sizeof(PP_ImageDataDesc)); |
546 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | 598 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); |
547 } | 599 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_ANDROID) |
548 | 600 *result_image_handle = image_handle; |
549 // Get the shared memory handle. | |
550 uint32_t byte_count = 0; | |
551 int32_t handle = 0; | |
552 if (enter_resource.object()->GetSharedMemory(&handle, &byte_count) == PP_OK) { | |
553 #if defined(OS_WIN) | |
554 ImageHandle ih = ImageData::HandleFromInt(handle); | |
555 *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); | |
556 #else | 601 #else |
557 *result_image_handle = ImageData::HandleFromInt(handle); | 602 // On X Windows ImageHandle is a SysV shared memory key. |
558 #endif // defined(OS_WIN) | 603 *result_image_handle = image_handle.fd; |
604 #endif | |
605 } else { | |
606 image_data_desc->clear(); | |
607 *result_image_handle = ImageData::NullHandle(); | |
559 } | 608 } |
560 } | 609 } |
561 | 610 |
562 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( | 611 void PPB_ImageData_Proxy::OnHostMsgCreateNaCl( |
563 PP_Instance instance, | 612 PP_Instance instance, |
564 int32_t format, | 613 int32_t format, |
565 const PP_Size& size, | 614 const PP_Size& size, |
566 PP_Bool init_to_zero, | 615 PP_Bool init_to_zero, |
567 HostResource* result, | 616 HostResource* result, |
568 std::string* image_data_desc, | 617 std::string* image_data_desc, |
569 ppapi::proxy::SerializedHandle* result_image_handle) { | 618 ppapi::proxy::SerializedHandle* result_image_handle) { |
570 result_image_handle->set_null_shmem(); | 619 PP_ImageDataDesc desc; |
571 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); | 620 IPC::PlatformFileForTransit image_handle; |
572 if (!dispatcher) | 621 uint32_t byte_count; |
573 return; | 622 PP_Resource resource = CreateImageData( |
623 instance, | |
624 static_cast<PP_ImageDataFormat>(format), | |
625 size, | |
626 true /* init_to_zero */, | |
627 true /* is_nacl_plugin */, | |
628 &desc, &image_handle, &byte_count); | |
574 | 629 |
575 thunk::EnterResourceCreation enter(instance); | |
576 if (enter.failed()) | |
577 return; | |
578 | |
579 PP_Resource resource = enter.functions()->CreateImageDataNaCl( | |
580 instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); | |
581 if (!resource) | |
582 return; | |
583 result->SetHostResource(instance, resource); | 630 result->SetHostResource(instance, resource); |
584 | 631 if (resource) { |
585 // Get the description, it's just serialized as a string. | |
586 thunk::EnterResourceNoLock<PPB_ImageData_API> enter_resource(resource, false); | |
587 if (enter_resource.failed()) | |
588 return; | |
589 PP_ImageDataDesc desc; | |
590 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { | |
591 image_data_desc->resize(sizeof(PP_ImageDataDesc)); | 632 image_data_desc->resize(sizeof(PP_ImageDataDesc)); |
592 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | 633 memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); |
634 result_image_handle->set_shmem(image_handle, byte_count); | |
635 } else { | |
636 image_data_desc->clear(); | |
637 result_image_handle->set_null_shmem(); | |
593 } | 638 } |
594 int local_fd; | |
595 uint32_t byte_count; | |
596 if (enter_resource.object()->GetSharedMemory(&local_fd, &byte_count) != PP_OK) | |
597 return; | |
598 // TODO(dmichael): Change trusted interface to return a PP_FileHandle, those | |
599 // casts are ugly. | |
600 base::PlatformFile platform_file = | |
601 #if defined(OS_WIN) | |
602 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)); | |
603 #elif defined(OS_POSIX) | |
604 local_fd; | |
605 #else | |
606 #error Not implemented. | |
607 #endif // defined(OS_WIN) | |
608 result_image_handle->set_shmem( | |
609 dispatcher->ShareHandleWithRemote(platform_file, false), | |
610 byte_count); | |
611 } | 639 } |
612 #endif // !defined(OS_NACL) | 640 #endif // !defined(OS_NACL) |
613 | 641 |
614 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( | 642 void PPB_ImageData_Proxy::OnPluginMsgNotifyUnusedImageData( |
615 const HostResource& old_image_data) { | 643 const HostResource& old_image_data) { |
616 PluginGlobals* plugin_globals = PluginGlobals::Get(); | 644 PluginGlobals* plugin_globals = PluginGlobals::Get(); |
617 if (!plugin_globals) | 645 if (!plugin_globals) |
618 return; // This may happen if the plugin is maliciously sending this | 646 return; // This may happen if the plugin is maliciously sending this |
619 // message to the renderer. | 647 // message to the renderer. |
620 | 648 |
621 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); | 649 EnterPluginFromHostResource<PPB_ImageData_API> enter(old_image_data); |
622 if (enter.succeeded()) { | 650 if (enter.succeeded()) { |
623 ImageData* image_data = static_cast<ImageData*>(enter.object()); | 651 ImageData* image_data = static_cast<ImageData*>(enter.object()); |
624 ImageDataCache::GetInstance()->ImageDataUsable(image_data); | 652 ImageDataCache::GetInstance()->ImageDataUsable(image_data); |
625 } | 653 } |
626 | 654 |
627 // The renderer sent us a reference with the message. If the image data was | 655 // The renderer sent us a reference with the message. If the image data was |
628 // still cached in our process, the proxy still holds a reference so we can | 656 // still cached in our process, the proxy still holds a reference so we can |
629 // remove the one the renderer just sent is. If the proxy no longer holds a | 657 // remove the one the renderer just sent is. If the proxy no longer holds a |
630 // reference, we released everything and we should also release the one the | 658 // reference, we released everything and we should also release the one the |
631 // renderer just sent us. | 659 // renderer just sent us. |
632 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( | 660 dispatcher()->Send(new PpapiHostMsg_PPBCore_ReleaseResource( |
633 API_ID_PPB_CORE, old_image_data)); | 661 API_ID_PPB_CORE, old_image_data)); |
634 } | 662 } |
635 | 663 |
636 } // namespace proxy | 664 } // namespace proxy |
637 } // namespace ppapi | 665 } // namespace ppapi |
OLD | NEW |