diff options
Diffstat (limited to 'content/renderer/browser_plugin/browser_plugin.cc')
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin.cc | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 8ba5421..fe3ff38 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -6,6 +6,9 @@ #include "base/message_loop.h" #include "base/string_util.h" +#if defined (OS_WIN) +#include "base/sys_info.h" +#endif #include "content/common/browser_plugin_messages.h" #include "content/public/common/content_client.h" #include "content/public/renderer/content_renderer_client.h" @@ -54,6 +57,7 @@ BrowserPlugin::BrowserPlugin( sad_guest_(NULL), guest_crashed_(false), resize_pending_(false), + navigate_src_sent_(false), parent_frame_(frame->identifier()) { BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); bindings_.reset(new BrowserPluginBindings(this)); @@ -90,13 +94,21 @@ std::string BrowserPlugin::GetSrcAttribute() const { void BrowserPlugin::SetSrcAttribute(const std::string& src) { if (src == src_ && !guest_crashed_) return; - if (!src.empty()) { + if (!src.empty() || navigate_src_sent_) { BrowserPluginManager::Get()->Send( - new BrowserPluginHostMsg_NavigateOrCreateGuest( + new BrowserPluginHostMsg_NavigateGuest( render_view_->GetRoutingID(), instance_id_, parent_frame_, - src)); + src, + gfx::Size(width(), height()))); + // Record that we sent a NavigateGuest message to embedder. Once we send + // such a message, subsequent SetSrcAttribute() calls must always send + // NavigateGuest messages to the embedder (even if |src| is empty), so + // resize works correctly for all cases (e.g. The embedder can reset the + // guest's |src| to empty value, resize and then set the |src| to a + // non-empty value). + navigate_src_sent_ = true; } src_ = src; guest_crashed_ = false; @@ -310,8 +322,9 @@ void BrowserPlugin::paint(WebCanvas* canvas, const WebRect& rect) { paint.setStyle(SkPaint::kFill_Style); paint.setColor(SK_ColorWHITE); canvas->drawRect(image_data_rect, paint); - // Stay at white if we have no src set, or we don't yet have a backing store. - if (!backing_store_.get() || src_.empty()) + // Stay at white if we have never set a non-empty src, or we don't yet have a + // backing store. + if (!backing_store_.get() || !navigate_src_sent_) return; float inverse_scale_factor = 1.0f / backing_store_->GetScaleFactor(); canvas->scale(inverse_scale_factor, inverse_scale_factor); @@ -327,23 +340,51 @@ void BrowserPlugin::updateGeometry( int old_height = height(); plugin_rect_ = window_rect; if (old_width == window_rect.width && - old_height == window_rect.height) + old_height == window_rect.height) { + return; + } + // Until an actual navigation occurs, there is no browser side embedder + // present to notify about geometry updates. In this case, after we've updated + // the BrowserPlugin's state we are done and can return immediately. + if (!navigate_src_sent_) return; const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); - const size_t size = window_rect.height * - stride * - GetDeviceScaleFactor() * - GetDeviceScaleFactor(); + // Make sure the size of the damage buffer is at least four bytes so that we + // can fit in a magic word to verify that the memory is shared correctly. + size_t size = + std::max(sizeof(unsigned int), + static_cast<size_t>(window_rect.height * + stride * + GetDeviceScaleFactor() * + GetDeviceScaleFactor())); // Don't drop the old damage buffer until after we've made sure that the // browser process has dropped it. - TransportDIB* new_damage_buffer = - RenderProcess::current()->CreateTransportDIB(size); - DCHECK(new_damage_buffer); + TransportDIB* new_damage_buffer = NULL; +#if defined(OS_WIN) + size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); + size_t shared_mem_size = size / allocation_granularity + 1; + shared_mem_size = shared_mem_size * allocation_granularity; + + base::SharedMemory shared_mem; + if (!shared_mem.CreateAnonymous(shared_mem_size)) + NOTREACHED() << "Unable to create shared memory of size:" << size; + new_damage_buffer = TransportDIB::Map(shared_mem.handle()); +#else + new_damage_buffer = RenderProcess::current()->CreateTransportDIB(size); +#endif + if (!new_damage_buffer) + NOTREACHED() << "Unable to create damage buffer"; + DCHECK(new_damage_buffer->memory()); + // Insert the magic word. + *static_cast<unsigned int*>(new_damage_buffer->memory()) = 0xdeadbeef; BrowserPluginHostMsg_ResizeGuest_Params params; params.damage_buffer_id = new_damage_buffer->id(); +#if defined(OS_WIN) + params.damage_buffer_size = size; +#endif params.width = window_rect.width; params.height = window_rect.height; params.resize_pending = resize_pending_; @@ -377,7 +418,7 @@ bool BrowserPlugin::acceptsInputEvents() { bool BrowserPlugin::handleInputEvent(const WebKit::WebInputEvent& event, WebKit::WebCursorInfo& cursor_info) { - if (guest_crashed_ || src_.empty()) + if (guest_crashed_ || !navigate_src_sent_) return false; bool handled = false; WebCursor cursor; |