* Given socket corruption or network errors these strings could contain
unprintable characters so we sanitise them reasonably. This also ameliorates a
potential security concern with arbitrary strings being written to a log, but
these connections are still considered trusted and users should not be
exposing RenderDoc ports to the internet.
* Most of the main entry points that can fail with relevant reasons now has a
way of specifying a message to return with it. This message can be displayed
to the user to give more information or context about an error.
* If the RenderDoc UI connects to a program, opens then deletes the captures,
then closes and is opened again - we don't want to report those deleted
captures as if they still exist. This now clears out any captures that no
longer exist.
* When a port is specified (with the usual :12345 suffix on the hostname) we use
that for remote replay connections. We disable target control enumeration
since that requires a port _range_ and captured applications self-assign those
ports. Those can still be accessed via a normal unsuffixed remote specifier -
even if there is no remote server running on the default port.
* This is a bit coarse, as e.g. if you have one window that is unsupported on an
API and another that is this will treat both as supported even if the active
window doesn't support capturing. This is an unlikely case and needs a new UI
to properly represent that.
* This prevents unnecessary conversions back and forth between rdcstr and const
char * when going through interfaces. In the OS specific layer this is rarely
an issue because most of the implementations don't convert to rdcstr, but it
is convenient to be able to pass in an rdcstr directly. The few cases where
there's an unecessary construction of an rdcstr is acceptable.
* A couple of places in the public API need to return a string from a global
function, so can't return an rdcstr due to C ABI, so they still return a const
char *.
* Similarly const char * is kept for logging, to avoid a dependency on rdcstr
and because that's one place where unnecessary conversions/constructions may
be impactful.
* Mostly moving includes from common headers to cpp where possible, and removing
includes of the whole thing where only enums or rdcstr etc are needed.
A new button is added to the UI so that we can cycle the currently active window when there are more windows to capture. It's like pressing the F11 button but it works on Android too.
* If the export doesn't need buffers, we export directly from the loaded
capture file instead of re-loading it.
* Add progress bars for the load step so it shows what's happening
instead of looking stalled.
* Reduce compression rate on XML+ZIP buffers as it took too long trying
to compress when exporting large captures.
* We assume that if the user injected libVkLayer_GLES_RenderDoc.so then
it's either a vulkan app and that's sufficient, or they linked
against it.
* Injecting our libraries over the top of that could cause problems -
at worst crashes, or at best we could end up with nested hooking with
double overhead, or the loaded renderdoc library won't be the one that
hooks and the workflow will break.
* We also make the frame counting consistent: Frame 0 is the frame from
device initialisation to first present, Frame 1 is from first present
to second, and so on after that.
* Mostly used for passing a progress float back during a long blocking
call like opening a capture or doing a copy.
* This is much more feasible for python to bind to.
* In several cases we just use a tiny lambda that updates a float anyway
since we can't push the progress directly into a progress dialog, but
need to let it query from a temporary in-between float.
* We also let an API be active without presenting, and then note when it
starts presenting. This lets us detect the case where an API has been
started up and used, but isn't presenting so we're not able to capture
it. Less confusing than telling the user no API is detected, and lets
us direct them to the relevant documentation.
* There's also a flag indicating if the API can be captured even if it
does present.
* We enforce a naming scheme more strongly - types, member functions,
and enum values must be UpperCaseCamel, and member variables must be
lowerCaseCamel. No underscores allowed.
* eventId not eventID or EID, and Id preferred to ID in general. Also
for resourceId.
* Removed some lingering hungarian m_Foo naming.
* Some pipeline state structs that are almost identical between the
different APIs are pulled out into common structs. Where something
doesn't make sense (e.g. viewport enable for vulkan) it will just be
set to a sensible default (in that case always true).
* Changed scissors to be x/y & width/height instead of sometimes
left/top/right/bottom
* Abbreviations are discouraged, e.g. operation not op, function not
func.
* 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.
* Previously once we started loading a capture we'd blindly continue
until we loaded it (and then it's assumed to be successful), or we
crash.
* Now errors can be reported during serialisation and bubbled up to
abort the file load process. The next steps are to add error checking
in each function serialise before doing any replay calls to the API
with potentially corrupt data, and on top of that catching API-only
errors when the serialisation is (seemingly) fine, and propagating
those in a reasonable way.
* We also harden the serialisation a bit so that if it reads an
obviously invalid byte length for a buffer or array count, it won't
continue. It's still not perfect as the sizes could still be large and
invalid but within range, but it should catch the worst cases.
* When opening a capture file, a format is now available to allow
easy import from another format without a completely different
interface. Only rdc files can be replayed, but any other file can
load and access structured data through the same interface.
* The replay initialisation and capture writing interfaces also use the
RDCFile instead of passing filenames or Serialisers around directly.
Driver initialisation parameters are now entirely private, and don't
need to be exposed - any agnostic metadata like thumbnail, driver, etc
are all accessed via the RDCFile container itself.
* Callstack resolution is now part of the container file, not the
back-end via way of its Serialiser.
* Importers/Exporters to other non-RDC formats are registered in a
similar way to replay/remote drivers.
* It is also then possible to construct an RDC file from thin air, by
creating an empty RDCFile container and filling it with data, then
requesting it to be written to disk.
* Since these types are more prevalent than originally designed, it
makes more sense to remove the namespace for ease of typing/naming.
* Also add a specialised type 'bytebuf' for an array of bytes.
* This makes mapping easier to SWIG since there's no special casing for
namespaced arrays. Especially so for nested cases like
rdctype::array<rdctype::str> -> rdcarray<rdcstr>