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

Side by Side Diff: webkit/glue/webplugin_impl.cc

Issue 18082: Improve scrolling performance when there are many windowed plugins in a page.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Call DestroyWindow on the right thread & ensure NPP_SetWindow is called right away Created 11 years, 11 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "config.h" 5 #include "config.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 9
10 MSVC_PUSH_WARNING_LEVEL(0); 10 MSVC_PUSH_WARNING_LEVEL(0);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 } 127 }
128 128
129 #if USE(JSC) 129 #if USE(JSC)
130 bool WebPluginContainer::isPluginView() const { 130 bool WebPluginContainer::isPluginView() const {
131 return true; 131 return true;
132 } 132 }
133 #endif 133 #endif
134 134
135 135
136 void WebPluginContainer::setFrameRect(const WebCore::IntRect& rect) { 136 void WebPluginContainer::setFrameRect(const WebCore::IntRect& rect) {
137 // WebKit calls move every time it paints (see RenderWidget::paint). No need
138 // to do expensive operations if we didn't actually move.
139 if (rect == frameRect())
140 return;
141
137 WebCore::Widget::setFrameRect(rect); 142 WebCore::Widget::setFrameRect(rect);
138 impl_->setFrameRect(rect); 143 impl_->setFrameRect(rect);
139 } 144 }
140 145
141 void WebPluginContainer::paint(WebCore::GraphicsContext* gc, 146 void WebPluginContainer::paint(WebCore::GraphicsContext* gc,
142 const WebCore::IntRect& damage_rect) { 147 const WebCore::IntRect& damage_rect) {
143 // In theory, we should call impl_->print(gc); when 148 // In theory, we should call impl_->print(gc); when
144 // impl_->webframe_->printing() is true but it still has placement issues so 149 // impl_->webframe_->printing() is true but it still has placement issues so
145 // keep that code off for now. 150 // keep that code off for now.
146 impl_->paint(gc, damage_rect); 151 impl_->paint(gc, damage_rect);
(...skipping 12 matching lines...) Expand all
159 } 164 }
160 165
161 void WebPluginContainer::setFocus() { 166 void WebPluginContainer::setFocus() {
162 WebCore::Widget::setFocus(); 167 WebCore::Widget::setFocus();
163 impl_->setFocus(); 168 impl_->setFocus();
164 } 169 }
165 170
166 void WebPluginContainer::show() { 171 void WebPluginContainer::show() {
167 // We don't want to force a geometry update when the plugin widget is 172 // We don't want to force a geometry update when the plugin widget is
168 // already visible as this involves a geometry update which may lead 173 // already visible as this involves a geometry update which may lead
169 // to unnecessary window moves in the plugin process. The only case 174 // to unnecessary window moves in the plugin process.
170 // where this does not apply is if the force_geometry_update_ flag 175 if (!impl_->visible_) {
171 // is set, which occurs when a plugin is created and does not have
172 // a parent. We can send out geometry updates only when the plugin
173 // widget has a parent.
174 if (!impl_->visible_ || impl_->force_geometry_update_) {
175 impl_->show(); 176 impl_->show();
176 WebCore::Widget::show(); 177 WebCore::Widget::show();
177 // This is to force an updategeometry call to the plugin process 178 // This is to force an updategeometry call to the plugin process
178 // where the plugin window can be hidden or shown. 179 // where the plugin window can be hidden or shown.
179 frameRectsChanged(); 180 frameRectsChanged();
180 } 181 }
181 } 182 }
182 183
183 void WebPluginContainer::hide() { 184 void WebPluginContainer::hide() {
184 // Please refer to WebPluginContainer::show for the reasoning behind 185 if (impl_->visible_) {
185 // the if check below.
186 if (impl_->visible_ || impl_->force_geometry_update_) {
187 impl_->hide(); 186 impl_->hide();
188 WebCore::Widget::hide(); 187 WebCore::Widget::hide();
189 // This is to force an updategeometry call to the plugin process 188 // This is to force an updategeometry call to the plugin process
190 // where the plugin window can be hidden or shown. 189 // where the plugin window can be hidden or shown.
191 frameRectsChanged(); 190 frameRectsChanged();
192 } 191 }
193 } 192 }
194 193
195 void WebPluginContainer::handleEvent(WebCore::Event* event) { 194 void WebPluginContainer::handleEvent(WebCore::Event* event) {
196 impl_->handleEvent(event); 195 impl_->handleEvent(event);
(...skipping 12 matching lines...) Expand all
209 // webkit is ignored. This function is called when the plugin eventually 208 // webkit is ignored. This function is called when the plugin eventually
210 // gets a parent. 209 // gets a parent.
211 void WebPluginContainer::setParentVisible(bool visible) { 210 void WebPluginContainer::setParentVisible(bool visible) {
212 WebCore::Widget::setParentVisible(visible); 211 WebCore::Widget::setParentVisible(visible);
213 if (visible) 212 if (visible)
214 show(); 213 show();
215 else 214 else
216 hide(); 215 hide();
217 } 216 }
218 217
218 // We override this function so that if the plugin is windowed, we can call
219 // NPP_SetWindow at the first possible moment. This ensures that NPP_SetWindow
220 // is called before the manual load data is sent to a plugin. If this order is
221 // reversed, Flash won't load videos.
222 void WebPluginContainer::setParent(WebCore::ScrollView* view) {
223 WebCore::Widget::setParent(view);
224 if (view) {
225 impl_->setFrameRect(frameRect());
226 impl_->delegate_->FlushGeometryUpdates();
227 }
228 }
229
219 void WebPluginContainer::windowCutoutRects(const WebCore::IntRect& bounds, 230 void WebPluginContainer::windowCutoutRects(const WebCore::IntRect& bounds,
220 WTF::Vector<WebCore::IntRect>* 231 WTF::Vector<WebCore::IntRect>*
221 cutouts) const { 232 cutouts) const {
222 impl_->windowCutoutRects(bounds, cutouts); 233 impl_->windowCutoutRects(bounds, cutouts);
223 } 234 }
224 235
225 void WebPluginContainer::didReceiveResponse( 236 void WebPluginContainer::didReceiveResponse(
226 const WebCore::ResourceResponse& response) { 237 const WebCore::ResourceResponse& response) {
227
228 set_ignore_response_error(false); 238 set_ignore_response_error(false);
229 239
230 HttpResponseInfo http_response_info; 240 HttpResponseInfo http_response_info;
231 ReadHttpResponseInfo(response, &http_response_info); 241 ReadHttpResponseInfo(response, &http_response_info);
232 242
233 impl_->delegate_->DidReceiveManualResponse( 243 impl_->delegate_->DidReceiveManualResponse(
234 http_response_info.url, 244 http_response_info.url,
235 base::SysWideToNativeMB(http_response_info.mime_type), 245 base::SysWideToNativeMB(http_response_info.mime_type),
236 base::SysWideToNativeMB(impl_->GetAllHeaders(response)), 246 base::SysWideToNativeMB(impl_->GetAllHeaders(response)),
237 http_response_info.expected_length, 247 http_response_info.expected_length,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 bool load_manually, 318 bool load_manually,
309 const std::string& mime_type, 319 const std::string& mime_type,
310 int arg_count, 320 int arg_count,
311 char** arg_names, 321 char** arg_names,
312 char** arg_values) 322 char** arg_values)
313 : windowless_(false), 323 : windowless_(false),
314 window_(NULL), 324 window_(NULL),
315 element_(element), 325 element_(element),
316 webframe_(webframe), 326 webframe_(webframe),
317 delegate_(delegate), 327 delegate_(delegate),
318 force_geometry_update_(false),
319 visible_(false), 328 visible_(false),
320 received_first_paint_notification_(false),
321 widget_(NULL), 329 widget_(NULL),
322 plugin_url_(plugin_url), 330 plugin_url_(plugin_url),
323 load_manually_(load_manually), 331 load_manually_(load_manually),
324 first_geometry_update_(true), 332 first_geometry_update_(true),
325 mime_type_(mime_type) { 333 mime_type_(mime_type) {
326 334
327 ArrayToVector(arg_count, arg_names, &arg_names_); 335 ArrayToVector(arg_count, arg_names, &arg_names_);
328 ArrayToVector(arg_count, arg_values, &arg_values_); 336 ArrayToVector(arg_count, arg_values, &arg_values_);
329 } 337 }
330 338
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 WebCore::IntPoint point = roundedIntPoint(ro->localToAbsolute()); 635 WebCore::IntPoint point = roundedIntPoint(ro->localToAbsolute());
628 WebCore::IntSize size(ro->width(), ro->height()); 636 WebCore::IntSize size(ro->width(), ro->height());
629 cutouts->append(WebCore::IntRect(point, size)); 637 cutouts->append(WebCore::IntRect(point, size));
630 } 638 }
631 } 639 }
632 } 640 }
633 } 641 }
634 } 642 }
635 643
636 void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) { 644 void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
645 if (!parent())
646 return;
647
637 // Compute a new position and clip rect for ourselves relative to the 648 // Compute a new position and clip rect for ourselves relative to the
638 // containing window. We ask our delegate to reposition us accordingly. 649 // containing window. We ask our delegate to reposition us accordingly.
639
640 // When the plugin is loaded we don't have a parent frame yet. We need
641 // to force the plugin window to get created in the plugin process,
642 // when the plugin widget position is updated. This occurs just after
643 // the plugin is loaded (See http://b/issue?id=892174).
644 if (!parent()) {
645 force_geometry_update_ = true;
646 return;
647 }
648
649 WebCore::Frame* frame = element_->document()->frame(); 650 WebCore::Frame* frame = element_->document()->frame();
650 WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame); 651 WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame);
651 WebViewImpl* webview = webframe->webview_impl(); 652 WebViewImpl* webview = webframe->webview_impl();
652 // It is valid for this function to be invoked in code paths where the 653 // It is valid for this function to be invoked in code paths where the
653 // the webview is closed. 654 // the webview is closed.
654 if (!webview->delegate()) { 655 if (!webview->delegate()) {
655 return; 656 return;
656 } 657 }
657 658
658 WebCore::IntRect window_rect; 659 WebCore::IntRect window_rect;
659 WebCore::IntRect clip_rect; 660 WebCore::IntRect clip_rect;
660 std::vector<gfx::Rect> cutout_rects; 661 std::vector<gfx::Rect> cutout_rects;
661 CalculateBounds(rect, &window_rect, &clip_rect, &cutout_rects); 662 CalculateBounds(rect, &window_rect, &clip_rect, &cutout_rects);
662 663
663 if (window_ && received_first_paint_notification_) { 664 delegate_->UpdateGeometry(
665 webkit_glue::FromIntRect(window_rect),
666 webkit_glue::FromIntRect(clip_rect));
667
668 if (window_) {
664 // Let the WebViewDelegate know that the plugin window needs to be moved, 669 // Let the WebViewDelegate know that the plugin window needs to be moved,
665 // so that all the HWNDs are moved together. 670 // so that all the HWNDs are moved together.
666 WebPluginGeometry move; 671 WebPluginGeometry move;
667 move.window = window_; 672 move.window = window_;
668 move.window_rect = webkit_glue::FromIntRect(window_rect); 673 move.window_rect = webkit_glue::FromIntRect(window_rect);
669 move.clip_rect = webkit_glue::FromIntRect(clip_rect); 674 move.clip_rect = webkit_glue::FromIntRect(clip_rect);
670 move.cutout_rects = cutout_rects; 675 move.cutout_rects = cutout_rects;
671 move.visible = visible_; 676 move.visible = visible_;
672 677
673 webview->delegate()->DidMove(webview, move); 678 webview->delegate()->DidMove(webview, move);
674 } 679 }
675 680
676 delegate_->UpdateGeometry(
677 webkit_glue::FromIntRect(window_rect),
678 webkit_glue::FromIntRect(clip_rect), cutout_rects,
679 windowless_ || received_first_paint_notification_ ? visible_ : false);
680
681 // delegate_ can go away as a result of above call, so check it first.
682 if (force_geometry_update_ && delegate_) {
683 force_geometry_update_ = false;
684 delegate_->FlushGeometryUpdates();
685 }
686
687 // Initiate a download on the plugin url. This should be done for the 681 // Initiate a download on the plugin url. This should be done for the
688 // first update geometry sequence. 682 // first update geometry sequence.
689 if (first_geometry_update_) { 683 if (first_geometry_update_) {
690 first_geometry_update_ = false; 684 first_geometry_update_ = false;
691 // An empty url corresponds to an EMBED tag with no src attribute. 685 // An empty url corresponds to an EMBED tag with no src attribute.
692 if (!load_manually_ && plugin_url_.is_valid()) { 686 if (!load_manually_ && plugin_url_.is_valid()) {
693 HandleURLRequestInternal("GET", false, NULL, 0, NULL, false, false, 687 HandleURLRequestInternal("GET", false, NULL, 0, NULL, false, false,
694 plugin_url_.spec().c_str(), NULL, false, 688 plugin_url_.spec().c_str(), NULL, false,
695 false); 689 false);
696 } 690 }
697 } 691 }
698 } 692 }
699 693
700 void WebPluginImpl::paint(WebCore::GraphicsContext* gc, 694 void WebPluginImpl::paint(WebCore::GraphicsContext* gc,
701 const WebCore::IntRect& damage_rect) { 695 const WebCore::IntRect& damage_rect) {
702 if (gc->paintingDisabled()) 696 if (gc->paintingDisabled())
703 return; 697 return;
704 698
705 if (!parent()) 699 if (!parent())
706 return; 700 return;
707 701
708 // Don't paint anything if the plugin doesn't intersect the damage rect. 702 // Don't paint anything if the plugin doesn't intersect the damage rect.
709 if (!widget_->frameRect().intersects(damage_rect)) 703 if (!widget_->frameRect().intersects(damage_rect))
710 return; 704 return;
711 705
712 // A windowed plugin starts out by being invisible regardless of the style
713 // which webkit tells us. The paint notification from webkit indicates that
714 // the plugin widget is being shown and we need to make sure that
715 // it becomes visible.
716 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=18901 for more
717 // details on this issue.
718 // TODO(iyengar): Remove this hack when this issue is fixed in webkit.
719 if (!received_first_paint_notification_) {
720 received_first_paint_notification_ = true;
721
722 if (!windowless_) {
723 WebCore::IntRect window_rect;
724 WebCore::IntRect clip_rect;
725 std::vector<gfx::Rect> cutout_rects;
726
727 CalculateBounds(widget_->frameRect(), &window_rect, &clip_rect,
728 &cutout_rects);
729
730 delegate_->UpdateGeometry(webkit_glue::FromIntRect(window_rect),
731 webkit_glue::FromIntRect(clip_rect),
732 cutout_rects, visible_);
733 delegate_->FlushGeometryUpdates();
734 }
735 }
736
737 gc->save(); 706 gc->save();
738 707
739 DCHECK(parent()->isFrameView()); 708 DCHECK(parent()->isFrameView());
740 WebCore::FrameView* view = static_cast<WebCore::FrameView*>(parent()); 709 WebCore::FrameView* view = static_cast<WebCore::FrameView*>(parent());
741 710
742 // The plugin is positioned in window coordinates, so it needs to be painted 711 // The plugin is positioned in window coordinates, so it needs to be painted
743 // in window coordinates. 712 // in window coordinates.
744 WebCore::IntPoint origin = view->windowToContents(WebCore::IntPoint(0, 0)); 713 WebCore::IntPoint origin = view->windowToContents(WebCore::IntPoint(0, 0));
745 gc->translate(static_cast<float>(origin.x()), 714 gc->translate(static_cast<float>(origin.x()),
746 static_cast<float>(origin.y())); 715 static_cast<float>(origin.y()));
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 client_index = clients_.erase(client_index); 1409 client_index = clients_.erase(client_index);
1441 if (resource_client) 1410 if (resource_client)
1442 resource_client->DidFail(); 1411 resource_client->DidFail();
1443 } 1412 }
1444 1413
1445 // This needs to be called now and not in the destructor since the 1414 // This needs to be called now and not in the destructor since the
1446 // webframe_ might not be valid anymore. 1415 // webframe_ might not be valid anymore.
1447 webframe_->set_plugin_delegate(NULL); 1416 webframe_->set_plugin_delegate(NULL);
1448 webframe_ = NULL; 1417 webframe_ = NULL;
1449 } 1418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698