UNPKG

5.67 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _glShader = require("gl-shader");
8
9var _glShader2 = _interopRequireDefault(_glShader);
10
11var _performanceNow = require("performance-now");
12
13var _performanceNow2 = _interopRequireDefault(_performanceNow);
14
15function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17function colorMatches(actual, expected) {
18 var dr = actual[0] - expected[0];
19 var dg = actual[1] - expected[1];
20 var db = actual[2] - expected[2];
21 var da = actual[3] - expected[3];
22 // we need to be fuzzy because implementation precision can differ
23 return dr * dr + dg * dg + db * db + da * da < 10; // euclidian distance < sqrt(10)
24}
25
26var VERTEX_SHADER = "attribute vec2 _p;\nvarying vec2 uv;\nvoid main() {\ngl_Position = vec4(_p,0.0,1.0);\nuv = vec2(0.5, 0.5) * (_p+vec2(1.0, 1.0));\n}";
27
28exports.default = function (gl) {
29 var w = gl.drawingBufferWidth,
30 h = gl.drawingBufferHeight;
31
32 var pixels = new Uint8Array(w * h * 4);
33
34 function colorAt(x, y) {
35 var i = (x + y * w) * 4;
36 var r = pixels[i + 0];
37 var g = pixels[i + 1];
38 var b = pixels[i + 2];
39 var a = pixels[i + 3];
40 return [r, g, b, a];
41 }
42
43 var buffer = gl.createBuffer();
44 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
45 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 4, 4, -1]), // see a-big-triangle
46 gl.STATIC_DRAW);
47 gl.viewport(0, 0, w, h);
48
49 return function (glsl) {
50 var data = {
51 compileTime: 0,
52 drawTime: 0
53 };
54 var errors = [];
55 var shader = void 0;
56 try {
57 var beforeCompilation = (0, _performanceNow2.default)();
58 shader = (0, _glShader2.default)(gl, VERTEX_SHADER, "precision highp float;varying vec2 uv;uniform float progress, ratio;vec4 getFromColor (vec2 uv) { return vec4(uv, 0.0, 1.0); } vec4 getToColor (vec2 uv) { return vec4(uv, 1.0, 1.0); } " + glsl + "\n void main () {\n gl_FragColor = transition(uv);\n }");
59 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); // this is just to force trigger a flush
60 var afterCompilation = (0, _performanceNow2.default)();
61 data.compileTime = afterCompilation - beforeCompilation;
62
63 // We now will check the transition is correctly rendering the {from, to} images in progress={0, 1}
64 // leaving all transition params to default zero value should not affect a transition to "work"
65
66 shader.bind();
67 shader.attributes._p.pointer();
68 shader.uniforms.ratio = w / h;
69
70 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); // this is just to force trigger a flush
71 var beforeDraw1 = (0, _performanceNow2.default)();
72 shader.uniforms.progress = 0;
73 gl.drawArrays(gl.TRIANGLES, 0, 3);
74 gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels); // we need to put this in the scope because impl like Chrome are lazy and this really trigger the work.
75 var afterDraw1 = (0, _performanceNow2.default)();
76 var draw1matches = [colorMatches(colorAt(0, 0), [0, 0, 0, 255]), colorMatches(colorAt(w - 1, 0), [255, 0, 0, 255]), colorMatches(colorAt(0, h - 1), [0, 255, 0, 255]), colorMatches(colorAt(w - 1, h - 1), [255, 255, 0, 255])];
77
78 var beforeDraw2 = (0, _performanceNow2.default)();
79 shader.uniforms.progress = 1;
80 gl.drawArrays(gl.TRIANGLES, 0, 3);
81 gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
82 var afterDraw2 = (0, _performanceNow2.default)();
83 var draw2matches = [colorMatches(colorAt(0, 0), [0, 0, 255, 255]), colorMatches(colorAt(w - 1, 0), [255, 0, 255, 255]), colorMatches(colorAt(0, h - 1), [0, 255, 255, 255]), colorMatches(colorAt(w - 1, h - 1), [255, 255, 255, 255])];
84
85 var drawErrorMessages = [];
86 if (draw1matches.some(function (t) {
87 return !t;
88 })) {
89 drawErrorMessages.push("render getFromColor(uv) when progress=0.0");
90 }
91 if (draw2matches.some(function (t) {
92 return !t;
93 })) {
94 drawErrorMessages.push("render getToColor(uv) when progress=1.0");
95 }
96 if (drawErrorMessages.length > 0) {
97 errors.push({
98 code: "Transition_draw_invalid",
99 type: "error",
100 message: "invalid transition, it must: " + drawErrorMessages.join(", ")
101 });
102 }
103
104 var drawTime1 = afterDraw1 - beforeDraw1;
105 var drawTime2 = afterDraw2 - beforeDraw2;
106 // average of the 2 draws for even better precision
107 data.drawTime = (drawTime1 + drawTime2) / 2;
108 } catch (e) {
109 var error = void 0;
110 var lines = e.message.split("\n");
111 for (var _i = 0, _len = lines.length; _i < _len; _i++) {
112 var i = lines[_i];
113 if (i.substr(0, 5) === "ERROR") {
114 error = i;
115 }
116 }
117 if (!error) {
118 errors.push({
119 line: 0,
120 code: "WebGL_unknown_error",
121 type: "error",
122 message: "Unknown error: " + e.message
123 });
124 } else {
125 var details = error.split(":");
126 if (details.length < 4) {
127 errors.push({
128 line: 0,
129 code: "WebGL_error",
130 type: "error",
131 message: error
132 });
133 } else {
134 var lineStr = details[2];
135 var _line = parseInt(lineStr, 10);
136 if (isNaN(_line)) _line = 0;
137 var _message = details.splice(3).join(":");
138 errors.push({
139 line: _line,
140 code: "WebGL_error",
141 type: "error",
142 message: _message
143 });
144 }
145 }
146 } finally {
147 if (shader) shader.dispose();
148 }
149 return {
150 data: data,
151 errors: errors
152 };
153 };
154};
\No newline at end of file