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

Side by Side Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 1166002: Fix handling of Mac accelerated plugin layers across tab switch. (Closed)
Patch Set: Created 10 years, 9 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
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | 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) 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698