In SkMatrix44.cpp, a matrix is considered uninvertible when its
determinant is smaller than 1e-8. This is an arbitrary absolute
threshold, and valid invertible matrices can have a tiny determinant
which then makes the matrix appear uninvertible. This causes layers
in chromium to disappear because compositor thinks they can't be drawn
validly. -->
https://code.google.com/p/chromium/issues/detail?id=222926
One possible bold solution - always decide the matrix is invertible,
unless the determinant is NaN or Inf (i.e. check
isfinite(determinant) or equivalent).
I tried this, and empirically, the world still seems to work. I
checked manually on various sites, ui_unittests, cc_unittests, and
compositing/transform layout tests. Only a few unit tests would need
updating.
Caveats if we would do this:
- may need to deal with some platform-dependent annoyance to get
isfinite() equivalents everywhere.
- catastrophic cancellation could occur. But I'm not seeing why this
would actually be a problem!
So I think it boils down to this: Is catastrophic cancellation really
an important issue for chromium/skia use case? Has anyone seen this
issue in chrome that motivated the arbitrary 1e-8 absolute threshold?
It seems to me that when catastrophic cancellation really does occur
in a 3d geometry scene, it's actually reasonable that the huge value
dominates and the small values get lost. We're not computing anything
in an iterative feedback loop, so cancellation errors would not
accumulate across frames of an animation. Within one frame, values
for bounding rects or transformed points that become obscenely large
is something we would need to handle correctly anyway, since they can
occur even without these "uninvertible" matrices. But to aggressively
say a matrix is not invertible just to avoid that issue seems to be
causing issues that actually don't exist?
thoughts?
~Shawn