Chromium Code Reviews| Index: content/renderer/browser_plugin/browser_plugin.cc |
| diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc |
| index f6234bf1c6459f047d64d428c29b9228cfc99165..f01113435ff7e0abaf5d3799ba024d8a4afeaed6 100644 |
| --- a/content/renderer/browser_plugin/browser_plugin.cc |
| +++ b/content/renderer/browser_plugin/browser_plugin.cc |
| @@ -50,10 +50,15 @@ const char kLoadRedirectEventName[] = "loadredirect"; |
| const char kLoadStartEventName[] = "loadstart"; |
| const char kLoadStopEventName[] = "loadstop"; |
| const char kNewURL[] = "newUrl"; |
| +const char kNewHeight[] = "newHeight"; |
| +const char kNewWidth[] = "newWidth"; |
| const char kOldURL[] = "oldUrl"; |
| +const char kOldHeight[] = "oldHeight"; |
| +const char kOldWidth[] = "oldWidth"; |
| const char kPartitionAttribute[] = "partition"; |
| const char kPersistPrefix[] = "persist:"; |
| const char kProcessId[] = "processId"; |
| +const char kSizeChangedEventName[] = "sizechanged"; |
| const char kSrcAttribute[] = "src"; |
| const char kType[] = "type"; |
| const char kURL[] = "url"; |
| @@ -100,6 +105,7 @@ BrowserPlugin::BrowserPlugin( |
| content_window_routing_id_(MSG_ROUTING_NONE), |
| focused_(false), |
| visible_(true), |
| + size_changed_in_flight_(false), |
| current_nav_entry_index_(0), |
| nav_entry_count_(0) { |
| BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); |
| @@ -168,27 +174,81 @@ void BrowserPlugin::SetAutoSizeAttribute(bool auto_size) { |
| if (auto_size_ == auto_size) |
| return; |
| auto_size_ = auto_size; |
| + last_view_size_ = plugin_rect_.size(); |
| + //backing_store_.reset(); |
|
lazyboy
2012/11/06 22:22:35
rm
Fady Samuel
2012/11/06 23:52:34
Done.
|
| UpdateGuestAutoSizeState(); |
| } |
| void BrowserPlugin::PopulateAutoSizeParameters( |
| - BrowserPluginHostMsg_AutoSize_Params* params) const { |
| + BrowserPluginHostMsg_AutoSize_Params* params) { |
| + // If maxWidth or maxHeight have not been set, set them to the container size. |
| + max_height_ = max_height_ ? max_height_ : height(); |
| + max_width_ = max_width_ ? max_width_ : width(); |
| + // minWidth should not be bigger than maxWidth, and minHeight should not be |
| + // bigger than maxHeight. |
| + min_height_ = std::min(min_height_, max_height_); |
| + min_width_ = std::min(min_width_, max_width_); |
| params->enable = auto_size_; |
| params->max_height = max_height_; |
| params->max_width = max_width_; |
| params->min_height = min_height_; |
| params->min_width = min_width_; |
| + |
|
lazyboy
2012/11/06 22:22:35
nit: rm
Fady Samuel
2012/11/06 23:52:34
Done.
|
| } |
| -void BrowserPlugin::UpdateGuestAutoSizeState() const { |
| +void BrowserPlugin::UpdateGuestAutoSizeState() { |
| if (!navigate_src_sent_) |
| return; |
| - BrowserPluginHostMsg_AutoSize_Params params; |
| - PopulateAutoSizeParameters(¶ms); |
| + BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| + PopulateAutoSizeParameters(&auto_size_params); |
| + BrowserPluginHostMsg_ResizeGuest_Params resize_params; |
| + int view_width = auto_size_params.max_width; |
| + int view_height = auto_size_params.max_height; |
| + if (!auto_size_params.enable) { |
| + view_width = width(); |
| + view_height = height(); |
| + } |
| + TransportDIB* new_damage_buffer = |
| + PopulateResizeGuestParameters(&resize_params, view_width, view_height); |
| + // AutoSize initiates a resize so we don't want to issue another resize, |
| + // we just want to make sure the damage buffer has been updated. |
| + resize_params.resize_pending = true; |
| + DCHECK(new_damage_buffer); |
| BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetAutoSize( |
| render_view_routing_id_, |
| instance_id_, |
| - params)); |
| + auto_size_params, |
| + resize_params)); |
| + if (damage_buffer_) |
| + FreeDamageBuffer(); |
| + damage_buffer_ = new_damage_buffer; |
| +} |
| + |
| +void BrowserPlugin::SizeChanged(const gfx::Size& old_view_size) { |
|
lazyboy
2012/11/06 22:22:35
This is size changed due to auto sizing only, mayb
Fady Samuel
2012/11/06 23:52:34
Done.
|
| + size_changed_in_flight_ = false; |
| + if (!HasListeners(kSizeChangedEventName)) |
| + return; |
| + |
| + WebKit::WebElement plugin = container()->element(); |
| + v8::HandleScope handle_scope; |
| + v8::Context::Scope context_scope( |
| + plugin.document().frame()->mainWorldScriptContext()); |
| + |
| + // Construct the loadStart event object. |
|
lazyboy
2012/11/06 22:22:35
nit: fix comment.
Fady Samuel
2012/11/06 23:52:34
Done.
|
| + v8::Local<v8::Object> event = v8::Object::New(); |
| + event->Set(v8::String::New(kOldHeight, sizeof(kOldHeight) - 1), |
| + v8::Integer::New(old_view_size.height()), |
| + v8::ReadOnly); |
| + event->Set(v8::String::New(kOldWidth, sizeof(kOldWidth) - 1), |
| + v8::Integer::New(old_view_size.width()), |
| + v8::ReadOnly); |
| + event->Set(v8::String::New(kNewHeight, sizeof(kNewHeight) - 1), |
| + v8::Integer::New(last_view_size_.height()), |
| + v8::ReadOnly); |
| + event->Set(v8::String::New(kNewWidth, sizeof(kNewWidth) - 1), |
| + v8::Integer::New(last_view_size_.width()), |
| + v8::ReadOnly); |
| + TriggerEvent(kSizeChangedEventName, &event); |
| } |
| void BrowserPlugin::SetMaxHeightAttribute(int max_height) { |
| @@ -227,6 +287,10 @@ void BrowserPlugin::SetMinWidthAttribute(int min_width) { |
| UpdateGuestAutoSizeState(); |
| } |
| +bool BrowserPlugin::InAutoSizeBounds(const gfx::Size& size) const { |
| + return size.width() <= max_width_ && size.height() <= max_height_; |
| +} |
| + |
| NPObject* BrowserPlugin::GetContentWindow() const { |
| if (content_window_routing_id_ == MSG_ROUTING_NONE) |
| return NULL; |
| @@ -320,6 +384,7 @@ void BrowserPlugin::InitializeEvents() { |
| event_listener_map_[kLoadRedirectEventName] = EventListeners(); |
| event_listener_map_[kLoadStartEventName] = EventListeners(); |
| event_listener_map_[kLoadStopEventName] = EventListeners(); |
| + event_listener_map_[kSizeChangedEventName] = EventListeners(); |
| } |
| void BrowserPlugin::RemoveEventListeners() { |
| @@ -427,8 +492,10 @@ void BrowserPlugin::Reload() { |
| void BrowserPlugin::UpdateRect( |
| int message_id, |
| const BrowserPluginMsg_UpdateRect_Params& params) { |
| - if (width() != params.view_size.width() || |
| - height() != params.view_size.height()) { |
| + if ((!auto_size_ && |
| + (width() != params.view_size.width() || |
| + height() != params.view_size.height())) || |
| + (auto_size_ && (!InAutoSizeBounds(params.view_size)))) { |
| BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( |
| render_view_routing_id_, |
| instance_id_, |
| @@ -436,16 +503,43 @@ void BrowserPlugin::UpdateRect( |
| gfx::Size(width(), height()))); |
| return; |
| } |
| + // If the view size has changed since we last updated. |
| + if (auto_size_ && (params.view_size != last_view_size_)) { |
| + if (backing_store_) |
| + backing_store_->Clear(SK_ColorWHITE); |
| + gfx::Size old_view_size = last_view_size_; |
| + last_view_size_ = params.view_size; |
| + // Schedule a SizeChanged instead of calling it directly to ensure that |
| + // the backing store has been updated before the developer attempts to |
|
lazyboy
2012/11/06 22:22:35
I'm not sure I totally understand this one, if you
Fady Samuel
2012/11/06 23:52:34
Yes. Also, if there are multiple updateRects queue
lazyboy
2012/11/07 07:39:09
Ah, I was about to suggest you write a test for th
|
| + // resize to avoid flicker. |size_changed_in_flight_| acts as a form of |
| + // flow control for SizeChanged events. If the guest's view size is changing |
| + // rapidly before a SizeChanged event fires, then we avoid scheduling |
| + // another SizedChanged event. SizedChanged reads the new size from |
| + // |last_view_size_| so we can be sure that it always fires an event |
| + // with the last seen view size. |
| + if (container_ && !size_changed_in_flight_) { |
| + size_changed_in_flight_ = true; |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&BrowserPlugin::SizeChanged, base::Unretained(this), |
| + old_view_size)); |
| + } |
| + } |
| float backing_store_scale_factor = |
| backing_store_.get() ? backing_store_->GetScaleFactor() : 1.0f; |
| - if (params.is_resize_ack || |
| - backing_store_scale_factor != params.scale_factor) { |
| + if (!backing_store_ || params.is_resize_ack || |
| + (backing_store_scale_factor != params.scale_factor) || |
| + params.view_size.width() > backing_store_->GetSize().width() || |
| + params.view_size.height() > backing_store_->GetSize().height()) { |
| + int backing_store_width = auto_size_ ? max_width_ : width(); |
| + int backing_store_height = auto_size_ ? max_height_: height(); |
| resize_pending_ = !params.is_resize_ack; |
| backing_store_.reset( |
| - new BrowserPluginBackingStore(gfx::Size(width(), height()), |
| - params.scale_factor)); |
| + new BrowserPluginBackingStore( |
| + gfx::Size(backing_store_width, backing_store_height), |
| + params.scale_factor)); |
| } |
| // Update the backing store. |
| @@ -753,41 +847,17 @@ void BrowserPlugin::updateGeometry( |
| int old_height = height(); |
| plugin_rect_ = window_rect; |
| if (auto_size_ || (old_width == window_rect.width && |
| - old_height == window_rect.height)) { |
| + old_height == window_rect.height)) { |
| return; |
| } |
| - |
| - const size_t stride = skia::PlatformCanvas::StrideForWidth(window_rect.width); |
| - // 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 = CreateTransportDIB(size); |
| pending_resize_params_.reset(); |
| scoped_ptr<BrowserPluginHostMsg_ResizeGuest_Params> params( |
| new BrowserPluginHostMsg_ResizeGuest_Params); |
| - params->damage_buffer_id = new_damage_buffer->id(); |
| -#if defined(OS_MACOSX) |
| - // |damage_buffer_id| is not enough to retrieve the damage buffer (on browser |
| - // side) since we don't let the browser cache the damage buffer. We need a |
| - // handle to the damage buffer for this. |
| - params->damage_buffer_handle = new_damage_buffer->handle(); |
| -#endif |
| -#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_; |
| - params->scale_factor = GetDeviceScaleFactor(); |
| + |
| + TransportDIB* new_damage_buffer = |
| + PopulateResizeGuestParameters(params.get(), width(), height()); |
| + DCHECK(new_damage_buffer); |
| if (navigate_src_sent_) { |
| BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( |
| @@ -820,6 +890,39 @@ void BrowserPlugin::FreeDamageBuffer() { |
| #endif |
| } |
| +TransportDIB* BrowserPlugin::PopulateResizeGuestParameters( |
| + BrowserPluginHostMsg_ResizeGuest_Params* params, |
| + int view_width, int view_height) { |
| + const size_t stride = skia::PlatformCanvas::StrideForWidth(view_width); |
| + // 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>(view_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 = CreateTransportDIB(size); |
| + params->damage_buffer_id = new_damage_buffer->id(); |
| +#if defined(OS_MACOSX) |
| + // |damage_buffer_id| is not enough to retrieve the damage buffer (on browser |
| + // side) since we don't let the browser cache the damage buffer. We need a |
| + // handle to the damage buffer for this. |
| + params->damage_buffer_handle = new_damage_buffer->handle(); |
| +#endif |
| +#if defined(OS_WIN) |
| + params->damage_buffer_size = size; |
| +#endif |
| + params->width = view_width; |
| + params->height = view_height; |
| + params->resize_pending = resize_pending_; |
| + params->scale_factor = GetDeviceScaleFactor(); |
| + return new_damage_buffer; |
| +} |
| + |
| BrowserPluginHostMsg_ResizeGuest_Params* |
| BrowserPlugin::GetPendingResizeParams() { |
| if (pending_resize_params_.get()) { |