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

Side by Side Diff: webkit/glue/plugins/webplugin_delegate_impl_mac.mm

Issue 572037: Merge 38216 - Make Carbon plugin idle event source robust against changes dur... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/307/src/
Patch Set: Created 10 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 6
7 #include "webkit/glue/plugins/webplugin_delegate_impl.h" 7 #include "webkit/glue/plugins/webplugin_delegate_impl.h"
8 8
9 #include <string> 9 #include <string>
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 class CarbonIdleEventSource { 84 class CarbonIdleEventSource {
85 public: 85 public:
86 // Returns the shared Carbon idle event source. 86 // Returns the shared Carbon idle event source.
87 static CarbonIdleEventSource* SharedInstance() { 87 static CarbonIdleEventSource* SharedInstance() {
88 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); 88 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
89 static CarbonIdleEventSource* event_source = new CarbonIdleEventSource(); 89 static CarbonIdleEventSource* event_source = new CarbonIdleEventSource();
90 return event_source; 90 return event_source;
91 } 91 }
92 92
93 // Registers the plugin delegate as interested in receiving idle events 93 // Registers the plugin delegate as interested in receiving idle events at
94 // suitable for a visible plugin. 94 // a rate appropriate for the given visibility. A delegate can safely be
95 // Registering a delegate as visible automatically unregisters it from the 95 // re-registered any number of times, with the latest registration winning.
96 // hidden event source. 96 void RegisterDelegate(WebPluginDelegateImpl* delegate, bool visible) {
97 void RegisterVisibleDelegate(WebPluginDelegateImpl* delegate) { 97 if (visible) {
98 UnregisterDelegate(delegate); 98 visible_delegates_->RegisterDelegate(delegate);
99 if (visible_delegates_.empty()) { 99 hidden_delegates_->UnregisterDelegate(delegate);
100 visible_timer_.Start( 100 } else {
101 base::TimeDelta::FromMilliseconds(kVisibleIdlePeriodMs), this, 101 hidden_delegates_->RegisterDelegate(delegate);
102 &CarbonIdleEventSource::SendVisiblePluginEvents); 102 visible_delegates_->UnregisterDelegate(delegate);
103 } 103 }
104 visible_delegates_.insert(delegate);
105 }
106
107 // Registers the plugin delegate as interested in receiving idle events
108 // suitable for a plugin that isn't visible.
109 // Registering a delegate as hidden automatically unregisters it from the
110 // visible event source.
111 void RegisterHiddenDelegate(WebPluginDelegateImpl* delegate) {
112 UnregisterDelegate(delegate);
113 if (hidden_delegates_.empty()) {
114 hidden_timer_.Start(
115 base::TimeDelta::FromMilliseconds(kHiddenIdlePeriodMs), this,
116 &CarbonIdleEventSource::SendHiddenPluginEvents);
117 }
118 hidden_delegates_.insert(delegate);
119 } 104 }
120 105
121 // Removes the plugin delegate from the list of plugins receiving idle events. 106 // Removes the plugin delegate from the list of plugins receiving idle events.
122 void UnregisterDelegate(WebPluginDelegateImpl* delegate) { 107 void UnregisterDelegate(WebPluginDelegateImpl* delegate) {
123 size_t removed = visible_delegates_.erase(delegate); 108 visible_delegates_->UnregisterDelegate(delegate);
124 if (removed > 0 && visible_delegates_.empty()) 109 hidden_delegates_->UnregisterDelegate(delegate);
125 visible_timer_.Stop();
126 removed = hidden_delegates_.erase(delegate);
127 if (removed > 0 && hidden_delegates_.empty())
128 hidden_timer_.Stop();
129 } 110 }
130 111
131 private: 112 private:
132 CarbonIdleEventSource() {} 113 class VisibilityGroup {
114 public:
115 explicit VisibilityGroup(int timer_period)
116 : timer_period_(timer_period), iterator_(delegates_.end()) {}
133 117
134 void SendVisiblePluginEvents() { 118 // Adds |delegate| to this visibility group.
135 SendIdleEventsToDelegates(visible_delegates_); 119 void RegisterDelegate(WebPluginDelegateImpl* delegate) {
136 } 120 if (delegates_.empty()) {
121 timer_.Start(base::TimeDelta::FromMilliseconds(timer_period_),
122 this, &VisibilityGroup::SendIdleEvents);
123 }
124 delegates_.insert(delegate);
125 }
137 126
138 void SendHiddenPluginEvents() { 127 // Removes |delegate| from this visibility group.
139 SendIdleEventsToDelegates(hidden_delegates_); 128 void UnregisterDelegate(WebPluginDelegateImpl* delegate) {
140 } 129 // If a plugin changes visibility during idle event handling, it
130 // may be removed from this set while SendIdleEvents is still iterating;
131 // if that happens and it's next on the list, increment the iterator
132 // before erasing so that the iteration won't be corrupted.
133 if ((iterator_ != delegates_.end()) && (*iterator_ == delegate))
134 ++iterator_;
135 size_t removed = delegates_.erase(delegate);
136 if (removed > 0 && delegates_.empty())
137 timer_.Stop();
138 }
141 139
142 void SendIdleEventsToDelegates( 140 private:
143 const std::set<WebPluginDelegateImpl*>& delegates) const { 141 // Fires off idle events for each delegate in the group.
144 for (std::set<WebPluginDelegateImpl*>::iterator i = delegates.begin(); 142 void SendIdleEvents() {
145 i != delegates.end();) { 143 for (iterator_ = delegates_.begin(); iterator_ != delegates_.end();) {
146 // If the plugin changes size or position during idle event handling, it 144 // Pre-increment so that the skip logic in UnregisterDelegates works.
147 // may be removed from this set; increment the iterator before calling 145 WebPluginDelegateImpl* delegate = *(iterator_++);
148 // into the delegate to ensure that the iteration won't be corrupted. 146 delegate->FireIdleEvent();
149 WebPluginDelegateImpl* delegate = *(i++); 147 }
150 delegate->FireIdleEvent();
151 } 148 }
152 }
153 149
154 base::RepeatingTimer<CarbonIdleEventSource> visible_timer_; 150 int timer_period_;
155 base::RepeatingTimer<CarbonIdleEventSource> hidden_timer_; 151 base::RepeatingTimer<VisibilityGroup> timer_;
156 std::set<WebPluginDelegateImpl*> visible_delegates_; 152 std::set<WebPluginDelegateImpl*> delegates_;
157 std::set<WebPluginDelegateImpl*> hidden_delegates_; 153 std::set<WebPluginDelegateImpl*>::iterator iterator_;
154 };
155
156 CarbonIdleEventSource()
157 : visible_delegates_(new VisibilityGroup(kVisibleIdlePeriodMs)),
158 hidden_delegates_(new VisibilityGroup(kHiddenIdlePeriodMs)) {}
159
160 scoped_ptr<VisibilityGroup> visible_delegates_;
161 scoped_ptr<VisibilityGroup> hidden_delegates_;
162
163 DISALLOW_COPY_AND_ASSIGN(CarbonIdleEventSource);
158 }; 164 };
159 #endif // !NP_NO_CARBON 165 #endif // !NP_NO_CARBON
160 166
161 } // namespace 167 } // namespace
162 168
163 WebPluginDelegateImpl::WebPluginDelegateImpl( 169 WebPluginDelegateImpl::WebPluginDelegateImpl(
164 gfx::PluginWindowHandle containing_view, 170 gfx::PluginWindowHandle containing_view,
165 NPAPI::PluginInstance *instance) 171 NPAPI::PluginInstance *instance)
166 : windowless_needs_set_window_(true), 172 : windowless_needs_set_window_(true),
167 // all Mac plugins are "windowless" in the Windows/X11 sense 173 // all Mac plugins are "windowless" in the Windows/X11 sense
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 int width = new_width ? new_width : old_width; 570 int width = new_width ? new_width : old_width;
565 window_bounds.left = target_x; 571 window_bounds.left = target_x;
566 window_bounds.top = target_y; 572 window_bounds.top = target_y;
567 window_bounds.right = window_bounds.left + width; 573 window_bounds.right = window_bounds.left + width;
568 window_bounds.bottom = window_bounds.top + height; 574 window_bounds.bottom = window_bounds.top + height;
569 SetWindowBounds(window, kWindowContentRgn, &window_bounds); 575 SetWindowBounds(window, kWindowContentRgn, &window_bounds);
570 } 576 }
571 } 577 }
572 578
573 void WebPluginDelegateImpl::UpdateIdleEventRate() { 579 void WebPluginDelegateImpl::UpdateIdleEventRate() {
574 if (clip_rect_.IsEmpty()) 580 bool plugin_visible = !clip_rect_.IsEmpty();
575 CarbonIdleEventSource::SharedInstance()->RegisterHiddenDelegate(this); 581 CarbonIdleEventSource::SharedInstance()->RegisterDelegate(this,
576 else 582 plugin_visible);
577 CarbonIdleEventSource::SharedInstance()->RegisterVisibleDelegate(this);
578 } 583 }
579 #endif // !NP_NO_CARBON 584 #endif // !NP_NO_CARBON
580 585
581 static bool WebInputEventIsWebMouseEvent(const WebInputEvent& event) { 586 static bool WebInputEventIsWebMouseEvent(const WebInputEvent& event) {
582 switch (event.type) { 587 switch (event.type) {
583 case WebInputEvent::MouseMove: 588 case WebInputEvent::MouseMove:
584 case WebInputEvent::MouseLeave: 589 case WebInputEvent::MouseLeave:
585 case WebInputEvent::MouseEnter: 590 case WebInputEvent::MouseEnter:
586 case WebInputEvent::MouseDown: 591 case WebInputEvent::MouseDown:
587 case WebInputEvent::MouseUp: 592 case WebInputEvent::MouseUp:
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 #ifndef NP_NO_QUICKDRAW 998 #ifndef NP_NO_QUICKDRAW
994 // Quickdraw-based plugins can draw at any time, so tell the renderer to 999 // Quickdraw-based plugins can draw at any time, so tell the renderer to
995 // repaint. 1000 // repaint.
996 // TODO: only do this if the contents of the offscreen window has changed, 1001 // TODO: only do this if the contents of the offscreen window has changed,
997 // so as not to spam the renderer with an unchanging image. 1002 // so as not to spam the renderer with an unchanging image.
998 if (instance()->drawing_model() == NPDrawingModelQuickDraw) 1003 if (instance()->drawing_model() == NPDrawingModelQuickDraw)
999 instance()->webplugin()->Invalidate(); 1004 instance()->webplugin()->Invalidate();
1000 #endif 1005 #endif
1001 } 1006 }
1002 #endif // !NP_NO_CARBON 1007 #endif // !NP_NO_CARBON
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698