diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-24 17:17:31 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-24 17:17:31 +0000 |
commit | 9399fbcf34de43afa5afb23da0746abd340ffd04 (patch) | |
tree | c3b8dc998d6246d8d6ea1b4d130315eab54f813c | |
parent | 5ff708d4cb71716b8cd32d24b4bcd8ebcfa19331 (diff) | |
download | chromium_src-9399fbcf34de43afa5afb23da0746abd340ffd04.zip chromium_src-9399fbcf34de43afa5afb23da0746abd340ffd04.tar.gz chromium_src-9399fbcf34de43afa5afb23da0746abd340ffd04.tar.bz2 |
Mac: Well-behaved accelerated plugins, actual fix
Configure the opengl view to draw below the window, draw the view with NSClearColor so that's transparent, and make the window non-opaque while plugins are showing, so that the opengl surface can show through.
This is a bit slower than previously without this patch, but it's about as fast as it was when we used CoreAnimation to show IOSurfaces.
Parts of this code are from Simon Fraser's MacTierra code (with permission).
BUG=44087,51748
TEST=
* Go to youtube. Findbar should show up on top of video. Go fullscreen. Tab overlay should show up on top of video.
* Go to youtube, drag tab with video out and to a new window. Video should continue playing.
* Install https://chrome.google.com/extensions/detail/bdnkaenpadjoldiddfdidinjmjeagaji , click browser action. Should still work.
* Install a transparent theme such as https://tools.google.com/chrome/intl/cy/themes/theme_at_mecko.html or http://chromium.googlecode.com/issues/attachment?aid=3778755830122130591&name=theme-bug.crx&token=27908ca7e699a023c8446657b24c4696 . Browser window shouldn't become transparent while videos are playing.
Review URL: http://codereview.chromium.org/3176027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57201 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/cocoa/chrome_browser_window.h | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/chrome_browser_window.mm | 18 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_mac.mm | 44 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 5 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 |
5 files changed, 73 insertions, 1 deletions
diff --git a/chrome/browser/cocoa/chrome_browser_window.h b/chrome/browser/cocoa/chrome_browser_window.h index e6366fd..810c87fb 100644 --- a/chrome/browser/cocoa/chrome_browser_window.h +++ b/chrome/browser/cocoa/chrome_browser_window.h @@ -38,6 +38,7 @@ const NSInteger kChromeWindowButtonsInterButtonSpacing = 7; NSButton* zoomButton_; BOOL entered_; scoped_nsobject<NSTrackingArea> widgetTrackingArea_; + int underlaySurfaceCount_; } // Tells the window to suppress title drawing. @@ -50,6 +51,11 @@ const NSInteger kChromeWindowButtonsInterButtonSpacing = 7; // Update the tracking areas for our window widgets as appropriate. - (void)updateTrackingAreas; +// Informs the window that an underlay surface has been added/removed. The +// window is non-opaque while underlay surfaces are present. +- (void)underlaySurfaceAdded; +- (void)underlaySurfaceRemoved; + @end @interface NSWindow (UndocumentedAPI) diff --git a/chrome/browser/cocoa/chrome_browser_window.mm b/chrome/browser/cocoa/chrome_browser_window.mm index 35aae1a..25826a3 100644 --- a/chrome/browser/cocoa/chrome_browser_window.mm +++ b/chrome/browser/cocoa/chrome_browser_window.mm @@ -243,6 +243,24 @@ namespace { } } +- (void)underlaySurfaceAdded { + DCHECK_GE(underlaySurfaceCount_, 0); + ++underlaySurfaceCount_; + + // We're having the OpenGL surface render under the window, so the window + // needs to be not opaque. + if (underlaySurfaceCount_ == 1) + [self setOpaque:NO]; +} + +- (void)underlaySurfaceRemoved { + --underlaySurfaceCount_; + DCHECK_GE(underlaySurfaceCount_, 0); + + if (underlaySurfaceCount_ == 0) + [self setOpaque:YES]; +} + - (void)windowMainStatusChanged { [closeButton_ setNeedsDisplay]; [zoomButton_ setNeedsDisplay]; diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index 36f393c..87b0fdc 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -135,6 +135,13 @@ void DisablePasswordInput() { // This subclass of NSView hosts the output of accelerated plugins on // the page. +// Informal protocol implemented by windows that need to be informed explicitly +// about underlay surfaces. +@protocol UnderlayableSurface +- (void)underlaySurfaceAdded; +- (void)underlaySurfaceRemoved; +@end + @interface AcceleratedPluginView : NSView { scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_; CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|. @@ -203,6 +210,14 @@ static CVReturn DrawOneAcceleratedPluginCallback( glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_ shareContext:nil]); + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableHolePunching)) { + // We "punch a hole" in the window, and have the WindowServer render the + // OpenGL surface underneath so we can draw over it. + GLint belowWindow = -1; + [glContext_ setValues:&belowWindow forParameter:NSOpenGLCPSurfaceOrder]; + } + cglContext_ = (CGLContextObj)[glContext_ CGLContextObj]; cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; @@ -210,7 +225,6 @@ static CVReturn DrawOneAcceleratedPluginCallback( GLint swapInterval = 1; [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; - // Set up a display link to do OpenGL rendering on a background thread. CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); CVDisplayLinkSetOutputCallback(displayLink_, @@ -234,6 +248,17 @@ static CVReturn DrawOneAcceleratedPluginCallback( } - (void)drawRect:(NSRect)rect { + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableHolePunching)) { + const NSRect* dirtyRects; + int dirtyRectCount; + [self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount]; + + // Punch a hole so that the OpenGL view shows through. + [[NSColor clearColor] set]; + NSRectFillList(dirtyRects, dirtyRectCount); + } + [self drawView]; } @@ -287,6 +312,23 @@ static CVReturn DrawOneAcceleratedPluginCallback( [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } + +- (void)viewWillMoveToWindow:(NSWindow*)newWindow { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableHolePunching)) { + return; + } + + if ([self window] && + [[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { + [static_cast<id>([self window]) underlaySurfaceRemoved]; + } + + if (newWindow && + [newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) { + [static_cast<id>(newWindow) underlaySurfaceAdded]; + } +} @end // RenderWidgetHostView -------------------------------------------------------- diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 4897923..35651dd 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1161,6 +1161,11 @@ const char kPasswordStore[] = "password-store"; // model. This will be removed once the last issues have been resolved. const char kDisableFlashCoreAnimation[] = "disable-flash-core-animation"; +// Temporary flag to disable hole punching for accelerated surfaces. This is +// here to aid debugging eventual problems, it can be removed once hole punching +// has been out there for a few dev channel releases without problems. +const char kDisableHolePunching[] = "disable-hole-punching"; + // Enables the tabs expose feature ( http://crbug.com/50307 ). const char kEnableExposeForTabs[] = "enable-expose-for-tabs"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 6d1d796..7614d3d 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -344,6 +344,7 @@ extern const char kPasswordStore[]; #if defined(OS_MACOSX) extern const char kDisableFlashCoreAnimation[]; +extern const char kDisableHolePunching[]; extern const char kEnableExposeForTabs[]; extern const char kEnableSandboxLogging[]; #else |