std/vp8: swizzle_ycck once, not once per MB row This prepares us to change std/vp8's YCC upsampling method from "basic" to "fancy, like libwebp". Wuffs' current implementation of "fancy" requires the initial Y coordinate to be zero, as fancy upsampling special cases the top row of the image and it's simpler if the top row (row zero) is always presented in the upsampling call. This is not an optimization or pessimization per se, but for the record, the performance impact is between negligible and a small improvement. name old speed new speed delta wuffs_webp_lossy_decode_image_19k_8bpp/clang14 33.7MB/s ± 0% 34.1MB/s ± 0% +1.28% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_40k_24bpp/clang14 106MB/s ± 0% 106MB/s ± 0% +0.09% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_77k_24bpp/clang14 129MB/s ± 0% 130MB/s ± 0% +0.54% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_552k_32bpp/clang14 207MB/s ± 0% 211MB/s ± 0% +1.90% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_4002k_24bpp/clang14 137MB/s ± 0% 138MB/s ± 0% +0.40% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_19k_8bpp/gcc12 32.9MB/s ± 0% 32.9MB/s ± 0% +0.05% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_40k_24bpp/gcc12 98.4MB/s ± 0% 98.8MB/s ± 0% +0.42% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_77k_24bpp/gcc12 125MB/s ± 0% 125MB/s ± 0% +0.17% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_552k_32bpp/gcc12 211MB/s ± 0% 214MB/s ± 0% +1.21% (p=0.008 n=5+5) wuffs_webp_lossy_decode_image_4002k_24bpp/gcc12 137MB/s ± 0% 137MB/s ± 0% ~ (p=0.095 n=5+5)
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c index 1e993d3..ec6e188 100644 --- a/release/c/wuffs-unsupported-snapshot.c +++ b/release/c/wuffs-unsupported-snapshot.c
@@ -83991,10 +83991,6 @@ } else { wuffs_vp8__decoder__filter_normal(self, a_workbuf, (v_mby - 1u)); } - v_status = wuffs_vp8__decoder__swizzle_one_row_of_macroblocks(self, a_dst, a_workbuf, (v_mby - 1u)); - if ( ! wuffs_base__status__is_ok(&v_status)) { - return wuffs_private_impl__status__ensure_not_a_suspension(v_status); - } } v_mby += 1u; } @@ -84288,6 +84284,7 @@ return wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); } v_y_min_incl = wuffs_base__u32__sat_sub((a_mby * 16u), 6u); + v_y_min_incl = 0u; v_y_max_excl = ((a_mby * 16u) + 10u); if ((a_mby + 1u) >= self->private_impl.f_mbh) { v_y_max_excl = self->private_impl.f_height;
diff --git a/std/vp8/decode_macroblocks.wuffs b/std/vp8/decode_macroblocks.wuffs index 1655d9b..59982b0 100644 --- a/std/vp8/decode_macroblocks.wuffs +++ b/std/vp8/decode_macroblocks.wuffs
@@ -48,10 +48,12 @@ this.filter_normal!(workbuf: args.workbuf, mby: mby - 1) } - status = this.swizzle_one_row_of_macroblocks!(dst: args.dst, workbuf: args.workbuf, mby: mby - 1) - if not status.is_ok() { - return status - } + // TODO(§): re-enable this when swizzle_ycck can take y_min_incl > 0. + // + // status = this.swizzle_one_row_of_macroblocks!(dst: args.dst, workbuf: args.workbuf, mby: mby - 1) + // if not status.is_ok() { + // return status + // } } mby += 1 @@ -375,6 +377,7 @@ // happens after decoder.swizzle_one_row_of_macroblocks returns), unless // we're swizzling the bottom-most row of macroblocks. y_min_incl = (args.mby * 16) ~sat- 6 + y_min_incl = 0 // TODO(§): delete this. y_max_excl = (args.mby * 16) + 10 if (args.mby + 1) >= this.mbh { y_max_excl = this.height @@ -425,6 +428,7 @@ v2: 1, v3: 0, ycc_model: base.YCC_MODEL__BT_601_STUDIO_RANGE as base.u8, + // TODO(§): let fancy upsampling work with y_min_incl > 0. ycc_upsampling: base.YCC_UPSAMPLING__BASIC as base.u8, scratch_buffer_2k: this.swizzle_ycck_scratch_buffer_2k[..]) return status