Bug 1387296 - Improve layerization and reduce invalidations in the tab bar. r?dao draft
authorMarkus Stange <mstange@themasta.com>
Mon, 14 Aug 2017 15:07:59 -0400
changeset 646019 47d7789d5e07843b865203d9dda66a372e292aff
parent 645464 2295210dcb650424a8ea9a29fb3a3420eb69fb4e
child 646987 3fdfd36619f9acdc35607228c12270eb9b230bca
push id73978
push userbmo:mstange@themasta.com
push dateMon, 14 Aug 2017 19:10:09 +0000
reviewersdao
bugs1387296
milestone57.0a1
Bug 1387296 - Improve layerization and reduce invalidations in the tab bar. r?dao MozReview-Commit-ID: H6UgWm4FNaZ
browser/base/content/tabbrowser.xml
browser/themes/shared/tabs.inc.css
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -7331,18 +7331,20 @@
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
     <content context="tabContextMenu">
       <xul:stack class="tab-stack" flex="1">
         <xul:vbox xbl:inherits="selected=visuallyselected,fadein"
                   class="tab-background">
-          <xul:hbox xbl:inherits="selected=visuallyselected"
-                    class="tab-line"/>
+          <xul:vbox class="tab-line-wrapper">
+            <xul:hbox xbl:inherits="selected=visuallyselected"
+                      class="tab-line"/>
+          </xul:vbox>
           <xul:spacer flex="1"/>
           <xul:hbox class="tab-bottom-line"/>
         </xul:vbox>
         <xul:hbox xbl:inherits="pinned,selected=visuallyselected,titlechanged,attention"
                   class="tab-content" align="center">
           <xul:image xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected"
                      class="tab-throbber"
                      role="presentation"
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -45,27 +45,31 @@
    the navigation toolbar. */
 .tabbrowser-tab[visuallyselected=true] {
   position: relative;
   z-index: 2;
 }
 
 .tab-content {
   padding: 0 9px;
+  /* Set pointer-events:none on this element in order to work around a problem
+     with layerization, see bug 1387296. */
+  pointer-events: none;
 }
 
 .tab-content[pinned] {
   padding: 0 12px;
 }
 
 .tab-throbber,
 .tab-icon-image,
 .tab-sharing-icon-overlay,
 .tab-icon-sound,
 .tab-close-button {
+  pointer-events: auto; /* counteract pointer-events: none on .tab-content */
   margin-top: 1px;
 }
 
 .tab-throbber,
 .tab-sharing-icon-overlay,
 .tab-icon-image {
   height: 16px;
   width: 16px;
@@ -292,16 +296,20 @@
   height: 2px;
 }
 
 /* Selected tab */
 
 .tab-background {
   border: 1px none transparent;
   background-clip: padding-box;
+  /* This element has a purely visual purpose and does not contain interactive
+     elements.
+     Set pointer-events: none in order to achieve better layerization. */
+  pointer-events: none;
 }
 
 #toolbar-menubar:not([autohide=true]) ~ #TabsToolbar > #tabbrowser-tabs > .tabbrowser-tab > .tab-stack > .tab-background {
   border-top-style: solid;
 }
 
 .tab-background[selected=true] {
   border-left-style: solid;
@@ -337,29 +345,38 @@
 .tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected=true]) {
   background-color: rgba(0,0,0,.1);
 }
 
 #TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected=true]) {
   background-color: rgba(255,255,255,.1);
 }
 
+.tab-line-wrapper {
+  /* Set overflow:hidden on this element so that the transform animation on
+     .tab-line does not cause unnecessary layers to be created during drawing.
+     This effectively tells layerization that .tab-line will never leave this
+     rectangle and that anything that does not intersect with this rectangle
+     can be merged into an existing layer under the tab line's layer. */
+  overflow: hidden;
+}
+
 .tab-line:not([selected=true]) {
   opacity: 0;
   transform: scaleX(0);
   transition: transform 250ms var(--animation-easing-function), opacity 250ms var(--animation-easing-function);
 }
 
-.tabbrowser-tab:hover > .tab-stack > .tab-background > .tab-line:not([selected=true]) {
+.tabbrowser-tab:hover > .tab-stack > .tab-background > .tab-line-wrapper > .tab-line:not([selected=true]) {
   background-color: rgba(0,0,0,.2);
   opacity: 1;
   transform: none;
 }
 
-#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab:hover > .tab-stack > .tab-background > .tab-line:not([selected=true]) {
+#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-tab:hover > .tab-stack > .tab-background > .tab-line-wrapper > .tab-line:not([selected=true]) {
   background-color: rgba(255,255,255,.2);
 }
 
 /* Pinned tabs */
 
 /* Pinned tab separators need position: absolute when positioned (during overflow). */
 #tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned]::before {
   height: 100%;