summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-24 17:17:31 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-24 17:17:31 +0000
commit9399fbcf34de43afa5afb23da0746abd340ffd04 (patch)
treec3b8dc998d6246d8d6ea1b4d130315eab54f813c
parent5ff708d4cb71716b8cd32d24b4bcd8ebcfa19331 (diff)
downloadchromium_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.h6
-rw-r--r--chrome/browser/cocoa/chrome_browser_window.mm18
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm44
-rw-r--r--chrome/common/chrome_switches.cc5
-rw-r--r--chrome/common/chrome_switches.h1
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