aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkXfermode.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-08-24 13:06:23 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-24 18:51:57 +0000
commitfb126fa96e0f49f5dc17a9a043acced68be99e93 (patch)
tree5a9616cb9fdf2600e4ad9454e96d6f8a1492a7a5 /src/core/SkXfermode.cpp
parentf05bddaac3d8219fcaf623b64897ced81c05d437 (diff)
rework plus blend mode
The most interesting parts of this are how plus interacts with partial coverage. Plus needs its clamp to happen after the lerp. Luckily, some of its math folds away: d' = clamp[ d*(1-c) + (s+d)*c ] == clamp[ d - dc + sc + dc ] == clamp[ d + sc ] What's nice there is that coverage can be folded into the src term. This suggests that we can re-write the plus stage to clamp internally (and thus, be viable for 8-bit) if we always pre-scale with coverage. We don't have a way to pre-scale with 565 coverage until now, but it's only a step or two away from there. We can use the alternate formulation we derived for alpha for lerp_565, calculating the alpha coverage from red, green, and blue coverages _and_ the values of src and dst alpha. While we already pre-scale srcover today for 8-bit or constant coverage, we cannot do the same for 565. When evaluating the expression d' = s + (1-a)d we need the a term to be pre-scaled with red's coverage when calculating dr', with blue's when calculating db', etc. Essentially we need to carry around a bunch of extra values, and we've got no way to do that. So instead, we'll just carefully pre-scale plus with any coverage, and keep post-lerping srcover when we have 565 coverage. Change-Id: I7a7a52eec7d482e1b98bb8a01ea0a3d5e67bef65 Reviewed-on: https://skia-review.googlesource.com/38300 Commit-Queue: Mike Klein <mtklein@chromium.org> Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/core/SkXfermode.cpp')
-rw-r--r--src/core/SkXfermode.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 29296c3343..8a66363f74 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -49,11 +49,17 @@ public:
p.append(SkRasterPipeline::load_8888, &src_ctx);
}
- SkBlendMode_AppendStagesNoClamp(fMode, &p);
- if (aa) {
- p.append(SkRasterPipeline::lerp_u8, &aa_ctx);
+ if (SkBlendMode_ShouldPreScaleCoverage(fMode, /*rgb_coverage=*/false)) {
+ if (aa) {
+ p.append(SkRasterPipeline::scale_u8, &aa_ctx);
+ }
+ SkBlendMode_AppendStages(fMode, &p);
+ } else {
+ SkBlendMode_AppendStages(fMode, &p);
+ if (aa) {
+ p.append(SkRasterPipeline::lerp_u8, &aa_ctx);
+ }
}
- SkBlendMode_AppendClampIfNeeded(fMode, &p);
if (kN32_SkColorType == kBGRA_8888_SkColorType) {
p.append(SkRasterPipeline::store_bgra, &dst_ctx);