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

Unified Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 3176027: Mac: Well-behaved accelerated plugins, actual fix (Closed)
Patch Set: test Created 10 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/renderer_host/render_widget_host_view_mac.mm
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 4a634b2b2c32afd7dbd6bbf49cfce77f2ccf6c31..37bd963d564fb9fe8c084560f789dd7e1d7bc3e1 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.
+// Informat protocol implemented by windows that need to be informed explicitly
+// about underlay surfaces.
+@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
+- (void)underlaySurfaceAdded;
+- (void)underlaySurfaceRemoved;
+@end
+
@interface AcceleratedPluginView : NSView {
scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_;
CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|.
@@ -148,10 +155,15 @@ void DisablePasswordInput() {
// True if the backing IO surface was updated since we last painted.
BOOL surfaceWasSwapped_;
+
+ // True if the surface might contain transparent pixels that need to be
+ // blended.
+ BOOL canDrawTransparent_;
}
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r
- pluginHandle:(gfx::PluginWindowHandle)pluginHandle;
+ pluginHandle:(gfx::PluginWindowHandle)pluginHandle
+ canDrawTransparent:(BOOL)canDrawTransparent;
- (void)drawView;
// This _must_ be atomic, since it's accessed from several threads.
@@ -187,11 +199,30 @@ static CVReturn DrawOneAcceleratedPluginCallback(
return result;
}
+- (BOOL)drawAsUnderlaySurface {
+ // Transparent plugins really need to be handled by the GPU process. Until
+ // 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
+ // 1.) They are drawn as underlay surface, blending with whatever is behind
+ // the browser window (instead of blending with the webpage as intended)
+ // 2.) They are blended with the web page but drawn on top of sibling windows
+ // such as the find bar and the fullscreen window overlay.
+ // Option 2 seems less bad, so don't show transparent plugins as underlays.
+ //
+ // Note that this never happens in practice at the moment, because
+ // |canDrawTransparent| will only be true for flash with wmode=transparent and
+ // sliverlight with a transparent background, and these don't use
+ // CoreAnimation when they're transparent.
+ return !canDrawTransparent_ && !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableHolePunching);
+}
+
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r
- pluginHandle:(gfx::PluginWindowHandle)pluginHandle {
+ pluginHandle:(gfx::PluginWindowHandle)pluginHandle
+ canDrawTransparent:(BOOL)canDrawTransparent {
if ((self = [super initWithFrame:NSZeroRect])) {
renderWidgetHostView_ = r;
pluginHandle_ = pluginHandle;
+ canDrawTransparent_ = canDrawTransparent;
[self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin];
@@ -203,6 +234,13 @@ static CVReturn DrawOneAcceleratedPluginCallback(
glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_
shareContext:nil]);
+ if ([self drawAsUnderlaySurface]) {
+ // 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 +248,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 +271,16 @@ static CVReturn DrawOneAcceleratedPluginCallback(
}
- (void)drawRect:(NSRect)rect {
+ if ([self drawAsUnderlaySurface]) {
+ 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 +334,22 @@ static CVReturn DrawOneAcceleratedPluginCallback(
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
+
+- (void)viewWillMoveToWindow:(NSWindow*)newWindow {
+ if (![self drawAsUnderlaySurface]) {
+ return;
+ }
+
+ 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
+ [[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) {
+ [static_cast<id>([self window]) underlaySurfaceRemoved];
+ }
+
+ if (newWindow &&
+ [newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) {
+ [static_cast<id>(newWindow) underlaySurfaceAdded];
+ }
+}
@end
// RenderWidgetHostView --------------------------------------------------------
@@ -763,16 +826,16 @@ void RenderWidgetHostViewMac::KillSelf() {
}
}
-gfx::PluginWindowHandle
-RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque,
- bool root) {
+gfx::PluginWindowHandle RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(
+ bool opaque, bool can_draw_transparent, bool root) {
// Create an NSView to host the plugin's/compositor's pixels.
gfx::PluginWindowHandle handle =
plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root);
- scoped_nsobject<NSView> plugin_view(
- [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this
- pluginHandle:handle]);
+ scoped_nsobject<NSView> plugin_view([[AcceleratedPluginView alloc]
+ initWithRenderWidgetHostViewMac:this
+ pluginHandle:handle
+ canDrawTransparent:can_draw_transparent]);
[plugin_view setHidden:YES];
[cocoa_view_ addSubview:plugin_view];
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | chrome/browser/renderer_host/test/test_render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698