implement matrix 0/1 todo

I figured I'd get this in while it was on my mind.

The first order pattern we're implementing here is

   return val == special_case ? p->splat(special_case)
                              : p->uniformF(uniforms->pushF(val));

which is, when we have a special case that we know skvm::Builder can
fold through, tell it about that by using splat() instead of a uniform.
That's exactly what we're doing for the bias column of the matrix;
adding zero will fold away into a no-op.

In the multiply we need to be a little more clever, because Builder will
not actually optimize x*0 into 0.  That's only true for most values, but
notably not inf/NaN.  So instead we do that folding ourselves, assuming
we won't encounter any inf/NaN color values (an untested assertion that
I trust you believe in).

smart_mad() is also a convenient place to test for 1*x+y -> x+y and
-1*x+y -> y-x.  skvm::Builder would do the first if we splatted the
1.0f, and I'm not sure about the second, but since we're optimizing
ourselves anyway, might as well handle all three in the same way.

Change-Id: I1733ef948268144df98d6f83cd455087ceab05e6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/279541
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Reed <reed@google.com>
1 file changed