Move coordinate downsampling out of grid

The grid shouldn't be concerned with attributes of the level.
Rename base class member of level structs to "base"
grid: Drop unused grid size members from tilemap
grid: Restructure around base class
Pass grid handle to read_tile callbacks
Use grid instead of level in cache key

(level, x, y) will become ambiguous once we have nested grids.
grid: Abstract region math into a helper function
grid: Add read_tile wrapper to grid_ops
grid: Pass x/y/w/h to read_tile handler via struct region
grid: Pass desired region within a tile to tilemap callback

This is necessary for nested grids.  Don't pass the region to simple
callbacks, since simple grids won't be able to host subgrids (there's
nowhere to store the per-tile subgrid).