| /* |
| * Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| * for details. All rights reserved. Use of this source code is governed by a |
| * BSD-style license that can be found in the LICENSE file. |
| */ |
| /** |
| * @description |
| */ |
| import "dart:html"; |
| import "dart:web_gl" as wgl; |
| import 'dart:typed_data'; |
| import "../../../testcommon.dart"; |
| import "resources/webgl-test.dart"; |
| import "resources/webgl-test-utils.dart" as wtu; |
| import "../../../../Utils/async_utils.dart"; |
| |
| main() { |
| document.body.setInnerHtml(''' |
| <span id="description" style="color: white"> |
| This test checks for drawing webgl to canvas 2d. The test process is as follows: |
| 1. draw a green rect on a webgl context. |
| 2. draw a red rect on a canvas 2d context, and check a pixel (should be red). |
| 3. draw the webgl contents on the canvas 2d context, and check a pixel (should be green). |
| 4. wait for few frames. |
| 5. draw a red rect on the canvas 2d context, and check a pixel (should be red). |
| 6. draw the webgl contents on the canvas 2d context, and check a pixel (see below explanation). |
| |
| Above test is executed for both preserve and non-preserve webgl contexts. |
| For the preserve webgl context, the pixel on #6 is green. |
| For the non-preserve webgl context, the pixel on #6 is undefined.[1] |
| |
| [1] http://www.khronos.org/registry/webgl/specs/latest/1.0/. |
| "This default behavior can be changed by setting the preserveDrawingBuffer |
| attribute of the WebGLContextAttributes object. If this flag is true, the |
| contents of the drawing buffer shall be preserved until the author either clears |
| or overwrites them. If this flag is false, attempting to perform operations |
| using this context as a source image after the rendering function has returned |
| can lead to undefined behavior.". |
| </span> |
| <canvas id="preserve-canvas3d" width="100" height="100"></canvas> |
| <canvas id="preserve-canvas2d" width="100" height="100"></canvas> |
| <canvas id="nonpreserve-canvas3d" width="100" height="100"></canvas> |
| <canvas id="nonpreserve-canvas2d" width="100" height="100"></canvas> |
| ''', treeSanitizer: new NullTreeSanitizer()); |
| |
| var preserve_ctx2D; |
| var preserve_canvas3D; |
| var preserve_gl; |
| var nonpreserve_ctx2D; |
| var nonpreserve_canvas3D; |
| var nonpreserve_gl; |
| var imgdata; |
| |
| createContexts() { |
| preserve_ctx2D = getContext2d("preserve-canvas2d"); |
| preserve_canvas3D = document.getElementById('preserve-canvas3d'); |
| preserve_gl = preserve_canvas3D.getContext('webgl', {'preserveDrawingBuffer': true}); |
| nonpreserve_ctx2D = getContext2d("nonpreserve-canvas2d"); |
| nonpreserve_canvas3D = document.getElementById('nonpreserve-canvas3d'); |
| nonpreserve_gl = nonpreserve_canvas3D.getContext('webgl', {'preserveDrawingBuffer': false}); |
| } |
| |
| renderWebGL(gl) { |
| gl.clearColor(0, 1, 0, 1); |
| gl.clear(wgl.COLOR_BUFFER_BIT); |
| } |
| |
| drawWebGLToCanvas2D(ctx2D, canvas3D, isDrawingBufferUndefined) { |
| // draw red rect on canvas 2d. |
| ctx2D.fillStyle = 'red'; |
| ctx2D.fillRect(0, 0, 100, 100); |
| var imageData = ctx2D.getImageData(0, 0, 1, 1); |
| imgdata = imageData.data; |
| shouldBe(imgdata[0], 255); |
| shouldBe(imgdata[1], 0); |
| shouldBe(imgdata[2], 0); |
| |
| // draw the webgl contents (green rect) on the canvas 2d context. |
| ctx2D.drawImage(canvas3D, 0, 0); |
| ctx2D.getImageData(0, 0, 1, 1); |
| imageData = ctx2D.getImageData(0, 0, 1, 1); |
| imgdata = imageData.data; |
| if (isDrawingBufferUndefined) { |
| // Current implementation draws transparent texture on the canvas 2d context, |
| // although the spec said it leads to undefined behavior. |
| shouldBe(imgdata[0], 255); |
| shouldBe(imgdata[1], 0); |
| shouldBe(imgdata[2], 0); |
| } else { |
| shouldBe(imgdata[0], 0); |
| shouldBe(imgdata[1], 255); |
| shouldBe(imgdata[2], 0); |
| } |
| |
| if (isDrawingBufferUndefined) |
| asyncEnd(); |
| } |
| |
| // create both canvas 2d and webgl contexts. |
| createContexts(); |
| // prepare webgl contents. |
| renderWebGL(preserve_gl); |
| renderWebGL(nonpreserve_gl); |
| |
| debug("Check for drawing webgl to canvas 2d on the same frame."); |
| debug("1) when drawingBuffer is preserved."); |
| drawWebGLToCanvas2D(preserve_ctx2D, preserve_canvas3D, false); |
| debug("2) when drawingBuffer is not preserved."); |
| drawWebGLToCanvas2D(nonpreserve_ctx2D, nonpreserve_canvas3D, false); |
| |
| asyncStart(); |
| setTimeout(() { |
| debug("Check for drawing webgl to canvas 2d several frames after drawing webgl contents."); |
| debug("1) when drawingBuffer is preserved."); |
| drawWebGLToCanvas2D(preserve_ctx2D, preserve_canvas3D, false); |
| debug("2) when drawingBuffer is not preserved. It leads to undefined behavior."); |
| drawWebGLToCanvas2D(nonpreserve_ctx2D, nonpreserve_canvas3D, true); |
| }, 50); |
| } |