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

Get better OpenGL version than 2.1 on macOS #3895

Closed

Conversation

metayan
Copy link

@metayan metayan commented Apr 5, 2023

Normally macOS gives us only OpenGL 2.1, but if we request 3.3 and create a new context, we get the best OpenGL version it has to offer.

Before:
INFO: Renderer: opengl
INFO: OpenGL version: 2.1 NVIDIA-14.0.32 355.11.11.10.10.143
WARN: Trilinear filtering disabled (OpenGL 3.0+ or ES 2.0+ required)

After:
INFO: Renderer: opengl
DEBUG: Creating GL Context
INFO: OpenGL version: 4.1 NVIDIA-14.0.32 355.11.11.10.10.143
INFO: Trilinear filtering enabled

when running with
--verbosity=verbose --render-driver=opengl

Note:
Since SDL_CreateRenderer causes a fallback to OpenGL 2.1, the profile and version attributes have to be set and the context created after.
This took a while to figure out.

Normally macOS gives us only OpenGL 2.1, but if we request 3.3 and
create a new context, we get the best OpenGL version it has to offer.

Before:
INFO: Renderer: opengl
INFO: OpenGL version: 2.1 NVIDIA-14.0.32 355.11.11.10.10.143
WARN: Trilinear filtering disabled (OpenGL 3.0+ or ES 2.0+ required)

After:
INFO: Renderer: opengl
DEBUG: Creating GL Context
INFO: OpenGL version: 4.1 NVIDIA-14.0.32 355.11.11.10.10.143
INFO: Trilinear filtering enabled

when running with
--verbosity=verbose --render-driver=opengl

Note:
Since SDL_CreateRenderer causes a fallback to OpenGL 2.1, the profile
and version attributes have to be set and the context created _after_.
This took a while to figure out.
Copy link
Collaborator

@rom1v rom1v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution.

Since SDL_CreateRenderer causes a fallback to OpenGL 2.1

Do you know where (in the SDL codebase)?

if we request 3.3 and create a new context, we get the best OpenGL version it has to offer.

What if the latest version available is <3.3? It will fail in that case.

I'm a bit afraid that this change is specific to your machine/drivers, and that it may fail otherwise.

If OpenGL 3 or 4 can be available on macOS, IMO it should even be changed on SDL directly (we can still try to make it work better on scrcpy temporarily).

app/src/screen.c Outdated
// Persuade macOS to give us something better than OpenGL 2.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if OpenGL 3.3 is not available? Is there a way to know which version is available?

Why SDL does not use the latest version availabe?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a macOS OpenGL strangeness that SDL seems to have left up to us to solve.
More explained in #3895 (comment) below.

app/src/screen.c Outdated
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
LOGD("Creating GL Context");
SDL_GLContext *gl_context;
gl_context = SDL_GL_CreateContext(screen->window);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably needs a matching SDL_GL_DestroyContext() somewhere.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Added SDL_GL_DeleteContext().

This way we get the best available OpenGL version on macOS.

Explanation at
Genymobile#3895
@metayan
Copy link
Author

metayan commented Apr 5, 2023

EDIT: Please ignore this - I found a better solution, which I'll push shortly.

Since SDL_CreateRenderer causes a fallback to OpenGL 2.1

Do you know where (in the SDL codebase)?

Found it mentioned at
https://stackoverflow.com/a/23858884
"… SDL lowering the context version is due to the fact that the renderer is implemented with OpenGL 2.1 calls, so it needs to create a 2.1 GL context."

Also discussed at
libsdl-org/SDL#1957
which ends with
"Marking won't fix for now, since the SDL render API doesn't support Core Profile."

if we request 3.3 and create a new context, we get the best OpenGL version it has to offer.

What if the latest version available is <3.3? It will fail in that case.

Changed to select OpenGL 3.2.

According to page 24 of
https://developer.apple.com/opengl/OpenGL-Capabilities-Tables.pdf
all hardware and software renderers can use OpenGL 3.2 since macOS 10.7.5.

Also, when choosing 3.2, I actually get 4.1, which is the highest that my computer supports under macOS:

INFO: Renderer: opengl
DEBUG: Creating OpenGL 3.2 Context
INFO: OpenGL version: 4.1 NVIDIA-14.0.32 355.11.11.10.10.143
INFO: Trilinear filtering enabled

Apparently that is how Apple chose to handle it:
"for macOS you either have 3.2 or 4.1, nothing in between"
from ocornut/imgui#1466 (comment)

A more thorough explanation of macOS OpenGL peculiarities:
ocornut/imgui#1466 (comment)

I'm a bit afraid that this change is specific to your machine/drivers, and that it may fail otherwise.

It seems like it's specific to OpenGL under macOS in general.
For the record, I'm using Catalina (10.15.7).
The change only affects the OpenGL drivers, so those who don't specify --render-driver=opengl get METAL under macOS.

If OpenGL 3 or 4 can be available on macOS, IMO it should even be changed on SDL directly (we can still try to make it work better on scrcpy temporarily).

The option to use higher OpenGL versions under macOS has been available for a long time, and SDL supports using them, but not automagically.

A solution in Lisp, for example, which starts with the highest version and keeps decreasing it until a context is created:
https://github.com/cbaggers/cepl.sdl2/blob/6da5a030db5e3579c5a1c5350b1ffb8fc9950e9a/cepl.sdl2.lisp#L139-L155

@metayan
Copy link
Author

metayan commented Apr 6, 2023

By only setting the Core Profile for the context, without specifying the OpenGL version, macOS seems to choose the highest available OpenGL version.

I've modified the PR accordingly.

The reason why SDL doesn't do this automagically:

Platform Issue (MacOSX): When MacOSX 10.7 introduced support for OpenGL beyond 2.1, they also introduced the core/compatibility dichotomy. However, they did not introduce support for the compatibility profile itself. Instead, MacOSX gives you a choice: core profile for versions 3.2 or higher, or just version 2.1. There is no way to get access to features after 2.1 and still access the Fixed Function Pipeline.

From https://www.khronos.org/opengl/wiki/OpenGL_Context#OpenGL_3.2_and_Profiles

@rom1v
Copy link
Collaborator

rom1v commented Apr 7, 2023

Thank you for the details 👍

I had a refactor commit related to screen/display on a local branch that I just pushed to dev: 051b74c

I rebased/reapplied your work above. Please check and review branch macos_opengl.

@metayan
Copy link
Author

metayan commented Apr 7, 2023

Looks good and works now.

@metayan metayan closed this Apr 7, 2023
@metayan metayan deleted the get-better-opengl-version-on-macos branch April 7, 2023 13:33
@rom1v
Copy link
Collaborator

rom1v commented Apr 7, 2023

You should not have closed it, it's not merged yet, and I cannot reopen since your branch has been deleted :/

I would like other people to test branch macos_opengl (with scrcpy --Vdebug --render-driver=opengl) on macOS before merging 😄

@metayan metayan restored the get-better-opengl-version-on-macos branch April 7, 2023 14:30
@metayan
Copy link
Author

metayan commented Apr 7, 2023

Oh, sorry.
Luckily I hadn't deleted it locally yet, so pushed it again.
Reopening. Hope it works.

@metayan metayan reopened this Apr 7, 2023
@metayan
Copy link
Author

metayan commented Apr 7, 2023

I thought that it's fine to delete, since it's in macos_opengl.
Well, we learn... ;)

@metayan
Copy link
Author

metayan commented Apr 7, 2023

Should I do something about the "This branch has conflicts that must be resolved" that's being shown at the end of this thread?

rom1v pushed a commit that referenced this pull request Apr 12, 2023
By default, SDL creates an OpenGL 2.1 context on macOS for an OpenGL
renderer. As a consequence, mipmapping is not supported.

Force to use a core profile context, to get a higher version.

Before:

    INFO: Renderer: opengl
    INFO: OpenGL version: 2.1 NVIDIA-14.0.32 355.11.11.10.10.143
    WARN: Trilinear filtering disabled (OpenGL 3.0+ or ES 2.0+ required)

After:

    INFO: Renderer: opengl
    DEBUG: Creating OpenGL Core Profile context
    INFO: OpenGL version: 4.1 NVIDIA-14.0.32 355.11.11.10.10.143
    INFO: Trilinear filtering enabled

when running with:

    scrcpy --verbosity=debug --render-driver=opengl

Note: Since SDL_CreateRenderer() causes a fallback to OpenGL 2.1, the
profile and version attributes have to be set and the context created
_after_.

PR #3895 <#3895>

Signed-off-by: Romain Vimont <rom@rom1v.com>
@rom1v
Copy link
Collaborator

rom1v commented Apr 12, 2023

Merged 👍 Thank you.

I would like other people to test branch macos_opengl (with scrcpy --Vdebug --render-driver=opengl) on macOS before merging 😄

I've got a confirmation that it works as expected. 👍

@rom1v rom1v closed this Apr 12, 2023
@metayan metayan deleted the get-better-opengl-version-on-macos branch November 28, 2023 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants