Bug 644832. Windowless plugins inside CSS transforms should be rendered. r=tnikkel
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 01 Apr 2011 10:33:46 +1300
changeset 64534 7dceef1d4e6670968c204d1a89300c8d1efc34c9
parent 64533 c96c353c9d5e37441fded130cfce0668e1569101
child 64535 e36b387929f0e67b070a87f1d4b4cd82b8af0e34
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs644832
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 644832. Windowless plugins inside CSS transforms should be rendered. r=tnikkel
layout/base/nsDisplayList.h
layout/base/nsPresContext.cpp
layout/generic/nsObjectFrame.h
modules/plugin/test/reftest/plugin-transform-1-ref.html
modules/plugin/test/reftest/plugin-transform-1.html
modules/plugin/test/reftest/plugin-transform-2-ref.html
modules/plugin/test/reftest/plugin-transform-2.html
modules/plugin/test/reftest/reftest.list
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2008,19 +2008,17 @@ public:
 
   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
   {
     if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
       return nsRect();
     return GetBounds(aBuilder);
   }
 
-#ifdef NS_DEBUG
   nsDisplayWrapList* GetStoredList() { return &mStoredList; }
-#endif
 
   virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
                        HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
   virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
                                    PRBool* aForceTransparentSurface = nsnull);
   virtual PRBool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2522,42 +2522,50 @@ PluginHideEnumerator(nsPtrHashKey<nsObje
   PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
   nsObjectFrame* f = aEntry->GetKey();
   f->GetEmptyClipConfiguration(closure->mOutputConfigurations);
   return PL_DHASH_NEXT;
 }
 
 static void
 RecoverPluginGeometry(nsDisplayListBuilder* aBuilder,
-    nsDisplayList* aList, PluginGeometryClosure* aClosure)
+    nsDisplayList* aList, PRBool aInTransform, PluginGeometryClosure* aClosure)
 {
   for (nsDisplayItem* i = aList->GetBottom(); i; i = i->GetAbove()) {
     switch (i->GetType()) {
     case nsDisplayItem::TYPE_PLUGIN: {
       nsDisplayPlugin* displayPlugin = static_cast<nsDisplayPlugin*>(i);
       nsObjectFrame* f = static_cast<nsObjectFrame*>(
           displayPlugin->GetUnderlyingFrame());
       // Ignore plugins which aren't supposed to be affected by this
       // operation --- their bounds will not have been included in the
       // display list computations so the visible region computed for them
       // would be incorrect
       nsPtrHashKey<nsObjectFrame>* entry =
         aClosure->mAffectedPlugins.GetEntry(f);
-      if (entry) {
+      // Windowed plugins in transforms are always ignored, we don't
+      // create configurations for them
+      if (entry && (!aInTransform || !f->GetWidget())) {
         displayPlugin->GetWidgetConfiguration(aBuilder,
                                               aClosure->mOutputConfigurations);
         // we've dealt with this plugin now
         aClosure->mAffectedPlugins.RawRemoveEntry(entry);
       }
       break;
     }
+    case nsDisplayItem::TYPE_TRANSFORM: {
+      nsDisplayList* sublist =
+          static_cast<nsDisplayTransform*>(i)->GetStoredList()->GetList();
+      RecoverPluginGeometry(aBuilder, sublist, PR_TRUE, aClosure);
+      break;
+    }
     default: {
       nsDisplayList* sublist = i->GetList();
       if (sublist) {
-        RecoverPluginGeometry(aBuilder, sublist, aClosure);
+        RecoverPluginGeometry(aBuilder, sublist, aInTransform, aClosure);
       }
       break;
     }
     }
   }
 }
 
 #ifdef DEBUG
@@ -2613,17 +2621,17 @@ nsRootPresContext::GetPluginGeometryUpda
 
 #ifdef DEBUG
     if (gDumpPluginList) {
       fprintf(stderr, "Plugins --- after optimization:\n");
       nsFrame::PrintDisplayList(&builder, list);
     }
 #endif
 
-    RecoverPluginGeometry(&builder, &list, &closure);
+    RecoverPluginGeometry(&builder, &list, PR_FALSE, &closure);
     list.DeleteAll();
   }
 
   // Plugins that we didn't find in the display list are not visible
   closure.mAffectedPlugins.EnumerateEntries(PluginHideEnumerator, &closure);
 }
 
 static PRBool
--- a/layout/generic/nsObjectFrame.h
+++ b/layout/generic/nsObjectFrame.h
@@ -207,16 +207,18 @@ public:
    */
   static void BeginSwapDocShells(nsIContent* aContent, void*);
   /**
    * If aContent has a nsObjectFrame, then set it up after a DocShell swap.
    * @see nsSubDocumentFrame::EndSwapDocShells.
    */
   static void EndSwapDocShells(nsIContent* aContent, void*);
 
+  nsIWidget* GetWidget() { return mWidget; }
+
 protected:
   nsObjectFrame(nsStyleContext* aContext);
   virtual ~nsObjectFrame();
 
   // NOTE:  This frame class does not inherit from |nsLeafFrame|, so
   // this is not a virtual method implementation.
   void GetDesiredSize(nsPresContext* aPresContext,
                       const nsHTMLReflowState& aReflowState,
@@ -272,18 +274,16 @@ protected:
    * system actually is, as long as aRegion and aPluginOrigin are consistent.
    * This will append a Configuration object to aConfigurations
    * containing the widget, its desired position, size and clip region.
    */
   void ComputeWidgetGeometry(const nsRegion& aRegion,
                              const nsPoint& aPluginOrigin,
                              nsTArray<nsIWidget::Configuration>* aConfigurations);
 
-  nsIWidget* GetWidget() { return mWidget; }
-
   nsresult SetAbsoluteScreenPosition(nsIDOMElement* element,
                                      nsIDOMClientRect* position,
                                      nsIDOMClientRect* clip);
 
   void NotifyPluginReflowObservers();
 
   friend class nsPluginInstanceOwner;
   friend class nsDisplayPlugin;
@@ -348,18 +348,18 @@ public:
 
   NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)
 
   // Compute the desired position and clip region of the plugin's widget.
   // This will only be called for plugins which have been registered
   // with the root pres context for geometry updates.
   // The widget, its new position, size and clip region are appended as
   // a Configuration record to aConfigurations.
-  // If there is no widget associated with the plugin, this
-  // simply does nothing.
+  // If the plugin has no widget, no configuration is added, but
+  // the plugin visibility state may be adjusted.
   void GetWidgetConfiguration(nsDisplayListBuilder* aBuilder,
                               nsTArray<nsIWidget::Configuration>* aConfigurations);
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager)
   {
     return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder,
                                                            aManager, 
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/plugin-transform-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<embed type="application/x-test"></embed>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/plugin-transform-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<embed type="application/x-test" style="-moz-transform:scale(1)"></embed>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/plugin-transform-2-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<div style="width:100px; height:100px; -moz-transform-origin:top left;
+            -moz-transform:scale(2); background:rgb(0,255,0)"></embed>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/plugin-transform-2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<embed type="application/x-test" drawmode="solid" color="FF00FF00"
+       style="width:100px; height:100px; -moz-transform-origin:top left;
+              -moz-transform:scale(2); display:block"></embed>
+</body>
+</html>
--- a/modules/plugin/test/reftest/reftest.list
+++ b/modules/plugin/test/reftest/reftest.list
@@ -12,8 +12,10 @@ fails-if(!haveTestPlugin&&!Android) skip
 fails-if(!haveTestPlugin) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
 fails-if(!haveTestPlugin) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-1-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-2-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-5-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-10-step.html plugin-background-ref.html
+fails-if(!haveTestPlugin) == plugin-transform-1.html plugin-transform-1-ref.html
+fails-if(!haveTestPlugin) fails-if(http.platform=="X11") == plugin-transform-2.html plugin-transform-2-ref.html # bug 468496