android-app-native/app/src/nativecode/rawdraw/CNFGOGLEGLDriver.c

189 lines
4.4 KiB
C

//Copyright (c) 2011, 2017, 2018 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
//portions from
//https://github.com/NVIDIA-developer-blog/code-samples/blob/master/posts/egl_OpenGl_without_Xserver/tinyegl.cc
//NOTE: This is a truly incomplete driver - if no EGL surface is available, it does not support direct buffer rendering.
//Additionally no input is connected.
#include "CNFG.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef USE_EGL_GET_DISPLAY
#include <EGL/egl.h>
#else
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
#ifdef USE_EGL_SURFACE
#include <GL/gl.h>
#else
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#endif
static const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
static int pbufferWidth = 0;
static int pbufferHeight = 0;
static EGLint pbufferAttribs[] = {
EGL_WIDTH, 0,
EGL_HEIGHT, 0,
EGL_NONE,
};
#ifdef CNFGOGL
#include <GL/glx.h>
#include <GL/glxext.h>
GLXContext CNFGCtx;
void * CNFGGetExtension( const char * extname ) { return glXGetProcAddressARB((const GLubyte *) extname); }
#endif
EGLDisplay eglDpy = 0;
EGLContext eglCtx = 0;
EGLSurface eglSurf = 0;
//These aren't actually used. Just here to allow linking.
XWindowAttributes CNFGWinAtt;
XClassHint *CNFGClassHint;
Display *CNFGDisplay;
Window CNFGWindow;
int CNFGWindowInvisible;
Pixmap CNFGPixmap;
GC CNFGGC;
GC CNFGWindowGC;
Visual * CNFGVisual;
int FullScreen = 0;
void CNFGGetDimensions( short * x, short * y )
{
*x = pbufferWidth;
*y = pbufferHeight;
}
void CNFGChangeWindowTitle( const char * WindowName )
{
}
void CNFGSetupFullscreen( const char * WindowName, int screen_no )
{
printf( "Full screen setup stubbed.\n" );
CNFGSetup( WindowName, 640, 480 );
}
void CNFGTearDown()
{
if( eglDpy )
{
eglTerminate( eglDpy );
}
//Unimplemented.
}
int CNFGSetup( const char * WindowName, int w, int h )
{
// glXMakeCurrent( CNFGDisplay, CNFGWindow, CNFGCtx );
eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
atexit( CNFGTearDown );
printf( "EGL Display: %p\n", eglDpy );
if( eglDpy == 0 )
{
printf( "Trying alternate method.\n" );
// obtain display by specifying an appropriate device. This is the preferred method today.
// load the function pointers for the device,platform extensions
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC) eglGetProcAddress("eglQueryDevicesEXT");
if(!eglQueryDevicesEXT) {
printf("ERROR: extension eglQueryDevicesEXT not available");
return(-1);
}
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
if(!eglGetPlatformDisplayEXT) {
printf("ERROR: extension eglGetPlatformDisplayEXT not available");
return(-1);
}
static const int MAX_DEVICES = 16;
EGLDeviceEXT devices[MAX_DEVICES];
EGLint numDevices;
eglQueryDevicesEXT(MAX_DEVICES, devices, &numDevices);
eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[0], 0);
printf( "EGL Backup Display: %p\n", eglDpy );
}
pbufferAttribs[1] = pbufferWidth = w;
pbufferAttribs[3] = pbufferHeight = h;
EGLint major, minor;
eglInitialize(eglDpy, &major, &minor);
EGLint numConfigs;
EGLConfig eglCfg;
eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);
printf( "EGL Major Minor: %d %d\n", major, minor );
eglBindAPI(EGL_OPENGL_API);
eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);
int err = eglGetError(); if(err != EGL_SUCCESS) { printf("1. Error %d\n", err); }
printf( "EGL Got context: %p\n", eglCtx );
if( w > 0 && h > 0 )
{
eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg, pbufferAttribs);
eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx);
printf( "EGL Current, with surface %p\n", eglSurf );
//Actually have a surface. Need to allocate it.
}
else
{
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);
printf( "EGL Current, no surface.\n" );
}
return 0;
}
int CNFGHandleInput()
{
//Stubbed (No input)
return 1;
}
void CNFGUpdateScreenWithBitmap( unsigned long * data, int w, int h )
{
printf( "Stubbed update screen\n" );
}
void CNFGSetVSync( int vson )
{
//No-op
}
void CNFGSwapBuffers()
{
//No-op
}