use mul_inv instead of div for tiling

Bug: skia:
Change-Id: I5f88e7923fe204faba8dc5d87454805a4d470d52
Reviewed-on: https://skia-review.googlesource.com/20688
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2017-06-23 14:21:25 -04:00 committed by Skia Commit-Bot
parent 81dd3e0c66
commit 51e46d5e1c
5 changed files with 3422 additions and 3309 deletions

View File

@ -71,6 +71,11 @@ struct SkJumper_SamplerCtx {
float scaley[SkJumper_kMaxStride];
};
struct SkJumper_TileCtx {
float scale;
float invScale; // cache of 1/scale
};
struct SkJumper_CallbackCtx {
MAYBE_MSABI void (*fn)(SkJumper_CallbackCtx* self, int active_pixels/*<= SkJumper_kMaxStride*/);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -945,25 +945,27 @@ SI F ulp_before(F f) {
return unaligned_load<F>(&bits);
}
SI F exclusive_clamp(F v, float limit) {
SI F exclusive_clamp(F v, const SkJumper_TileCtx* ctx) {
v = max(0,v);
return min(v, ulp_before(limit));
return min(v, ulp_before(ctx->scale));
}
SI F exclusive_repeat(F v, float limit) {
v = v - floor_(v/limit)*limit;
return min(v, ulp_before(limit));
SI F exclusive_repeat(F v, const SkJumper_TileCtx* ctx) {
v = v - floor_(v*ctx->invScale)*ctx->scale;
return min(v, ulp_before(ctx->scale));
}
SI F exclusive_mirror(F v, float limit) {
v = abs_( (v-limit) - (limit+limit)*floor_((v-limit)/(limit+limit)) - limit );
SI F exclusive_mirror(F v, const SkJumper_TileCtx* ctx) {
auto limit = ctx->scale;
auto invLimit = ctx->invScale;
v = abs_( (v-limit) - (limit+limit)*floor_((v-limit)*(invLimit*0.5f)) - limit );
return min(v, ulp_before(limit));
}
// Clamp x or y to [0,limit) == [0,limit - 1 ulp] (think, sampling from images).
STAGE(clamp_x) { r = exclusive_clamp (r, *(const float*)ctx); }
STAGE(clamp_y) { g = exclusive_clamp (g, *(const float*)ctx); }
STAGE(repeat_x) { r = exclusive_repeat(r, *(const float*)ctx); }
STAGE(repeat_y) { g = exclusive_repeat(g, *(const float*)ctx); }
STAGE(mirror_x) { r = exclusive_mirror(r, *(const float*)ctx); }
STAGE(mirror_y) { g = exclusive_mirror(g, *(const float*)ctx); }
STAGE(clamp_x) { r = exclusive_clamp (r, (const SkJumper_TileCtx*)ctx); }
STAGE(clamp_y) { g = exclusive_clamp (g, (const SkJumper_TileCtx*)ctx); }
STAGE(repeat_x) { r = exclusive_repeat(r, (const SkJumper_TileCtx*)ctx); }
STAGE(repeat_y) { g = exclusive_repeat(g, (const SkJumper_TileCtx*)ctx); }
STAGE(mirror_x) { r = exclusive_mirror(r, (const SkJumper_TileCtx*)ctx); }
STAGE(mirror_y) { g = exclusive_mirror(g, (const SkJumper_TileCtx*)ctx); }
// Clamp x to [0,1], both sides exclusive (think, gradients).
STAGE( clamp_x_1) { r = min(max(0, r), 1.0f); }

View File

@ -298,8 +298,12 @@ bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dstCS, SkA
gather->ctable = pm.ctable() ? pm.ctable()->readColors() : nullptr;
gather->stride = pm.rowBytesAsPixels();
auto limit_x = alloc->make<float>(pm. width()),
limit_y = alloc->make<float>(pm.height());
auto limit_x = alloc->make<SkJumper_TileCtx>(),
limit_y = alloc->make<SkJumper_TileCtx>();
limit_x->scale = pm.width();
limit_x->invScale = 1.0f / pm.width();
limit_y->scale = pm.height();
limit_y->invScale = 1.0f / pm.height();
auto append_tiling_and_gather = [&] {
switch (fTileModeX) {