diff options
author | dcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-20 01:54:04 +0000 |
---|---|---|
committer | dcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-20 01:54:04 +0000 |
commit | d2a2a409f713ce9f28b8d40b3ed2ef9140057a38 (patch) | |
tree | 4e0f6cf3097fd7dd09e726fac7bd791409fd493b /content | |
parent | 7cb5029c99a5b3164e7b190538c245e0617b4fd9 (diff) | |
download | chromium_src-d2a2a409f713ce9f28b8d40b3ed2ef9140057a38.zip chromium_src-d2a2a409f713ce9f28b8d40b3ed2ef9140057a38.tar.gz chromium_src-d2a2a409f713ce9f28b8d40b3ed2ef9140057a38.tar.bz2 |
Implement Clipboard::ReadImage on Linux.
I split the IPC up into two parts on Linux--one that reads the image on the UI
thread, and a second part that encodes the image on the file thread before
replying. I've also switched it to send the data over shared memory instead of passing a (potentially) huge blob of data over IPC.
BUG=75237
TEST=Local testing.
Review URL: http://codereview.chromium.org/6871001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82212 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/clipboard_message_filter.cc | 63 | ||||
-rw-r--r-- | content/browser/renderer_host/clipboard_message_filter.h | 3 | ||||
-rw-r--r-- | content/common/clipboard_messages.h | 6 | ||||
-rw-r--r-- | content/renderer/renderer_glue.cc | 11 |
4 files changed, 58 insertions, 25 deletions
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc index 1b09839..65d2178 100644 --- a/content/browser/renderer_host/clipboard_message_filter.cc +++ b/content/browser/renderer_host/clipboard_message_filter.cc @@ -46,9 +46,7 @@ void ClipboardMessageFilter::OverrideThreadForMessage( if (message.type() == ClipboardHostMsg_ReadImage::ID) *thread = BrowserThread::FILE; #elif defined(USE_X11) - if (message.type() == ClipboardHostMsg_ReadImage::ID) - *thread = BrowserThread::BACKGROUND_X11; - else if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart) + if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart) *thread = BrowserThread::UI; #endif } @@ -65,7 +63,7 @@ bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message, IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAsciiText, OnReadAsciiText) IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML) - IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadImage, OnReadImage) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage) #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync, OnFindPboardWriteString) @@ -144,25 +142,48 @@ void ClipboardMessageFilter::OnReadHTML( } void ClipboardMessageFilter::OnReadImage( - ui::Clipboard::Buffer buffer, std::string* data) { + ui::Clipboard::Buffer buffer, IPC::Message* reply_msg) { SkBitmap bitmap = GetClipboard()->ReadImage(buffer); - if (bitmap.isNull()) - return; - - std::vector<unsigned char> png_data; - SkAutoLockPixels lock(bitmap); - if (gfx::PNGCodec::EncodeWithCompressionLevel( - static_cast<const unsigned char*>(bitmap.getPixels()), - gfx::PNGCodec::FORMAT_BGRA, - gfx::Size(bitmap.width(), bitmap.height()), - bitmap.rowBytes(), - false, - std::vector<gfx::PNGCodec::Comment>(), - Z_BEST_SPEED, - &png_data)) { - data->assign(reinterpret_cast<char*>(vector_as_array(&png_data)), - png_data.size()); + +#if defined(USE_X11) + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod( + this, &ClipboardMessageFilter::OnReadImageReply, bitmap, reply_msg)); +#else + OnReadImageReply(bitmap, reply_msg); +#endif +} + +void ClipboardMessageFilter::OnReadImageReply( + SkBitmap bitmap, IPC::Message* reply_msg) { + base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle(); + uint32 image_size = 0; + std::string reply_data; + if (!bitmap.isNull()) { + std::vector<unsigned char> png_data; + SkAutoLockPixels lock(bitmap); + if (gfx::PNGCodec::EncodeWithCompressionLevel( + static_cast<const unsigned char*>(bitmap.getPixels()), + gfx::PNGCodec::FORMAT_BGRA, + gfx::Size(bitmap.width(), bitmap.height()), + bitmap.rowBytes(), + false, + std::vector<gfx::PNGCodec::Comment>(), + Z_BEST_SPEED, + &png_data)) { + base::SharedMemory buffer; + if (buffer.CreateAndMapAnonymous(png_data.size())) { + memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size()); + if (buffer.GiveToProcess(peer_handle(), &image_handle)) { + image_size = png_data.size(); + } + } + } } + ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle, + image_size); + Send(reply_msg); } void ClipboardMessageFilter::OnReadAvailableTypes( diff --git a/content/browser/renderer_host/clipboard_message_filter.h b/content/browser/renderer_host/clipboard_message_filter.h index b77a5a2..3128852 100644 --- a/content/browser/renderer_host/clipboard_message_filter.h +++ b/content/browser/renderer_host/clipboard_message_filter.h @@ -38,7 +38,8 @@ class ClipboardMessageFilter : public BrowserMessageFilter { void OnReadText(ui::Clipboard::Buffer buffer, string16* result); void OnReadAsciiText(ui::Clipboard::Buffer buffer, std::string* result); void OnReadHTML(ui::Clipboard::Buffer buffer, string16* markup, GURL* url); - void OnReadImage(ui::Clipboard::Buffer buffer, std::string* data); + void OnReadImage(ui::Clipboard::Buffer buffer, IPC::Message* reply_msg); + void OnReadImageReply(SkBitmap bitmap, IPC::Message* reply_msg); #if defined(OS_MACOSX) void OnFindPboardWriteString(const string16& text); #endif diff --git a/content/common/clipboard_messages.h b/content/common/clipboard_messages.h index 7fe14af..5b06d2f 100644 --- a/content/common/clipboard_messages.h +++ b/content/common/clipboard_messages.h @@ -7,6 +7,7 @@ #include <string> #include <vector> +#include "base/shared_memory.h" #include "content/common/common_param_traits.h" #include "ipc/ipc_message_macros.h" #include "ipc/ipc_param_traits.h" @@ -45,9 +46,10 @@ IPC_SYNC_MESSAGE_CONTROL1_2(ClipboardHostMsg_ReadHTML, ui::Clipboard::Buffer /* buffer */, string16 /* markup */, GURL /* url */) -IPC_SYNC_MESSAGE_CONTROL1_1(ClipboardHostMsg_ReadImage, +IPC_SYNC_MESSAGE_CONTROL1_2(ClipboardHostMsg_ReadImage, ui::Clipboard::Buffer /* buffer */, - std::string /* PNG-encoded image */) + base::SharedMemoryHandle /* PNG-encoded image */, + uint32 /* image size */) #if defined(OS_MACOSX) IPC_MESSAGE_CONTROL1(ClipboardHostMsg_FindPboardWriteStringAsync, string16 /* text */) diff --git a/content/renderer/renderer_glue.cc b/content/renderer/renderer_glue.cc index 60a8d47..5ad03fd 100644 --- a/content/renderer/renderer_glue.cc +++ b/content/renderer/renderer_glue.cc @@ -14,6 +14,7 @@ #include "base/command_line.h" #include "base/memory/ref_counted.h" +#include "base/shared_memory.h" #include "base/string_util.h" #include "content/common/clipboard_messages.h" #include "content/common/content_switches.h" @@ -168,7 +169,15 @@ void ClipboardReadHTML(ui::Clipboard::Buffer buffer, string16* markup, } void ClipboardReadImage(ui::Clipboard::Buffer buffer, std::string* data) { - RenderThread::current()->Send(new ClipboardHostMsg_ReadImage(buffer, data)); + base::SharedMemoryHandle image_handle; + uint32 image_size; + RenderThread::current()->Send( + new ClipboardHostMsg_ReadImage(buffer, &image_handle, &image_size)); + if (base::SharedMemory::IsHandleValid(image_handle)) { + base::SharedMemory buffer(image_handle, true); + buffer.Map(image_size); + data->append(static_cast<char*>(buffer.memory()), image_size); + } } bool ClipboardReadData(ui::Clipboard::Buffer buffer, const string16& type, |