Commit Graph

29 Commits

Author SHA1 Message Date
Mike Klein
761d27c4d7 update SkRasterPipeline::run() to also take y
y isn't used yet.  This is just a warmup that updates the callers.

Change-Id: I78f4f44e2b82f72b3a39fa8a8bdadef1d1b8a99e
Reviewed-on: https://skia-review.googlesource.com/18381
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-06-01 17:05:13 +00:00
Mike Klein
b24704d35f SkRasterPipeline in SkArenaAlloc
Bug: skia:6673

Change-Id: Ia2bae4f6a9039a007a10b6b45bcf2f0854bf6e5c
Reviewed-on: https://skia-review.googlesource.com/17794
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-05-24 14:54:15 +00:00
Mike Klein
0a76b413ea add compile, use it in blitter
I expanded an existing bench to show off the difference:

    SkRasterPipeline_…
    300  …compile 1x  …run 1.14x

Change-Id: I5d63d602cda3f78d2d0891fcc85baf5514632900
Reviewed-on: https://skia-review.googlesource.com/17458
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
2017-05-22 16:41:22 +00:00
Mike Klein
1859f69d20 some basic speed ups for SkRasterPipeline::append()
The new bench demos the speedup:
    SkRasterPipelineReuse_…
    …full 1x  …some 1.8x  …none 5.22x

Change-Id: I5e51fb4316ae04558710ce62560850584ccb4aea
Reviewed-on: https://skia-review.googlesource.com/17449
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-05-22 14:08:06 +00:00
Mike Klein
f45e3d78a4 try Herb's new to_srgb
This was 6-8% faster than the previous code on my Trashcan.

Change-Id: I70081009e233c83226d6d302f871fb7e86cdc438
Reviewed-on: https://skia-review.googlesource.com/16986
Reviewed-by: Matt Sarett <msarett@google.com>
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-05-16 22:03:05 +00:00
Mike Klein
c7be00366b remove to_2dot2 and from_2dot2
The parametric_{r,g,b} stages are just as good now;
under the hood it's all going through approx_powf.

Change-Id: If7f3ae1e24fcee2ddb201c1d66ce1dd64820c89a
Reviewed-on: https://skia-review.googlesource.com/14320
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-04-26 14:38:25 +00:00
Mike Klein
795c5b1567 jumper, implement 2.2 stages with approx_powf
My main interest is getting rid of weird code, but it's also faster.
The new bench drops from 667 to 412.

Change-Id: Ibf889601284cf925780320c828394f79937dc705
Reviewed-on: https://skia-review.googlesource.com/14035
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-04-21 17:16:07 +00:00
Mike Klein
cb79393e88 Drop SkRasterPipelineBench N to 15.
This highlights overheads and instruction set switch costs.

At time of writing on my HSW laptop,
   N = 16:  76ns
   N = 15: 291ns

BUG=skia:6289

Change-Id: I01751e8f5ea6cf946e7710822d9bc742712553e9
Reviewed-on: https://skia-review.googlesource.com/8984
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-02-27 15:11:35 +00:00
Mike Klein
8729e5bbf7 Simplify more: remove SkRasterPipeline::compile().
It's easier to work on SkJumper if everything funnels through run().

I don't anticipate huge benefit from compile() without JITing,
but it's something we can always put back if we find a need.

Change-Id: Id5256fd21495e8195cad1924dbad81856416d913
Reviewed-on: https://skia-review.googlesource.com/8468
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
2017-02-16 12:23:06 +00:00
Mike Klein
319ba3d3a1 Move shader register setup to SkRasterPipelineBlitter.
We've been seeding the initial values of our registers to x+0.5,y+0.5,
1,0, 0,0,0,0 (useful values for shaders to start with) in all pipelines.
This CL changes that to do so only when blitting, and only when we have
a shader.

The nicest part of this change is that SkRasterPipeline itself no longer
needs to have a concept of y, or what x means.  It just marches x
through [x,x+n), and the blitter handles y and layers the meaning of
"dst x coordinate" onto x.

This ought to make SkSplicer a little easier to work with too.

dm --src gm --config f16 srgb 565 all draws the same.

Change-Id: I69d8c1cc14a06e5dfdd6a7493364f43a18f8dec5
Reviewed-on: https://skia-review.googlesource.com/7353
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-01-23 20:00:23 +00:00
Mike Klein
f76885694d Add a bench to exercise legacy-mode SkRasterPipeline behavior.
No fancy f16 or sRGB here... just good old legacy 8888.

Change-Id: I21eb7c0d8e2c7a7d92e9d8a8bae9d318c4daa7e5
Reviewed-on: https://skia-review.googlesource.com/7109
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-01-17 15:56:11 +00:00
Mike Klein
8c8cb5bfc5 simplify by removing _d stages
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: I75e232faee6ad48f65bac5b119a461280b27bbc8
Reviewed-on: https://skia-review.googlesource.com/6661
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-01-06 16:14:00 +00:00
Mike Klein
a2d25ec0ef Use stack instead of malloc() for most calls to SkRasterPipeline::run().
Also split bench into run/compile variants to measure the effect:
 Before …f16_compile 1x  …f16_run 1.02x  …srgb_compile 1.56x  …srgb_run 1.61x
 After  …f16_run 1x  …f16_compile 1.01x  …srgb_compile 1.58x  …srgb_run 1.59x

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: I8e65fb2acdbb05ccc0b3894f16d7646603c3e74d
Reviewed-on: https://skia-review.googlesource.com/6621
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2017-01-05 20:41:43 +00:00
Mike Klein
d37d5d9649 Revert "Revert "clamp to premul when reading premul sRGB""
This reverts commit 2e018f548d.

Reason for revert: doesn't appear to have been the roll problem.

Original change's description:
> Revert "clamp to premul when reading premul sRGB"
> 
> This reverts commit 04e10da836.
> 
> Reason for revert: roll?
> 
> Change-Id: Id0a8dcd62763bd6eddde120c513ca97e098a4268
> Reviewed-on: https://skia-review.googlesource.com/6022
> Commit-Queue: Mike Klein <mtklein@chromium.org>
> Reviewed-by: Mike Klein <mtklein@chromium.org>
> 

TBR=mtklein@chromium.org,reviews@skia.org,brianosman@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: I399ca5e728ce6766c6707682c4c6b685681ffdeb
Reviewed-on: https://skia-review.googlesource.com/6025
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
2016-12-14 13:38:41 +00:00
Mike Klein
2e018f548d Revert "clamp to premul when reading premul sRGB"
This reverts commit 04e10da836.

Reason for revert: roll?

Change-Id: Id0a8dcd62763bd6eddde120c513ca97e098a4268
Reviewed-on: https://skia-review.googlesource.com/6022
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
2016-12-14 04:24:08 +00:00
Mike Klein
04e10da836 clamp to premul when reading premul sRGB
It's pretty easy to start with sound premultiplied linear floats, pack those to sRGB encoded bytes, then read them back to linear floats and find them not quite premultiplied, with a color channel just a smidge greater than the alpha channel.  This can happen basically any time we have different transfer functions for alpha and colors... sRGB being the only one we draw into.

This is an annoying problem with no known good solution.  So apply the clamp hammer.

These new calls on SkRasterPipeline should make it impossible to get wrong.

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: I4c974f4a7b151f3f684946f1e83d06b1b288fd01
Reviewed-on: https://skia-review.googlesource.com/5945
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-12-13 22:09:57 +00:00
Mike Klein
729b582962 Consistent naming.
For stages that have {r,g,b,a} and {dr,dg,db,da} versions, name the {r,g,b,a} one "foo" and the {dr,dg,db,da} on "foo_d".  The {r,g,b,a} registers are the ones most commonly used and fastest, so they get short ordinary names, and the d-registers are less commonly used and sometimes slower, so they get a suffix.

Some stages naturally opearate on all 8 registers (the xfermodes, accumulate).  These names for those look fine and aren't ambiguous.

Also, a bit more re-arrangement in _opts.h.

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: Ia20029247642798a60a2566e8a26b84ed101dbd0
Reviewed-on: https://skia-review.googlesource.com/5291
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-11-29 00:29:32 +00:00
Mike Klein
e03339a354 Convert blitter over to new style from_srgb, to_srgb.
Every sRGB GM changes, none noticeably.

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: I632845aea0f40751639cccbcfde8fa270cae0301
Reviewed-on: https://skia-review.googlesource.com/5275
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-11-28 21:13:34 +00:00
Mike Klein
af49b19582 Start each pipeline with (x,y) in (dr,dg) registers for the shader.
Image shaders need to do some geometry work before sampling the image colors:
  1) determine dst coordinates
  2) map back to src coordinates
  3) tiling

Feeding (x,y) through as (dr,dg) registers makes step 1) easy, perhaps trivial, while leaving (r,g,b,a) with their usual meanings, "the color", starting with the paint color.

This is easy to tweak into something like (x+0.5, y+0.5, 1) in (dr,dg,db) once this lands.  Mostly I just want to get all the uninteresting boilerplate out of the way first.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4791
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Change-Id: Ia07815d942ded6672dc1df785caf80a508fc8f37
Reviewed-on: https://skia-review.googlesource.com/4791
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-11-15 14:48:57 +00:00
Mike Klein
bd3fe475b8 Convert SkRasterPipeline loads and stores to indirect.
This allows us to change the underlying pointer without rebuilding the pipeline, e.g. when moving the blitter from scanline to scanline.

The extra overhead when not needed is measurable but small, <2%.  We can always add back direct stages later for cases where we know the context pointer will not change.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3943

Change-Id: I827d7e6e4e67d02dd2802610f898f98c5f36f8cb
Reviewed-on: https://skia-review.googlesource.com/3943
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-10-26 18:15:03 +00:00
Mike Klein
e9f74b89c0 SkRasterPipeline::compile().
I'm not yet caching these in the blitter, and speed is essentially unchanged in the bench where I am now building and compiling the pipeline only once.  This may not be able to stay a simple std::function after I figure out caching, but for now it's a nice fit.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3911

Change-Id: I9545af589f73baf9f17cb4e6ace9a814c2478fe9
Reviewed-on: https://skia-review.googlesource.com/3911
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-10-25 18:04:16 +00:00
Mike Klein
afb48b6227 Just add the F16 bench from https://skia-review.googlesource.com/c/2860/
BUG=skia:
TBR=msarett@google.com

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2875

Change-Id: I615d7aead07196f5c14b22be6f96e7d555a495a8
Reviewed-on: https://skia-review.googlesource.com/2875
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
2016-10-03 19:32:09 +00:00
Mike Klein
fa9f241a85 Add an enum layer of indirection for stock raster pipeline stages.
This is handy now, and becomes necessary with fancier backends:
   - most code can't speak the type of AVX pipeline stages,
     so indirection's definitely needed there;
   - if the pipleine is entirely composed of stock stages,
     these enum values become an abstract recipe that can be JITted.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2782
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Change-Id: Iedd62e99ce39e94cf3e6ffc78c428f0ccc182342
Reviewed-on: https://skia-review.googlesource.com/2782
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-09-29 18:11:29 +00:00
Mike Klein
baaf8ad952 Start moving SkRasterPipeline stages to SkOpts.
This lets them pick up runtime CPU specializations.  Here I've plugged in SSE4.1.  This is still one of the N prelude CLs to full 8-at-a-time AVX.

I've moved the union of the stages used by SkRasterPipelineBench and SkRasterPipelineBlitter to SkOpts... they'll all be used by the blitter eventually.  Picking up SSE4.1 specialization here (even still just 4 pixels at a time) is a significant speedup, especially to store_srgb(), so much that it's no longer really interesting to compare against the fused-but-default-instruction-set version in the bench.  So that's gone now.

That left the SkRasterPipeline unit test as the only other user of the EasyFn simplified interface to SkRasterPipeline.  So I converted that back down to the bare-metal interface, and EasyFn and its friends became SkRasterPipeline_opts.h exclusive abbreviations (now called Kernel_Sk4f).  This isn't really unexpected: SkXfermode also wanted to build up its own little abstractions, and once you build your own abstraction, the value of an additional EasyFn-like layer plummets to negative.

For simplicity I've left the SkXfermode stages alone, except srcover() which was always part of the blitter.  No particular reason except keeping the churn down while I hack.  These _can_ be in SkOpts, but don't have to be until we go 8-at-a-time.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2752
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Change-Id: I3b476b18232a1598d8977e425be2150059ab71dc
Reviewed-on: https://skia-review.googlesource.com/2752
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-09-29 16:20:26 +00:00
Mike Klein
c8dd6bc3e7 Rearrange SkRasterPipeline scanline tail handling.
We used to step at a 4-pixel stride as long as possible, then run up to 3 times, one pixel at a time.  Now replace those 1-at-a-time runs with a single tail stamp if there are 1-3 remaining pixels.

This style is simply more efficient: e.g. we'll blend and lerp once for 3 pixels instead of 3 times.  This should make short blits significantly more efficient.  It's also more future-oriented... AVX+ on Intel and SVE on ARM support masked loads and stores, so we can do the entire tail in one direct step.

This also makes it possible to re-arrange the code a bit to encapsulate each stage better.  I think generally this code reads more clearly than the old code, but YMMV.  I've arranged things so you write one function, but it's compiled into two specializations, one for tail=0 (Body) and one for tail>0 (Tail).  It's pretty tidy.

For now I've just burned a register to pass around tail.  It's 2 bits now, maybe soon 3 with AVX, and capped at 4 for even the craziest new toys, so there are plenty of places we can pack it if we want to get clever.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2717

Change-Id: I45852a3e5d4c5b5e9315302c46601aee0d32265f
Reviewed-on: https://skia-review.googlesource.com/2717
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-09-28 15:28:24 +00:00
Mike Klein
1f4a874add SkRasterPipeline: add last() and docs.
Today if you use the simple SK_RASTER_STAGE interface to build a pipeline, each stage you add calls into a next stage.  The last stage you add calls into a special backstop stage JustReturn that, well, just returns, ending the pipeline.

This adds last(), which cuts that last stage off the pipeline.  Instead, the stage you add using last() returns directly, ending the pipeline itself without jumping into JustReturn.

This reduces the overhead of using the pipelined version of SkRasterPipelineBench from ~25% to ~20% on my desktop.

Also, add docs.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2713

Change-Id: I11469378e2765c6e34db52eb3eef648d6612da3f
Reviewed-on: https://skia-review.googlesource.com/2713
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
2016-09-27 17:46:54 +00:00
mtklein
fe2042e60f SkRasterPipeline: new APIs for fusion
Most visibly this adds a macro SK_RASTER_STAGE that cuts down on the boilerplate of defining a raster pipeline stage function.

Most interestingly, SK_RASTER_STAGE doesn't define a SkRasterPipeline::Fn, but rather a new type EasyFn.  This function is always static and inlined, and the details of interacting with the SkRasterPipeline::Stage are taken care of for you: ctx is just passed as a void*, and st->next() is always called.  All EasyFns have to do is take care of the meat of the work: update r,g,b, etc. and read and write from their context.

The really neat new feature here is that you can either add EasyFns to a pipeline with the new append() functions, _or_ call them directly yourself.  This lets you use the same set of pieces to build either a pipelined version of the function or a custom, fused version.  The bench shows this off.

On my desktop, the pipeline version of the bench takes about 25% more time to run than the fused one.

The old approach to creating stages still works fine.  I haven't updated SkXfermode.cpp or SkArithmeticMode.cpp because they seemed just as clear using Fn directly as they would have using EasyFn.

If this looks okay to you I will rework the comments in SkRasterPipeline to explain SK_RASTER_STAGE and EasyFn a bit as I've done here in the CL description.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2195853002

Review-Url: https://codereview.chromium.org/2195853002
2016-07-29 14:27:41 -07:00
mtklein
566ea9b9fc Tune linear->sRGB constants to round-trip all bytes.
I basically just ran a big 5-deep for-loop over the five constants here.
This is the first set of coefficients I found that round trips all bytes.
I suspect there are many such sets.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2162063003
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Review-Url: https://codereview.chromium.org/2162063003
2016-07-20 12:10:11 -07:00
mtklein
281b33fdd9 SkRasterPipeline preliminaries
Re-uploading to see if I can get a CL number < 2^31.
    patch from issue 2147533002 at patchset 240001 (http://crrev.com/2147533002#ps240001)

Already reviewed at the other crrev link.
TBR=

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2147533002
CQ_INCLUDE_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Review-Url: https://codereview.chromium.org/2144573004
2016-07-12 15:01:26 -07:00