Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2078)

Unified Diff: content/renderer/browser_plugin/browser_plugin.cc

Issue 11360106: Browser Plugin: Implement AutoSize (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reupload Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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(&params);
+ 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()) {

Powered by Google App Engine
This is Rietveld 408576698