Chromium Code Reviews| 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 |