Title: [170315] trunk/Source/WebCore
Revision
170315
Author
[email protected]
Date
2014-06-23 14:01:19 -0700 (Mon, 23 Jun 2014)

Log Message

Reduce synchronous layout triggered by _javascript_-based media controls
https://bugs.webkit.org/show_bug.cgi?id=134208

Patch by Joseph Pecoraro <[email protected]> on 2014-06-23
Reviewed by Eric Carlson.

Avoid always querying the offsetWidth and offsetHeight of the timeline
by only calculating these values when the timeline may change size.
Also avoid doing work in a few cases where properties did not
actually change.

* Modules/mediacontrols/mediaControlsApple.js:
(Controller):

(Controller.prototype.setNeedsTimelineMetricsUpdate):
(Controller.prototype.updateTimelineMetricsIfNeeded):
Only update the timeline metrics when they may have changed.

(Controller.prototype.updateControls):
(Controller.prototype.handleTimelineMouseMove):
(Controller.prototype.progressFillStyle):
(Controller.prototype.showControls):
(Controller.prototype.addControls):
Mark timeline metrics need update based on various UI changes.

(Controller.prototype.setStatusHidden):
Only do work if the hidden status changed.
Mark timeline metrics need update if the timeline is changed.

(Controller.prototype.updateProgress):
Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.

* Modules/mediacontrols/mediaControlsiOS.js:
(ControllerIOS):
(ControllerIOS.prototype.updateControls):

(ControllerIOS.prototype.updateProgress):
Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.

(ControllerIOS.prototype.handleWirelessPlaybackChange):
Mark timeline metrics need update as button may have changed.

(ControllerIOS.prototype.handleWirelessTargetAvailableChange):
Only do work if the availability changed.
Mark timeline metrics need update as a new button may have appeared.

(ControllerIOS.prototype.set pageScaleFactor):
Only do work if the page scale factor changed.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (170314 => 170315)


--- trunk/Source/WebCore/ChangeLog	2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/ChangeLog	2014-06-23 21:01:19 UTC (rev 170315)
@@ -1,3 +1,53 @@
+2014-06-23  Joseph Pecoraro  <[email protected]>
+
+        Reduce synchronous layout triggered by _javascript_-based media controls
+        https://bugs.webkit.org/show_bug.cgi?id=134208
+
+        Reviewed by Eric Carlson.
+
+        Avoid always querying the offsetWidth and offsetHeight of the timeline
+        by only calculating these values when the timeline may change size.
+        Also avoid doing work in a few cases where properties did not
+        actually change.
+
+        * Modules/mediacontrols/mediaControlsApple.js:
+        (Controller):
+
+        (Controller.prototype.setNeedsTimelineMetricsUpdate):
+        (Controller.prototype.updateTimelineMetricsIfNeeded):
+        Only update the timeline metrics when they may have changed.
+
+        (Controller.prototype.updateControls):
+        (Controller.prototype.handleTimelineMouseMove):
+        (Controller.prototype.progressFillStyle):
+        (Controller.prototype.showControls):
+        (Controller.prototype.addControls):
+        Mark timeline metrics need update based on various UI changes.
+
+        (Controller.prototype.setStatusHidden):
+        Only do work if the hidden status changed.
+        Mark timeline metrics need update if the timeline is changed.
+
+        (Controller.prototype.updateProgress):
+        Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.
+
+        * Modules/mediacontrols/mediaControlsiOS.js:
+        (ControllerIOS):
+        (ControllerIOS.prototype.updateControls):
+
+        (ControllerIOS.prototype.updateProgress):
+        Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.
+
+        (ControllerIOS.prototype.handleWirelessPlaybackChange):
+        Mark timeline metrics need update as button may have changed.
+
+        (ControllerIOS.prototype.handleWirelessTargetAvailableChange):
+        Only do work if the availability changed.
+        Mark timeline metrics need update as a new button may have appeared.
+
+        (ControllerIOS.prototype.set pageScaleFactor):
+        Only do work if the page scale factor changed.
+
 2014-06-23  Brady Eidson  <[email protected]>
 
         Add skeleton code for updated Gamepad API

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js (170314 => 170315)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js	2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js	2014-06-23 21:01:19 UTC (rev 170315)
@@ -11,6 +11,7 @@
     this.controls = {};
     this.listeners = {};
     this.isLive = false;
+    this.statusHidden = true;
 
     this.addVideoListeners();
     this.createBase();
@@ -250,6 +251,21 @@
         return this.video.controls || this.isFullScreen();
     },
 
+    setNeedsTimelineMetricsUpdate: function()
+    {
+        this.timelineMetricsNeedsUpdate = true;
+    },
+
+    updateTimelineMetricsIfNeeded: function()
+    {
+        if (this.timelineMetricsNeedsUpdate) {
+            this.timelineLeft = this.controls.timeline.offsetLeft;
+            this.timelineWidth = this.controls.timeline.offsetWidth;
+            this.timelineHeight = this.controls.timeline.offsetHeight;
+            this.timelineMetricsNeedsUpdate = false;
+        }
+    },
+
     updateBase: function()
     {
         if (this.shouldHaveAnyUI()) {
@@ -480,6 +496,7 @@
         else
             this.setControlsType(Controller.InlineControls);
 
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     updateStatusDisplay: function(event)
@@ -723,9 +740,10 @@
         if (this.controls.thumbnail.classList.contains(this.ClassNames.hidden))
             return;
 
+        this.updateTimelineMetricsIfNeeded();
         this.controls.thumbnail.classList.add(this.ClassNames.show);
         var localPoint = webkitConvertPointFromPageToNode(this.controls.timeline, new WebKitPoint(event.clientX, event.clientY));
-        var percent = (localPoint.x - this.controls.timeline.offsetLeft) / this.controls.timeline.offsetWidth;
+        var percent = (localPoint.x - this.timelineLeft) / this.timelineWidth;
         percent = Math.max(Math.min(1, percent), 0);
         this.controls.thumbnail.style.left = percent * 100 + '%';
 
@@ -897,7 +915,7 @@
 
     progressFillStyle: function(context)
     {
-        var height = this.controls.timeline.offsetHeight;
+        var height = this.timelineHeight;
         var gradient = context.createLinearGradient(0, 0, 0, height);
         gradient.addColorStop(0, 'rgb(2, 2, 2)');
         gradient.addColorStop(1, 'rgb(23, 23, 23)');
@@ -906,8 +924,11 @@
 
     updateProgress: function()
     {
-        var width = this.controls.timeline.offsetWidth;
-        var height = this.controls.timeline.offsetHeight;
+        this.updateTimelineMetricsIfNeeded();
+
+        var width = this.timelineWidth;
+        var height = this.timelineHeight;
+
         var context = document.getCSSCanvasContext('2d', 'timeline-' + this.timelineID, width, height);
         context.clearRect(0, 0, width, height);
 
@@ -970,6 +991,8 @@
     {
         this.controls.panel.classList.add(this.ClassNames.show);
         this.controls.panel.classList.remove(this.ClassNames.hidden);
+
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     hideControls: function()
@@ -992,6 +1015,7 @@
     addControls: function()
     {
         this.base.appendChild(this.controls.panel);
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     updateTime: function()
@@ -1010,11 +1034,17 @@
 
     setStatusHidden: function(hidden)
     {
+        if (this.statusHidden === hidden)
+            return;
+
+        this.statusHidden = hidden;
+
         if (hidden) {
             this.controls.statusDisplay.classList.add(this.ClassNames.hidden);
             this.controls.currentTime.classList.remove(this.ClassNames.hidden);
             this.controls.timeline.classList.remove(this.ClassNames.hidden);
             this.controls.remainingTime.classList.remove(this.ClassNames.hidden);
+            this.setNeedsTimelineMetricsUpdate();
         } else {
             this.controls.statusDisplay.classList.remove(this.ClassNames.hidden);
             this.controls.currentTime.classList.add(this.ClassNames.hidden);

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js (170314 => 170315)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js	2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js	2014-06-23 21:01:19 UTC (rev 170315)
@@ -11,6 +11,7 @@
 
     this.updateWirelessTargetAvailable();
     this.updateWirelessPlaybackStatus();
+    this.setNeedsTimelineMetricsUpdate();
 
     host.controlsDependOnPageScaleFactor = true;
 };
@@ -215,6 +216,7 @@
         else
             this.setControlsType(Controller.InlineControls);
 
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     updateTime: function() {
@@ -229,8 +231,8 @@
     updateProgress: function() {
         Controller.prototype.updateProgress.call(this);
 
-        var width = this.controls.timeline.offsetWidth;
-        var height = this.controls.timeline.offsetHeight;
+        var width = this.timelineWidth;
+        var height = this.timelineHeight;
 
         // Magic number, matching the value for ::-webkit-media-controls-timeline::-webkit-slider-thumb
         // in mediaControlsiOS.css. Since we cannot ask the thumb for its offsetWidth as it's in its own
@@ -389,11 +391,17 @@
 
     handleWirelessPlaybackChange: function(event) {
         this.updateWirelessPlaybackStatus();
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     handleWirelessTargetAvailableChange: function(event) {
-        this.hasWirelessPlaybackTargets = event.availability == "available";
+        var wirelessPlaybackTargetsAvailable = event.availability == "available";
+        if (this.hasWirelessPlaybackTargets === wirelessPlaybackTargetsAvailable)
+            return;
+
+        this.hasWirelessPlaybackTargets = wirelessPlaybackTargetsAvailable;
         this.updateWirelessTargetAvailable();
+        this.setNeedsTimelineMetricsUpdate();
     },
 
     handleWirelessPickerButtonTouchStart: function() {
@@ -416,6 +424,9 @@
     },
 
     set pageScaleFactor(newScaleFactor) {
+        if (this._pageScaleFactor === newScaleFactor)
+            return;
+
         this._pageScaleFactor = newScaleFactor;
 
         if (newScaleFactor) {
@@ -425,6 +436,7 @@
             if (this.controls.panel) {
                 this.controls.panel.style.width = (newScaleFactor * 100) + "%";
                 this.controls.panel.style.webkitTransform = scaleTransform;
+                this.setNeedsTimelineMetricsUpdate();
                 this.updateProgress();
             }
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to