Because I got tired of having to manually postprocess ground truth files
for shader tests.
A bit strange / funny that the first ever version of my code manages to
produce smaller files than both stb_image and ImageMagick (with
-compress RunTimeLengthEncoded), for some reason both pick some strange
inefficient run combinations in various scenarios, such as "copy 2" +
"repeat 3" where I pick "repeat 5". And the difference is not
insignificant -- when testing with some shader test files, it resulted
in a ~17% smaller size!
The plugin follows the stricter variant of the spec by default (i.e.,
splitting runs across scanline boundaries) -- so that's *not* the
reason for the weird differences between my code and theirs -- but
provides an option to not do that for even smaller files. Which I'm
going to use for shader ground truth test files, because there every
byte counts. This option together with the above difference causes files
to be ~25% smaller, which is quite a lot.
Mainly important for Shader::addSource() to prevent it from creating a
needless copy, but doesn't hurt to do the same also for
uniformLocation(), bindAttributeLocation() etc. -- it'll avoid a runtime
strlen() in that case at least.
And this, this change allows the growable Array to use malloc() instead
of new, and thus also realloc(), saving unnecessary reallocations if the
memory can be grown in-place. All because Containers::Pair is trivially
copyable while std::pair wasn't.
There isn't any good reason to use the STL anymore.
Hm, and here I used the "capability" of std::pair that allowed it to
store references. I don't even want to know what all was involved to
support that, Containers::Reference is much easier to reason about.
Apparently even `= {}` was broken for std::pair once, not to mention the
unnecessary extra overhead with this type not being trivially copyable.
Good riddance.
Given that I made a breaking change by returning Containers::String
instead of a std::string, I can take it further and replace also
std::pair with Containers::Pair -- it won't bring any more pain to the
users, they have to change their code anyway.
Co-authored-by: Hugo Amiard <hugo.amiard@wonderlandengine.com>
Same as in the previous commit, most cases are inputs so a StringStl.h
compatibility include will do, the only breaking change is
GL::Shader::sources() which now returns a StringIterable instead of a
std::vector<std::string> (ew).
Awesome about this whole thing is that The Shader API now allows
creating a shader from sources coming either from string view literals
or Utility::Resource completely without having to allocate any strings
internally, because all those can be just non-owning references wrapped
with String::nullTerminatedGlobalView(). The only parts which aren't
references are the #line markers, but (especially on 64bit) those can
easily fit into the 22-byte (or 10-byte on 32bit) SSO storage.
Also, various Shader constructors and assignment operators had to be
deinlined in order to avoid having to include the String header, which
would be needed for Array destruction during a move.
Co-authored-by: Hugo Amiard <hugo.amiard@wonderlandengine.com>
Most of these are just inputs, so a compatibility StringStl.h include
will do, the only exception is the callback for which there needs to
stay a deprecated overload (which is internally delegated from the
StringView one).
Also explicitly testing with non-null-terminated strings -- the APIs
take an explicit size so it shouldn't be a problem, but it's always good
to have this verified independently. Drivers are crap, you know.
One consequence of no longer using an impossible-to-forward-declare
std::string is that I had to deinline the DebugGroup constructor because
it no longer worked with just a forward-declared StringView.
The previous callback pointer was needed just to disambiguate, so it can
be a bool; the user pointer can be set from the caller already instead
of being done in each variant again.