OpenImageIO/oiio — pull request #260 by lgritz (2012-03-22 00:42:08+00:00)
Title: Review: Optimize texture MIPmap level switching for TIFF textures

Observation: the texture system is often reading tiles from an image file very incoherently with respect to the MIPmap level (e.g., one tile may be from mip level 3, the next from 4, the next from 3, the next from 5, etc.). This translates to a call sequence of: seek_subimage, read_tile, seek_subimage, read_tile, etc. It so happens that for TIFF files, every seek_subimage call was rather expensive, doing a TIFFSetDirectory and riffling through the TIFF tags to create a completely new ImageSpec including all metadata. This is very expensive, and could tend to happen on every tile read. This is fairly unique to TIFF, and isn't very expensive to do a seek_subimage for OpenEXR images, for example.

Observation #2: Except for resolution, obviously, we don't expect any of the rest of the metadata to differ between levels of a MIPmap (not in the way it would between distinct subimages in a multi-image file, for example). And even if it did, the texture system doesn't care; it considers level 0 to be the canonical metadata (other than resolution, offset, and tile size) for the whole subimage.

So this patch optimizes texture MIPmap level switching for TIFF textures -- when merely switching MIP levels (not subimages), we avoid clearing m_spec and rediscovering all the metadata from scratch, instead only altering the fields that are expected/allowed to change between MIP levels.

I'm running some benchmarks to see if this translates to an important performance improvement, I will report back. But it seems wasteful to do what we were doing before, this has to cut down a lot on the time it takes to fetch a tile into the ImageCache, and consequently should improve threading performance because locks and whatnot will not need to be held as long if tile reads are faster.