From 300747225ca2de6db483287fa44ed24d18765b99 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Sun, 8 May 2016 06:42:57 +0000 Subject: Rewrite OpenGL-related code under the driver model. Class Fl_Gl_Window_Driver, with its platform-specific derived classes, is created to hold platform-specific, OpenGL code. File gl_draw.cxx still needs to be converted to the driver model. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11716 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Gl_Choice.cxx | 414 +++++++++++++++++++++++++++------------------------ 1 file changed, 219 insertions(+), 195 deletions(-) (limited to 'src/Fl_Gl_Choice.cxx') diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index 6d5e8f6e4..5eb55cac5 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -16,49 +16,221 @@ // http://www.fltk.org/str.php // -#include +#include "config_lib.h" #if HAVE_GL # include -# include # include # include # include "Fl_Gl_Choice.H" +# include +# include # include # include "flstring.h" # include -#if defined(WIN32) -#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H" -#elif defined(__APPLE__) // PORTME: platform OpenGL management -#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H" -#elif defined(FL_PORTING) -# pragma message "FL_PORTING: add code to list and select OpenGL drawing contexts" -#else -#endif - -# ifdef WIN32 -void fl_save_dc(HWND, HDC); -#elif defined(__APPLE__) // PORTME: platform OpenGL management -extern void gl_texture_reset(); -#endif + +static GLContext *context_list = 0; +static int nContext = 0, NContext = 0; + +static void add_context(GLContext ctx) { + if (!ctx) return; + if (nContext==NContext) { + if (!NContext) NContext = 8; + NContext *= 2; + context_list = (GLContext*)realloc( + context_list, NContext*sizeof(GLContext)); + } + context_list[nContext++] = ctx; +} + +static void del_context(GLContext ctx) { + int i; + for (i=0; inext) - if (g->mode == m && g->alist == alistp) + if (g->mode == m && g->alist == alistp) return g; + return NULL; +} + + +static GLContext cached_context; +static Fl_Window* cached_window; + + +#ifdef FL_CFG_GFX_QUARTZ +#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H" +extern void gl_texture_reset(); + +Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp) +{ + Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp); + if (g) return g; + NSOpenGLPixelFormat* fmt = Fl_Cocoa_Screen_Driver::mode_to_NSOpenGLPixelFormat(m, alistp); + if (!fmt) return 0; + g = new Fl_Gl_Choice(m, alistp, first); + first = g; + g->pixelformat = fmt; + return g; +} + +GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { + GLContext context, shared_ctx = 0; + if (context_list && nContext) shared_ctx = context_list[0]; + // resets the pile of string textures used to draw strings + // necessary before the first context is created + if (!shared_ctx) gl_texture_reset(); + context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window); + if (!context) return 0; + add_context((GLContext)context); + return (context); +} + +void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { + if (context != cached_context || w != cached_window) { + cached_context = context; + cached_window = w; + Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(context); + } +} + +void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) { + if (cached_context == context) { + cached_context = 0; + cached_window = 0; + Fl_Cocoa_Screen_Driver::GL_cleardrawable(); + } + Fl_Cocoa_Screen_Driver::GLcontext_release(context); + del_context(context); +} + +#endif // FL_CFG_GFX_QUARTZ + +#ifdef FL_CFG_GFX_GDI +# include +#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H" +extern void fl_save_dc(HWND, HDC); + +Fl_Gl_Choice *Fl_WinAPI_Gl_Window_Driver::find(int m, const int *alistp) +{ + Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp); + if (g) return g; + + // Replacement for ChoosePixelFormat() that finds one with an overlay + // if possible: + HDC gc = (HDC)fl_graphics_driver->gc(); + if (!gc) gc = fl_GetDC(0); + int pixelformat = 0; + PIXELFORMATDESCRIPTOR chosen_pfd; + for (int i = 1; ; i++) { + PIXELFORMATDESCRIPTOR pfd; + if (!DescribePixelFormat(gc, i, sizeof(pfd), &pfd)) break; + // continue if it does not satisfy our requirements: + if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue; + if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue; + if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue; + if ((m & FL_ACCUM) && !pfd.cAccumBits) continue; + if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue; + if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue; + if ((m & FL_DEPTH) && !pfd.cDepthBits) continue; + if ((m & FL_STENCIL) && !pfd.cStencilBits) continue; + // see if better than the one we have already: + if (pixelformat) { + // offering non-generic rendering is better (read: hardware accelleration) + if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) && + (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue; + // offering overlay is better: + else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {} + // otherwise more bit planes is better: + else if (chosen_pfd.cColorBits > pfd.cColorBits) continue; + else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue; + } + pixelformat = i; + chosen_pfd = pfd; + } + //printf("Chosen pixel format is %d\n", pixelformat); + if (!pixelformat) return 0; + + g = new Fl_Gl_Choice(m, alistp, first); + first = g; + + g->pixelformat = pixelformat; + g->pfd = chosen_pfd; + + return g; +} + + +GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) +{ + Fl_X* i = Fl_X::i(window); + HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc; + if (!hdc) { + hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); + fl_save_dc(i->xid, hdc); + SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd)); +# if USE_COLORMAP + if (fl_palette) SelectPalette(hdc, fl_palette, FALSE); +# endif + } + GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); + if (context) { + if (context_list && nContext) + wglShareLists(context_list[0], context); + add_context(context); + } + return context; +} + + +void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { + if (context != cached_context || w != cached_window) { + cached_context = context; + cached_window = w; + wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context); + } +} + +void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) { + if (cached_context == context) { + cached_context = 0; + cached_window = 0; + wglMakeCurrent(0, 0); + } + wglDeleteContext(context); + del_context(context); +} + +#endif // FL_CFG_GFX_GDI + +#ifdef FL_CFG_GFX_XLIB +# include -#if defined(USE_X11) +Fl_Gl_Choice *Fl_X11_Gl_Window_Driver::find(int m, const int *alistp) +{ + Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp); + if (g) return g; + const int *blist; int list[32]; - + if (alistp) blist = alistp; else { @@ -71,16 +243,16 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) { list[n++] = GLX_GREEN_SIZE; list[n++] = (m & FL_RGB8) ? 8 : 1; if (m & FL_ALPHA) { - list[n++] = GLX_ALPHA_SIZE; - list[n++] = (m & FL_RGB8) ? 8 : 1; + list[n++] = GLX_ALPHA_SIZE; + list[n++] = (m & FL_RGB8) ? 8 : 1; } if (m & FL_ACCUM) { - list[n++] = GLX_ACCUM_GREEN_SIZE; - list[n++] = 1; - if (m & FL_ALPHA) { - list[n++] = GLX_ACCUM_ALPHA_SIZE; - list[n++] = 1; - } + list[n++] = GLX_ACCUM_GREEN_SIZE; + list[n++] = 1; + if (m & FL_ALPHA) { + list[n++] = GLX_ACCUM_ALPHA_SIZE; + list[n++] = 1; + } } } if (m & FL_DOUBLE) { @@ -104,7 +276,7 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) { list[n] = 0; blist = list; } - + fl_open_display(); XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist); if (!visp) { @@ -113,109 +285,29 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) { # endif return 0; } - -#elif defined(__APPLE__) // PORTME: platform OpenGL management - NSOpenGLPixelFormat* fmt = Fl_Cocoa_Screen_Driver::mode_to_NSOpenGLPixelFormat(m, alistp); - if (!fmt) return 0; -#elif defined(WIN32) - - // Replacement for ChoosePixelFormat() that finds one with an overlay - // if possible: - HDC gc = (HDC)fl_graphics_driver->gc(); - if (!gc) gc = fl_GetDC(0); - int pixelformat = 0; - PIXELFORMATDESCRIPTOR chosen_pfd; - for (int i = 1; ; i++) { - PIXELFORMATDESCRIPTOR pfd; - if (!DescribePixelFormat(gc, i, sizeof(pfd), &pfd)) break; - // continue if it does not satisfy our requirements: - if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue; - if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue; - if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue; - if ((m & FL_ACCUM) && !pfd.cAccumBits) continue; - if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue; - if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue; - if ((m & FL_DEPTH) && !pfd.cDepthBits) continue; - if ((m & FL_STENCIL) && !pfd.cStencilBits) continue; - // see if better than the one we have already: - if (pixelformat) { - // offering non-generic rendering is better (read: hardware accelleration) - if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) && - (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue; - // offering overlay is better: - else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {} - // otherwise more bit planes is better: - else if (chosen_pfd.cColorBits > pfd.cColorBits) continue; - else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue; - } - pixelformat = i; - chosen_pfd = pfd; - } - //printf("Chosen pixel format is %d\n", pixelformat); - if (!pixelformat) return 0; -#else -# error platform unsupported -#endif - - g = new Fl_Gl_Choice; - g->mode = m; - g->alist = alistp; - g->next = first; + g = new Fl_Gl_Choice(m, alistp, first); first = g; - -#if defined(USE_X11) + g->vis = visp; - + if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */ visp->visualid == fl_visual->visualid && !fl_getenv("MESA_PRIVATE_CMAP")) g->colormap = fl_colormap; else g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), - visp->visual, AllocNone); -# elif defined(WIN32) - g->pixelformat = pixelformat; - g->pfd = chosen_pfd; -# elif defined(__APPLE_QUARTZ__) // PORTME: platform OpenGL management - g->pixelformat = fmt; -# else -# error unsupported platform -# endif - + visp->visual, AllocNone); + return g; } -static GLContext *context_list = 0; -static int nContext = 0, NContext = 0; -static void add_context(GLContext ctx) { - if (!ctx) return; - if (nContext==NContext) { - if (!NContext) NContext = 8; - NContext *= 2; - context_list = (GLContext*)realloc( - context_list, NContext*sizeof(GLContext)); - } - context_list[nContext++] = ctx; -} - -static void del_context(GLContext ctx) { - int i; - for (i=0; ivis); } -#if defined(USE_X11) - -GLContext fl_create_gl_context(XVisualInfo* vis) { +GLContext Fl_X11_Gl_Window_Driver::create_gl_context(XVisualInfo *vis) { GLContext shared_ctx = 0; if (context_list && nContext) shared_ctx = context_list[0]; GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1); @@ -224,95 +316,27 @@ GLContext fl_create_gl_context(XVisualInfo* vis) { return context; } -#elif defined(WIN32) - -GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { - Fl_X* i = Fl_X::i(window); - HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc; - if (!hdc) { - hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); - fl_save_dc(i->xid, hdc); - SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd)); -# if USE_COLORMAP - if (fl_palette) SelectPalette(hdc, fl_palette, FALSE); -# endif - } - GLContext context = - layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); - if (context) { - if (context_list && nContext) - wglShareLists(context_list[0], context); - add_context(context); - } - return context; -} - -# elif defined(__APPLE__) // PORTME: platform OpenGL management - -GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { - GLContext context, shared_ctx = 0; - if (context_list && nContext) shared_ctx = context_list[0]; - // resets the pile of string textures used to draw strings - // necessary before the first context is created - if (!shared_ctx) gl_texture_reset(); - context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window); - if (!context) return 0; - add_context((GLContext)context); - return (context); -} -# else -# error unsupported platform -# endif - -static GLContext cached_context; -static Fl_Window* cached_window; - -void fl_set_gl_context(Fl_Window* w, GLContext context) { +void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; -# if defined(USE_X11) glXMakeCurrent(fl_display, fl_xid(w), context); -# elif defined(WIN32) - wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context); -# elif defined(__APPLE__) // PORTME: platform OpenGL management - Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(context); -# else -# error unsupported platform -# endif } } -void fl_no_gl_context() { - cached_context = 0; - cached_window = 0; -# if defined(USE_X11) - glXMakeCurrent(fl_display, 0, 0); -# elif defined(WIN32) - wglMakeCurrent(0, 0); -# elif defined(__APPLE__) // PORTME: platform OpenGL management - Fl_Cocoa_Screen_Driver::GL_cleardrawable(); -# else -# error unsupported platform -# endif -} - -void fl_delete_gl_context(GLContext context) { - if (cached_context == context) fl_no_gl_context(); -# if defined(USE_X11) +void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) { + if (cached_context == context) { + cached_context = 0; + cached_window = 0; + glXMakeCurrent(fl_display, 0, 0); + } glXDestroyContext(fl_display, context); -# elif defined(WIN32) - wglDeleteContext(context); -# elif defined(__APPLE__) // PORTME: platform OpenGL management - Fl_Cocoa_Screen_Driver::GLcontext_release(context); -# else -# error unsupported platform -# endif del_context(context); } -#endif // HAVE_GL +#endif // FL_CFG_GFX_XLIB +#endif // HAVE_GL // // End of "$Id$". -- cgit v1.2.3