Make the Silverlight CAOpenGLLayer opaque if we know the plug-in contents is opaque...
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Aug 2012 20:33:21 +0000 (20:33 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Aug 2012 20:33:21 +0000 (20:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=93508
<rdar://problem/12056765>

Reviewed by Simon Fraser.

* Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm:
(WebKit::NetscapePluginModule::determineQuirks):
* Shared/Plugins/PluginQuirks.h:
Rename the MakeTransparentIfBackgroundAttributeExists quirk to MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists
since we'll explicitly check for opaque background colors (at least one opaque background color for now), instead of just making the
plug-in transparent whenever there's a background specified.

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::isTransparentSilverlightBackgroundValue):
Helper function for determining if a background value is transparent. Just check for opaque black now and treat everything else as transparent.

(WebKit::NetscapePlugin::initialize):
Call isTransparentSilverlightBackgroundValue.

* WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm:
(WebKit::makeCGLPresentLayerOpaque):
Helper function for grabbing the CGLPresentLayer from the layer hierarchy and setting it to be opaque.

(WebKit::NetscapePlugin::updatePluginLayer):
Call makeCGLPresentLayerOpaque if the plug-in has the MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists quirk and
the plug-in is not transparent.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@125081 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm
Source/WebKit2/Shared/Plugins/PluginQuirks.h
Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm

index 8653a2f..74a28eb 100644 (file)
@@ -1,3 +1,33 @@
+2012-08-08  Anders Carlsson  <andersca@apple.com>
+
+        Make the Silverlight CAOpenGLLayer opaque if we know the plug-in contents is opaque to reduce blending
+        https://bugs.webkit.org/show_bug.cgi?id=93508
+        <rdar://problem/12056765>
+
+        Reviewed by Simon Fraser.
+
+        * Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm:
+        (WebKit::NetscapePluginModule::determineQuirks):
+        * Shared/Plugins/PluginQuirks.h:
+        Rename the MakeTransparentIfBackgroundAttributeExists quirk to MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists
+        since we'll explicitly check for opaque background colors (at least one opaque background color for now), instead of just making the
+        plug-in transparent whenever there's a background specified.
+
+        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
+        (WebKit::isTransparentSilverlightBackgroundValue):
+        Helper function for determining if a background value is transparent. Just check for opaque black now and treat everything else as transparent.
+
+        (WebKit::NetscapePlugin::initialize):
+        Call isTransparentSilverlightBackgroundValue.
+
+        * WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm:
+        (WebKit::makeCGLPresentLayerOpaque):
+        Helper function for grabbing the CGLPresentLayer from the layer hierarchy and setting it to be opaque.
+
+        (WebKit::NetscapePlugin::updatePluginLayer):
+        Call makeCGLPresentLayerOpaque if the plug-in has the MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists quirk and
+        the plug-in is not transparent.
+
 2012-08-08  Mikhail Pozdnyakov  <mikhail.pozdnyakov@intel.com>
 
         [WK2] Coding style violation was brought with r125031
index 439de79..a4635e0 100644 (file)
@@ -477,8 +477,8 @@ void NetscapePluginModule::determineQuirks()
 
     if (plugin.bundleIdentifier == "com.microsoft.SilverlightPlugin") {
         // Silverlight doesn't explicitly opt into transparency, so we'll do it whenever
-        // there's a 'background' attribute.
-        m_pluginQuirks.add(PluginQuirks::MakeTransparentIfBackgroundAttributeExists);
+        // there's a 'background' attribute that's set to a transparent color.
+        m_pluginQuirks.add(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists);
 
         // Silverlight has a workaround for a leak in Safari 2. This workaround is
         // applied when the user agent does not contain "Version/3" so we append it
index c0a67d3..e99f71a 100644 (file)
@@ -40,13 +40,13 @@ public:
         // Supports receiving a paint event, even when using CoreAnimation rendering.
         SupportsSnapshotting,
 
-        // Make the plug-in transparent if it has a "background" attribute set.
+        // Make the plug-in opaque unless it has a "background" attribute set to a transparent color
+        // according to http://msdn.microsoft.com/en-us/library/cc838148(VS.95).aspx
+        // A non-existent "background" attribute is interpreted as the named color White which is opaque.
         // Microsoft Silverlight doesn't opt into transparency using NPN_SetValue and
-        // NPPVpluginTransparentBool, so we'll always force if the plug-in has a "background"
-        // attribute specified, regardless of it's value.
-        // FIXME: We could get more fancy here and check for specific values that we know are
-        // transparent.
-        MakeTransparentIfBackgroundAttributeExists,
+        // NPPVpluginTransparentBool, so we'll always force it unless the plug-in has a "background"
+        // attribute that specifies a opaque color.
+        MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists,
 
         // Whether calling NPP_GetValue with NPPVpluginCoreAnimationLayer returns a retained Core Animation
         // layer or not. According to the NPAPI specifications, plug-in shouldn't return a retained layer but
index 4d82cff..a86e583 100644 (file)
@@ -548,6 +548,18 @@ bool NetscapePlugin::allowPopups() const
     return false;
 }
 
+#if PLUGIN_ARCHITECTURE(MAC)
+static bool isTransparentSilverlightBackgroundValue(const String& backgroundValue)
+{
+    // FIXME: We should handle all the cases from http://msdn.microsoft.com/en-us/library/cc838148(VS.95).aspx here
+    // instead of just hard-coding black.
+    if (backgroundValue == "#000000")
+        return false;
+
+    return true;
+}
+#endif
+
 bool NetscapePlugin::initialize(const Parameters& parameters)
 {
     uint16_t mode = parameters.isFullFramePlugin ? NP_FULL : NP_EMBED;
@@ -581,10 +593,10 @@ bool NetscapePlugin::initialize(const Parameters& parameters)
     }
 
 #if PLUGIN_ARCHITECTURE(MAC)
-    if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeTransparentIfBackgroundAttributeExists)) {
+    if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) {
         for (size_t i = 0; i < parameters.names.size(); ++i) {
             if (equalIgnoringCase(parameters.names[i], "background")) {
-                setIsTransparent(true);
+                setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i]));
                 break;
             }
         }
index f1fa2f6..8a447df 100644 (file)
@@ -1057,6 +1057,27 @@ PlatformLayer* NetscapePlugin::pluginLayer()
     return static_cast<PlatformLayer*>(m_pluginLayer.get());
 }
 
+static void makeCGLPresentLayerOpaque(CALayer *pluginRootLayer)
+{
+    // We look for a layer that's the only sublayer of the root layer that is an instance
+    // of the CGLPresentLayer class which in turn is a subclass of CAOpenGLLayer and make
+    // it opaque if all these conditions hold.
+
+    NSArray *sublayers = [pluginRootLayer sublayers];
+    if ([sublayers count] != 1)
+        return;
+
+    Class cglPresentLayerClass = NSClassFromString(@"CGLPresentLayer");
+    if (![cglPresentLayerClass isSubclassOfClass:[CAOpenGLLayer class]])
+        return;
+
+    CALayer *layer = [sublayers objectAtIndex:0];
+    if (![layer isKindOfClass:cglPresentLayerClass])
+        return;
+
+    [layer setOpaque:YES];
+}
+
 void NetscapePlugin::updatePluginLayer()
 {
     if (m_drawingModel != NPDrawingModelCoreAnimation)
@@ -1086,6 +1107,10 @@ void NetscapePlugin::updatePluginLayer()
         m_pluginLayer = reinterpret_cast<CALayer *>(value);
     else
         m_pluginLayer.adoptNS(reinterpret_cast<CALayer *>(value));
+
+    if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists) &&
+        !m_isTransparent)
+        makeCGLPresentLayerOpaque(m_pluginLayer.get());
 }
 
 #ifndef NP_NO_CARBON