Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jit-test / tests / basic / createMandelSet.js
1 // |jit-test| slow;
2
3 // XXXbz I would dearly like to wrap it up into a function to avoid polluting
4 // the global scope, but the function ends up heavyweight, and then we lose on
5 // the jit.
6 load(libdir + "mandelbrot-results.js");
7 //function testMandelbrotAll() {
8   // Configuration options that affect which codepaths we follow.
9   var doImageData = true;
10   var avoidSparseArray = true;
11
12   // Control of iteration numbers and sizing.  We'll do
13   // scaler * colorNames.length iterations or so before deciding that we
14   // don't escape.
15   const scaler = 5;
16   const numRows = 600;
17   const numCols = 600;
18
19   const colorNames = [
20     "black",
21     "green",
22     "blue",
23     "red",
24     "purple",
25     "orange",
26     "cyan",
27     "yellow",
28     "magenta",
29     "brown",
30     "pink",
31     "chartreuse",
32     "darkorange",
33     "crimson",
34     "gray",
35     "deeppink",
36     "firebrick",
37     "lavender",
38     "lawngreen",
39     "lightsalmon",
40     "lime",
41     "goldenrod"
42   ];
43   const threshold = (colorNames.length - 1) * scaler;
44
45   // Now set up our colors
46   var colors = [];
47   // 3-part for loop (iterators buggy, we will add a separate test for them)
48   for (var colorNameIdx = 0; colorNameIdx < colorNames.length; ++colorNameIdx) {
49   //for (var colorNameIdx in colorNames) {
50     colorNameIdx = parseInt(colorNameIdx);
51     colors.push([colorNameIdx, colorNameIdx, colorNameIdx, 0]);
52   }
53
54   // Storage for our point data
55   var points;
56
57   var scratch = {};
58   var scratchZ = {};
59   function complexMult(a, b) {
60     var newr = a.r * b.r - a.i * b.i;
61     var newi = a.r * b.i + a.i * b.r;
62     scratch.r = newr;
63     scratch.i = newi;
64     return scratch;
65   }
66   function complexAdd(a, b) {
67     scratch.r = a.r + b.r;
68     scratch.i = a.i + b.i;
69     return scratch;
70   }
71   function abs(a) {
72     return Math.sqrt(a.r * a.r + a.i * a.i);
73   }
74
75   function escapeAbsDiff(normZ, absC) {
76     var absZ = Math.sqrt(normZ);
77     return normZ > absZ + absC;
78   }
79
80   function escapeNorm2(normZ) {
81     return normZ > 4;
82   }
83
84   function fuzzyColors(i) {
85     return Math.floor(i / scaler) + 1;
86   }
87
88   function moddedColors(i) {
89     return (i % (colorNames.length - 1)) + 1;
90   }
91
92   function computeEscapeSpeedObjects(real, imag) {
93     var c = { r: real, i: imag }
94     scratchZ.r = scratchZ.i = 0;
95     var absC = abs(c);
96     for (var i = 0; i < threshold; ++i) {
97       scratchZ = complexAdd(c, complexMult(scratchZ, scratchZ));
98       if (escape(scratchZ.r * scratchZ.r + scratchZ.i * scratchZ.i,
99                  absC)) {
100         return colorMap(i);
101       }
102     }
103     return 0;
104   }
105
106   function computeEscapeSpeedOneObject(real, imag) {
107     // fold in the fact that we start with 0
108     var r = real;
109     var i = imag;
110     var absC = abs({r: real, i: imag});
111     for (var j = 0; j < threshold; ++j) {
112       var r2 = r * r;
113       var i2 = i * i;
114       if (escape(r2 + i2, absC)) {
115         return colorMap(j);
116       }
117       i = 2 * r * i + imag;
118       r = r2 - i2 + real;
119     }
120     return 0;
121   }
122
123   function computeEscapeSpeedDoubles(real, imag) {
124     // fold in the fact that we start with 0
125     var r = real;
126     var i = imag;
127     var absC = Math.sqrt(real * real + imag * imag);
128     for (var j = 0; j < threshold; ++j) {
129       var r2 = r * r;
130       var i2 = i * i;
131       if (escape(r2 + i2, absC)) {
132         return colorMap(j);
133       }
134       i = 2 * r * i + imag;
135       r = r2 - i2 + real;
136     }
137     return 0;
138   }
139
140   var computeEscapeSpeed = computeEscapeSpeedDoubles;
141   var escape = escapeNorm2;
142   var colorMap = fuzzyColors;
143
144   function addPointOrig(pointArray, n, i, j) {
145     if (!points[n]) {
146       points[n] = [];
147       points[n].push([i, j, 1, 1]);
148     } else {
149       var point = points[n][points[n].length-1];
150       if (point[0] == i && point[1] == j - point[3]) {
151         ++point[3];
152       } else {
153         points[n].push([i, j, 1, 1]);
154       }
155     }
156   }
157
158   function addPointImagedata(pointArray, n, col, row) {
159     var slotIdx = ((row * numCols) + col) * 4;
160     pointArray[slotIdx] = colors[n][0];
161     pointArray[slotIdx+1] = colors[n][1];
162     pointArray[slotIdx+2] = colors[n][2];
163     pointArray[slotIdx+3] = colors[n][3];
164   }
165
166   function createMandelSet() {
167     var realRange = { min: -2.1, max: 1 };
168     var imagRange = { min: -1.5, max: 1.5 };
169
170     var addPoint;
171     if (doImageData) {
172       addPoint = addPointImagedata;
173       points = new Array(4*numCols*numRows);
174       if (avoidSparseArray) {
175         for (var idx = 0; idx < 4*numCols*numRows; ++idx) {
176           points[idx] = 0;
177         }
178       }
179     } else {
180       addPoint = addPointOrig;
181       points = [];
182     }
183     var realStep = (realRange.max - realRange.min)/numCols;
184     var imagStep = (imagRange.min - imagRange.max)/numRows;
185     for (var i = 0, curReal = realRange.min;
186          i < numCols;
187          ++i, curReal += realStep) {
188       for (var j = 0, curImag = imagRange.max;
189            j < numRows;
190            ++j, curImag += imagStep) {
191         var n = computeEscapeSpeed(curReal, curImag);
192         addPoint(points, n, i, j)
193       }
194     }
195     var result;
196     if (doImageData) {
197       if (colorMap == fuzzyColors) {
198         result = mandelbrotImageDataFuzzyResult;
199       } else {
200         result = mandelbrotImageDataModdedResult;
201       }
202     } else {
203       result = mandelbrotNoImageDataResult;
204     }
205     return points.toSource() == result;
206   }
207
208   const escapeTests = [ escapeAbsDiff ];
209   const colorMaps = [ fuzzyColors, moddedColors ];
210   const escapeComputations = [ computeEscapeSpeedObjects,
211                                computeEscapeSpeedOneObject,
212                                computeEscapeSpeedDoubles ];
213   // Test all possible escape-speed generation codepaths, using the
214   // imageData + sparse array avoidance storage.
215   doImageData = true;
216   avoidSparseArray = true;
217   for (var escapeIdx in escapeTests) {
218     escape = escapeTests[escapeIdx];
219     for (var colorMapIdx in colorMaps) {
220       colorMap = colorMaps[colorMapIdx];
221       for (var escapeComputationIdx in escapeComputations) {
222         computeEscapeSpeed = escapeComputations[escapeComputationIdx];
223         assertEq(createMandelSet(), true);
224       }
225     }
226   }
227
228   // Test all possible storage strategies. Note that we already tested
229   // doImageData == true with avoidSparseArray == true.
230   escape = escapeAbsDiff;
231   colorMap = fuzzyColors; // This part doesn't really matter too much here
232   computeEscapeSpeed = computeEscapeSpeedDoubles;
233
234   doImageData = true;
235   avoidSparseArray = false;
236   assertEq(createMandelSet(), true);
237
238   escape = escapeNorm2;
239   doImageData = false;  // avoidSparseArray doesn't matter here
240   assertEq(createMandelSet(), true);
241 //}
242 //testMandelbrotAll();