Bug 1657771 - Implement scaling and flipping for SwCompositor. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D86500
This commit is contained in:
Matt Woodrow 2020-08-11 04:46:31 +00:00
Родитель f58b056b55
Коммит 6c1b2412c5
5 изменённых файлов: 201 добавлений и 102 удалений

Просмотреть файл

@ -44,16 +44,14 @@ skip-if(Android) == webgl-capturestream-test.html?preserve wrapper.html?green.pn
# Does we draw the correct colors in the correct places?
# Combinations: PowerSet([readback, aa, preserve, premult, alpha]) x [frame=1,frame=6]
# This is 2^6 = 64 combinations.
#
# These currently fail with SWGL - Bug 1657771
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&__&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&__&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
@ -63,14 +61,14 @@ skip-if(Android)
skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&__&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) fails-if(swgl) == webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&__&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
@ -80,14 +78,14 @@ skip-if(Android)
skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
@ -97,14 +95,14 @@ fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender)
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) fails-if(swgl) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(0-1,0-30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11&&!webrender) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png

Просмотреть файл

@ -110,10 +110,10 @@ impl SwTile {
surface: &SwSurface,
transform: &CompositorSurfaceTransform,
clip_rect: &DeviceIntRect,
) -> Option<(DeviceIntRect, DeviceIntRect)> {
) -> Option<(DeviceIntRect, DeviceIntRect, bool)> {
let valid = self.valid_rect.translate(self.origin(surface).to_vector());
let valid = transform.transform_rect(&valid.to_f32().cast_unit()).unwrap().round_out().to_i32();
valid.cast_unit().intersection(clip_rect).map(|r| (r.translate(-valid.origin.to_vector().cast_unit()), r))
valid.cast_unit().intersection(clip_rect).map(|r| (r.translate(-valid.origin.to_vector().cast_unit()), r, transform.m22 < 0.0))
}
}
@ -245,6 +245,7 @@ impl DrawTileHelper {
src: &DeviceIntRect,
surface: &SwSurface,
tile: &SwTile,
flip_y: bool,
) {
let dx = dest.origin.x as f32 / viewport.size.width as f32;
let dy = dest.origin.y as f32 / viewport.size.height as f32;
@ -258,12 +259,12 @@ impl DrawTileHelper {
0.0,
0.0,
0.0,
-2.0 * dh,
if flip_y { 2.0 * dh } else { -2.0 * dh },
0.0,
-1.0 + 2.0 * dx,
1.0 - 2.0 * dy,
if flip_y { -1.0 + 2.0 * dy } else { 1.0 - 2.0 * dy },
1.0,
],
],
);
let sx = src.origin.x as f32 / surface.tile_size.width as f32;
let sy = src.origin.y as f32 / surface.tile_size.height as f32;
@ -271,6 +272,7 @@ impl DrawTileHelper {
let sh = src.size.height as f32 / surface.tile_size.height as f32;
self.gl
.uniform_matrix_3fv(self.tex_matrix_loc, false, &[sw, 0.0, 0.0, 0.0, sh, 0.0, sx, sy, 1.0]);
self.gl.bind_texture(gl::TEXTURE_2D, tile.tex_id);
self.gl.draw_arrays(gl::TRIANGLE_STRIP, 0, 4);
}
@ -289,8 +291,9 @@ struct SwCompositeJob {
/// Locked framebuffer that may be shared among many jobs
locked_dst: swgl::LockedResource,
src_rect: DeviceIntRect,
dst_offset: DeviceIntPoint,
dst_rect: DeviceIntRect,
opaque: bool,
flip_y: bool,
}
/// The SwComposite thread processes a queue of composite jobs, also signaling
@ -336,10 +339,12 @@ impl SwCompositeThread {
job.src_rect.origin.y,
job.src_rect.size.width,
job.src_rect.size.height,
job.dst_offset.x,
job.dst_offset.y,
job.dst_rect.origin.x,
job.dst_rect.origin.y,
job.dst_rect.size.width,
job.dst_rect.size.height,
job.opaque,
false,
job.flip_y,
);
// Release locked resources before modifying job count
drop(job);
@ -365,6 +370,7 @@ impl SwCompositeThread {
src_rect: DeviceIntRect,
dst_rect: DeviceIntRect,
opaque: bool,
flip_y: bool,
) {
// There are still tile updates happening, so send the job to the SwComposite thread.
*self.job_count.lock().unwrap() += 1;
@ -373,8 +379,9 @@ impl SwCompositeThread {
locked_src,
locked_dst,
src_rect,
dst_offset: dst_rect.origin,
dst_rect,
opaque,
flip_y,
})
.expect("Failing queuing SwComposite job");
}
@ -515,10 +522,10 @@ impl SwCompositor {
tile: &SwTile,
) {
if let Some(ref composite_thread) = self.composite_thread {
if let Some((src_rect, dst_rect)) = tile.composite_rects(surface, transform, clip_rect) {
if let Some((src_rect, dst_rect, flip_y)) = tile.composite_rects(surface, transform, clip_rect) {
if let Some(texture) = self.gl.lock_texture(tile.color_id) {
let framebuffer = self.locked_framebuffer.clone().unwrap();
composite_thread.queue_composite(texture, framebuffer, src_rect, dst_rect, surface.is_opaque);
composite_thread.queue_composite(texture, framebuffer, src_rect, dst_rect, surface.is_opaque, flip_y);
}
}
}
@ -937,7 +944,7 @@ impl Compositor for SwCompositor {
let viewport = dirty.translate(info.origin.to_vector());
let draw_tile = self.draw_tile.as_ref().unwrap();
draw_tile.enable(&viewport);
draw_tile.draw(&viewport, &viewport, &dirty, &surface, &tile);
draw_tile.draw(&viewport, &viewport, &dirty, &surface, &tile, false);
draw_tile.disable();
native_gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, 0);
@ -1001,8 +1008,8 @@ impl Compositor for SwCompositor {
blend = true;
}
for tile in &surface.tiles {
if let Some((src_rect, dst_rect)) = tile.composite_rects(surface, transform, clip_rect) {
draw_tile.draw(&viewport, &dst_rect, &src_rect, surface, tile);
if let Some((src_rect, dst_rect, flip_y)) = tile.composite_rects(surface, transform, clip_rect) {
draw_tile.draw(&viewport, &dst_rect, &src_rect, surface, tile, flip_y);
}
}
}

Просмотреть файл

@ -3863,8 +3863,9 @@ static void scale_blit(Texture& srctex, const IntRect& srcReq, int srcZ,
}
}
static void linear_row(uint32_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset, sampler2DArray sampler) {
static void linear_row_blit(uint32_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset,
sampler2DArray sampler) {
vec2 uv = init_interp(srcUV, vec2_scalar(srcDU, 0.0f));
for (; span >= 4; span -= 4) {
auto srcpx = textureLinearPackedRGBA8(sampler, ivec2(uv), srcZOffset);
@ -3880,8 +3881,9 @@ static void linear_row(uint32_t* dest, int span, const vec2_scalar& srcUV,
}
}
static void linear_row(uint8_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset, sampler2DArray sampler) {
static void linear_row_blit(uint8_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset,
sampler2DArray sampler) {
vec2 uv = init_interp(srcUV, vec2_scalar(srcDU, 0.0f));
for (; span >= 4; span -= 4) {
auto srcpx = textureLinearPackedR8(sampler, ivec2(uv), srcZOffset);
@ -3897,8 +3899,9 @@ static void linear_row(uint8_t* dest, int span, const vec2_scalar& srcUV,
}
}
static void linear_row(uint16_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset, sampler2DArray sampler) {
static void linear_row_blit(uint16_t* dest, int span, const vec2_scalar& srcUV,
float srcDU, int srcZOffset,
sampler2DArray sampler) {
vec2 uv = init_interp(srcUV, vec2_scalar(srcDU, 0.0f));
for (; span >= 4; span -= 4) {
auto srcpx = textureLinearPackedRG8(sampler, ivec2(uv), srcZOffset);
@ -3952,15 +3955,16 @@ static void linear_blit(Texture& srctex, const IntRect& srcReq, int srcZ,
for (int rows = dstBounds.height(); rows > 0; rows--) {
switch (bpp) {
case 1:
linear_row((uint8_t*)dest, span, srcUV, srcDUV.x, srcZOffset, &sampler);
linear_row_blit((uint8_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
break;
case 2:
linear_row((uint16_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
linear_row_blit((uint16_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
break;
case 4:
linear_row((uint32_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
linear_row_blit((uint32_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
break;
default:
assert(false);
@ -3971,6 +3975,76 @@ static void linear_blit(Texture& srctex, const IntRect& srcReq, int srcZ,
}
}
static void linear_row_composite(uint32_t* dest, int span,
const vec2_scalar& srcUV, float srcDU,
int srcZOffset, sampler2DArray sampler) {
vec2 uv = init_interp(srcUV, vec2_scalar(srcDU, 0.0f));
for (; span >= 4; span -= 4) {
WideRGBA8 srcpx =
textureLinearUnpackedRGBA8(sampler, ivec2(uv), srcZOffset);
WideRGBA8 dstpx = unpack(unaligned_load<PackedRGBA8>(dest));
PackedRGBA8 r = pack(srcpx + dstpx - muldiv255(dstpx, alphas(srcpx)));
unaligned_store(dest, r);
dest += 4;
uv.x += 4 * srcDU;
}
if (span > 0) {
WideRGBA8 srcpx =
textureLinearUnpackedRGBA8(sampler, ivec2(uv), srcZOffset);
PackedRGBA8 dstpx = unaligned_load<PackedRGBA8>(dest);
WideRGBA8 dstpxu = unpack(dstpx);
PackedRGBA8 r = pack(srcpx + dstpxu - muldiv255(dstpxu, alphas(srcpx)));
auto mask = span_mask_RGBA8(span);
unaligned_store(dest, (mask & dstpx) | (~mask & r));
}
}
static void linear_composite(Texture& srctex, const IntRect& srcReq, int srcZ,
Texture& dsttex, const IntRect& dstReq, int dstZ,
bool invertY) {
assert(srctex.internal_format == GL_RGBA8 ||
srctex.internal_format == GL_R8 || srctex.internal_format == GL_RG8);
// Compute valid dest bounds
IntRect dstBounds = dsttex.sample_bounds(dstReq, invertY);
// Check if sampling bounds are empty
if (dstBounds.is_empty()) {
return;
}
// Initialize sampler for source texture
sampler2DArray_impl sampler;
init_sampler(&sampler, srctex);
init_depth(&sampler, srctex);
sampler.filter = TextureFilter::LINEAR;
// Compute source UVs
int srcZOffset = srcZ * sampler.height_stride;
vec2_scalar srcUV(srcReq.x0, srcReq.y0);
vec2_scalar srcDUV(float(srcReq.width()) / dstReq.width(),
float(srcReq.height()) / dstReq.height());
// Skip to clamped source start
srcUV += srcDUV * vec2_scalar(dstBounds.x0, dstBounds.y0);
// Offset source UVs to texel centers and scale by lerp precision
srcUV = linearQuantize(srcUV + 0.5f, 128);
srcDUV *= 128.0f;
// Calculate dest pointer from clamped offsets
int bpp = dsttex.bpp();
assert(bpp == 4);
int destStride = dsttex.stride();
char* dest = dsttex.sample_ptr(dstReq, dstBounds, dstZ, invertY);
// Inverted Y must step downward along dest rows
if (invertY) {
destStride = -destStride;
}
int span = dstBounds.width();
for (int rows = dstBounds.height(); rows > 0; rows--) {
linear_row_composite((uint32_t*)dest, span, srcUV, srcDUV.x, srcZOffset,
&sampler);
dest += destStride;
srcUV.y += srcDUV.y;
}
}
extern "C" {
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@ -4093,7 +4167,8 @@ void UnlockResource(LockedTexture* resource) {
// by another thread.
void Composite(LockedTexture* lockedDst, LockedTexture* lockedSrc, GLint srcX,
GLint srcY, GLsizei srcWidth, GLsizei srcHeight, GLint dstX,
GLint dstY, GLboolean opaque, GLboolean flip) {
GLint dstY, GLsizei dstWidth, GLsizei dstHeight,
GLboolean opaque, GLboolean flip) {
if (!lockedDst || !lockedSrc) {
return;
}
@ -4124,40 +4199,49 @@ void Composite(LockedTexture* lockedDst, LockedTexture* lockedSrc, GLint srcX,
if (flip) {
dest_stride = -dest_stride;
}
IntRect srcReq = {srcX, srcY, srcX + srcWidth, srcY + srcHeight};
IntRect dstReq = {dstX, dstY, dstX + dstWidth, dstY + dstHeight};
GLenum filter = GL_LINEAR; // TODO
if (opaque) {
for (int y = 0; y < srcHeight; y++) {
memcpy(dest, src, srcWidth * bpp);
dest += dest_stride;
src += src_stride;
if (!srcReq.same_size(dstReq) && filter == GL_LINEAR) {
linear_blit(srctex, srcReq, 0, dsttex, dstReq, 0, flip);
} else {
scale_blit(srctex, srcReq, 0, dsttex, dstReq, 0, flip);
}
} else {
for (int y = 0; y < srcHeight; y++) {
char* end = src + srcWidth * bpp;
while (src + 4 * bpp <= end) {
WideRGBA8 srcpx = unpack(unaligned_load<PackedRGBA8>(src));
WideRGBA8 dstpx = unpack(unaligned_load<PackedRGBA8>(dest));
PackedRGBA8 r = pack(srcpx + dstpx - muldiv255(dstpx, alphas(srcpx)));
unaligned_store(dest, r);
src += 4 * bpp;
dest += 4 * bpp;
}
if (src < end) {
WideRGBA8 srcpx = unpack(unaligned_load<PackedRGBA8>(src));
WideRGBA8 dstpx = unpack(unaligned_load<PackedRGBA8>(dest));
U32 r = bit_cast<U32>(
pack(srcpx + dstpx - muldiv255(dstpx, alphas(srcpx))));
unaligned_store(dest, r.x);
if (src + bpp < end) {
unaligned_store(dest + bpp, r.y);
if (src + 2 * bpp < end) {
unaligned_store(dest + 2 * bpp, r.z);
}
if (!srcReq.same_size(dstReq) && filter == GL_LINEAR) {
linear_composite(srctex, srcReq, 0, dsttex, dstReq, 0, flip);
} else {
for (int y = 0; y < srcHeight; y++) {
char* end = src + srcWidth * bpp;
while (src + 4 * bpp <= end) {
WideRGBA8 srcpx = unpack(unaligned_load<PackedRGBA8>(src));
WideRGBA8 dstpx = unpack(unaligned_load<PackedRGBA8>(dest));
PackedRGBA8 r = pack(srcpx + dstpx - muldiv255(dstpx, alphas(srcpx)));
unaligned_store(dest, r);
src += 4 * bpp;
dest += 4 * bpp;
}
dest += end - src;
src = end;
if (src < end) {
WideRGBA8 srcpx = unpack(unaligned_load<PackedRGBA8>(src));
WideRGBA8 dstpx = unpack(unaligned_load<PackedRGBA8>(dest));
U32 r = bit_cast<U32>(
pack(srcpx + dstpx - muldiv255(dstpx, alphas(srcpx))));
unaligned_store(dest, r.x);
if (src + bpp < end) {
unaligned_store(dest + bpp, r.y);
if (src + 2 * bpp < end) {
unaligned_store(dest + 2 * bpp, r.z);
}
}
dest += end - src;
src = end;
}
dest += dest_stride - srcWidth * bpp;
src += src_stride - srcWidth * bpp;
}
dest += dest_stride - srcWidth * bpp;
src += src_stride - srcWidth * bpp;
}
}
}

Просмотреть файл

@ -294,6 +294,8 @@ extern "C" {
src_height: GLsizei,
dst_x: GLint,
dst_y: GLint,
dst_width: GLsizei,
dst_height: GLsizei,
opaque: GLboolean,
flip: GLboolean,
);
@ -2278,9 +2280,11 @@ impl LockedResource {
src_x: GLint,
src_y: GLint,
src_width: GLsizei,
src_height: GLint,
src_height: GLsizei,
dst_x: GLint,
dst_y: GLint,
dst_width: GLsizei,
dst_height: GLsizei,
opaque: bool,
flip: bool,
) {
@ -2294,6 +2298,8 @@ impl LockedResource {
src_height,
dst_x,
dst_y,
dst_width,
dst_height,
opaque as GLboolean,
flip as GLboolean,
);

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename S>
static PackedRGBA8 textureLinearPackedRGBA8(S sampler, ivec2 i, int zoffset) {
static WideRGBA8 textureLinearUnpackedRGBA8(S sampler, ivec2 i, int zoffset) {
assert(sampler->format == TextureFormat::RGBA8);
ivec2 frac = i & 0x7F;
i >>= 7;
@ -48,7 +48,12 @@ static PackedRGBA8 textureLinearPackedRGBA8(S sampler, ivec2 i, int zoffset) {
auto cdh = combine(highHalf(c0), highHalf(d0));
cdl += ((cdh - cdl) * fracx.zzzzwwww) >> 7;
return pack(combine(HalfRGBA8(abl), HalfRGBA8(cdl)));
return combine(HalfRGBA8(abl), HalfRGBA8(cdl));
}
template <typename S>
static PackedRGBA8 textureLinearPackedRGBA8(S sampler, ivec2 i, int zoffset) {
return pack(textureLinearUnpackedRGBA8(sampler, i, zoffset));
}
template <typename S>
@ -143,21 +148,21 @@ static PackedRG8 textureLinearPackedRG8(S sampler, ivec2 i, int zoffset) {
uint16_t* buf = (uint16_t*)sampler->buf;
// Load RG bytes for two adjacent pixels - rgRG
auto a0 = unaligned_load<V4<uint8_t> >(&buf[row0.x]);
auto b0 = unaligned_load<V4<uint8_t> >(&buf[row0.y]);
auto a0 = unaligned_load<V4<uint8_t>>(&buf[row0.x]);
auto b0 = unaligned_load<V4<uint8_t>>(&buf[row0.y]);
auto ab0 = CONVERT(combine(a0, b0), V8<int16_t>);
// Load two pixels for next row
auto a1 = unaligned_load<V4<uint8_t> >(&buf[row1.x]);
auto b1 = unaligned_load<V4<uint8_t> >(&buf[row1.y]);
auto a1 = unaligned_load<V4<uint8_t>>(&buf[row1.x]);
auto b1 = unaligned_load<V4<uint8_t>>(&buf[row1.y]);
auto ab1 = CONVERT(combine(a1, b1), V8<int16_t>);
// Blend rows
ab0 += ((ab1 - ab0) * fracy.xxxxyyyy) >> 7;
auto c0 = unaligned_load<V4<uint8_t> >(&buf[row0.z]);
auto d0 = unaligned_load<V4<uint8_t> >(&buf[row0.w]);
auto c0 = unaligned_load<V4<uint8_t>>(&buf[row0.z]);
auto d0 = unaligned_load<V4<uint8_t>>(&buf[row0.w]);
auto cd0 = CONVERT(combine(c0, d0), V8<int16_t>);
auto c1 = unaligned_load<V4<uint8_t> >(&buf[row1.z]);
auto d1 = unaligned_load<V4<uint8_t> >(&buf[row1.w]);
auto c1 = unaligned_load<V4<uint8_t>>(&buf[row1.z]);
auto d1 = unaligned_load<V4<uint8_t>>(&buf[row1.w]);
auto cd1 = CONVERT(combine(c1, d1), V8<int16_t>);
// Blend rows
cd0 += ((cd1 - cd0) * fracy.zzzzwwww) >> 7;
@ -177,4 +182,3 @@ static PackedRG8 textureLinearPackedRG8(S sampler, ivec2 i, int zoffset) {
return pack(WideRG8(abcdl));
}