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" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); | 128 TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); |
| 129 } | 129 } |
| 130 | 130 |
| 131 } // namespace | 131 } // namespace |
| 132 | 132 |
| 133 // AcceleratedPluginView ------------------------------------------------------ | 133 // AcceleratedPluginView ------------------------------------------------------ |
| 134 | 134 |
| 135 // This subclass of NSView hosts the output of accelerated plugins on | 135 // This subclass of NSView hosts the output of accelerated plugins on |
| 136 // the page. | 136 // the page. |
| 137 | 137 |
| 138 // Informat protocol implemented by windows that need to be informed explicitly | |
| 139 // about underlay surfaces. | |
| 140 @protocol UnderlayableSurface | |
|
pink (ping after 24hrs)
2010/08/24 17:18:55
If it's a @protocol, then it's formal. s/Informal/
Nico
2010/08/24 17:27:55
Not really, since nothing implements this protocol
| |
| 141 - (void)underlaySurfaceAdded; | |
| 142 - (void)underlaySurfaceRemoved; | |
| 143 @end | |
| 144 | |
| 138 @interface AcceleratedPluginView : NSView { | 145 @interface AcceleratedPluginView : NSView { |
| 139 scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_; | 146 scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_; |
| 140 CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|. | 147 CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|. |
| 141 scoped_nsobject<NSOpenGLContext> glContext_; | 148 scoped_nsobject<NSOpenGLContext> glContext_; |
| 142 CGLContextObj cglContext_; // weak, backed by |glContext_|. | 149 CGLContextObj cglContext_; // weak, backed by |glContext_|. |
| 143 | 150 |
| 144 CVDisplayLinkRef displayLink_; // Owned by us. | 151 CVDisplayLinkRef displayLink_; // Owned by us. |
| 145 | 152 |
| 146 RenderWidgetHostViewMac* renderWidgetHostView_; // weak | 153 RenderWidgetHostViewMac* renderWidgetHostView_; // weak |
| 147 gfx::PluginWindowHandle pluginHandle_; // weak | 154 gfx::PluginWindowHandle pluginHandle_; // weak |
| 148 | 155 |
| 149 // True if the backing IO surface was updated since we last painted. | 156 // True if the backing IO surface was updated since we last painted. |
| 150 BOOL surfaceWasSwapped_; | 157 BOOL surfaceWasSwapped_; |
| 158 | |
| 159 // True if the surface might contain transparent pixels that need to be | |
| 160 // blended. | |
| 161 BOOL canDrawTransparent_; | |
| 151 } | 162 } |
| 152 | 163 |
| 153 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r | 164 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r |
| 154 pluginHandle:(gfx::PluginWindowHandle)pluginHandle; | 165 pluginHandle:(gfx::PluginWindowHandle)pluginHandle |
| 166 canDrawTransparent:(BOOL)canDrawTransparent; | |
| 155 - (void)drawView; | 167 - (void)drawView; |
| 156 | 168 |
| 157 // This _must_ be atomic, since it's accessed from several threads. | 169 // This _must_ be atomic, since it's accessed from several threads. |
| 158 @property BOOL surfaceWasSwapped; | 170 @property BOOL surfaceWasSwapped; |
| 159 @end | 171 @end |
| 160 | 172 |
| 161 @implementation AcceleratedPluginView : NSView | 173 @implementation AcceleratedPluginView : NSView |
| 162 @synthesize surfaceWasSwapped = surfaceWasSwapped_; | 174 @synthesize surfaceWasSwapped = surfaceWasSwapped_; |
| 163 | 175 |
| 164 - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime { | 176 - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 180 const CVTimeStamp* now, | 192 const CVTimeStamp* now, |
| 181 const CVTimeStamp* outputTime, | 193 const CVTimeStamp* outputTime, |
| 182 CVOptionFlags flagsIn, | 194 CVOptionFlags flagsIn, |
| 183 CVOptionFlags* flagsOut, | 195 CVOptionFlags* flagsOut, |
| 184 void* displayLinkContext) { | 196 void* displayLinkContext) { |
| 185 CVReturn result = | 197 CVReturn result = |
| 186 [(AcceleratedPluginView*)displayLinkContext getFrameForTime:outputTime]; | 198 [(AcceleratedPluginView*)displayLinkContext getFrameForTime:outputTime]; |
| 187 return result; | 199 return result; |
| 188 } | 200 } |
| 189 | 201 |
| 202 - (BOOL)drawAsUnderlaySurface { | |
| 203 // Transparent plugins really need to be handled by the GPU process. Until | |
| 204 // then, we have the coice of two evils: | |
|
pink (ping after 24hrs)
2010/08/24 17:18:55
choice
Nico
2010/08/24 17:27:55
will fix when i touch this file again (probably so
| |
| 205 // 1.) They are drawn as underlay surface, blending with whatever is behind | |
| 206 // the browser window (instead of blending with the webpage as intended) | |
| 207 // 2.) They are blended with the web page but drawn on top of sibling windows | |
| 208 // such as the find bar and the fullscreen window overlay. | |
| 209 // Option 2 seems less bad, so don't show transparent plugins as underlays. | |
| 210 // | |
| 211 // Note that this never happens in practice at the moment, because | |
| 212 // |canDrawTransparent| will only be true for flash with wmode=transparent and | |
| 213 // sliverlight with a transparent background, and these don't use | |
| 214 // CoreAnimation when they're transparent. | |
| 215 return !canDrawTransparent_ && !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 216 switches::kDisableHolePunching); | |
| 217 } | |
| 218 | |
| 190 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r | 219 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r |
| 191 pluginHandle:(gfx::PluginWindowHandle)pluginHandle { | 220 pluginHandle:(gfx::PluginWindowHandle)pluginHandle |
| 221 canDrawTransparent:(BOOL)canDrawTransparent { | |
| 192 if ((self = [super initWithFrame:NSZeroRect])) { | 222 if ((self = [super initWithFrame:NSZeroRect])) { |
| 193 renderWidgetHostView_ = r; | 223 renderWidgetHostView_ = r; |
| 194 pluginHandle_ = pluginHandle; | 224 pluginHandle_ = pluginHandle; |
| 225 canDrawTransparent_ = canDrawTransparent; | |
| 195 | 226 |
| 196 [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; | 227 [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; |
| 197 | 228 |
| 198 NSOpenGLPixelFormatAttribute attributes[] = | 229 NSOpenGLPixelFormatAttribute attributes[] = |
| 199 { NSOpenGLPFAAccelerated, NSOpenGLPFADoubleBuffer, 0}; | 230 { NSOpenGLPFAAccelerated, NSOpenGLPFADoubleBuffer, 0}; |
| 200 | 231 |
| 201 glPixelFormat_.reset([[NSOpenGLPixelFormat alloc] | 232 glPixelFormat_.reset([[NSOpenGLPixelFormat alloc] |
| 202 initWithAttributes:attributes]); | 233 initWithAttributes:attributes]); |
| 203 glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_ | 234 glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_ |
| 204 shareContext:nil]); | 235 shareContext:nil]); |
| 205 | 236 |
| 237 if ([self drawAsUnderlaySurface]) { | |
| 238 // We "punch a hole" in the window, and have the WindowServer render the | |
| 239 // OpenGL surface underneath so we can draw over it. | |
| 240 GLint belowWindow = -1; | |
| 241 [glContext_ setValues:&belowWindow forParameter:NSOpenGLCPSurfaceOrder]; | |
| 242 } | |
| 243 | |
| 206 cglContext_ = (CGLContextObj)[glContext_ CGLContextObj]; | 244 cglContext_ = (CGLContextObj)[glContext_ CGLContextObj]; |
| 207 cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; | 245 cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; |
| 208 | 246 |
| 209 // Draw at beam vsync. | 247 // Draw at beam vsync. |
| 210 GLint swapInterval = 1; | 248 GLint swapInterval = 1; |
| 211 [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; | 249 [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; |
| 212 | 250 |
| 213 | |
| 214 // Set up a display link to do OpenGL rendering on a background thread. | 251 // Set up a display link to do OpenGL rendering on a background thread. |
| 215 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); | 252 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); |
| 216 CVDisplayLinkSetOutputCallback(displayLink_, | 253 CVDisplayLinkSetOutputCallback(displayLink_, |
| 217 &DrawOneAcceleratedPluginCallback, self); | 254 &DrawOneAcceleratedPluginCallback, self); |
| 218 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( | 255 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( |
| 219 displayLink_, cglContext_, cglPixelFormat_); | 256 displayLink_, cglContext_, cglPixelFormat_); |
| 220 CVDisplayLinkStart(displayLink_); | 257 CVDisplayLinkStart(displayLink_); |
| 221 } | 258 } |
| 222 return self; | 259 return self; |
| 223 } | 260 } |
| 224 | 261 |
| 225 - (void)drawView { | 262 - (void)drawView { |
| 226 // Called on a background thread. Synchronized via the CGL context lock. | 263 // Called on a background thread. Synchronized via the CGL context lock. |
| 227 CGLLockContext(cglContext_); | 264 CGLLockContext(cglContext_); |
| 228 | 265 |
| 229 renderWidgetHostView_->DrawAcceleratedSurfaceInstance( | 266 renderWidgetHostView_->DrawAcceleratedSurfaceInstance( |
| 230 cglContext_, pluginHandle_); | 267 cglContext_, pluginHandle_); |
| 231 | 268 |
| 232 CGLFlushDrawable(cglContext_); | 269 CGLFlushDrawable(cglContext_); |
| 233 CGLUnlockContext(cglContext_); | 270 CGLUnlockContext(cglContext_); |
| 234 } | 271 } |
| 235 | 272 |
| 236 - (void)drawRect:(NSRect)rect { | 273 - (void)drawRect:(NSRect)rect { |
| 274 if ([self drawAsUnderlaySurface]) { | |
| 275 const NSRect* dirtyRects; | |
| 276 int dirtyRectCount; | |
| 277 | |
| 278 [self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount]; | |
| 279 // Punch a hole so that the OpenGL view shows through. | |
| 280 [[NSColor clearColor] set]; | |
| 281 NSRectFillList(dirtyRects, dirtyRectCount); | |
| 282 } | |
| 283 | |
| 237 [self drawView]; | 284 [self drawView]; |
| 238 } | 285 } |
| 239 | 286 |
| 240 - (void)rightMouseDown:(NSEvent*)event { | 287 - (void)rightMouseDown:(NSEvent*)event { |
| 241 // The NSResponder documentation: "Note: The NSView implementation of this | 288 // The NSResponder documentation: "Note: The NSView implementation of this |
| 242 // method does not pass the message up the responder chain, it handles it | 289 // method does not pass the message up the responder chain, it handles it |
| 243 // directly." | 290 // directly." |
| 244 // That's bad, we want the next responder (RWHVMac) to handle this event to | 291 // That's bad, we want the next responder (RWHVMac) to handle this event to |
| 245 // dispatch it to the renderer. | 292 // dispatch it to the renderer. |
| 246 [[self nextResponder] rightMouseDown:event]; | 293 [[self nextResponder] rightMouseDown:event]; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 object:self]; | 327 object:self]; |
| 281 } | 328 } |
| 282 [glContext_ makeCurrentContext]; | 329 [glContext_ makeCurrentContext]; |
| 283 } | 330 } |
| 284 | 331 |
| 285 - (void)dealloc { | 332 - (void)dealloc { |
| 286 CVDisplayLinkRelease(displayLink_); | 333 CVDisplayLinkRelease(displayLink_); |
| 287 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 334 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 288 [super dealloc]; | 335 [super dealloc]; |
| 289 } | 336 } |
| 337 | |
| 338 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { | |
| 339 if (![self drawAsUnderlaySurface]) { | |
| 340 return; | |
| 341 } | |
| 342 | |
| 343 if ([self window] && | |
|
pink (ping after 24hrs)
2010/08/24 17:18:55
do you need the extra window null checks? [nil res
Nico
2010/08/24 17:27:55
i don't need them, but i thought it's clearer.
si
| |
| 344 [[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { | |
| 345 [static_cast<id>([self window]) underlaySurfaceRemoved]; | |
| 346 } | |
| 347 | |
| 348 if (newWindow && | |
| 349 [newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) { | |
| 350 [static_cast<id>(newWindow) underlaySurfaceAdded]; | |
| 351 } | |
| 352 } | |
| 290 @end | 353 @end |
| 291 | 354 |
| 292 // RenderWidgetHostView -------------------------------------------------------- | 355 // RenderWidgetHostView -------------------------------------------------------- |
| 293 | 356 |
| 294 // static | 357 // static |
| 295 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 358 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
| 296 RenderWidgetHost* widget) { | 359 RenderWidgetHost* widget) { |
| 297 return new RenderWidgetHostViewMac(widget); | 360 return new RenderWidgetHostViewMac(widget); |
| 298 } | 361 } |
| 299 | 362 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 756 | 819 |
| 757 void RenderWidgetHostViewMac::KillSelf() { | 820 void RenderWidgetHostViewMac::KillSelf() { |
| 758 if (shutdown_factory_.empty()) { | 821 if (shutdown_factory_.empty()) { |
| 759 [cocoa_view_ setHidden:YES]; | 822 [cocoa_view_ setHidden:YES]; |
| 760 MessageLoop::current()->PostTask(FROM_HERE, | 823 MessageLoop::current()->PostTask(FROM_HERE, |
| 761 shutdown_factory_.NewRunnableMethod( | 824 shutdown_factory_.NewRunnableMethod( |
| 762 &RenderWidgetHostViewMac::ShutdownHost)); | 825 &RenderWidgetHostViewMac::ShutdownHost)); |
| 763 } | 826 } |
| 764 } | 827 } |
| 765 | 828 |
| 766 gfx::PluginWindowHandle | 829 gfx::PluginWindowHandle RenderWidgetHostViewMac::AllocateFakePluginWindowHandle( |
| 767 RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, | 830 bool opaque, bool can_draw_transparent, bool root) { |
| 768 bool root) { | |
| 769 // Create an NSView to host the plugin's/compositor's pixels. | 831 // Create an NSView to host the plugin's/compositor's pixels. |
| 770 gfx::PluginWindowHandle handle = | 832 gfx::PluginWindowHandle handle = |
| 771 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | 833 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); |
| 772 | 834 |
| 773 scoped_nsobject<NSView> plugin_view( | 835 scoped_nsobject<NSView> plugin_view([[AcceleratedPluginView alloc] |
| 774 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this | 836 initWithRenderWidgetHostViewMac:this |
| 775 pluginHandle:handle]); | 837 pluginHandle:handle |
| 838 canDrawTransparent:can_draw_transparent]); | |
| 776 [plugin_view setHidden:YES]; | 839 [plugin_view setHidden:YES]; |
| 777 | 840 |
| 778 [cocoa_view_ addSubview:plugin_view]; | 841 [cocoa_view_ addSubview:plugin_view]; |
| 779 plugin_views_[handle] = plugin_view; | 842 plugin_views_[handle] = plugin_view; |
| 780 | 843 |
| 781 return handle; | 844 return handle; |
| 782 } | 845 } |
| 783 | 846 |
| 784 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( | 847 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( |
| 785 gfx::PluginWindowHandle window) { | 848 gfx::PluginWindowHandle window) { |
| (...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2300 NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType]; | 2363 NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType]; |
| 2301 [pboard declareTypes:toDeclare owner:nil]; | 2364 [pboard declareTypes:toDeclare owner:nil]; |
| 2302 return [pboard setString:text forType:NSStringPboardType]; | 2365 return [pboard setString:text forType:NSStringPboardType]; |
| 2303 } | 2366 } |
| 2304 | 2367 |
| 2305 - (BOOL)readSelectionFromPasteboard:(NSPasteboard*)pboard { | 2368 - (BOOL)readSelectionFromPasteboard:(NSPasteboard*)pboard { |
| 2306 return NO; | 2369 return NO; |
| 2307 } | 2370 } |
| 2308 | 2371 |
| 2309 @end | 2372 @end |
| OLD | NEW |