()
| 21 | } |
| 22 | |
| 23 | function doReftest() { |
| 24 | if (reftestBlocked) return; |
| 25 | if (doReftest.done) return; |
| 26 | if (reportResultToServer.reported) return; |
| 27 | doReftest.done = true; |
| 28 | var img = new Image(); |
| 29 | img.onload = () => { |
| 30 | assert(img.width == Module['canvas'].width, `Invalid width: ${Module['canvas'].width}, should be ${img.width}`); |
| 31 | assert(img.height == Module['canvas'].height, `Invalid height: ${Module['canvas'].height}, should be ${img.height}`); |
| 32 | |
| 33 | var canvas = document.createElement('canvas'); |
| 34 | canvas.width = img.width; |
| 35 | canvas.height = img.height; |
| 36 | var ctx = canvas.getContext('2d'); |
| 37 | ctx.drawImage(img, 0, 0); |
| 38 | var expected = ctx.getImageData(0, 0, img.width, img.height).data; |
| 39 | |
| 40 | var actualUrl = Module['canvas'].toDataURL(); |
| 41 | var actualImage = new Image(); |
| 42 | actualImage.onload = () => { |
| 43 | /* |
| 44 | document.body.appendChild(img); // for comparisons |
| 45 | var div = document.createElement('div'); |
| 46 | div.innerHTML = '^=expected, v=actual'; |
| 47 | document.body.appendChild(div); |
| 48 | document.body.appendChild(actualImage); // to grab it for creating the test reference |
| 49 | */ |
| 50 | |
| 51 | var actualCanvas = document.createElement('canvas'); |
| 52 | actualCanvas.width = actualImage.width; |
| 53 | actualCanvas.height = actualImage.height; |
| 54 | var actualCtx = actualCanvas.getContext('2d'); |
| 55 | actualCtx.drawImage(actualImage, 0, 0); |
| 56 | var actual = actualCtx.getImageData(0, 0, actualImage.width, actualImage.height).data; |
| 57 | |
| 58 | // Allow each pixel R,G,B component to be off by a few units to account for possible shading |
| 59 | // differences between GPUs. |
| 60 | function dampenError(error) { |
| 61 | return Math.max(error-2, 0); |
| 62 | } |
| 63 | |
| 64 | var total = 0; |
| 65 | var width = img.width; |
| 66 | var height = img.height; |
| 67 | for (var x = 0; x < width; x++) { |
| 68 | for (var y = 0; y < height; y++) { |
| 69 | total += dampenError(Math.abs(expected[y*width*4 + x*4 + 0] - actual[y*width*4 + x*4 + 0])); |
| 70 | total += dampenError(Math.abs(expected[y*width*4 + x*4 + 1] - actual[y*width*4 + x*4 + 1])); |
| 71 | total += dampenError(Math.abs(expected[y*width*4 + x*4 + 2] - actual[y*width*4 + x*4 + 2])); |
| 72 | } |
| 73 | } |
| 74 | // floor, to allow some margin of error for antialiasing |
| 75 | var wrong = Math.floor(total / (img.width*img.height*3)); |
| 76 | if (wrong || reftestRebaseline) { |
| 77 | // Generate a png of the actual rendered image and send it back |
| 78 | // to the server. |
| 79 | Module['canvas'].toBlob((blob) => { |
| 80 | sendFileToServer('actual.png', blob); |
no test coverage detected