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/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 |