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/CAOpenGLLayer.h> | 5 #include <QuartzCore/CAOpenGLLayer.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 #import "base/chrome_application_mac.h" | 9 #import "base/chrome_application_mac.h" |
10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 42 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
43 return modifiers; | 43 return modifiers; |
44 } | 44 } |
45 | 45 |
46 @interface RenderWidgetHostViewCocoa (Private) | 46 @interface RenderWidgetHostViewCocoa (Private) |
47 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; | 47 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; |
48 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 48 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
49 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; | 49 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; |
50 - (void)cancelChildPopups; | 50 - (void)cancelChildPopups; |
51 - (void)callSetNeedsDisplayInRect:(NSValue*)rect; | 51 - (void)callSetNeedsDisplayInRect:(NSValue*)rect; |
52 - (void)attachPluginLayer; | |
52 @end | 53 @end |
53 | 54 |
54 namespace { | 55 namespace { |
55 | 56 |
56 // Maximum number of characters we allow in a tooltip. | 57 // Maximum number of characters we allow in a tooltip. |
57 const size_t kMaxTooltipLength = 1024; | 58 const size_t kMaxTooltipLength = 1024; |
58 | 59 |
59 } | 60 } |
60 | 61 |
61 // GPUPluginLayer -------------------------------------------------------------- | 62 // AcceleratedPluginLayer ------------------------------------------------------ |
62 | 63 |
63 // This subclass of CAOpenGLLayer hosts the output of the GPU-accelerated | 64 // This subclass of CAOpenGLLayer hosts the output of accelerated plugins on |
64 // plugins on the page. | 65 // the page. |
65 | 66 |
66 @interface GPUPluginLayer : CAOpenGLLayer { | 67 @interface AcceleratedPluginLayer : CAOpenGLLayer { |
67 RenderWidgetHostViewMac* renderWidgetHostView_; // weak | 68 RenderWidgetHostViewMac* renderWidgetHostView_; // weak |
68 } | 69 } |
69 | 70 |
70 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 71 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
71 @end | 72 @end |
72 | 73 |
73 @implementation GPUPluginLayer | 74 @implementation AcceleratedPluginLayer |
74 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 75 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
75 self = [super init]; | 76 self = [super init]; |
76 if (self != nil) { | 77 if (self != nil) { |
77 renderWidgetHostView_ = r; | 78 renderWidgetHostView_ = r; |
78 } | 79 } |
79 return self; | 80 return self; |
80 } | 81 } |
81 | 82 |
82 -(void)drawInCGLContext:(CGLContextObj)glContext | 83 - (void)drawInCGLContext:(CGLContextObj)glContext |
83 pixelFormat:(CGLPixelFormatObj)pixelFormat | 84 pixelFormat:(CGLPixelFormatObj)pixelFormat |
84 forLayerTime:(CFTimeInterval)timeInterval | 85 forLayerTime:(CFTimeInterval)timeInterval |
85 displayTime:(const CVTimeStamp *)timeStamp { | 86 displayTime:(const CVTimeStamp *)timeStamp { |
86 renderWidgetHostView_->DrawAcceleratedSurfaceInstances(glContext); | 87 renderWidgetHostView_->DrawAcceleratedSurfaceInstances(glContext); |
87 [super drawInCGLContext:glContext | 88 [super drawInCGLContext:glContext |
88 pixelFormat:pixelFormat | 89 pixelFormat:pixelFormat |
89 forLayerTime:timeInterval | 90 forLayerTime:timeInterval |
90 displayTime:timeStamp]; | 91 displayTime:timeStamp]; |
91 } | 92 } |
93 | |
94 - (void)setFrame:(CGRect)rect { | |
95 // The frame we get when the superlayer resizes doesn't make sense, so ignore | |
96 // it and just match the superlayer's size. See the email thread referenced in | |
97 // ensureAcceleratedPluginLayer for an explanation of why the superlayer | |
98 // isn't trustworthy. | |
99 if ([self superlayer]) | |
100 [super setFrame:[[self superlayer] bounds]]; | |
101 else | |
102 [super setFrame:rect]; | |
103 } | |
92 @end | 104 @end |
93 | 105 |
94 // RenderWidgetHostView -------------------------------------------------------- | 106 // RenderWidgetHostView -------------------------------------------------------- |
95 | 107 |
96 // static | 108 // static |
97 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 109 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
98 RenderWidgetHost* widget) { | 110 RenderWidgetHost* widget) { |
99 return new RenderWidgetHostViewMac(widget); | 111 return new RenderWidgetHostViewMac(widget); |
100 } | 112 } |
101 | 113 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 rect.set_height(size.height()); | 222 rect.set_height(size.height()); |
211 [cocoa_view_ setFrame:[(BaseView*)[cocoa_view_ superview] RectToNSRect:rect]]; | 223 [cocoa_view_ setFrame:[(BaseView*)[cocoa_view_ superview] RectToNSRect:rect]]; |
212 } | 224 } |
213 | 225 |
214 gfx::NativeView RenderWidgetHostViewMac::GetNativeView() { | 226 gfx::NativeView RenderWidgetHostViewMac::GetNativeView() { |
215 return native_view(); | 227 return native_view(); |
216 } | 228 } |
217 | 229 |
218 void RenderWidgetHostViewMac::MovePluginWindows( | 230 void RenderWidgetHostViewMac::MovePluginWindows( |
219 const std::vector<webkit_glue::WebPluginGeometry>& moves) { | 231 const std::vector<webkit_glue::WebPluginGeometry>& moves) { |
220 // The only case we need to notice plugin window moves is the case | 232 // Handle movement of accelerated plugins, which are the only "windowed" |
221 // of the GPU plugin. As soon as the GPU plugin becomes the GPU | 233 // plugins that exist on the Mac. |
222 // process all of this code will go away. | |
223 if (moves.size() > 0) { | 234 if (moves.size() > 0) { |
224 for (std::vector<webkit_glue::WebPluginGeometry>::const_iterator iter = | 235 for (std::vector<webkit_glue::WebPluginGeometry>::const_iterator iter = |
225 moves.begin(); | 236 moves.begin(); |
226 iter != moves.end(); | 237 iter != moves.end(); |
227 ++iter) { | 238 ++iter) { |
228 webkit_glue::WebPluginGeometry geom = *iter; | 239 webkit_glue::WebPluginGeometry geom = *iter; |
229 // Ignore bogus moves which claim to move the plugin to (0, 0) | 240 // Ignore bogus moves which claim to move the plugin to (0, 0) |
230 // with width and height (0, 0) | 241 // with width and height (0, 0) |
231 if (geom.window_rect.x() != 0 || | 242 if (geom.window_rect.x() != 0 || |
232 geom.window_rect.y() != 0 || | 243 geom.window_rect.y() != 0 || |
233 geom.window_rect.width() != 0 || | 244 geom.window_rect.width() != 0 || |
234 geom.window_rect.height() != 0) { | 245 geom.window_rect.height() != 0) { |
235 plugin_container_manager_.MovePluginContainer(geom); | 246 plugin_container_manager_.MovePluginContainer(geom); |
236 } | 247 } |
237 } | 248 } |
238 } | 249 } |
239 | |
240 // All plugin stuff is TBD. TODO(avi,awalker): fill in | |
241 // http://crbug.com/8192 | |
242 } | 250 } |
243 | 251 |
244 void RenderWidgetHostViewMac::Focus() { | 252 void RenderWidgetHostViewMac::Focus() { |
245 [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; | 253 [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; |
246 } | 254 } |
247 | 255 |
248 void RenderWidgetHostViewMac::Blur() { | 256 void RenderWidgetHostViewMac::Blur() { |
249 [[cocoa_view_ window] makeFirstResponder:nil]; | 257 [[cocoa_view_ window] makeFirstResponder:nil]; |
250 } | 258 } |
251 | 259 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 if (shutdown_factory_.empty()) { | 517 if (shutdown_factory_.empty()) { |
510 [cocoa_view_ setHidden:YES]; | 518 [cocoa_view_ setHidden:YES]; |
511 MessageLoop::current()->PostTask(FROM_HERE, | 519 MessageLoop::current()->PostTask(FROM_HERE, |
512 shutdown_factory_.NewRunnableMethod( | 520 shutdown_factory_.NewRunnableMethod( |
513 &RenderWidgetHostViewMac::ShutdownHost)); | 521 &RenderWidgetHostViewMac::ShutdownHost)); |
514 } | 522 } |
515 } | 523 } |
516 | 524 |
517 gfx::PluginWindowHandle | 525 gfx::PluginWindowHandle |
518 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle() { | 526 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle() { |
519 // If we don't already have a GPUPluginLayer allocated for our view, | 527 // Make sure we have a layer for the plugin to draw into. |
520 // set one up now. | 528 [cocoa_view_ ensureAcceleratedPluginLayer]; |
521 if (gpu_plugin_layer_.get() == nil) { | |
522 RenderWidgetHostViewCocoa* our_view = native_view(); | |
523 // Try to get AppKit to allocate the layer | |
524 [our_view setWantsLayer:YES]; | |
525 CALayer* root_layer = [our_view layer]; | |
526 if (root_layer == nil) { | |
527 root_layer = [CALayer layer]; | |
528 [our_view setLayer:root_layer]; | |
529 } | |
530 | |
531 GPUPluginLayer* gpu_layer = | |
532 [[GPUPluginLayer alloc] initWithRenderWidgetHostViewMac:this]; | |
533 | |
534 // Make our layer resize to fit the superlayer | |
535 gpu_layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; | |
536 // Set up its initial size | |
537 [gpu_layer setFrame:NSRectToCGRect([our_view bounds])]; | |
538 | |
539 [root_layer addSublayer:gpu_layer]; | |
540 gpu_plugin_layer_.reset(gpu_layer); | |
541 } | |
542 | 529 |
543 return plugin_container_manager_.AllocateFakePluginWindowHandle(); | 530 return plugin_container_manager_.AllocateFakePluginWindowHandle(); |
544 } | 531 } |
545 | 532 |
546 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( | 533 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( |
547 gfx::PluginWindowHandle window) { | 534 gfx::PluginWindowHandle window) { |
548 plugin_container_manager_.DestroyFakePluginWindowHandle(window); | 535 plugin_container_manager_.DestroyFakePluginWindowHandle(window); |
549 } | 536 } |
550 | 537 |
551 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( | 538 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( |
(...skipping 13 matching lines...) Expand all Loading... | |
565 int32 height, | 552 int32 height, |
566 TransportDIB::Handle transport_dib) { | 553 TransportDIB::Handle transport_dib) { |
567 plugin_container_manager_.SetSizeAndTransportDIB(window, | 554 plugin_container_manager_.SetSizeAndTransportDIB(window, |
568 width, | 555 width, |
569 height, | 556 height, |
570 transport_dib); | 557 transport_dib); |
571 } | 558 } |
572 | 559 |
573 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 560 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
574 gfx::PluginWindowHandle window) { | 561 gfx::PluginWindowHandle window) { |
575 [gpu_plugin_layer_.get() setNeedsDisplay]; | 562 [cocoa_view_ drawAcceleratedPluginLayer]; |
576 } | 563 } |
577 | 564 |
578 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstances( | 565 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstances( |
579 CGLContextObj context) { | 566 CGLContextObj context) { |
580 CGLSetCurrentContext(context); | 567 CGLSetCurrentContext(context); |
581 gfx::Rect rect = GetWindowRect(); | 568 gfx::Rect rect = GetWindowRect(); |
582 glMatrixMode(GL_PROJECTION); | 569 glMatrixMode(GL_PROJECTION); |
583 glLoadIdentity(); | 570 glLoadIdentity(); |
584 // Note that we place the origin at the upper left corner with +y | 571 // Note that we place the origin at the upper left corner with +y |
585 // going down | 572 // going down |
586 glOrtho(0, rect.width(), rect.height(), 0, -1, 1); | 573 glOrtho(0, rect.width(), rect.height(), 0, -1, 1); |
587 glMatrixMode(GL_MODELVIEW); | 574 glMatrixMode(GL_MODELVIEW); |
588 glLoadIdentity(); | 575 glLoadIdentity(); |
589 | 576 |
590 plugin_container_manager_.Draw(context); | 577 plugin_container_manager_.Draw(context); |
591 } | 578 } |
592 | 579 |
580 void RenderWidgetHostViewMac::AcceleratedSurfaceContextChanged() { | |
581 plugin_container_manager_.ForceTextureReload(); | |
582 } | |
583 | |
593 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(bool deemphasized) { | 584 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(bool deemphasized) { |
594 // Mac uses tab-modal sheets, so this is a no-op. | 585 // Mac uses tab-modal sheets, so this is a no-op. |
595 } | 586 } |
596 | 587 |
597 void RenderWidgetHostViewMac::ShutdownHost() { | 588 void RenderWidgetHostViewMac::ShutdownHost() { |
598 shutdown_factory_.RevokeAll(); | 589 shutdown_factory_.RevokeAll(); |
599 render_widget_host_->Shutdown(); | 590 render_widget_host_->Shutdown(); |
600 // Do not touch any members at this point, |this| has been deleted. | 591 // Do not touch any members at this point, |this| has been deleted. |
601 } | 592 } |
602 | 593 |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 // recorded. | 1045 // recorded. |
1055 renderWidgetHostView_->tab_switch_paint_time_ = base::TimeTicks(); | 1046 renderWidgetHostView_->tab_switch_paint_time_ = base::TimeTicks(); |
1056 } | 1047 } |
1057 } else { | 1048 } else { |
1058 [[NSColor whiteColor] set]; | 1049 [[NSColor whiteColor] set]; |
1059 NSRectFill(dirtyRect); | 1050 NSRectFill(dirtyRect); |
1060 if (renderWidgetHostView_->whiteout_start_time_.is_null()) | 1051 if (renderWidgetHostView_->whiteout_start_time_.is_null()) |
1061 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now(); | 1052 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now(); |
1062 } | 1053 } |
1063 | 1054 |
1064 // This helps keep the GPU plugins' output in better sync with the | 1055 // This helps keep accelerated plugins' output in better sync with the |
1065 // window as it resizes. | 1056 // window as it resizes. |
1066 [renderWidgetHostView_->gpu_plugin_layer_.get() setNeedsDisplay]; | 1057 [accelerated_plugin_layer_.get() setNeedsDisplay]; |
1067 } | 1058 } |
1068 | 1059 |
1069 - (BOOL)canBecomeKeyView { | 1060 - (BOOL)canBecomeKeyView { |
1070 if (!renderWidgetHostView_->render_widget_host_) | 1061 if (!renderWidgetHostView_->render_widget_host_) |
1071 return NO; | 1062 return NO; |
1072 | 1063 |
1073 return canBeKeyView_; | 1064 return canBeKeyView_; |
1074 } | 1065 } |
1075 | 1066 |
1076 - (BOOL)acceptsFirstResponder { | 1067 - (BOOL)acceptsFirstResponder { |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1671 } | 1662 } |
1672 } | 1663 } |
1673 | 1664 |
1674 - (void)pasteAsPlainText:(id)sender { | 1665 - (void)pasteAsPlainText:(id)sender { |
1675 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { | 1666 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { |
1676 static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> | 1667 static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> |
1677 ForwardEditCommand("PasteAndMatchStyle", ""); | 1668 ForwardEditCommand("PasteAndMatchStyle", ""); |
1678 } | 1669 } |
1679 } | 1670 } |
1680 | 1671 |
1672 - (void)ensureAcceleratedPluginLayer { | |
1673 if (accelerated_plugin_layer_.get()) | |
1674 return; | |
1675 | |
1676 AcceleratedPluginLayer* plugin_layer = [[AcceleratedPluginLayer alloc] | |
pink (ping after 24hrs)
2010/03/23 17:32:04
objC should use objC naming: pluginLayer, etc.
| |
1677 initWithRenderWidgetHostViewMac:renderWidgetHostView_.get()]; | |
1678 accelerated_plugin_layer_.reset(plugin_layer); | |
1679 // Make our layer resize to fit the superlayer | |
1680 plugin_layer.autoresizingMask = kCALayerWidthSizable | | |
1681 kCALayerHeightSizable; | |
1682 // Make the view layer-backed so that there will be a layer to hang the | |
1683 // |layer| off of. This is not the "right" way to host a sublayer in a view, | |
1684 // but the right way would require making the whole view's drawing system | |
1685 // layer-based (using setLayer:). We don't want to do that (at least not | |
1686 // yet) so instead we override setLayer: and re-bind our plugin layer each | |
1687 // time the view's layer changes. For discussion see: | |
1688 // http://lists.apple.com/archives/Cocoa-dev/2009/Feb/msg01132.html | |
1689 [self setWantsLayer:YES]; | |
1690 [self attachPluginLayer]; | |
1691 } | |
1692 | |
1693 - (void)attachPluginLayer { | |
1694 CALayer* plugin_layer = accelerated_plugin_layer_.get(); | |
1695 if (!plugin_layer) | |
1696 return; | |
1697 | |
1698 CALayer* root_layer = [self layer]; | |
1699 DCHECK(root_layer != nil); | |
1700 [plugin_layer setFrame:NSRectToCGRect([self bounds])]; | |
1701 [root_layer addSublayer:plugin_layer]; | |
1702 renderWidgetHostView_->AcceleratedSurfaceContextChanged(); | |
1703 } | |
1704 | |
1705 - (void)setLayer:(CALayer *)newLayer { | |
1706 CALayer* plugin_layer = accelerated_plugin_layer_.get(); | |
1707 if (!newLayer && [plugin_layer superlayer]) | |
1708 [plugin_layer removeFromSuperlayer]; | |
1709 | |
1710 [super setLayer:newLayer]; | |
1711 if ([self layer]) | |
1712 [self attachPluginLayer]; | |
1713 } | |
1714 | |
1715 - (void)drawAcceleratedPluginLayer { | |
1716 [accelerated_plugin_layer_.get() setNeedsDisplay]; | |
1717 } | |
1718 | |
1681 @end | 1719 @end |
OLD | NEW |