They're not parsed since 6b22a11170
(2020), so there's no point in keeping those workarounds. They're only
kept in utility application sources as they're parsed for pages, and in
tweakable implementations where it's easier to just copypaste the whole
ifdef expression from the header every time instead of modifying it to
not include DOXYGEN_GENERATING_OUTPUT.
The test added in previous commit now passes. Besides the behavior being
different for single- and multi-bind calls, an additional "interesting"
behavior is that the glBindBufferBase() / glBindBufferRange()
apparently also creates the GL object, if not already (in contrast to
the multi-bind APIs which *require* the GL objects to be created
before).
And use static functions with an explicit "self" pointer instead. Those
have half the size (8 vs 16 bytes on 64bit x86), which in turn reduces
the state tracker memory use by about 750 bytes. On desktop GL with an
Intel GPU & Mesa this reduces the state tracker allocation size by almot
10%, from 8.3 kB to 7.6 kB. Not bad.
Apart from small memory savings, this also removes the need to include
the full class definiton from the State headers on MSVC (because
on that compiler the member function pointer size is different based on
whether the type definition is known or not, IMAGINE THAT BEING A
FEATURE AND NOT A BUG), leading to less header dependencies and better
incremental compile times there.
This was already done in some cases (and the Vk library used this from
the beginning), and as I'm about to add some more extension-dependent
functionality it felt like a good time to finish that change, finally.
In some cases the *Implementation() could even be dropped in favor of
pointing to the GL API directly (such as is already done for various
glUniform*() calls), that'd be another step -- this is good enough for
now.
Apparently even `= {}` was broken for std::pair once, not to mention the
unnecessary extra overhead with this type not being trivially copyable.
Good riddance.
Since glGetBufferSubData() is only exposed on Emscripten 2.0.17 and up,
both functions are not available on older versions. This is to avoid any
accidental foot guns since it explodes at compile time. The webgl2 CI
will be upgraded to 2.0.17 in a later commit.
All the tests were updated to explicitly check that non-null-terminated
strings get handled properly (the GL label APIs have an explicit size,
so it *should*, but just in case). Also, because various subclasses
override the setter to return correct type for method chaining and the
override has to be deinlined to avoid relying on a StringView include,
the tests are now explicitly done for each leaf class, instead of the
subclass
The <string> being removed from the base class for all GL objects may
affect downstream projects which relied on it being included. In case of
Magnum, the breakages were already fixed in the previous commit.
Compile time improvement for the MagnumGL library alone is 0.2 second or
4% (6.1 seconds before, 5.9 after). Not bad, given that there's three
more files to compile and strings are still heavily used in other GL
debug output APIs and all shader stuff. For a build of just the GL
library and all tests, it goes down from 28.9 seconds to 28.1. Most
tests also still rely quite heavily on std::stringstream for debug
output testing, so the numbers still could go further.
Also test it properly and add a check for extension availability. Sigh,
seems like nobody ran this test on an Apple device since this thing got
added in 75d238f50b ...
This means that instead of 12 separate allocations we have just one,
allocating everything together in a contiguous piece of memory. That
should be also a bit more cache friendly when accessing the state as
it's not scattered around the memory like crazy.
Because there are no Pointer indirections needed anymore, the State
members are just references now. That resulted in a lot of sweeping
changes around the whole GL library, but they're all trivial, changing
`->` to `.`, mostly.
There's two more nested allocations in the TextureState struct, will
take care of them in a separate commit.
Bloaty says it saved 10 kB in Debug build of MagnumGL:
VM SIZE FILE SIZE
-------------- --------------
[ = ] 0 .debug_info +1.59Ki +0.0%
+0.4% +1.50Ki .text +1.50Ki +0.4%
[ = ] 0 .debug_str +409 +0.0%
[ = ] 0 .debug_line +276 +0.1%
[ = ] 0 .debug_abbrev +20 +0.0%
-28.6% -2 [LOAD [RX]] -2 -28.6%
[ = ] 0 [Unmapped] -4.28Ki -41.0%
-22.7% -9.23Ki .rodata -9.23Ki -22.7%
-0.8% -7.73Ki TOTAL -9.73Ki -0.1%
And 4 kB in Release:
VM SIZE FILE SIZE
-------------- --------------
+1.1% +3.44Ki .text +3.44Ki +1.1%
+1.7% +1.39Ki .eh_frame +1.39Ki +1.7%
[ = ] 0 [Unmapped] +656 +51%
-25.5% -9.47Ki .rodata -9.47Ki -25.5%
-0.7% -4.64Ki TOTAL -4.00Ki -0.4%
That's not negative, so I guess that's good. This change is of course
more significant in the context of a minimal WebGL build, where the exe
can be as little as 50 kB -- there 4 kB is almost 10% of the size.
Was Magnum::GL::Extensions::GL before and the redundancy was completely
unnecessary. Potential future extensions coming from GLX, EGL or whatnot
will most probably be in the Platform namespace in a completely separate
file, so this is not a problem.
All code internal to the GL library is affected, not much the outside,
as that is handled by the compatibility alias.
At the moment just the GL library itself w/o the tests, and without
backwards compatibility aliases. The following types were left in the
root namespace, despite being in the GL/ directory, as they will get
moved back soon:
* Image, CompressedImage and their dimensional typedefs
* ImageView, CompressedImageView and their dimensional typedefs
* PixelStorage
Not PixelFormat etc., that one will stay in the GL namespace and a
completely new PixelFormat enum will be provided in the root namespace.
Minimal updates (just the include guards) so Git is hopefully able to
detect the rename and track the history properly.
Everything except Magnum::GL doesn't compile now.
They were utterly confusing, as it was completely unclear what the units
of offset/size parameters are, whether byte sizes or element counts (and
moreover, some of these APIs had offset in bytes and size in count and
some not). All of those are deprecated now, with hinting the user to
convert to non-templated APIs in combination with
Containers::arrayCast(). Moreover, the non-templated range map()
function doesn't return just void* anymore, but a properly sized
ArrayView<char>. The old map() (which doesn't take range) still returns
just a pointer (but also a char* instead of void* for consistency), as
getting size there is non-trivial (and impossible on old ES/WebGL).
The switch to ArrayView might be a source breaking change, but I
silently hope that everyone was just using the templated functions
anyway (that are deprecated now). So, in short, this was before:
T* a = buf.map<T>(0, size_in_what_i_have_no_idea);
And this is now, with proper size safety and clear API:
ArrayView<T> a = Containers::arrayCast<T>(buf.map(0, size_in_bytes);
The deprecated APIs will be removed at some point in the future, as
usual.