gonetz / GLideN64

A new generation, open-source graphics plugin for N64 emulators.
Other
772 stars 180 forks source link

Dynamic code adaptability to GL versions. #1276

Closed gonetz closed 7 years ago

gonetz commented 7 years ago

GLideN64 currently supports the following graphics API: OpenGL, GLES2, GLES3, GLES3.1 OpenGL support also divided on GL 3.3 and GL 4.3+ It causes the following problems:

My primary concern is variety of version specific code. I made lots of efforts to keep all specific stuff in separate files, but it still plagues parts of code, which intended to be general for all GL versions. Now I want to try to create a proxy class, which will separate algorithms in code from concrete graphics functions and hide all details about their initialization and use. I (think that I) know how to do it on desktop, but I don't have good understanding of the situation on mobile platforms. I want to clarify the following:

This also related to number of GLideN64 build for Android. If we can load everything via eglGetProcAddress, can we provide only one version of GLideN64, which will ask for necessary GL context via

    CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, _);
    CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, _);

?

fzurita commented 7 years ago

Is it possible to get all necessary functions, provided by GLES_X version and defined in <GLESX/glx.h> via EGL mechanism? For example, if I found that GL version is GLES2.0, can I get all functions from gl2.h via eglGetProcAddress?

Yes. In fact, the gl31.h header file is backwards compatible with gl3.h and g2.h. All functions can be loaded using eglGetProcAddress. If we try to retrieve a gles 3.1 function in a device that has an older gl version, we won't get a valid function.

Is EGL/egl.h available for all supported Android devices?

Yes, EGL is standard in Android starting in API level 9. Mupen64Plus AE currently has a required API level of 15.

Here is a funny tidbit about EGL: https://twitter.com/id_aa_carmack/status/387383037794603008

Edit: It appears I did some research a while back on EGL, see this pull request: https://github.com/gonetz/GLideN64/pull/998 And to quote:

Hmmm.... eglGetProcAddress may not be reliable against all Android versions/devices, specially against GLES core functions. dlSym can be used under those circumstances instead though... need to do more research.

Edit: After more research, eglGetProcAddress should be reliable against all extension functions. If the KHR_get_all_proc_addresses extension is implemented, eglGetProcAddress is reliable against all functions. If not, dlsym should be used to load the core functions.

Edit 2: More updates. KHR_get_all_proc_addresses is implemented in EGL 1.4 which is included in API level 17 of android and higher. For older devices, dlsym should be used for core functions.

API level 17 is Android version 4.2. So if we don't want to use dlsym, we can drop support for Android version 4.1 and below. I vote for dropping support since those devices can't run GLideN64 well at all.

fzurita commented 7 years ago

Here is where it says that gles 2, 3, 3.1, and 3.2 can share header files:

https://www.khronos.org/registry/gles/#headers32

Errr, it doesn't actually say that, it only says that gl2ext.h can be shared. But any ways, I'm still pretty sure the same header file can be used for all supported GLES functions.

Edit: This could be useful: https://github.com/Dav1dde/glad

gonetz commented 7 years ago

So, we can load everything needed via EGL. Great! Can we provide only one version of GLideN64, which can ask application for GL context for any GL version supported by device?

fzurita commented 7 years ago

I think that will be more difficult. I don't think GL and GLES headers are compatible. We should see how dolphin does this and use them as a model. I think they use one binary for all GL versions.

gonetz commented 7 years ago

glad can generate a common header for all GL versions. In fact, it is not so important. I can use different loaders for each GL version. Each loader may use its own header. I more concerning about link issues: do you need to link separate lib for each GLES version?

fzurita commented 7 years ago

No, they can all link against the EGL shared object library.