diff options
Diffstat (limited to 'src/jumper/SkJumper_stages.cpp')
-rw-r--r-- | src/jumper/SkJumper_stages.cpp | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/src/jumper/SkJumper_stages.cpp b/src/jumper/SkJumper_stages.cpp index fefd30c6a8..c7b165a8d6 100644 --- a/src/jumper/SkJumper_stages.cpp +++ b/src/jumper/SkJumper_stages.cpp @@ -194,13 +194,15 @@ SI T* ptr_at_xy(const SkJumper_MemoryCtx* ctx, int dx, int dy) { return (T*)ctx->pixels + dy*ctx->stride + dx; } +// clamp v to [0,limit). +SI F clamp(F v, F limit) { + F inclusive = bit_cast<F>( bit_cast<U32>(limit) - 1 ); // Exclusive -> inclusive. + return min(max(0, v), inclusive); +} + // Used by gather_ stages to calculate the base pointer and a vector of indices to load. template <typename T> SI U32 ix_and_ptr(T** ptr, const SkJumper_GatherCtx* ctx, F x, F y) { - auto clamp = [](F v, F limit) { - limit = bit_cast<F>( bit_cast<U32>(limit) - 1 ); // Exclusive -> inclusive. - return min(max(0, v), limit); - }; x = clamp(x, ctx->width); y = clamp(y, ctx->height); @@ -1521,3 +1523,45 @@ STAGE(gauss_a_to_rgba, Ctx::None) { g = a; b = a; } + +// A specialized fused image shader for clamp-x, clamp-y, non-sRGB sampling. +STAGE(bilerp_clamp_8888, SkJumper_GatherCtx* ctx) { + // (cx,cy) are the center of our sample. + F cx = r, + cy = g; + + // All sample points are at the same fractional offset (fx,fy). + // They're the 4 corners of a logical 1x1 pixel surrounding (x,y) at (0.5,0.5) offsets. + F fx = fract(cx + 0.5f), + fy = fract(cy + 0.5f); + + // We'll accumulate the color of all four samples into {r,g,b,a} directly. + r = g = b = a = 0; + + for (float dy = -0.5f; dy <= +0.5f; dy += 1.0f) + for (float dx = -0.5f; dx <= +0.5f; dx += 1.0f) { + // (x,y) are the coordinates of this sample point. + F x = cx + dx, + y = cy + dy; + + // ix_and_ptr() will clamp to the image's bounds for us. + const uint32_t* ptr; + U32 ix = ix_and_ptr(&ptr, ctx, x,y); + + F sr,sg,sb,sa; + from_8888(gather(ptr, ix), &sr,&sg,&sb,&sa); + + // In bilinear interpolation, the 4 pixels at +/- 0.5 offsets from the sample pixel center + // are combined in direct proportion to their area overlapping that logical query pixel. + // At positive offsets, the x-axis contribution to that rectangle is fx, + // or (1-fx) at negative x. Same deal for y. + F sx = (dx > 0) ? fx : 1.0f - fx, + sy = (dy > 0) ? fy : 1.0f - fy, + area = sx * sy; + + r += sr * area; + g += sg * area; + b += sb * area; + a += sa * area; + } +} |