Chromium Code Reviews| 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 |