OpenGL/ES20 Proxy Library Detailed Design (Draft)

Revision

Version

Author

Date

Notes

0.90

Jammy Zhou

Nov 25, 2010

Initial Version

0.91

Jammy Zhou

Dec 2, 2010

Add GLX support

0.92

Jammy Zhou

Dec 3, 2010

Update based on Jesse's comments

Overview

This GL Proxy library will be designed and implemented to support runtime selection of OpenGL and OpenGL ES2.0 backends for different toolkits such as Qt and Efl/Evas. OpenGL ES2.0 can be seen as subset of OpenGL 2.0 for embedded GPU, so OpenGL and OpenGL ES2.0 backends can be made interchangeable in most cases. To achieve this, only APIs for programmable pipeline will be covered in this proxy library for OpenGL core functionality. Then for toolkits or applications to use this proxy library, fixed pipeline implementations should be replaced with GLSL shader implementations. Besides, some OpenGL or OpenGL ES2.0 specific features implemented by extensions also need to be supported in this library, so that toolkits or applications based on this proxy library still can use these features.

Entry and Exit

Entry Function

int glProxyInit(PROXY_BACKEND_OPTION *pProxyBackend);

Parameters:

pProxyBackend -- pointer to backend option, used to select/return backend type

  • UNKNOWN_BACKEND for automatic backend selection
  • OPENGL_BACKEND for specify OpenGL backend explicitly
  • OPENGL_ES20_BACKEND for specify OpenGL ES2.0 backend explicitly

Return:

  • 0 for initialization success, and -1 for initialization failure

Exit Function

int glProxyClose(void);

Return:

  • 0 for success, and -1 for failure

Backend Selection Logic

glproxy_backedn_selection.jpg

Two types of backends will be supported in this proxy library, OpenGL 2.x and OpenGL ES2.0. Pseudo code for backend selection is given below, and to determine if the OpenGL/ES20 library is hardware accelerated or not, we can check GL_RENDERER, GL_VENDOR, or something else (TBD during implementation).

if (OPENGL_BACKEND == option) {

  • /*** user prefers OpenGL backend ***/
  • if (GL library available) {
    • /*** use GL library for symbol resolve ***/
    } else {
    • /*** no GL library, try OpenGL ES2.0 backend instead ***/
    • if (GLES2 library available) {
      • /*** use GLES2 library for symbol resolve ***/
      } else {
      • /*** return error ***/
      }
    }

} else if (OPENGL_ES20_BACKEND == option) {

  • /*** user prefers OpenGL ES2.0 backend (libGLESv2.so) ***/
  • if (GLES2 library available) {
    • /*** use GLES2 library for symbol resolve ***/
    } else {
    • /*** no GLES2 library, try OpenGL backend ***/
    • if (GL library available) {
      • /*** use GL library for symbol resolve ***/
      } else {
      • /*** return error ***/
      }
    }

} else {

  • /*** select backend automatically ***/
  • if (GL and GLES2 both installed) {
    • if (GLES2 is HW) {
      • /*** use GLES2 backend ***/
      } else if (GL is HW) {
      • /*** use GL backend ***/
      } else {
      • /*** use GLES2 backend by default ***/
      }
    } else if (only GL installed) {
    • /*** use GL backend ***/
    } else if (only GLES2 installed) {
    • /*** use GLES2 backend ***/
    } else {
    • /*** return error ***/
    }

}

Proxy Functions and Runtime Symbol Resolve

The naming convention for the GL proxy functions (actually function pointers) is to replace original “gl” prefix with “pfnProxy”. Because GLX APIs are part of libGL.so, proxy functions for GLX should also be defined and resolved similarly, then the dependency on libGL.so for OpenGL/GLX applications can be removed throughly.

Take glActiveTexture for example here. Original glActiveTexture definition in <GLES2/gl2.h>:

GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);

Define pfnProxyActiveTexture accordingly as below:

typedef GL_APICALL void (GLAPIENTRY * PFNPROXYACTIVETEXTUREPROC) (GLenum texture);

PFNPROXYACTIVETEXTUREPROC pfnProxyActiveTexture = NULL;

Then pfnProxyActiveTexture will be initialized in glProxyInit() by resolving glActiveTexture based on selected backend, function glProxyGetProcAddr() will be defined to get the address of this symbol

void * glProxyGetProcAddr(void * handle, const char * symbol_name) {

return dlsym(handle, symbol_name); eglGetProcAddress and glXGetProcAddress/ARB?

}

To use the proxy function in GLProxy based toolkits, following definitions are exported by this proxy library, so that glActiveTexture can still be used to avoid too much renaming

#define glActiveTexture pfnProxyActiveTexture

OpenGL Core Functionality Support

The header file gl_proxy.h will be exported for core functionality and definitions, which will be based on <GLES2/gl2.h> and <GL/gl.h>. These core proxy functions will be resolved in glProxyCoreInit() function, and the basic layout of gl_proxy.h is given below.

/*** Data type definitions ***/

typedef void GLvoid;

……

/*** Macro definitions ***/

#define GL_DEPTH_BUFFER_BIT 0x00000100

……

/*** Common proxy functions ***/

typedef GL_APICALL void (GLAPIENTRY * PFNPROXYACTIVETEXTUREPROC) (GLenum texture);

……

#define glActiveTexture pfnProxyActiveTexture

……

export PFNPROXYACTIVETEXTUREPROC pfnProxyActiveTexture;

……

/*** OpenGL specific if any ***/

……

/*** OpenGL ES2.0 specific if any ***/

……

OpenGL Extended Functionality Support

The header file gl_proxy_ext.h will be exported for extended functionality and definitions, which will be based on <GLES2/gl2ext.h> and <GL/glext.h>. These extended proxy functions will be resolved in glProxyExtInit() function, and the layout of gl_proxy_ext.h is given below.

/*** Macro definitions specific for OpenGL ES2.0 extensions ***/

#ifndef GL_OES_compressed_ETC1_RGB8_texture

#define GL_ETC1_RGB8_OES 0x8D64

#endif

……

/*** Macro definitions specific for OpenGL extensions ***/

……

/*** Proxy functions specific for OpenGL ES2.0 extensions ***/

typedef GL_APICALL void (GL_APIENTRY *PFNPROXYEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum target, GLeglImageOES image);

……

#define glEGLImageTargetTexture2DOES pfnProxyEGLImageTargetTexture2DOES

……

export PFNPROXYEGLIMAGETARGETTEXTURE2DOESPROC pfnProxyEGLImageTargetTexture2DOES;

……

/*** Proxy functions specific for OpenGL extensions ***/

......

GLX Support

glx_proxy.h/glx_proxy.c will be implemented for GLX API runtime resolve, which is only done for OpenGL backend. As for EGL APIs, they don't needed to be resolved at runtime, because there is a separate library libEGL.so for holding these APIs.

Data Types and Definitions

Some new data types and global variables are defined below.

/*** Enumeration type for backend options ***/

typedef enum {

UNKNOWN_BACKEND = -1,

OPENGL_BACKEND,

OPENGL_ES20_BACKEND,

MAX_BACKEND = OPENGL_ES20_BACKEND

} PROXY_BACKEND_OPTION;

/*** indicate current backend ***/

PROXY_BACKEND_OPTION proxyBackend = UNKNOWN_BACKEND;

/*** library names for different backends ***/

const char *opengl_libraries[] = {

“/usr/lib/libGL.so”,

“/usr/lib/libGLESv2.so”,

};

References

http://www.khronos.org/registry/gles/specs/2.0/es_cm_spec_2.0.25.pdf


WorkingGroups/Middleware/Graphics/Specs/1105/GLProxy/Design (last modified 2010-12-03 01:51:30)