Home | History | Annotate | Download | only in contrib
      1 Contributing to SkJumper
      2 ========================
      3 
      4 SkJumper is the execution engine of SkRasterPipeline, a system we've been using
      5 to accelerate CPU-bound work inside Skia, most notably color-space conversions
      6 and color-correct drawing.
      7 
      8 (This is where I'd put my link to design document if I had one...)
      9 
     10 SkJumper is more annoying to contribute to than most Skia code because of its
     11 offline compilation step.  You'll need particular tools installed on your
     12 machine and to tell GN about them.  This document is designed to guide you
     13 through this process and ease some of that annoyance.
     14 
     15 One-time Setup
     16 --------------
     17 
     18 To generate stage code you need Clang 5.0, objdump, and ccache.  It's best that
     19 Clang is exactly the same version we typically use (as of writing 5.0.0) and
     20 you'll need objdump to be compiled with support for x86-64, ARMv7, and ARMv8.
     21 
     22 The easiest way to satisfy these contraints is to get your hands on a Mac and
     23 install [Homebrew](https://brew.sh).  Once you have `brew` installed, run this
     24 to get the tools you need:
     25 
     26 <!--?prettify lang=sh?-->
     27 
     28     brew install llvm binutils ccache
     29 
     30 Setting up GN
     31 -------------------------
     32 
     33 With your tools installed, tell GN about them
     34 
     35     skia_jumper_clang = path/to/clang-5.0
     36     skia_jumper_objdump = path/to/gobjdump
     37     skia_jumper_ccache = path/to/ccache
     38 
     39 then regenerate and build as normal.
     40 
     41 If you look in your GN out directory, you should now see a bunch of `.o` files,
     42 and `git status` should show no changes to `src/jumper/SkJumper_generated*.S`.
     43 That's good.  Those object files are the intermediates we parse to produce
     44 the assembly files.  We just leave them around in case you want to look at
     45 them yourself.
     46 
     47 Make A Change
     48 -------------
     49 
     50 Let's use the `from_srgb` stage as a little playground to make a real change.
     51 Linearizing sRGB encoded bytes is slow, so let's pretend we've decided to trade
     52 quality for speed, approximating the existing implementation with a simple square.
     53 
     54 Open up `SkJumper_stages.cpp` and find the `from_srgb` stage.  It'll look like
     55 
     56 <!--?prettify lang=cc?-->
     57 
     58     STAGE(from_srgb) {
     59         r = from_srgb(r);
     60         g = from_srgb(g);
     61         b = from_srgb(b);
     62     }
     63 
     64 Let's replace whatever's there with our fast approximation:
     65 
     66 <!--?prettify lang=cc?-->
     67 
     68     STAGE(from_srgb) {
     69         r *= r;
     70         g *= g;
     71         b *= b;
     72     }
     73 
     74 When you save and re-Ninja, you should now see changes to
     75 `src/jumper/SkJumper_generated.S` and `src/jumper/SkJumper_generated_win.S`.
     76 If you can't read assembly, no big deal.  If you can, run `git diff`.  You
     77 should see the various `sk_from_srgb_*` functions get dramatically simpler,
     78 something like three multiplies and a couple other bookkeeping instructions.
     79 
     80 It's not unusual for isolated changes in one stage to cause seemingly unrelated
     81 changes in another.  When adding or removing any code you'll usually see all
     82 the comments in branch instructions change a little bit, but the actual
     83 instruction on the left won't change.  When adding or removing uses of
     84 constants, you'll often see both the comment and instruction on the left change
     85 for other loads of constants from memory, especially on x86-64.  You'll also
     86 see some code that looks like garbage change; those are the constants.  If
     87 any of this worries you, please do go running to someone who knows more for
     88 help, but odds are everything is fine.
     89 
     90 At this point things should just be business as usual.  Any time you change
     91 `SkJumper_stages.cpp`, Ninja ought to notice and regenerate the assembly files.
     92 
     93 Adding a new Stage
     94 ------------------
     95 
     96 Adding a new stage is a lot like changing an existing stage.  Edit
     97 `SkJumper_stages.cpp`, build Skia, test, repeat until correct.
     98 
     99 You'll just need to also edit `SkRasterPipeline.h` to add your new stage to the
    100 macro listing all the stages.  The stage name is the handle normal Skia code
    101 uses to refer to the stage abstractly, and the wiring between
    102 `SkRasterPipeline::foo` and `STAGE(foo) { ... }` should work automatically.
    103