Skip to content

Commit

Permalink
Clarify rounding behavior of out-of-bounds src rects for blitFramebuf…
Browse files Browse the repository at this point in the history
…fer. (KhronosGroup#3185)

Make conformance2/rendering/blitframebuffer-filter-outofbounds.html easier to read.
  • Loading branch information
kdashg authored Dec 4, 2020
1 parent 57477aa commit 568bf1e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,57 +72,51 @@

if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
// Blit read framebuffer to the image in draw framebuffer.
var test = [
var tests = [
// [srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1]
[-2, -2, 4, 4, 1, 1, 4, 4], // only src region is out-of-bounds, dst region has different width/height as src region.
[-2, -2, 4, 4, 1, 1, 7, 7], // only src region is out-of-bounds, dst region has the same width/height as src region.
[0, 0, 6, 6, 7, 7, 10, 10], // only dst region is out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.
[0, 0, 6, 6, 4, 4, 10, 10], // only dst region is out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.
[-2, -2, 4, 4, 7, 7, 10, 10], // both src and dst region are out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.
[-2, -2, 4, 4, 4, 4, 10, 10], // both src and dst region are out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.
[-2, -2, 4, 4, 2, 2, 10, 10], // both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 8] , and x or y equals to 4) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.
[-2, -2, 4, 4, 3, 3, 10, 10], // both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 7] , and x or y equals to 5) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.
[-2, -2, 4, 4, 10, 10, 2, 2], // both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [2, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.
[-2, -2, 4, 4, 10, 10, 3, 3], // both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [3, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the read sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.

{ args: [-2, -2, 4, 4, 1, 1, 4, 4], changedDstRect: [2, 2, 4, 4], desc: 'only src region is out-of-bounds, dst region has different width/height as src region.'},
{ args: [-2, -2, 4, 4, 1, 1, 7, 7], changedDstRect: [3, 3, 7, 7], desc: 'only src region is out-of-bounds, dst region has the same width/height as src region.'},
{ args: [0, 0, 6, 6, 7, 7, 10, 10], changedDstRect: [7, 7, 8, 8], desc: 'only dst region is out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'},
{ args: [0, 0, 6, 6, 4, 4, 10, 10], changedDstRect: [4, 4, 8, 8], desc: 'only dst region is out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'},
{ args: [-2, -2, 4, 4, 7, 7, 10, 10], changedDstRect: [8, 8, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'},
{ args: [-2, -2, 4, 4, 4, 4, 10, 10], changedDstRect: [6, 6, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'},
{ args: [-2, -2, 4, 4, 2, 2, 10, 10], changedDstRect: [2 + 2/6*8, 2 + 2/6*8, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 8] , and x or y equals to 4) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'},
{ args: [-2, -2, 4, 4, 3, 3, 10, 10], changedDstRect: [5, 5, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 7] , and x or y equals to 5) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'},
{ args: [-2, -2, 4, 4, 10, 10, 2, 2], changedDstRect: [2, 2, 7, 7], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [2, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'},
{ args: [-2, -2, 4, 4, 10, 10, 3, 3], changedDstRect: [3, 3, 8, 8], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [3, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the read sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'},
];

var realBlittedDstRegion = [
[2, 2, 4, 4],
[3, 3, 7, 7],
[7, 7, 8, 8],
[4, 4, 8, 8],
[8, 8, 8, 8],
[6, 6, 8, 8],
[5, 5, 8, 8],
[5, 5, 8, 8],
[2, 2, 7, 7],
[3, 3, 8, 8],
]
var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8);
var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8);

for (var i = 0; i < test.length; ++i) {
for (const test of tests) {
const args = test.args;
const changedDstRect = test.changedDstRect;
debug("");
debug("both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]");
debug("blitting from src region [" + test[i][0] + ", " + test[i][1] + ", " + test[i][2] + ", " + test[i][3] + "] to dst region [" + test[i][4] + ", " + test[i][5] + ", " + test[i][6] + ", " + test[i][7] + "]");
debug("Both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]");
debug(`Blitting from src region [${args.slice(0, 4)}] to dst region [${args.slice(4, 8)}]`);
debug(`Expects changed dst region of [${changedDstRect}]`);
debug(`Explaination: ${test.desc}`);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
gl.bindTexture(gl.TEXTURE_2D, tex_draw);
gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.blitFramebuffer(test[i][0], test[i][1], test[i][2], test[i][3], test[i][4], test[i][5], test[i][6], test[i][7], gl.COLOR_BUFFER_BIT, filter);
gl.blitFramebuffer(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], gl.COLOR_BUFFER_BIT, filter);

// Read pixels and check the correctness.
var pixels = new Uint8Array(size * size * 4);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels);


for (var ii = 0; ii < size; ++ii) {
for (var jj = 0; jj < size; ++jj) {
var loc = ii * size + jj;
var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];

var expectedColor = [0, 0, 0, 0];
if (ii >= realBlittedDstRegion[i][0] && ii < realBlittedDstRegion[i][2] && jj >= realBlittedDstRegion[i][1] && jj < realBlittedDstRegion[i][3]) {
if (ii >= changedDstRect[0] && ii < changedDstRect[2] && jj >= changedDstRect[1] && jj < changedDstRect[3]) {
expectedColor = [0x20, 0x20, 0x20, 0xff];

// We may need to covert the color space for pixels in blit region
Expand Down Expand Up @@ -163,6 +157,7 @@
var filters = [gl.LINEAR, gl.NEAREST];
for (var ii = 0; ii < filters.length; ++ii) {
blitframebuffer_filter_outofbounds(gl.RGBA8, gl.RGBA8, filters[ii]);
break;
blitframebuffer_filter_outofbounds(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii]);
blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii]);
blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii]);
Expand Down
3 changes: 1 addition & 2 deletions specs/latest/2.0/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1403,8 +1403,7 @@ <h4>Framebuffer objects</h4>
SAMPLE_BUFFERS for the draw framebuffer is zero, the samples corresponding to each pixel location in
the source are converted to a single sample before being written to the destination.<br><br>

For any source pixel lying outside the read framebuffer, the corresponding destination pixel remains
untouched.<br><br>
Any distination pixel who's center corresponds to a point outside the source buffer remain untouched.<br><br>

When blitting to the color attachment of the WebGL context's default back buffer, a context
created with <code>alpha:false</code> is considered to have internal
Expand Down

0 comments on commit 568bf1e

Please sign in to comment.