Commit 5e2cbcad authored by Sunny Sachanandani's avatar Sunny Sachanandani Committed by Commit Bot

webgl: Fix webgl canvas flip y issue with "save as image"

When copying drawing buffer texture to canvas resource provider flip
vertically based on whether the resource provider's coordinate system
matches with the drawing buffer's.  Tested manually by simulating the
ChromeOS vertical flip state by overriding the flags in code.

Added a pixel test to simulate "save as image" functionality by using
toDataURL() which creates a snapshot of the canvas in a similar way.

Change-Id: I6e42ed6cf25ba0256294eb2859bbec8f93f94eca
Bug: 998661
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810023Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698719}
parent 0dd98c7f
<!DOCTYPE HTML>
<!-- READ BEFORE UPDATING:
If this test is updated make sure to increment the "revision" value of the
associated test in content/test/gpu/page_sets/pixel_tests.py. This will ensure
that the baseline images are regenerated on the next run.
-->
<html>
<head>
<meta name="viewport" content="initial-scale=1">
<title>WebGL Canvas Save/Copy Image Test</title>
<style type="text/css">
.nomargin {
margin: 0px auto;
}
</style>
<script>
let g_swapsBeforeAck = 15;
function waitForFinish()
{
if (g_swapsBeforeAck == 0) {
sendResult("SUCCESS");
} else {
g_swapsBeforeAck--;
window.requestAnimationFrame(waitForFinish);
}
}
function sendResult(status) {
if (domAutomationController) {
domAutomationController.send(status);
} else {
console.log(status);
}
}
function main()
{
let canvas = document.getElementById("c");
let gl = canvas.getContext("webgl");
if (!gl) {
sendResult("FAILURE", "WebGL context not supported");
return;
}
// Diagonally opposite green and blue box, over red box to test correctness
// w.r.t. to both vertical and horizontal flips.
gl.scissor(0, 0, 100, 100);
gl.enable(gl.SCISSOR_TEST);
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.scissor(0, 50, 50, 50);
gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.scissor(50, 0, 50, 50);
gl.clearColor(0, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
let dataURL = canvas.toDataURL();
let image = document.getElementById("i");
image.src = dataURL;
waitForFinish();
}
</script>
</head>
<body onload="main()" class="nomargin" style="display:inline-flex">
<canvas id="c" width="100" height="100" class="nomargin" style="background-color:black"></canvas>
<img id="i" width="100" height="100" class="nomargin" style="background-color:black">
</body>
</html>
......@@ -615,6 +615,64 @@ class PixelTestPages(object):
'color': [255, 0, 0],
},
]),
PixelTestPage(
'pixel_webgl_copy_image.html',
base_name + '_WebGLCopyImage',
test_rect=[0, 0, 200, 100],
revision=0, # Golden image revision is not used
tolerance=3,
expected_colors=[
{
'comment': 'canvas top left, green',
'location': [5, 5],
'size': [40, 40],
'color': [0, 255, 0],
},
{
'comment': 'canvas bottom right, blue',
'location': [55, 55],
'size': [40, 40],
'color': [0, 0, 255],
},
{
'comment': 'canvas top right, red',
'location': [55, 5],
'size': [40, 40],
'color': [255, 0, 0],
},
{
'comment': 'canvas bottom left, red',
'location': [5, 55],
'size': [40, 40],
'color': [255, 0, 0],
},
{
'comment': 'image top left, green',
'location': [105, 5],
'size': [40, 40],
'color': [0, 255, 0],
},
{
'comment': 'image bottom right, blue',
'location': [155, 55],
'size': [40, 40],
'color': [0, 0, 255],
},
{
'comment': 'image top right, red',
'location': [155, 5],
'size': [40, 40],
'color': [255, 0, 0],
},
{
'comment': 'image bottom left, red',
'location': [105, 55],
'size': [40, 40],
'color': [255, 0, 0],
},
]),
]
......
......@@ -1636,7 +1636,7 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
// CopyToPlatformTexture is done correctly. See crbug.com/794706.
gl->Flush();
bool flip_y = is_origin_top_left_ && !canvas()->LowLatencyEnabled();
bool flip_y = IsOriginTopLeft() != resource_provider->IsOriginTopLeft();
return drawing_buffer_->CopyToPlatformTexture(
gl, texture_target, texture_id, 0 /*texture LOD */, true, flip_y,
IntPoint(0, 0), IntRect(IntPoint(0, 0), drawing_buffer_->Size()),
......
......@@ -126,6 +126,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
const CanvasColorParams& ColorParams() const { return color_params_; }
void SetFilterQuality(SkFilterQuality quality) { filter_quality_ = quality; }
const IntSize& Size() const { return size_; }
bool IsOriginTopLeft() const { return is_origin_top_left_; }
virtual bool IsValid() const = 0;
virtual bool IsAccelerated() const = 0;
// Returns true if the resource can be used by the display compositor.
......@@ -196,7 +197,6 @@ class PLATFORM_EXPORT CanvasResourceProvider
return context_provider_wrapper_;
}
unsigned GetMSAASampleCount() const { return msaa_sample_count_; }
bool IsOriginTopLeft() const { return is_origin_top_left_; }
GrSurfaceOrigin GetGrSurfaceOrigin() const {
return is_origin_top_left_ ? kTopLeft_GrSurfaceOrigin
: kBottomLeft_GrSurfaceOrigin;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment