Add a new graphics test for CanvasRenderingContext2D functions: getImageData and...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Feb 2016 06:21:37 +0000 (06:21 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Feb 2016 06:21:37 +0000 (06:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151716

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2016-02-05
Reviewed by Darin Adler.

The purpose of this test is to measure the performance of getImageData
and putImageData functions. This test draws a background on the canvas
and then gets some random tiles from this background and draw them in
destinations different from their original sources.

* Animometer/resources/debug-runner/tests.js: Adding the new test to the canvas simple tests suite.

* Animometer/resources/extensions.js:
(Array.prototype.shuffle): Shuffles the elements of an array.

(Point.zero): Returns a new Point object whose x and y are equal zero.
(Point.prototype.str): Used for debugging the Point object.

* Animometer/tests/simple/resources/tiled-canvas-image.js: Added.
(CanvasImageTile):
(CanvasImageTile.prototype.getImageData):
(CanvasImageTile.prototype.putImageData):
(Stage.call.initialize):
(Stage.call._createTiles):
(Stage.call._nextTilePosition):
(Stage.call.tune):
(Stage.call._drawBackground):
(Stage.call.animate):
(Stage.call.complexity):
(Stage.call):
* Animometer/tests/simple/tiled-canvas-image.html: Added.

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

PerformanceTests/Animometer/resources/debug-runner/tests.js
PerformanceTests/Animometer/resources/extensions.js
PerformanceTests/Animometer/tests/simple/resources/tiled-canvas-image.js [new file with mode: 0644]
PerformanceTests/Animometer/tests/simple/tiled-canvas-image.html [new file with mode: 0644]
PerformanceTests/ChangeLog

index f5497105d2d9b46e3c88561a7bf084d2379ff95d..d362d35e020a72ca7ff44264165eb5f9f0bd376b 100644 (file)
@@ -235,7 +235,11 @@ Suites.push(new Suite("Basic canvas path suite",
         {
             url: "simple/simple-canvas-paths.html?pathType=rectFill",
             name: "Canvas rects, fill"
-        }
+        },
+        {
+            url: "simple/tiled-canvas-image.html",
+            name: "Canvas put/get image data"
+        },
     ]
 ));
 
index 7a24545d8fb2b6e5ed7ac66406768cdc45b678a7..6d9ebe57be75b331651a62e1e2331f26f0c2d434 100644 (file)
@@ -48,12 +48,26 @@ if (!Array.prototype.find) {
     };
 }
 
+Array.prototype.shuffle = function()
+{
+    for (var index = this.length - 1; index >= 0; --index) {
+        var randomIndex = Math.floor(Math.random() * (index + 1));
+        this.swap(index, randomIndex);
+    }
+    return this;
+}
+
 function Point(x, y)
 {
     this.x = x;
     this.y = y;
 }
 
+Point.zero = function()
+{
+    return new Point(0, 0);
+}
+
 Point.pointOnCircle = function(angle, radius)
 {
     return new Point(radius * Math.cos(angle), radius * Math.sin(angle));
@@ -90,6 +104,11 @@ Point.prototype =
         return new Point(this.x / 2, this.y / 2);
     },
 
+    str: function()
+    {
+        return "x = " + this.x + ", y = " + this.y;
+    },
+    
     add: function(other)
     {
         if(isNaN(other.x))
diff --git a/PerformanceTests/Animometer/tests/simple/resources/tiled-canvas-image.js b/PerformanceTests/Animometer/tests/simple/resources/tiled-canvas-image.js
new file mode 100644 (file)
index 0000000..61dd5ea
--- /dev/null
@@ -0,0 +1,119 @@
+(function() {
+
+function CanvasImageTile(stage, source)
+{
+    this._context = stage.context;
+    this._size = stage.tileSize;
+    this.source = source;
+}
+
+CanvasImageTile.prototype.getImageData = function()
+{
+    this._imagedata = this._context.getImageData(this.source.x, this.source.y, this._size.width, this._size.height);
+}
+
+CanvasImageTile.prototype.putImageData = function(destination)
+{
+    this._context.putImageData(this._imagedata, destination.x, destination.y);
+}
+
+TiledCanvasImageStage = Utilities.createSubclass(Stage,
+    function(element, options)
+    {
+        Stage.call(this);
+    }, {
+
+    initialize: function(benchmark)
+    {
+        Stage.prototype.initialize.call(this, benchmark);
+        this.context = this.element.getContext("2d");
+        this._setupTiles();
+    },
+
+    _setupTiles: function()
+    {
+        const maxTilesPerRow = 50;
+        const maxTilesPerCol = 50;
+
+        this.tileSize = this.size.multiply(new Point(1 / maxTilesPerRow, 1 / maxTilesPerCol));
+
+        this._tiles = new Array(maxTilesPerRow * maxTilesPerCol);
+
+        var source = Point.zero();
+        for (var index = 0; index < this._tiles.length; ++index) {
+            this._tiles[index] = new CanvasImageTile(this, source);
+            source = this._nextTilePosition(source);
+        }
+
+        this._ctiles = 0;
+    },
+
+    _nextTilePosition: function(destination)
+    {
+        var next = destination.add(this.tileSize);
+
+        if (next.x >= this._size.width)
+            return new Point(0, next.y >= this._size.height ? 0 : next.y);
+
+        return new Point(next.x, destination.y);
+    },
+
+    tune: function(count)
+    {
+        this._ctiles += count;
+
+        this._ctiles = Math.max(this._ctiles, 0);    
+        this._ctiles = Math.min(this._ctiles, this._tiles.length);
+
+        return this._ctiles;
+    },
+
+    _drawBackground: function()
+    {
+        var size = this._benchmark._stage.size;
+        var gradient = this.context.createLinearGradient(0, 0, size.width, 0);
+        gradient.addColorStop(0, "red");
+        gradient.addColorStop(1, "white");
+        this.context.save();
+            this.context.fillStyle = gradient;
+            this.context.fillRect(0, 0, size.width, size.height);
+        this.context.restore();
+    },
+
+    animate: function(timeDelta)
+    {
+        this._drawBackground();
+
+        if (!this._ctiles)
+            return;
+
+        this._tiles.shuffle();
+
+        var destinations = new Array(this._ctiles);
+        for (var index = 0; index < this._ctiles; ++index) {
+            this._tiles[index].getImageData();
+            destinations[index] = this._tiles[index].source;
+        }
+
+        destinations.shuffle();
+
+        for (var index = 0; index < this._ctiles; ++index)
+            this._tiles[index].putImageData(destinations[index]);
+    },
+    
+    complexity: function()
+    {
+        return this._ctiles;
+    }
+});
+
+TiledCanvasImageBenchmark = Utilities.createSubclass(Benchmark,
+    function(options)
+    {
+        Benchmark.call(this, new TiledCanvasImageStage(), options);
+    }
+);
+
+window.benchmarkClass = TiledCanvasImageBenchmark;
+
+})();
diff --git a/PerformanceTests/Animometer/tests/simple/tiled-canvas-image.html b/PerformanceTests/Animometer/tests/simple/tiled-canvas-image.html
new file mode 100644 (file)
index 0000000..5c5b4c8
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <link rel="stylesheet" type="text/css" href="../resources/stage.css">
+</head>
+<body>
+    <canvas id="stage"></canvas>
+    <script src="../../resources/strings.js"></script>
+    <script src="../../resources/extensions.js"></script>
+    <script src="../resources/algorithm.js"></script>
+    <script src="../resources/sampler.js"></script>
+    <script src="../resources/math.js"></script>
+    <script src="../resources/main.js"></script>
+    <script src="resources/tiled-canvas-image.js"></script>
+</body>
+</html>
index c171a07ea65f5ea9eef5cb2d9ab95a4e5edfdbfc..fcacdd45fc844c199c3dc023e60f56974bf84d2e 100644 (file)
@@ -1,3 +1,37 @@
+2016-02-05  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Add a new graphics test for CanvasRenderingContext2D functions: getImageData and putImageData
+        https://bugs.webkit.org/show_bug.cgi?id=151716
+
+        Reviewed by Darin Adler.
+
+        The purpose of this test is to measure the performance of getImageData
+        and putImageData functions. This test draws a background on the canvas
+        and then gets some random tiles from this background and draw them in
+        destinations different from their original sources.
+        
+        * Animometer/resources/debug-runner/tests.js: Adding the new test to the canvas simple tests suite.
+        
+        * Animometer/resources/extensions.js:
+        (Array.prototype.shuffle): Shuffles the elements of an array.
+        
+        (Point.zero): Returns a new Point object whose x and y are equal zero.
+        (Point.prototype.str): Used for debugging the Point object.
+        
+        * Animometer/tests/simple/resources/tiled-canvas-image.js: Added.
+        (CanvasImageTile):
+        (CanvasImageTile.prototype.getImageData):
+        (CanvasImageTile.prototype.putImageData):
+        (Stage.call.initialize):
+        (Stage.call._createTiles):
+        (Stage.call._nextTilePosition):
+        (Stage.call.tune):
+        (Stage.call._drawBackground):
+        (Stage.call.animate):
+        (Stage.call.complexity):
+        (Stage.call):
+        * Animometer/tests/simple/tiled-canvas-image.html: Added.
+
 2016-01-07  Jon Lee  <jonlee@apple.com>
 
         Fix new test.