Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bye bye std::string in the GL library #499

Merged
merged 27 commits into from
Jan 2, 2023
Merged

Bye bye std::string in the GL library #499

merged 27 commits into from
Jan 2, 2023

Conversation

mosra
Copy link
Owner

@mosra mosra commented Mar 3, 2021

As usual, a Saturday afternoon task that turned out to cut much deeper than anticipated. Things to do:

  • port label() / setLabel() away from std::string -- bc88442
    • all label tests need to be updated to explicitly check that we handle non-null-terminated strings properly (the GL label APIs have an explicit size, so it should, but just in case)
    • duplicate setLabel()/label() tests for all Query and Texture subclasses in order to verify these are correctly implemented and exported (since those are all deinlined in new files now)
    • changelog entries, mention all the breaking changes
  • port DebugOutput, DebugGroup away from std::string
    • test for non-null-terminated strings
    • explicit test for the deprecated debug output callback
    • changelog entries, mention all the breaking changes
  • port Shader and AbstractShaderProgram away from std::string
    • test for non-null-terminated strings
    • #line statements added to shader sources need Utility::format() to return a String -- mosra/corrade@ea9f217
    • Shader::addFile() needs Utility::Path::readString() to return a String -- mosra/corrade@a211a75
    • Shader tests need expanding quite a lot to verify we're correctly copying (or not) if and only if the input view isn't global
    • changelog entries, mention all the breaking changes
  • port the nasty workaround for xfb outputs for NV on Windows
    • test for non-null-terminated strings
    • needs explicit testing from someone with a NV card and Windows
  • various <string> includes may need to be added to various places not anymore, 65a935c
    • ideally I should first fix CORRADE_SKIP() to not need them, because that's the major reason for these -- mosra/corrade@8d077cc
  • Drop the std::pair from AbstractShaderProgram::validate() as it's a breaking change already anyway
    • Take that as a chance to remove it from all internal places in GL as well
  • Update Shader::compile() to use an ArrayTuple for the output instead of two allocations
  • Update builtin shaders to use string view literals, avoiding temporary allocations
    • The actual improvement will happen once Utility::Resource starts supporting null-terminated views -- mosra/corrade@9ef4b4a
    • Look at the improvements with Heaptrack to be actually sure about the improvement

Related to: #293

@mosra mosra added this to the 2021.0a milestone Mar 3, 2021
@LB--
Copy link
Contributor

LB-- commented Mar 18, 2021

the nasty workaround for xfb outputs for NV on Windows needs explicit testing from someone with a NV card

I have a GTX 1660 Ti, will that work?

@mosra
Copy link
Owner Author

mosra commented Mar 18, 2021

Yes, absolutely. I'll keep you in mind when I get back to this :)

mosra and others added 26 commits January 1, 2023 23:51
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.
Those are reserved for temporary TODOs and debugging, not meant to stay
there forever.
So far everything everywhere was just testing the success case, without
checking that the message is properly retrieved and returned. Sigh.
The test added in previous commit passed on Mesa, but not on
SwiftShader.
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.
Do it the same as for the skinning stuff, format() and string
multiplication. No need to get this crazy.
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>
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>
Apparently even `= {}` was broken for std::pair once, not to mention the
unnecessary extra overhead with this type not being trivially copyable.
Good riddance.
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.
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.
One of the last remaining leftovers.
From some, at least. The easings need to wait for a growable String.
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.
Not built by default, but handy for profiling.
@mosra mosra force-pushed the gl-bye-bye-std-string branch from 44b27f5 to ac03515 Compare January 1, 2023 23:24
@mosra mosra merged commit ac03515 into master Jan 2, 2023
@mosra mosra deleted the gl-bye-bye-std-string branch January 2, 2023 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants