OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <QuartzCore/QuartzCore.h> | 5 #include <QuartzCore/QuartzCore.h> |
6 | 6 |
7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
8 | 8 |
9 #include "app/surface/io_surface_support_mac.h" | 9 #include "app/surface/io_surface_support_mac.h" |
10 #import "base/chrome_application_mac.h" | 10 #import "base/chrome_application_mac.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/histogram.h" | 12 #include "base/histogram.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #import "base/scoped_nsautorelease_pool.h" | |
14 #import "base/scoped_nsobject.h" | 15 #import "base/scoped_nsobject.h" |
15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
16 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
17 #include "chrome/browser/browser_trial.h" | 18 #include "chrome/browser/browser_trial.h" |
18 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" | 19 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" |
19 #import "chrome/browser/cocoa/view_id_util.h" | 20 #import "chrome/browser/cocoa/view_id_util.h" |
20 #include "chrome/browser/plugin_process_host.h" | 21 #include "chrome/browser/plugin_process_host.h" |
21 #include "chrome/browser/renderer_host/backing_store_mac.h" | 22 #include "chrome/browser/renderer_host/backing_store_mac.h" |
22 #include "chrome/browser/renderer_host/render_process_host.h" | 23 #include "chrome/browser/renderer_host/render_process_host.h" |
23 #include "chrome/browser/renderer_host/render_view_host.h" | 24 #include "chrome/browser/renderer_host/render_view_host.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 sizeof(CFArrayRef), &inputSources); | 121 sizeof(CFArrayRef), &inputSources); |
121 CFRelease(inputSources); | 122 CFRelease(inputSources); |
122 } | 123 } |
123 | 124 |
124 void DisablePasswordInput() { | 125 void DisablePasswordInput() { |
125 TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); | 126 TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); |
126 } | 127 } |
127 | 128 |
128 } // namespace | 129 } // namespace |
129 | 130 |
130 // AcceleratedPluginLayer ------------------------------------------------------ | 131 // AcceleratedPluginView ------------------------------------------------------ |
131 | 132 |
132 // This subclass of CAOpenGLLayer hosts the output of accelerated plugins on | 133 // This subclass of NSView hosts the output of accelerated plugins on |
133 // the page. | 134 // the page. |
134 | 135 |
135 @interface AcceleratedPluginLayer : CAOpenGLLayer { | 136 @interface AcceleratedPluginView : NSView { |
137 scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_; | |
138 CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|. | |
139 scoped_nsobject<NSOpenGLContext> glContext_; | |
140 CGLContextObj cglContext_; // weak, backed by |glContext_|. | |
141 | |
142 CVDisplayLinkRef displayLink_; // Owned by us. | |
143 | |
136 RenderWidgetHostViewMac* renderWidgetHostView_; // weak | 144 RenderWidgetHostViewMac* renderWidgetHostView_; // weak |
145 gfx::PluginWindowHandle pluginHandle_; // weak | |
146 | |
147 // True if the backing IO surface was updated since we last painted. | |
148 BOOL surfaceWasSwapped_; | |
137 } | 149 } |
138 | 150 |
139 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 151 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r |
152 pluginHandle:(gfx::PluginWindowHandle)pluginHandle; | |
153 - (void)drawView; | |
154 | |
155 // This _must_ be atomic, since it's accessed from several threads. | |
156 @property BOOL surfaceWasSwapped; | |
140 @end | 157 @end |
141 | 158 |
142 @implementation AcceleratedPluginLayer | 159 @implementation AcceleratedPluginView : NSView |
143 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 160 @synthesize surfaceWasSwapped = surfaceWasSwapped_; |
144 self = [super init]; | 161 |
145 if (self != nil) { | 162 - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime { |
163 // There is no autorelease pool when this method is called because it will be | |
164 // called from a background thread. | |
165 base::ScopedNSAutoreleasePool pool; | |
166 | |
167 if (![self surfaceWasSwapped]) | |
168 return kCVReturnSuccess; | |
169 | |
170 [self drawView]; | |
171 [self setSurfaceWasSwapped:NO]; | |
172 return kCVReturnSuccess; | |
173 } | |
174 | |
175 // This is the renderer output callback function | |
176 static CVReturn MyDisplayLinkCallback( | |
stuartmorgan
2010/08/11 16:40:44
Can we give this a better name please?
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will change to "DrawOneAcceleratedPluginCallback".
| |
177 CVDisplayLinkRef displayLink, | |
178 const CVTimeStamp* now, | |
179 const CVTimeStamp* outputTime, | |
180 CVOptionFlags flagsIn, | |
181 CVOptionFlags* flagsOut, | |
182 void* displayLinkContext) { | |
183 CVReturn result = | |
184 [(AcceleratedPluginView*)displayLinkContext getFrameForTime:outputTime]; | |
185 return result; | |
186 } | |
187 | |
188 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r | |
189 pluginHandle:(gfx::PluginWindowHandle)pluginHandle { | |
190 if ((self = [super initWithFrame:NSZeroRect])) { | |
146 renderWidgetHostView_ = r; | 191 renderWidgetHostView_ = r; |
192 pluginHandle_ = pluginHandle; | |
193 | |
194 [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; | |
195 | |
196 NSOpenGLPixelFormatAttribute attributes[] = | |
197 { NSOpenGLPFAAccelerated, NSOpenGLPFADoubleBuffer, 0}; | |
198 | |
199 glPixelFormat_.reset([[NSOpenGLPixelFormat alloc] | |
200 initWithAttributes:attributes]); | |
201 glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_ | |
202 shareContext:nil]); | |
203 | |
204 cglContext_ = (CGLContextObj)[glContext_ CGLContextObj]; | |
205 cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; | |
206 | |
207 // Draw at beam vsync. | |
208 GLint swapInterval = 1; | |
209 [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; | |
210 | |
211 | |
212 // Set up a display link to do OpenGL rendering on a background thread. | |
213 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); | |
214 CVDisplayLinkSetOutputCallback(displayLink_, &MyDisplayLinkCallback, self); | |
215 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( | |
216 displayLink_, cglContext_, cglPixelFormat_); | |
217 CVDisplayLinkStart(displayLink_); | |
147 } | 218 } |
148 return self; | 219 return self; |
149 } | 220 } |
150 | 221 |
151 - (void)drawInCGLContext:(CGLContextObj)glContext | 222 - (void)drawView { |
152 pixelFormat:(CGLPixelFormatObj)pixelFormat | 223 // Called on a background thread. Synchronized via the CGL context lock. |
153 forLayerTime:(CFTimeInterval)timeInterval | 224 CGLLockContext(cglContext_); |
154 displayTime:(const CVTimeStamp *)timeStamp { | 225 |
155 renderWidgetHostView_->DrawAcceleratedSurfaceInstances(glContext); | 226 renderWidgetHostView_->DrawAcceleratedSurfaceInstance( |
156 [super drawInCGLContext:glContext | 227 cglContext_, pluginHandle_); |
157 pixelFormat:pixelFormat | 228 |
158 forLayerTime:timeInterval | 229 CGLFlushDrawable(cglContext_); |
159 displayTime:timeStamp]; | 230 CGLUnlockContext(cglContext_); |
160 } | 231 } |
161 | 232 |
162 - (void)setFrame:(CGRect)rect { | 233 - (void)drawRect:(NSRect)rect { |
163 // The frame we get when the superlayer resizes doesn't make sense, so ignore | 234 [self drawView]; |
164 // it and just match the superlayer's size. See the email thread referenced in | 235 } |
165 // ensureAcceleratedPluginLayer for an explanation of why the superlayer | 236 |
166 // isn't trustworthy. | 237 - (void)globalFrameDidChange:(NSNotification*)notification { |
167 [CATransaction begin]; | 238 CGLLockContext(cglContext_); |
168 [CATransaction setValue:[NSNumber numberWithInt:0] | 239 [glContext_ update]; |
169 forKey:kCATransactionAnimationDuration]; | 240 |
170 if ([self superlayer]) | 241 // You would think that -update updates the viewport. You would be wrong. |
171 [super setFrame:[[self superlayer] bounds]]; | 242 CGLSetCurrentContext(cglContext_); |
172 else | 243 NSSize size = [self frame].size; |
173 [super setFrame:rect]; | 244 glViewport(0, 0, size.width, size.height); |
174 [CATransaction commit]; | 245 |
246 CGLUnlockContext(cglContext_); | |
247 } | |
248 | |
249 - (void)renewGState { | |
250 // Synchronize with window server to avoid flashes or corrupt drawing. | |
251 [[self window] disableScreenUpdatesUntilFlush]; | |
252 [self globalFrameDidChange:nil]; | |
253 [super renewGState]; | |
254 } | |
255 | |
256 - (void)lockFocus { | |
257 [super lockFocus]; | |
258 | |
259 // If we're using OpenGL, make sure it is connected and that the display link | |
260 // is running. | |
261 if ([glContext_ view] != self) { | |
262 [glContext_ setView:self]; | |
263 | |
264 [[NSNotificationCenter defaultCenter] | |
265 addObserver:self | |
266 selector:@selector(globalFrameDidChange:) | |
267 name:NSViewGlobalFrameDidChangeNotification | |
268 object:self]; | |
269 } | |
270 [glContext_ makeCurrentContext]; | |
271 } | |
272 | |
273 - (void)dealloc { | |
274 CVDisplayLinkRelease(displayLink_); | |
275 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
276 [super dealloc]; | |
175 } | 277 } |
176 @end | 278 @end |
177 | 279 |
178 // RenderWidgetHostView -------------------------------------------------------- | 280 // RenderWidgetHostView -------------------------------------------------------- |
179 | 281 |
180 // static | 282 // static |
181 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 283 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
182 RenderWidgetHost* widget) { | 284 RenderWidgetHost* widget) { |
183 return new RenderWidgetHostViewMac(widget); | 285 return new RenderWidgetHostViewMac(widget); |
184 } | 286 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 // Handle movement of accelerated plugins, which are the only "windowed" | 411 // Handle movement of accelerated plugins, which are the only "windowed" |
310 // plugins that exist on the Mac. | 412 // plugins that exist on the Mac. |
311 if (moves.size() > 0) { | 413 if (moves.size() > 0) { |
312 for (std::vector<webkit_glue::WebPluginGeometry>::const_iterator iter = | 414 for (std::vector<webkit_glue::WebPluginGeometry>::const_iterator iter = |
313 moves.begin(); | 415 moves.begin(); |
314 iter != moves.end(); | 416 iter != moves.end(); |
315 ++iter) { | 417 ++iter) { |
316 webkit_glue::WebPluginGeometry geom = *iter; | 418 webkit_glue::WebPluginGeometry geom = *iter; |
317 // Ignore bogus moves which claim to move the plugin to (0, 0) | 419 // Ignore bogus moves which claim to move the plugin to (0, 0) |
318 // with width and height (0, 0) | 420 // with width and height (0, 0) |
319 if (geom.window_rect.x() != 0 || | 421 if (geom.window_rect.x() == 0 && |
320 geom.window_rect.y() != 0 || | 422 geom.window_rect.y() == 0 && |
321 geom.window_rect.width() != 0 || | 423 geom.window_rect.IsEmpty()) { |
322 geom.window_rect.height() != 0) { | 424 continue; |
323 plugin_container_manager_.MovePluginContainer(geom); | |
324 } | 425 } |
426 | |
427 gfx::Rect rect = geom.window_rect; | |
428 if (geom.visible) { | |
429 rect.set_x(rect.x() + geom.clip_rect.x()); | |
430 rect.set_y(rect.y() + geom.clip_rect.y()); | |
431 rect.set_width(geom.clip_rect.width()); | |
432 rect.set_height(geom.clip_rect.height()); | |
433 } | |
434 | |
435 PluginViewMap::iterator it = plugin_views_.find(geom.window); | |
436 CHECK(plugin_views_.end() != it); | |
stuartmorgan
2010/08/11 16:40:44
CHECK? Really? Crashing end-users doesn't seem lik
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will change these to DCHECKs and add if tests for
| |
437 NSRect new_rect([cocoa_view_ RectToNSRect:rect]); | |
438 [it->second setFrame:new_rect]; | |
439 [it->second setNeedsDisplay:YES]; | |
440 | |
441 plugin_container_manager_.MovePluginContainer(geom); | |
325 } | 442 } |
326 } | 443 } |
327 } | 444 } |
328 | 445 |
329 void RenderWidgetHostViewMac::Focus() { | 446 void RenderWidgetHostViewMac::Focus() { |
330 [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; | 447 [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; |
331 } | 448 } |
332 | 449 |
333 void RenderWidgetHostViewMac::Blur() { | 450 void RenderWidgetHostViewMac::Blur() { |
334 [[cocoa_view_ window] makeFirstResponder:nil]; | 451 [[cocoa_view_ window] makeFirstResponder:nil]; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 // an event comes in that would "cancel" it, it receives the OnCancelMode | 580 // an event comes in that would "cancel" it, it receives the OnCancelMode |
464 // message and can kill itself. Alas, on the Mac, views cannot capture events | 581 // message and can kill itself. Alas, on the Mac, views cannot capture events |
465 // outside of themselves. On Windows, if Destroy is being called on a view, | 582 // outside of themselves. On Windows, if Destroy is being called on a view, |
466 // then the event causing the destroy had also cancelled any popups by the | 583 // then the event causing the destroy had also cancelled any popups by the |
467 // time Destroy() was called. On the Mac we have to destroy all the popups | 584 // time Destroy() was called. On the Mac we have to destroy all the popups |
468 // ourselves. | 585 // ourselves. |
469 | 586 |
470 if (!is_popup_menu_) { | 587 if (!is_popup_menu_) { |
471 // Depth-first destroy all popups. Use ShutdownHost() to enforce | 588 // Depth-first destroy all popups. Use ShutdownHost() to enforce |
472 // deepest-first ordering. | 589 // deepest-first ordering. |
473 for (RenderWidgetHostViewCocoa* subview in [cocoa_view_ subviews]) { | 590 for (NSView* subview in [cocoa_view_ subviews]) { |
474 [subview renderWidgetHostViewMac]->ShutdownHost(); | 591 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) |
592 continue; // Skip plugin views. | |
stuartmorgan
2010/08/11 16:40:44
s/plugin/accelerated/
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will fix.
| |
593 | |
594 [static_cast<RenderWidgetHostViewCocoa*>(subview) | |
595 renderWidgetHostViewMac]->ShutdownHost(); | |
475 } | 596 } |
476 | 597 |
477 // We've been told to destroy. | 598 // We've been told to destroy. |
478 [cocoa_view_ retain]; | 599 [cocoa_view_ retain]; |
479 [cocoa_view_ removeFromSuperview]; | 600 [cocoa_view_ removeFromSuperview]; |
480 [cocoa_view_ autorelease]; | 601 [cocoa_view_ autorelease]; |
481 } else { | 602 } else { |
482 // From the renderer's perspective, the pop-up menu is represented by a | 603 // From the renderer's perspective, the pop-up menu is represented by a |
483 // RenderWidget. The actual Mac implementation uses a native pop-up menu | 604 // RenderWidget. The actual Mac implementation uses a native pop-up menu |
484 // and doesn't actually make use of the RenderWidgetHostViewCocoa that | 605 // and doesn't actually make use of the RenderWidgetHostViewCocoa that |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
608 [cocoa_view_ setHidden:YES]; | 729 [cocoa_view_ setHidden:YES]; |
609 MessageLoop::current()->PostTask(FROM_HERE, | 730 MessageLoop::current()->PostTask(FROM_HERE, |
610 shutdown_factory_.NewRunnableMethod( | 731 shutdown_factory_.NewRunnableMethod( |
611 &RenderWidgetHostViewMac::ShutdownHost)); | 732 &RenderWidgetHostViewMac::ShutdownHost)); |
612 } | 733 } |
613 } | 734 } |
614 | 735 |
615 gfx::PluginWindowHandle | 736 gfx::PluginWindowHandle |
616 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, | 737 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, |
617 bool root) { | 738 bool root) { |
618 // Make sure we have a layer for the plugin to draw into. | 739 // Create an NSView to host the plugin's/compositor's pixels. |
619 [cocoa_view_ ensureAcceleratedPluginLayer]; | 740 gfx::PluginWindowHandle handle = |
741 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | |
620 | 742 |
621 return plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | 743 scoped_nsobject<NSView> plugin_view( |
744 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this | |
745 pluginHandle:handle]); | |
746 [plugin_view setHidden:YES]; | |
747 | |
748 [cocoa_view_ addSubview:plugin_view]; | |
749 plugin_views_[handle] = plugin_view; | |
750 | |
751 return handle; | |
622 } | 752 } |
623 | 753 |
624 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( | 754 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( |
625 gfx::PluginWindowHandle window) { | 755 gfx::PluginWindowHandle window) { |
756 PluginViewMap::iterator it = plugin_views_.find(window); | |
757 CHECK(plugin_views_.end() != it); | |
758 [it->second removeFromSuperview]; | |
759 plugin_views_.erase(it); | |
760 | |
626 plugin_container_manager_.DestroyFakePluginWindowHandle(window); | 761 plugin_container_manager_.DestroyFakePluginWindowHandle(window); |
627 } | 762 } |
628 | 763 |
629 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( | 764 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( |
630 gfx::PluginWindowHandle window, | 765 gfx::PluginWindowHandle window, |
631 int32 width, | 766 int32 width, |
632 int32 height, | 767 int32 height, |
633 uint64 io_surface_identifier) { | 768 uint64 io_surface_identifier) { |
769 PluginViewMap::iterator it = plugin_views_.find(window); | |
770 CHECK(plugin_views_.end() != it); | |
771 | |
634 plugin_container_manager_.SetSizeAndIOSurface(window, | 772 plugin_container_manager_.SetSizeAndIOSurface(window, |
635 width, | 773 width, |
636 height, | 774 height, |
637 io_surface_identifier); | 775 io_surface_identifier); |
776 | |
777 if (plugin_container_manager_.IsRootContainer(window)) { | |
778 // Fake up a WebPluginGeometry for the root window to set the | |
779 // container's size; we will never get a notification from the | |
780 // browser about the root window, only plugins. | |
781 webkit_glue::WebPluginGeometry geom; | |
782 gfx::Rect rect(0, 0, width, height); | |
783 geom.window = window; | |
784 geom.window_rect = rect; | |
785 geom.clip_rect = rect; | |
786 geom.visible = true; | |
787 MovePluginWindows(std::vector<webkit_glue::WebPluginGeometry>(1, geom)); | |
788 } | |
638 } | 789 } |
639 | 790 |
640 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( | 791 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( |
641 gfx::PluginWindowHandle window, | 792 gfx::PluginWindowHandle window, |
642 int32 width, | 793 int32 width, |
643 int32 height, | 794 int32 height, |
644 TransportDIB::Handle transport_dib) { | 795 TransportDIB::Handle transport_dib) { |
796 PluginViewMap::iterator it = plugin_views_.find(window); | |
797 CHECK(plugin_views_.end() != it); | |
stuartmorgan
2010/08/11 16:40:44
Again, why CHECK?
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will change.
| |
798 | |
645 plugin_container_manager_.SetSizeAndTransportDIB(window, | 799 plugin_container_manager_.SetSizeAndTransportDIB(window, |
646 width, | 800 width, |
647 height, | 801 height, |
648 transport_dib); | 802 transport_dib); |
649 } | 803 } |
650 | 804 |
651 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 805 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
652 gfx::PluginWindowHandle window) { | 806 gfx::PluginWindowHandle window) { |
653 [cocoa_view_ drawAcceleratedPluginLayer]; | 807 PluginViewMap::iterator it = plugin_views_.find(window); |
654 if (GetRenderWidgetHost()->is_gpu_rendering_active()) { | 808 CHECK(plugin_views_.end() != it); |
stuartmorgan
2010/08/11 16:40:44
And here, and below, and in DrawAcceleratedSurface
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will change.
| |
655 // Additionally dirty the entire region of the view to make AppKit | 809 CHECK([it->second isKindOfClass:[AcceleratedPluginView class]]); |
656 // and Core Animation think that our CALayer needs to repaint | 810 |
657 // itself. | 811 AcceleratedPluginView* view = static_cast<AcceleratedPluginView*>(it->second); |
658 [cocoa_view_ setNeedsDisplayInRect:[cocoa_view_ frame]]; | 812 [view setHidden:NO]; |
659 } | 813 [view setSurfaceWasSwapped:YES]; |
660 } | 814 } |
661 | 815 |
662 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstances( | 816 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
663 CGLContextObj context) { | 817 CGLContextObj context, gfx::PluginWindowHandle plugin_handle) { |
818 // Called on the display link thread. | |
819 PluginViewMap::iterator it = plugin_views_.find(plugin_handle); | |
820 CHECK(plugin_views_.end() != it); | |
821 | |
664 CGLSetCurrentContext(context); | 822 CGLSetCurrentContext(context); |
665 gfx::Rect rect = GetWindowRect(); | 823 // TODO(thakis): Pixel or view coordinates? |
824 NSSize size = [it->second frame].size; | |
825 | |
666 glMatrixMode(GL_PROJECTION); | 826 glMatrixMode(GL_PROJECTION); |
667 glLoadIdentity(); | 827 glLoadIdentity(); |
668 // Note that we place the origin at the upper left corner with +y | 828 // Note that we place the origin at the upper left corner with +y |
669 // going down | 829 // going down |
670 glOrtho(0, rect.width(), rect.height(), 0, -1, 1); | 830 glOrtho(0, size.width, size.height, 0, -1, 1); |
671 glMatrixMode(GL_MODELVIEW); | 831 glMatrixMode(GL_MODELVIEW); |
672 glLoadIdentity(); | 832 glLoadIdentity(); |
673 | 833 |
674 plugin_container_manager_.Draw( | 834 plugin_container_manager_.Draw( |
675 context, GetRenderWidgetHost()->is_gpu_rendering_active()); | 835 context, plugin_handle, GetRenderWidgetHost()->is_gpu_rendering_active()); |
676 } | 836 } |
677 | 837 |
678 void RenderWidgetHostViewMac::AcceleratedSurfaceContextChanged() { | 838 void RenderWidgetHostViewMac::ForceTextureReload() { |
679 plugin_container_manager_.ForceTextureReload(); | 839 plugin_container_manager_.ForceTextureReload(); |
680 } | 840 } |
681 | 841 |
682 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(bool deemphasized) { | 842 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(bool deemphasized) { |
683 // Mac uses tab-modal sheets, so this is a no-op. | 843 // Mac uses tab-modal sheets, so this is a no-op. |
684 } | 844 } |
685 | 845 |
686 void RenderWidgetHostViewMac::ShutdownHost() { | 846 void RenderWidgetHostViewMac::ShutdownHost() { |
687 shutdown_factory_.RevokeAll(); | 847 shutdown_factory_.RevokeAll(); |
688 render_widget_host_->Shutdown(); | 848 render_widget_host_->Shutdown(); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 // (However, there are still some keys that Cocoa swallows, e.g. the key | 1078 // (However, there are still some keys that Cocoa swallows, e.g. the key |
919 // equivalent that Cocoa uses for toggling the input langauge. In this case, | 1079 // equivalent that Cocoa uses for toggling the input langauge. In this case, |
920 // that's actually a good thing, though -- see http://crbug.com/26115 .) | 1080 // that's actually a good thing, though -- see http://crbug.com/26115 .) |
921 return YES; | 1081 return YES; |
922 } | 1082 } |
923 | 1083 |
924 - (void)keyEvent:(NSEvent*)theEvent { | 1084 - (void)keyEvent:(NSEvent*)theEvent { |
925 [self keyEvent:theEvent wasKeyEquivalent:NO]; | 1085 [self keyEvent:theEvent wasKeyEquivalent:NO]; |
926 } | 1086 } |
927 | 1087 |
928 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv { | 1088 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv { |
929 DCHECK([theEvent type] != NSKeyDown || | 1089 DCHECK([theEvent type] != NSKeyDown || |
930 !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); | 1090 !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); |
931 | 1091 |
932 if ([theEvent type] == NSFlagsChanged) { | 1092 if ([theEvent type] == NSFlagsChanged) { |
933 // Ignore NSFlagsChanged events from the NumLock and Fn keys as | 1093 // Ignore NSFlagsChanged events from the NumLock and Fn keys as |
934 // Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm"). | 1094 // Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm"). |
935 int keyCode = [theEvent keyCode]; | 1095 int keyCode = [theEvent keyCode]; |
936 if (!keyCode || keyCode == 10 || keyCode == 63) | 1096 if (!keyCode || keyCode == 10 || keyCode == 63) |
937 return; | 1097 return; |
938 } | 1098 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1120 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); | 1280 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); |
1121 } | 1281 } |
1122 | 1282 |
1123 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation | 1283 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation |
1124 // events. On the Mac we must kill popups on outside events, thus this lovely | 1284 // events. On the Mac we must kill popups on outside events, thus this lovely |
1125 // case of filicide caused by events on parent views. | 1285 // case of filicide caused by events on parent views. |
1126 - (void)cancelChildPopups { | 1286 - (void)cancelChildPopups { |
1127 // If this view can be the key view, it is not a popup. Therefore, if it has | 1287 // If this view can be the key view, it is not a popup. Therefore, if it has |
1128 // any children, they are popups that need to be canceled. | 1288 // any children, they are popups that need to be canceled. |
1129 if (canBeKeyView_) { | 1289 if (canBeKeyView_) { |
1130 for (RenderWidgetHostViewCocoa* subview in [self subviews]) { | 1290 for (NSView* subview in [self subviews]) { |
1131 subview->renderWidgetHostView_->KillSelf(); | 1291 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) |
1292 continue; // Skip plugin views. | |
1293 | |
1294 [static_cast<RenderWidgetHostViewCocoa*>(subview) | |
1295 renderWidgetHostViewMac]->KillSelf(); | |
1132 } | 1296 } |
1133 } | 1297 } |
1134 } | 1298 } |
1135 | 1299 |
1136 - (void)setFrameSize:(NSSize)newSize { | 1300 - (void)setFrameSize:(NSSize)newSize { |
1137 [super setFrameSize:newSize]; | 1301 [super setFrameSize:newSize]; |
1138 if (renderWidgetHostView_->render_widget_host_) | 1302 if (renderWidgetHostView_->render_widget_host_) |
1139 renderWidgetHostView_->render_widget_host_->WasResized(); | 1303 renderWidgetHostView_->render_widget_host_->WasResized(); |
1140 } | 1304 } |
1141 | 1305 |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1969 } | 2133 } |
1970 | 2134 |
1971 // Inserting text will delete all marked text automatically. | 2135 // Inserting text will delete all marked text automatically. |
1972 hasMarkedText_ = NO; | 2136 hasMarkedText_ = NO; |
1973 } | 2137 } |
1974 | 2138 |
1975 - (void)viewDidMoveToWindow { | 2139 - (void)viewDidMoveToWindow { |
1976 // If we move into a new window, refresh the frame information. We don't need | 2140 // If we move into a new window, refresh the frame information. We don't need |
1977 // to do it if it was the same window as it used to be in, since that case | 2141 // to do it if it was the same window as it used to be in, since that case |
1978 // is covered by DidBecomeSelected. | 2142 // is covered by DidBecomeSelected. |
1979 // We only want to do this for real browser views, not popups. | 2143 // We only want to do this for real browser views, not popups. |
stuartmorgan
2010/08/11 16:40:44
Move all this comment to just above the |if (newWi
Ken Russell (switch to Gerrit)
2010/08/14 02:12:11
Will do.
| |
1980 if (canBeKeyView_) { | 2144 if (canBeKeyView_) { |
1981 NSWindow* newWindow = [self window]; | 2145 NSWindow* newWindow = [self window]; |
1982 // Pointer comparison only, since we don't know if lastWindow_ is still | 2146 // Pointer comparison only, since we don't know if lastWindow_ is still |
1983 // valid. | 2147 // valid. |
1984 if (newWindow && (newWindow != lastWindow_)) { | 2148 if (newWindow) { |
1985 lastWindow_ = newWindow; | 2149 if (newWindow != lastWindow_) { |
1986 renderWidgetHostView_->WindowFrameChanged(); | 2150 lastWindow_ = newWindow; |
2151 renderWidgetHostView_->WindowFrameChanged(); | |
2152 } | |
2153 renderWidgetHostView_->ForceTextureReload(); | |
1987 } | 2154 } |
1988 } | 2155 } |
1989 | 2156 |
1990 // If we switch windows (or are removed from the view hierarchy), cancel any | 2157 // If we switch windows (or are removed from the view hierarchy), cancel any |
1991 // open mouse-downs. | 2158 // open mouse-downs. |
1992 if (hasOpenMouseDown_) { | 2159 if (hasOpenMouseDown_) { |
1993 WebMouseEvent event; | 2160 WebMouseEvent event; |
1994 event.type = WebInputEvent::MouseUp; | 2161 event.type = WebInputEvent::MouseUp; |
1995 event.button = WebMouseEvent::ButtonLeft; | 2162 event.button = WebMouseEvent::ButtonLeft; |
1996 if (renderWidgetHostView_->render_widget_host_) | 2163 if (renderWidgetHostView_->render_widget_host_) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2042 } | 2209 } |
2043 } | 2210 } |
2044 | 2211 |
2045 - (void)pasteAsPlainText:(id)sender { | 2212 - (void)pasteAsPlainText:(id)sender { |
2046 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { | 2213 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { |
2047 static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> | 2214 static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> |
2048 ForwardEditCommand("PasteAndMatchStyle", ""); | 2215 ForwardEditCommand("PasteAndMatchStyle", ""); |
2049 } | 2216 } |
2050 } | 2217 } |
2051 | 2218 |
2052 - (void)ensureAcceleratedPluginLayer { | |
2053 if (acceleratedPluginLayer_.get()) | |
2054 return; | |
2055 | |
2056 AcceleratedPluginLayer* pluginLayer = [[AcceleratedPluginLayer alloc] | |
2057 initWithRenderWidgetHostViewMac:renderWidgetHostView_.get()]; | |
2058 acceleratedPluginLayer_.reset(pluginLayer); | |
2059 // Make our layer resize to fit the superlayer | |
2060 pluginLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; | |
2061 // Make the view layer-backed so that there will be a layer to hang the | |
2062 // |layer| off of. This is not the "right" way to host a sublayer in a view, | |
2063 // but the right way would require making the whole view's drawing system | |
2064 // layer-based (using setLayer:). We don't want to do that (at least not | |
2065 // yet) so instead we override setLayer: and re-bind our plugin layer each | |
2066 // time the view's layer changes. For discussion see: | |
2067 // http://lists.apple.com/archives/Cocoa-dev/2009/Feb/msg01132.html | |
2068 [self setWantsLayer:YES]; | |
2069 [self attachPluginLayer]; | |
2070 } | |
2071 | |
2072 - (void)attachPluginLayer { | |
2073 CALayer* pluginLayer = acceleratedPluginLayer_.get(); | |
2074 if (!pluginLayer) | |
2075 return; | |
2076 | |
2077 CALayer* rootLayer = [self layer]; | |
2078 DCHECK(rootLayer != nil); | |
2079 [pluginLayer setFrame:NSRectToCGRect([self bounds])]; | |
2080 [rootLayer addSublayer:pluginLayer]; | |
2081 renderWidgetHostView_->AcceleratedSurfaceContextChanged(); | |
2082 } | |
2083 | |
2084 - (void)setLayer:(CALayer *)newLayer { | |
2085 CALayer* pluginLayer = acceleratedPluginLayer_.get(); | |
2086 if (!newLayer && [pluginLayer superlayer]) | |
2087 [pluginLayer removeFromSuperlayer]; | |
2088 | |
2089 [super setLayer:newLayer]; | |
2090 if ([self layer]) | |
2091 [self attachPluginLayer]; | |
2092 } | |
2093 | |
2094 - (void)drawAcceleratedPluginLayer { | 2219 - (void)drawAcceleratedPluginLayer { |
2095 [acceleratedPluginLayer_.get() setNeedsDisplay]; | 2220 [acceleratedPluginLayer_.get() setNeedsDisplay]; |
2096 } | 2221 } |
2097 | 2222 |
2098 - (void)cancelComposition { | 2223 - (void)cancelComposition { |
2099 if (!hasMarkedText_) | 2224 if (!hasMarkedText_) |
2100 return; | 2225 return; |
2101 | 2226 |
2102 // Cancel the ongoing composition. [NSInputManager markedTextAbandoned:] | 2227 // Cancel the ongoing composition. [NSInputManager markedTextAbandoned:] |
2103 // doesn't call any NSTextInput functions, such as setMarkedText or | 2228 // doesn't call any NSTextInput functions, such as setMarkedText or |
(...skipping 15 matching lines...) Expand all Loading... | |
2119 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); | 2244 renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); |
2120 | 2245 |
2121 [self cancelComposition]; | 2246 [self cancelComposition]; |
2122 } | 2247 } |
2123 | 2248 |
2124 - (ViewID)viewID { | 2249 - (ViewID)viewID { |
2125 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; | 2250 return VIEW_ID_TAB_CONTAINER_FOCUS_VIEW; |
2126 } | 2251 } |
2127 | 2252 |
2128 @end | 2253 @end |
OLD | NEW |