Add 16bpc (RGBA64 / 64bpp) high-precision color pipeline support - #188
Open
edco wants to merge 1 commit into
Open
Add 16bpc (RGBA64 / 64bpp) high-precision color pipeline support#188edco wants to merge 1 commit into
edco wants to merge 1 commit into
Conversation
- Introduce optional `16bpc` feature flag for 16-bit per channel rendering. - Add `Pixel` and `HighPixel` trait abstractions with `PremultipliedColorU16`, `ColorU16`, and `AlphaU16`. - Provide concrete dual-pipeline specialization (`highp::Pipeline` for 8bpc and `highp::PipelineU16` for 16bpc) to guarantee zero performance regression on 8bpc rendering. - Add `DynamicPixmap`, `DynamicPixmapMut`, and `DynamicPixmapRef` enums for polymorphic buffer management. - Support 16-bit PNG decoding/encoding and 16bpc pattern textures. - Expand test suite to validate both 8bpc and 16bpc pipelines across all 160 integration tests and 64 unit tests. - Add layer compositing benchmarks and 16bpc benchmark dispatching.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request: 16bpc Color Pipeline Support for tiny-skia
This pull request introduces native 16-bit per channel (RGBA64 / 64bpp premultiplied) color rendering support to
tiny-skia, gated behind an optional16bpcfeature flag.Authored mostly by Gemini 3.7 Flash in Google Antigravity IDE. Forgive me for this AI slop.
Supports a corresponding PR to resvg: linebender/resvg#1125
Summary
16bpcfeature flag for 16-bit per channel rendering.PixelandHighPixeltrait abstractions withPremultipliedColorU16,ColorU16, andAlphaU16.highp::Pipelinefor 8bpc andhighp::PipelineU16for 16bpc) to guarantee zero performance regression on 8bpc rendering.DynamicPixmap,DynamicPixmapMut, andDynamicPixmapRefenums for polymorphic buffer management.Key Highlights
Pixel&HighPixeltraits):PixmapGeneric<P>,PixmapMutGeneric<'_, P>,PixmapRefGeneric<'_, P>,PainterGeneric<'_, P>, andRasterPipelineBlitter<P>without runtime overhead.type Pixmap = PixmapGeneric<PremultipliedColorU8>).highpfloating-point SIMD pipeline stages to load from and store directly intoPixmapU16buffers.Patternshader supports both 8bpc and 16bpc source textures viaDynamicPixmapRef, sampling at full 16-bit fidelity acrossNearest,Bilinear, andBicubicinterpolation.PixmapU16::decode_png,PixmapU16::encode_png,PixmapU16::save_png).DynamicPixmap,DynamicPixmapMut, andDynamicPixmapRefenums for polymorphic 8bpc / 16bpc canvas management.dash,fill,stroke,gradients,hairline,pattern,mask,gamma,pixmap,path,png, andu16_precision) now executes against both the 8bpc and 16bpc raster pipelines with tolerance validation.TINY_SKIA_BENCH_16BPCenvironment switch andbenches/src/draw_pixmap.rslayer compositing benchmarks.default = ["std", "simd", "png-format"]) maintains existing 8bpc behavior, performance, and binary size.Benchmarks
1. 8bpc Rendering: Baseline (Before) vs. Current (After)
blend::color_burnblend::color_dodgeblend::colorblend::hueblend::luminosityblend::saturationblend::soft_lightgradients::*::hqpatterns::hqpatterns::lqpatterns::plaindraw_pixmap::*fill::*/clip::*2. 16bpc Mode vs. 8bpc Mode Performance
source_over,screen,plus,multiply)color_burn,dodge,color,hue,soft_light)two_stops,three_stops)simple_radial,two_point_radial)path_aa,rect_aa,spiral)clear,opaque,all)patterns::hq)3. Compiled Binary Size (
tiny-skialibtiny_skia.rlib, Release Build)libtiny_skia.rlib)--features 16bpcEnabled)Configuration & Command Reference
Feature Flag
16bpc(off by default): Enables 16-bit per channel color types (PixmapU16,PremultipliedColorU16,ColorU16), the 16bpc raster pipeline (highp::STAGES_U16), and 16-bit PNG I/O.Environment Variable
TINY_SKIA_BENCH_16BPC(benchmark runner only): When set to any value duringcargo bench --features 16bpc, instructs benchmark cases to allocatePixmapU16instead ofPixmapand measure the 16bpc rendering pipeline.Command Examples
1. Building & Testing
2. Running Benchmarks
Changed & Added Files (Changelog)
src/color.rsAlphaU16/ALPHA_U16_TRANSPARENT/ALPHA_U16_OPAQUE[NEW]: 16bpc equivalents toAlphaU8and its constants.ColorU16[NEW]: 16bpc equivalent toColorU8, including constructors (from_rgba,from_rgba8), getters,premultiply(), andto_color_u8().PremultipliedColorU16[NEW]: 16bpc equivalent toPremultipliedColorU8, including constructors (from_rgba,from_rgba_unchecked,from_rgba8), getters,demultiply(),is_opaque(), andto_color_u8().Color::to_color_u16()/PremultipliedColor::to_color_u16()[NEW]: 16bpc equivalents toto_color_u8().premultiply_u16(c, a)/color_f32_to_u16(...)[NEW]: 16bpc premultiplication and float conversion helpers using bit-exact rounded integer arithmetic ((c * a + 32768) / 65535).src/geom.rsIntSizeExtandIntRectExt) abovemod screen_int_rect_teststo resolve theclippy::items_after_test_modulelint.src/lib.rsPixmapU16,PixmapU16Mut,PixmapU16Ref,DynamicPixmap,DynamicPixmapMut,DynamicPixmapRef,ColorU16,PremultipliedColorU16,AlphaU16, andHighPixel).src/mask.rsMask::from_pixmap<P: Pixel>[MODIFIED]: Generalized to construct alpha/luminance masks from generic 8bpc and 16bpc pixmaps.Mask::apply_to_u16[NEW]: 16bpc equivalent for applying masks to 16bpc buffers using high-precision scaling.src/math.rsmul_div65535_round(a, b)/div65535_round(x)[NEW]: Fast 32-bit register arithmetic for rounded 16-bit channel division(a * b + 0x8000) / 65535.src/painter.rsPainterGeneric<'a, P: Pixel>[MODIFIED / GENERIC]:fill_rect,fill_path,stroke_path,draw_paint, anddraw_pixmapare made generic over pixel format, serving both 8bpc and 16bpc canvases.DynamicPixmap&DynamicPixmapMut[NEW]: 8bpc/16bpc runtime enum dispatchers for painter methods.blend_u16_op(dst, src, mode)[NEW]: 16bpc software compositor for all 29 separable and non-separable Porter-Duff and SVG blend modes.src/pipeline/blitter.rsRasterPipelineBlitter<'a, P: HighPixel>[MODIFIED / GENERIC]:new,blit_anti_h,blit_v, andblit_rectare made generic over pixel format for both 8bpc and 16bpc.src/pipeline/highp.rsHighPixelTrait [NEW]: Defines pipeline execution hooks (run_highp,run_lowp) implemented forPremultipliedColorU8andPremultipliedColorU16.Pipeline&PipelineU16[SPECIALIZED]: Preserved concrete non-genericPipelineand staticSTAGEStable for 8bpc to ensure zero LLVM stack spill regressions, alongside a concretePipelineU16and staticSTAGES_U16dispatch table for 16bpc.stage_fn!,blend_fn!,blend_fn2!,blend_fn3!) generate both 8bpc and 16bpc concrete stage functions from unified mathematical bodies with zero code duplication.load_16161616/load_16161616_tail/store_16161616/store_16161616_tail/unnorm_u16[NEW]: 16bpc SIMD load, store, and un-normalization stages (16bpc equivalents to the 8888 stages).gather/sampler_2x2/sampler_4x4/sample[MODIFIED]: Upgraded texture pattern sampling to unpack directly from 16bpc source textures (DynamicPixmapRef).src/pipeline/lowp.rsPipeline::fmt[NEW]: Addedcore::fmt::Debugimplementation for the low-precision pipeline context struct.src/pipeline/mod.rsSubPixmapMutGeneric<'a, P: Pixel>[MODIFIED / GENERIC]: Maintains continuous byte storage (pub data: &'a mut [u8]) with typed chunk accessors (slice4_at_xy,slice16_at_xy,slice_mask_at_xy,slice16_mask_at_xy), ensuring zero-cost indexing across both pixmaps and 1-byte mask buffers.RasterPipelineBuilder::compileandRasterPipelineGeneric::runcompile and dispatch directly to concrete stage function tables (highp::STAGESfor 8bpc,highp::STAGES_U16for 16bpc,lowp::STAGESfor lowp).src/pixmap.rsPixelTrait [NEW]: Core trait defining pixel memory layout and color/alpha conversions.PixmapGeneric<P>/PixmapMutGeneric<P>/PixmapRefGeneric<P>[MODIFIED / GENERIC]: Generic implementations ofnew,from_vec,data,pixels,fill,clone_rect, anddraw_pixmapfor both 8bpc and 16bpc.PixmapU16::encode_png/save_png/decode_png[NEW]: 16bpc equivalents to the 8bpc PNG I/O methods.DynamicPixmap,DynamicPixmapMut, andDynamicPixmapRef[NEW]: Polymorphic runtime representations wrapping eitherU8orU16pixmaps.src/shaders/pattern.rsPattern<'a>[MODIFIED]: Generalized to storeDynamicPixmapRef<'a>, allowing pattern shaders to wrap either 8bpc or 16bpc source pixmaps viaPattern::new_u16andPattern::from_pixmap.benches/src/[MODIFIED]is_16bpc()inbenches/src/main.rs[NEW]: Environment variable parser checkingTINY_SKIA_BENCH_16BPC.draw_pixmap.rs[NEW FILE]: Layer compositing benchmarks across all 29 blend modes in both 8bpc and 16bpc.blend.rs/clip.rs/fill.rs/gradients.rs/hairline.rs/patterns.rs/spiral.rs[MODIFIED]: Added 16bpc benchmark dispatching whenTINY_SKIA_BENCH_16BPCis active.tests/integration/common.rs[NEW FILE]assert_pixmap_eq<P: Pixel>&assert_mask_eq: Generic visual test assertions supporting strict byte-for-byte matching on 8bpc (tolerance = 0) and precision-adjusted comparison on 16bpc (tolerance <= 2-3).test_raster!: Macro running test bodies against both 8bpc and 16bpc pipelines.tests/integration/*.rs[MODIFIED]dash.rs/fill.rs/stroke.rs/gradients.rs/hairline.rs/pattern.rs/mask.rs/gamma.rs/pixmap.rs/skia_dash.rs: Converted to dual-pipeline tests executing on both 8bpc and 16bpc pipelines.tests/integration/u16_precision.rs[NEW FILE]continuous_gradient_sub_8bit_steps/solid_fill_and_draw/path_and_hairline_rendering: Precision tests validating sub-8bit gradient steps, fine alpha ramps, and 16bpc PNG roundtripping.