Add new benchmark tests.
[WebKit-https.git] / PerformanceTests / Animometer / tests / master / resources / image-data.js
1 (function() {
2
3 var ImageDataStage = Utilities.createSubclass(Stage,
4     function() {
5         Stage.call(this);
6
7         this.testElements = [];
8         this._offsetIndex = 0;
9     }, {
10
11     testImageSrc: './../resources/yin-yang.png',
12
13     initialize: function(benchmark)
14     {
15         Stage.prototype.initialize.call(this, benchmark);
16
17         var waitForLoad = new SimplePromise;
18         var img = new Image;
19
20         img.addEventListener('load', function onImageLoad(e) {
21             img.removeEventListener('load', onImageLoad);
22             waitForLoad.resolve(img);
23         });
24
25         img.src = this.testImageSrc;
26
27         waitForLoad.then(function(img) {
28             this.testImage = img;
29             this.testImageWidth = img.naturalWidth;
30             this.testImageHeight = img.naturalHeight;
31
32             this.diffuseXOffset = 4,
33             this.diffuseYOffset = this.testImageWidth * 4;
34
35             benchmark.readyPromise.resolve();
36         }.bind(this));
37     },
38
39     tune: function(count)
40     {
41         if (count == 0)
42             return;
43
44         if (count < 0) {
45             this._offsetIndex = Math.max(this._offsetIndex + count, 0);
46             for (var i = this._offsetIndex; i < this.testElements.length; ++i)
47                 this.testElements[i].style.visibility = "hidden";
48             return;
49         }
50
51         this._offsetIndex = this._offsetIndex + count;
52         var index = Math.min(this._offsetIndex, this.testElements.length);
53         for (var i = 0; i < index; ++i)
54             this.testElements[i].style.visibility = "";
55         if (this._offsetIndex <= this.testElements.length)
56             return;
57
58         index = this._offsetIndex - this.testElements.length;
59         for (var i = 0; i < index; ++i) {
60             var element = this._createTestElement();
61             this.testElements.push(element);
62             this.element.appendChild(element);
63         }
64     },
65
66     _createTestElement: function() {
67         var element = document.createElement('canvas');
68         element.width = this.testImageWidth;
69         element.height = this.testImageHeight;
70
71         var context = element.getContext("2d");
72
73         // Put draw image into the canvas
74         context.drawImage(this.testImage, 0, 0, this.testImageWidth, this.testImageHeight);
75
76         // randomize location
77         var left = Stage.randomInt(0, this.size.width - this.testImageWidth);
78         var top = Stage.randomInt(0, this.size.height - this.testImageHeight);
79
80         element.style.top = top + 'px';
81         element.style.left = left + 'px';
82         element.style.width = this.testImageWidth + 'px';
83         element.style.height = this.testImageHeight + 'px';
84
85         return element;
86     },
87
88     animate: function(timeDelta) {
89         for (var i = 0; i < this._offsetIndex; ++i) {
90             var context = this.testElements[i].getContext("2d");
91
92             // Get image data
93             var imageData = context.getImageData(0, 0, this.testImageWidth, this.testImageHeight);
94
95             var rgbaLen = 4,
96                 didDraw = false,
97                 neighborPixelIndex,
98                 dataLen = imageData.data.length;
99             for (var j = 0; j < dataLen; j += rgbaLen) {
100                 if (imageData.data[j + 3] === 0)
101                     continue;
102
103                 // get random neighboring pixel color
104                 neighborPixelIndex = this._getRandomNeighboringPixelIndex(j, dataLen);
105
106                 // Update the RGB data
107                 imageData.data[j] = imageData.data[neighborPixelIndex];
108                 imageData.data[j + 1] = imageData.data[neighborPixelIndex + 1];
109                 imageData.data[j + 2] = imageData.data[neighborPixelIndex + 2];
110                 imageData.data[j + 3] = Math.max(imageData.data[neighborPixelIndex + 3] - j % 10, 0);
111                 didDraw = true;
112             }
113
114             // Put the image data back into the canvas
115             context.putImageData(imageData, 0, 0);
116
117              // If it didn't draw restart
118             if (!didDraw)
119                 context.drawImage(this.testImage, 0, 0, this.testImageWidth, this.testImageHeight)
120         }
121     },
122
123     _getRandomNeighboringPixelIndex: function(pixelIdx, pixelArrayLength) {
124         var xOffset = Stage.randomInt(-1, 1),
125             yOffset = Stage.randomInt(-1, 1),
126             resultPixelIdx = pixelIdx;
127
128         // Add X to the result
129         resultPixelIdx += (this.diffuseXOffset * xOffset);
130         // Add Y to the result
131         resultPixelIdx += (this.diffuseYOffset * yOffset);
132
133         // Don't fall off the end of the image
134         if (resultPixelIdx > pixelArrayLength)
135             resultPixelIdx = pixelIdx;
136
137         // Don't fall off the beginning of the image
138         if (resultPixelIdx < 0)
139             resultPixelIdx = 0;
140
141         return resultPixelIdx;
142     },
143
144     complexity: function()
145     {
146         return this._offsetIndex;
147     }
148 });
149
150 var ImageDataBenchmark = Utilities.createSubclass(Benchmark,
151     function(options)
152     {
153         Benchmark.call(this, new ImageDataStage(), options);
154     }, {
155
156     waitUntilReady: function() {
157         this.readyPromise = new SimplePromise;
158         return this.readyPromise;
159     }
160 });
161
162 window.benchmarkClass = ImageDataBenchmark;
163
164 }());