Skip to content

Commit

Permalink
Fixing bug with segfaulting TransferFromImageBitmap(null)
Browse files Browse the repository at this point in the history
There was an issue with OffscreenCanvas created from transferring
control from a onscreen canvas, and using a BitmapRenderer context
with the TransferFromImageBitmap(null).

According to the standard TransferFromImageBitmap(null) has to reset the
internal bitmap and create a black transparent one.
https://html.spec.whatwg.org/multipage/canvas.html#the-imagebitmaprenderingcontext-interface

This CL also adds new tests, and fixes some issues with naming in the
tests.

This CL also moves a method that should have been protected and not
public in the first place.

Bug: 1188892
Change-Id: I79f5487c99618fa0bbaf8c436b710766f82ce657
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2785425
Reviewed-by: Juanmi Huertas <[email protected]>
Reviewed-by: Yi Xu <[email protected]>
Commit-Queue: Juanmi Huertas <[email protected]>
Auto-Submit: Juanmi Huertas <[email protected]>
Cr-Commit-Position: refs/heads/master@{#867359}
  • Loading branch information
Juanmihd authored and chromium-wpt-export-bot committed Mar 30, 2021
1 parent d8e2f73 commit 5dacd60
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Canvas's ImageBitmapRenderingContext test</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context">
<script>
var width = 10;
var height = 10;

function testCanvas(ctx, r, g, b, a)
{
var color = ctx.getImageData(5, 5, 1, 1).data;
assert_array_equals(color, [r, g, b, a]);
}

promise_test(function() {
function transferFromImageBitmapToBlobOffscreen(greenImage) {
var bitmapCanvas = document.createElement('canvas');
bitmapCanvas.width = width;
bitmapCanvas.height = height;
var offscreenCanvas = bitmapCanvas.transferControlToOffscreen();
var bitmapCtx = offscreenCanvas.getContext('bitmaprenderer');
bitmapCtx.transferFromImageBitmap(greenImage);

return offscreenCanvas.convertToBlob();
}

function drawBlobToCanvas(blob) {
// Make sure the bitmap renderer canvas is filled correctly.
var pngImage = new Image();
var myCanvasToTest = document.createElement('canvas');
myCanvasToTest.width = width;
myCanvasToTest.height = height;

// Wait for the blob img to load.
return new Promise(function(resolve) {
pngImage.src = URL.createObjectURL(blob);
pngImage.onload = function() {
var myCtxToTest = myCanvasToTest.getContext('2d');
myCtxToTest.drawImage(pngImage, 0, 0);
resolve(myCtxToTest);
};
});
}

var greenCanvas = document.createElement('canvas');
greenCanvas.width = width;
greenCanvas.height = height;
var greenCtx = greenCanvas.getContext('2d');
greenCtx.fillStyle = '#0f0';
greenCtx.fillRect(0, 0, width, height);

return createImageBitmap(greenCanvas).then(
greenImage => transferFromImageBitmapToBlobOffscreen(greenImage)
).then(
blob => drawBlobToCanvas(blob)
).then(
ctx => testCanvas(ctx, 0, 255, 0, 255)
);
},'Test that convertToBlob works and produce the expected image');

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Canvas's ImageBitmapRenderingContext test</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context">
<script>
var width = 10;
var height = 10;

function testCanvas(bitmapCanvas, r, g, b, a)
{
var myCanvas = document.createElement('canvas');
myCanvas.width = width;
myCanvas.height = height;
var myCtx = myCanvas.getContext('2d');
myCtx.drawImage(bitmapCanvas, 0, 0);
var color = myCtx.getImageData(5, 5, 1, 1).data;
assert_array_equals(color, [r, g, b, a]);
}

promise_test(function() {
function testTransferFromImageBitmapNullability(greenImage) {
var bitmapCanvas = document.createElement('canvas');
bitmapCanvas.width = width;
bitmapCanvas.height = height;
var offscreenCanvas = bitmapCanvas.transferControlToOffscreen();
var bitmapCtx = offscreenCanvas.getContext('bitmaprenderer');
bitmapCtx.transferFromImageBitmap(greenImage);

// Make sure the bitmap renderer canvas is filled correctly.
var myCanvas = document.createElement('canvas');
var myCtx = myCanvas.getContext('bitmaprenderer');
myCtx.transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
testCanvas(myCanvas, 0, 255, 0, 255);

// Test that after transfering for second time to ImageBitmap produces
// a black bitmap of the same size
var myCanvas2 = document.createElement('canvas');
var myCtx2 = myCanvas2.getContext('bitmaprenderer');
myCtx2.transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
testCanvas(myCanvas2, 0, 0, 0, 0);
}

var greenCanvas = document.createElement('canvas');
greenCanvas.width = width;
greenCanvas.height = height;
var greenCtx = greenCanvas.getContext('2d');
greenCtx.fillStyle = '#0f0';
greenCtx.fillRect(0, 0, width, height);

return Promise.all([
createImageBitmap(greenCanvas),
]).then(([greenImage]) => {
testTransferFromImageBitmapNullability(greenImage);
});
},'Test that transferToImageBitmap works and that resets the imagebitmap to black');

</script>
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
bitmapCanvas.width = width;
bitmapCanvas.height = height;
var bitmapCtx = bitmapCanvas.getContext('bitmaprenderer');
bitmapCtx.transferFromImageBitmap(greenImage);

// Make sure the bitmap renderer canvas is filled correctly.
bitmapCtx.transferFromImageBitmap(greenImage);
testCanvas(bitmapCanvas, 0, 255, 0, 255);

// Test if passing null resets the bitmap renderer canvas.
Expand Down

0 comments on commit 5dacd60

Please sign in to comment.