Bug 1092842 - When setting cliprects on background color display items, don't shrink them to exclude opaque borders (unless there's nonzero border-radius). r=mattwoodrow, a=lmandel
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 12 Nov 2014 20:53:03 +1300
changeset 226056 19296c34b1ca
parent 226055 4ccd3e117f5d
child 226057 9e4c3c78fe01
push id4127
push userryanvm@gmail.com
push date2014-11-13 21:27 +0000
treeherdermozilla-beta@9e4c3c78fe01 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, lmandel
bugs1092842
milestone34.0
Bug 1092842 - When setting cliprects on background color display items, don't shrink them to exclude opaque borders (unless there's nonzero border-radius). r=mattwoodrow, a=lmandel By not excluding opaque borders from the display item cliprects, we produce a larger opaque area for opaque background items.
dom/plugins/test/mochitest/mochitest.ini
dom/plugins/test/mochitest/test_bug1092842.html
layout/base/nsDisplayList.cpp
--- a/dom/plugins/test/mochitest/mochitest.ini
+++ b/dom/plugins/test/mochitest/mochitest.ini
@@ -35,16 +35,17 @@ support-files =
 [test_bug784131.html]
 [test_bug813906.html]
 [test_bug852315.html]
 [test_bug854082.html]
 [test_bug863792.html]
 [test_bug967694.html]
 [test_bug985859.html]
 [test_bug986930.html]
+[test_bug1092842.html]
 [test_cocoa_focus.html]
 skip-if = toolkit != "cocoa"
 support-files = cocoa_focus.html
 [test_cocoa_window_focus.html]
 skip-if = toolkit != "cocoa"
 support-files = cocoa_window_focus.html
 [test_cookies.html]
 [test_copyText.html]
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/mochitest/test_bug1092842.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Bug 1092842</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<body onload="startTest()">
+  <script type="application/javascript;version=1.8">
+  SimpleTest.waitForExplicitFinish();
+  setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
+
+  var p = null;
+
+  function startTest() {
+    p = document.getElementById('theplugin');
+    if (!p.hasWidget()) {
+      todo(false, "This test is only relevant for windowed plugins");
+      SimpleTest.finish();
+      return;
+    }
+
+    // Wait for the plugin to have painted once.
+    var interval = setInterval(function() {
+      if (!p.getPaintCount())
+        return;
+
+      clearInterval(interval);
+      doTest();
+      SimpleTest.finish();
+    }, 100);
+  }
+
+  function doTest() {
+    is(p.getClipRegionRectCount(), 1, "getClipRegionRectCount should be a single rect");
+    is(p.getClipRegionRectEdge(0,2) - p.getClipRegionRectEdge(0,0), 100, "width of clip region rect");
+    is(p.getClipRegionRectEdge(0,3) - p.getClipRegionRectEdge(0,1), 26, "height of clip region rect");
+  }
+  </script>
+
+  <div style="position:fixed; z-index:1; left:0; right:0; top:0; height:100px; border-bottom:24px solid blue; background:pink; transform:translateZ(0)"></div>
+  <object id="theplugin" type="application/x-test" drawmode="solid" color="ff00ff00" wmode="window"
+          style="position:absolute; top:50px; left:0; width:100px; height:100px"></object>
+
+  <p id="display"></p>
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1865,37 +1865,46 @@ nsDisplayBackgroundImage::AppendBackgrou
   nscolor color;
   if (!nsCSSRendering::IsCanvasFrame(aFrame) && bg) {
     bool drawBackgroundImage;
     color =
       nsCSSRendering::DetermineBackgroundColor(presContext, bgSC, aFrame,
                                                drawBackgroundImage, drawBackgroundColor);
   }
 
-  bool hasInsetShadow = aFrame->StyleBorder()->mBoxShadow &&
-                        aFrame->StyleBorder()->mBoxShadow->HasShadowWithInset(true);
+  const nsStyleBorder* borderStyle = aFrame->StyleBorder();
+  bool hasInsetShadow = borderStyle->mBoxShadow &&
+                        borderStyle->mBoxShadow->HasShadowWithInset(true);
   bool willPaintBorder = !isThemed && !hasInsetShadow &&
-                         aFrame->StyleBorder()->HasBorder();
+                         borderStyle->HasBorder();
 
   nsPoint toRef = aBuilder->ToReferenceFrame(aFrame);
 
   // An auxiliary list is necessary in case we have background blending; if that
   // is the case, background items need to be wrapped by a blend container to
   // isolate blending to the background
   nsDisplayList bgItemList;
   // Even if we don't actually have a background color to paint, we may still need
   // to create an item for hit testing.
   if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) ||
       aBuilder->IsForEventDelivery()) {
-
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
     if (bg && !aBuilder->IsForEventDelivery()) {
+      // Disable the will-paint-border optimization for background
+      // colors with no border-radius. Enabling it for background colors
+      // doesn't help much (there are no tiling issues) and clipping the
+      // background breaks detection of the element's border-box being
+      // opaque. For nonzero border-radius we still need it because we
+      // want to inset the background if possible to avoid antialiasing
+      // artifacts along the rounded corners.
+      bool useWillPaintBorderOptimization = willPaintBorder &&
+          nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius);
       SetBackgroundClipRegion(clipState, aFrame, toRef,
                               bg->BottomLayer(),
-                              willPaintBorder);
+                              useWillPaintBorderOptimization);
     }
     bgItemList.AppendNewToTop(
         new (aBuilder) nsDisplayBackgroundColor(aBuilder, aFrame, bg,
                                                 drawBackgroundColor ? color : NS_RGBA(0, 0, 0, 0)));
   }
 
   if (isThemed) {
     nsITheme* theme = presContext->GetTheme();