Skip to content

Commit 678bfed

Browse files
committed
kernel4: assume colors in alpha-premultiplied sRGB format
See http://ssp.impulsetrain.com/gamma-premult.html for a description of the format. Pre-multiplied alpha only matters for translucent objects; draw a few such shapes in the test render. Signed-off-by: Elias Naur <mail@eliasnaur.com>
1 parent eb37db1 commit 678bfed

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

piet-gpu/shader/kernel4.comp

+6-4
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,19 @@ void main() {
207207
break;
208208
case Cmd_Color:
209209
CmdColor color = Cmd_Color_read(cmd_alloc, cmd_ref);
210-
vec4 fg_rgba = unpacksRGB(color.rgba_color);
210+
vec4 fg = unpacksRGB(color.rgba_color);
211211
for (uint k = 0; k < CHUNK; k++) {
212-
rgb[k] = mix(rgb[k], fg_rgba.rgb, area[k] * fg_rgba.a);
212+
vec4 fg_k = fg * area[k];
213+
rgb[k] = rgb[k] * (1.0 - fg_k.a) + fg_k.rgb;
213214
}
214215
cmd_ref.offset += 4 + CmdColor_size;
215216
break;
216217
case Cmd_Image:
217218
CmdImage fill_img = Cmd_Image_read(cmd_alloc, cmd_ref);
218-
vec4 rgba[CHUNK] = fillImage(xy_uint, fill_img);
219+
vec4 img[CHUNK] = fillImage(xy_uint, fill_img);
219220
for (uint k = 0; k < CHUNK; k++) {
220-
rgb[k] = mix(rgb[k], rgba[k].rgb, area[k] * rgba[k].a);
221+
vec4 fg_k = img[k] * area[k];
222+
rgb[k] = rgb[k] * (1.0 - fg_k.a) + fg_k.rgb;
221223
}
222224
cmd_ref.offset += 4 + CmdImage_size;
223225
break;

piet-gpu/src/lib.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub use render_ctx::PietGpuRenderContext;
77

88
use rand::{Rng, RngCore};
99

10-
use piet::kurbo::{BezPath, Circle, Point, Vec2};
10+
use piet::kurbo::{BezPath, Circle, Point, Shape, Vec2};
1111
use piet::{Color, ImageFormat, RenderContext};
1212

1313
use piet_gpu_types::encoder::Encode;
@@ -74,6 +74,7 @@ pub fn render_scene(rc: &mut impl RenderContext) {
7474
);
7575
//render_cardioid(rc);
7676
render_clip_test(rc);
77+
render_alpha_test(rc);
7778
//render_tiger(rc);
7879
}
7980

@@ -124,6 +125,33 @@ fn render_clip_test(rc: &mut impl RenderContext) {
124125
}
125126
}
126127

128+
#[allow(unused)]
129+
fn render_alpha_test(rc: &mut impl RenderContext) {
130+
// Alpha compositing tests. kernel4 expects colors encoded in alpha-premultiplied sRGB:
131+
//
132+
// [α,sRGB(α⋅R),sRGB(α⋅G),sRGB(α⋅B)]
133+
//
134+
// See also http://ssp.impulsetrain.com/gamma-premult.html.
135+
rc.fill(diamond(Point::new(1024.0, 100.0)), &Color::Rgba32(0xff0000ff));
136+
rc.fill(diamond(Point::new(1024.0, 125.0)), &Color::Rgba32(0x00ba0080));
137+
rc.save();
138+
rc.clip(diamond(Point::new(1024.0, 150.0)));
139+
rc.fill(diamond(Point::new(1024.0, 175.0)), &Color::Rgba32(0x0000ba80));
140+
rc.restore();
141+
}
142+
143+
fn diamond(origin: Point) -> impl Shape {
144+
let mut path = BezPath::new();
145+
const SIZE: f64 = 50.0;
146+
path.move_to((origin.x, origin.y - SIZE));
147+
path.line_to((origin.x + SIZE, origin.y));
148+
path.line_to((origin.x, origin.y + SIZE));
149+
path.line_to((origin.x - SIZE, origin.y));
150+
path.close_path();
151+
return path;
152+
}
153+
154+
#[allow(unused)]
127155
fn render_tiger(rc: &mut impl RenderContext) {
128156
let xml_str = std::str::from_utf8(include_bytes!("../Ghostscript_Tiger.svg")).unwrap();
129157
let start = std::time::Instant::now();

0 commit comments

Comments
 (0)