OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import <QuartzCore/QuartzCore.h> | 6 #import <QuartzCore/QuartzCore.h> |
7 | 7 |
8 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | 8 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 WebPluginDelegateImpl::WebPluginDelegateImpl( | 255 WebPluginDelegateImpl::WebPluginDelegateImpl( |
256 gfx::PluginWindowHandle containing_view, | 256 gfx::PluginWindowHandle containing_view, |
257 PluginInstance *instance) | 257 PluginInstance *instance) |
258 : windowed_handle_(NULL), | 258 : windowed_handle_(NULL), |
259 // all Mac plugins are "windowless" in the Windows/X11 sense | 259 // all Mac plugins are "windowless" in the Windows/X11 sense |
260 windowless_(true), | 260 windowless_(true), |
261 plugin_(NULL), | 261 plugin_(NULL), |
262 instance_(instance), | 262 instance_(instance), |
263 parent_(containing_view), | 263 parent_(containing_view), |
264 quirks_(0), | 264 quirks_(0), |
| 265 use_buffer_context_(true), |
265 buffer_context_(NULL), | 266 buffer_context_(NULL), |
266 layer_(nil), | 267 layer_(nil), |
267 surface_(NULL), | 268 surface_(NULL), |
268 renderer_(nil), | 269 renderer_(nil), |
269 containing_window_has_focus_(false), | 270 containing_window_has_focus_(false), |
270 initial_window_focus_(false), | 271 initial_window_focus_(false), |
271 container_is_visible_(false), | 272 container_is_visible_(false), |
272 have_called_set_window_(false), | 273 have_called_set_window_(false), |
273 ime_enabled_(false), | 274 ime_enabled_(false), |
274 keyup_ignore_count_(0), | 275 keyup_ignore_count_(0), |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 #endif | 686 #endif |
686 | 687 |
687 if (window_size_changed || clip_rect_changed || force_set_window) | 688 if (window_size_changed || clip_rect_changed || force_set_window) |
688 WindowlessSetWindow(); | 689 WindowlessSetWindow(); |
689 } | 690 } |
690 | 691 |
691 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, | 692 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, |
692 const gfx::Rect& damage_rect) { | 693 const gfx::Rect& damage_rect) { |
693 // If we get a paint event before we are completely set up (e.g., a nested | 694 // If we get a paint event before we are completely set up (e.g., a nested |
694 // call while the plugin is still in NPP_SetWindow), bail. | 695 // call while the plugin is still in NPP_SetWindow), bail. |
695 if (!have_called_set_window_ || !buffer_context_) | 696 if (!have_called_set_window_ || (use_buffer_context_ && !buffer_context_)) |
696 return; | 697 return; |
697 DCHECK(buffer_context_ == context); | 698 DCHECK(!use_buffer_context_ || buffer_context_ == context); |
698 | 699 |
699 static base::StatsRate plugin_paint("Plugin.Paint"); | 700 static base::StatsRate plugin_paint("Plugin.Paint"); |
700 base::StatsScope<base::StatsRate> scope(plugin_paint); | 701 base::StatsScope<base::StatsRate> scope(plugin_paint); |
701 | 702 |
702 // Plugin invalidates trigger asynchronous paints with the original | 703 gfx::Rect paint_rect; |
703 // invalidation rect; the plugin may be resized before the paint is handled, | 704 if (use_buffer_context_) { |
704 // so we need to ensure that the damage rect is still sane. | 705 // Plugin invalidates trigger asynchronous paints with the original |
705 const gfx::Rect paint_rect(damage_rect.Intersect( | 706 // invalidation rect; the plugin may be resized before the paint is handled, |
706 gfx::Rect(0, 0, window_rect_.width(), window_rect_.height()))); | 707 // so we need to ensure that the damage rect is still sane. |
| 708 paint_rect = damage_rect.Intersect( |
| 709 gfx::Rect(0, 0, window_rect_.width(), window_rect_.height())); |
| 710 } else { |
| 711 // Use the actual window region when drawing directly to the window context. |
| 712 paint_rect = damage_rect.Intersect(window_rect_); |
| 713 } |
707 | 714 |
708 ScopedActiveDelegate active_delegate(this); | 715 ScopedActiveDelegate active_delegate(this); |
709 | 716 |
710 #ifndef NP_NO_QUICKDRAW | 717 #ifndef NP_NO_QUICKDRAW |
711 if (instance()->drawing_model() == NPDrawingModelQuickDraw) | 718 if (instance()->drawing_model() == NPDrawingModelQuickDraw) |
712 qd_manager_->MakePortCurrent(); | 719 qd_manager_->MakePortCurrent(); |
713 #endif | 720 #endif |
714 | 721 |
715 CGContextSaveGState(context); | 722 CGContextSaveGState(context); |
716 | 723 |
| 724 if (!use_buffer_context_) { |
| 725 // Reposition the context origin so that plugins will draw at the correct |
| 726 // location in the window. |
| 727 CGContextClipToRect(context, paint_rect.ToCGRect()); |
| 728 CGContextTranslateCTM(context, window_rect_.x(), window_rect_.y()); |
| 729 } |
| 730 |
717 switch (instance()->event_model()) { | 731 switch (instance()->event_model()) { |
718 #ifndef NP_NO_CARBON | 732 #ifndef NP_NO_CARBON |
719 case NPEventModelCarbon: { | 733 case NPEventModelCarbon: { |
720 NPEvent paint_event = { 0 }; | 734 NPEvent paint_event = { 0 }; |
721 paint_event.what = updateEvt; | 735 paint_event.what = updateEvt; |
722 paint_event.message = reinterpret_cast<uint32>(np_cg_context_.window); | 736 paint_event.message = reinterpret_cast<uint32>(np_cg_context_.window); |
723 paint_event.when = TickCount(); | 737 paint_event.when = TickCount(); |
724 instance()->NPP_HandleEvent(&paint_event); | 738 instance()->NPP_HandleEvent(&paint_event); |
725 break; | 739 break; |
726 } | 740 } |
727 #endif | 741 #endif |
728 case NPEventModelCocoa: { | 742 case NPEventModelCocoa: { |
729 NPCocoaEvent paint_event; | 743 NPCocoaEvent paint_event; |
730 memset(&paint_event, 0, sizeof(NPCocoaEvent)); | 744 memset(&paint_event, 0, sizeof(NPCocoaEvent)); |
731 paint_event.type = NPCocoaEventDrawRect; | 745 paint_event.type = NPCocoaEventDrawRect; |
732 paint_event.data.draw.context = context; | 746 paint_event.data.draw.context = context; |
733 paint_event.data.draw.x = paint_rect.x(); | 747 paint_event.data.draw.x = paint_rect.x(); |
734 paint_event.data.draw.y = paint_rect.y(); | 748 paint_event.data.draw.y = paint_rect.y(); |
735 paint_event.data.draw.width = paint_rect.width(); | 749 paint_event.data.draw.width = paint_rect.width(); |
736 paint_event.data.draw.height = paint_rect.height(); | 750 paint_event.data.draw.height = paint_rect.height(); |
737 instance()->NPP_HandleEvent(&paint_event); | 751 instance()->NPP_HandleEvent(&paint_event); |
738 break; | 752 break; |
739 } | 753 } |
740 } | 754 } |
741 | 755 |
742 // The backing buffer can change during the call to NPP_HandleEvent, in which | 756 if (use_buffer_context_) { |
743 // case the old context is (or is about to be) invalid. | 757 // The backing buffer can change during the call to NPP_HandleEvent, in |
744 if (context == buffer_context_) | 758 // which case the old context is (or is about to be) invalid. |
| 759 if (context == buffer_context_) |
| 760 CGContextRestoreGState(context); |
| 761 } else { |
| 762 // Always restore the context to the saved state. |
745 CGContextRestoreGState(context); | 763 CGContextRestoreGState(context); |
| 764 } |
746 } | 765 } |
747 | 766 |
748 void WebPluginDelegateImpl::WindowlessSetWindow() { | 767 void WebPluginDelegateImpl::WindowlessSetWindow() { |
749 if (!instance()) | 768 if (!instance()) |
750 return; | 769 return; |
751 | 770 |
752 window_.x = 0; | 771 window_.x = 0; |
753 window_.y = 0; | 772 window_.y = 0; |
754 window_.height = window_rect_.height(); | 773 window_.height = window_rect_.height(); |
755 window_.width = window_rect_.width(); | 774 window_.width = window_rect_.width(); |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 new_bounds.bottom != current_bounds.bottom) | 1127 new_bounds.bottom != current_bounds.bottom) |
1109 SetWindowBounds(window, kWindowContentRgn, &new_bounds); | 1128 SetWindowBounds(window, kWindowContentRgn, &new_bounds); |
1110 } | 1129 } |
1111 | 1130 |
1112 void WebPluginDelegateImpl::UpdateIdleEventRate() { | 1131 void WebPluginDelegateImpl::UpdateIdleEventRate() { |
1113 bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty(); | 1132 bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty(); |
1114 CarbonIdleEventSource::SharedInstance()->RegisterDelegate(this, | 1133 CarbonIdleEventSource::SharedInstance()->RegisterDelegate(this, |
1115 plugin_visible); | 1134 plugin_visible); |
1116 } | 1135 } |
1117 | 1136 |
| 1137 void WebPluginDelegateImpl::SetNoBufferContext() { |
| 1138 use_buffer_context_ = false; |
| 1139 } |
| 1140 |
1118 void WebPluginDelegateImpl::FireIdleEvent() { | 1141 void WebPluginDelegateImpl::FireIdleEvent() { |
1119 // Avoid a race condition between IO and UI threads during plugin shutdown | 1142 // Avoid a race condition between IO and UI threads during plugin shutdown |
1120 if (!instance()) | 1143 if (!instance()) |
1121 return; | 1144 return; |
1122 // Don't send idle events until we've called SetWindow. | 1145 // Don't send idle events until we've called SetWindow. |
1123 if (!have_called_set_window_) | 1146 if (!have_called_set_window_) |
1124 return; | 1147 return; |
1125 | 1148 |
1126 #ifndef NP_NO_QUICKDRAW | 1149 #ifndef NP_NO_QUICKDRAW |
1127 // Check whether it's time to turn the QuickDraw fast path back on. | 1150 // Check whether it's time to turn the QuickDraw fast path back on. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 qd_manager_->SetFastPathEnabled(enabled); | 1212 qd_manager_->SetFastPathEnabled(enabled); |
1190 qd_port_.port = qd_manager_->port(); | 1213 qd_port_.port = qd_manager_->port(); |
1191 WindowlessSetWindow(); | 1214 WindowlessSetWindow(); |
1192 // Send a paint event so that the new buffer gets updated immediately. | 1215 // Send a paint event so that the new buffer gets updated immediately. |
1193 WindowlessPaint(buffer_context_, clip_rect_); | 1216 WindowlessPaint(buffer_context_, clip_rect_); |
1194 } | 1217 } |
1195 #endif // !NP_NO_QUICKDRAW | 1218 #endif // !NP_NO_QUICKDRAW |
1196 | 1219 |
1197 } // namespace npapi | 1220 } // namespace npapi |
1198 } // namespace webkit | 1221 } // namespace webkit |
OLD | NEW |