* On the immediate context after an ExecuteCommandList we were properly
restoring the state if specified, but if the state isn't to be
restored it must be cleared - otherwise we incorrectly inherit state
from the deferred context.
* ARB_texture_view only works on textures allocated with
ARB_texture_storage so we have to check for both extensions and then
use texture storage to allocate space for the destination array
texture.
* This means we don't have a lingering size >0 for an array that won't
be used for NULL. Mostly on read this is immaterial but on write it
is significant.
* This is a *very* light-touch analytics system that will track the
simplest and most anonymous statistics that can be useful in
determining which features are most used or perhaps underused, and
where it's best to direct development attention.
* It is entirely implemented in the UI layer, no analytics-gathering
code exists in the library that's injected into programs, and of
course no capture data (screenshots, resource contents, shaders, etc
etc) is transmitted.
* Once it's turned on, it will apply to both development and release
builds. It tracks stats over a month, and then at the beginning of a
new month it sends the previous data.
* When the user first starts up a build with analytics if there's no
previous analytics database then they are informed of the new code and
asked to approve it. They have the option of selecting to manually
verify any sent reports, or just opt-ing out entirely.
* When we need to cache a texture or buffer locally then before this
commit we'd transfer the whole resource, and re-transfer it every time
the event changed even if the contents haven't changed.
* Instead now we track the previous contents on both sides, and just
send a list of deltas to apply.
* On android reading pixel-by-pixel out of the mapped memory is
*incredibly* slow - taking up to 1.5s for a fullscreen depth texture.
It's faster to copy to a temporary array, and this shouldn't have a
huge effect on other platforms.
* Previously each read and write would 1:1 become a send or recv call.
* Now we buffer writes and send in batch (or when a chunk finishes),
and every time we read we try to non-blocking read more data to fill
the buffer, to allow batching reads where possible without blocking
on data that will never come.