From c9241b83f9832992f153a3aed4cf7517d249dc6b Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 12 Jan 2013 18:06:37 +0000 Subject: [PATCH] Use a single GL context for all windows. --- linux/glwindow.cpp | 149 +++++++++++++++++++++++---------------------- linux/toolbar.cpp | 56 +++++++++-------- 2 files changed, 107 insertions(+), 98 deletions(-) diff --git a/linux/glwindow.cpp b/linux/glwindow.cpp index 49d3d676..8d2567b7 100644 --- a/linux/glwindow.cpp +++ b/linux/glwindow.cpp @@ -1,7 +1,3 @@ -// -// OpenGL window -// - #include #include #include @@ -14,12 +10,17 @@ struct GLWindowPrivate { GtkWidget *widget; - Display* xdisplay; - GLXContext context; LC_CURSOR_TYPE Cursor; - bool Multisample; +// bool Multisample; }; +static Display* WindowDisplay = NULL; +static GdkVisual* WindowGdkVisual = NULL; +static XVisualInfo* WindowXVisualInfo = NULL; +static bool WindowMultisample = false; +static GLXContext WindowContext; +int WindowContextCount; + // ============================================================================= // static functions @@ -158,76 +159,76 @@ GLWindow::~GLWindow() g_free(m_pData); } -bool GLWindow::CreateFromWindow (void *data) +bool GLWindow::CreateFromWindow(void *data) { - int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0 }; GLWindowPrivate *prv = (GLWindowPrivate*)m_pData; - Display *dpy = GDK_DISPLAY(); - GdkVisual *visual; - XVisualInfo *vi = NULL; - // choose visual - visual = gdk_visual_get_system(); - if (visual->depth < 16) - printf("OpenGL fatal error: LeoCAD needs a display with at least 16 bit colors.\n"); - - if (dpy == NULL) + if (WindowContext) + WindowContextCount++; + else { - printf("OpenGL fatal error: Cannot get display.\n"); - return false; - } - prv->xdisplay = dpy; + int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0 }; - int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1); + WindowDisplay = GDK_DISPLAY(); - if (AASamples > 1) - { - int attrlistAA[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, AASamples, 0 }; - vi = pfnglXChooseVisual(dpy, DefaultScreen(dpy), attrlistAA); + if (!WindowDisplay) + { + printf("OpenGL fatal error: Cannot get display.\n"); + return false; + } - if (vi) - prv->Multisample = true; - else - printf("OpenGL error: Could not find multisample visual.\n"); - } + WindowGdkVisual = gdk_visual_get_system(); + if (WindowGdkVisual->depth < 16) + printf("OpenGL fatal error: LeoCAD needs a display with at least 16 bit colors.\n"); - if (!vi) - { - vi = pfnglXChooseVisual(dpy, DefaultScreen(dpy), attrlist); - if (vi == NULL) + int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1); + + if (AASamples > 1) + { + int attrlistAA[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, AASamples, 0 }; + WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlistAA); + + if (WindowXVisualInfo) + WindowMultisample = true; + else + printf("OpenGL error: Could not find multisample visual.\n"); + } + + if (!WindowXVisualInfo) + { + WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlist); + if (!WindowXVisualInfo) + { + printf("OpenGL fatal error: glXChooseVisual failed.\n"); + return false; + } + } + + WindowGdkVisual = gdkx_visual_get(WindowXVisualInfo->visualid); + if (WindowGdkVisual == NULL) + { + printf("OpenGL fatal error: Cannot get visual.\n"); + return false; + } + + WindowContext = pfnglXCreateContext(WindowDisplay, WindowXVisualInfo, NULL, True); + + if (!WindowContext) { - printf("OpenGL fatal error: glXChooseVisual failed.\n"); + printf("OpenGL fatal error: Cannot create context.\n"); return false; } - } + } - visual = gdkx_visual_get(vi->visualid); - if (visual == NULL) - { - printf("OpenGL fatal error: Cannot get visual.\n"); - return false; - } - - gtk_widget_push_colormap(gdk_colormap_new(visual, TRUE)); - gtk_widget_push_visual(visual); + gtk_widget_push_colormap(gdk_colormap_new(WindowGdkVisual, TRUE)); + gtk_widget_push_visual(WindowGdkVisual); prv->widget = gtk_drawing_area_new(); gtk_widget_set_double_buffered(GTK_WIDGET(prv->widget), FALSE); - if (m_pShare == NULL) - prv->context = pfnglXCreateContext(dpy, vi, NULL, True); - else - { - GLWindowPrivate *share = (GLWindowPrivate*)m_pShare->m_pData; - - prv->context = pfnglXCreateContext(dpy, vi, share->context, True); - } - gtk_widget_pop_visual(); gtk_widget_pop_colormap(); - XFree(vi); - GTK_WIDGET_SET_FLAGS(prv->widget, GTK_CAN_FOCUS); gtk_widget_set_events(GTK_WIDGET(prv->widget), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | @@ -249,46 +250,50 @@ bool GLWindow::CreateFromWindow (void *data) void GLWindow::DestroyContext() { - GLWindowPrivate *prv = (GLWindowPrivate*)m_pData; + if (!WindowContext) + return; - if (prv->context == pfnglXGetCurrentContext()) - pfnglXMakeCurrent(prv->xdisplay, None, NULL); + WindowContextCount--; - if (prv->context) - pfnglXDestroyContext(prv->xdisplay, prv->context); + if (WindowContextCount) + return; - prv->context = NULL; + if (WindowContext == pfnglXGetCurrentContext()) + pfnglXMakeCurrent(WindowDisplay, None, NULL); + + pfnglXDestroyContext(WindowDisplay, WindowContext); + WindowContext = NULL; + + XFree(WindowXVisualInfo); + WindowXVisualInfo = NULL; } void GLWindow::OnInitialUpdate() { - GLWindowPrivate *prv = (GLWindowPrivate*)m_pData; - MakeCurrent(); GL_InitializeSharedExtensions(); // GL_InitializeExtensions(); - if (prv->Multisample) + if (WindowMultisample) glEnable(GL_MULTISAMPLE_ARB); } bool GLWindow::MakeCurrent() { GLWindowPrivate *prv = (GLWindowPrivate*)m_pData; - gboolean ret = false; - if (prv->context) - ret = pfnglXMakeCurrent(prv->xdisplay, GDK_WINDOW_XWINDOW(prv->widget->window), prv->context); + if (!WindowContext) + return false; - return ret; + return pfnglXMakeCurrent(WindowDisplay, GDK_WINDOW_XWINDOW(prv->widget->window), WindowContext); } void GLWindow::SwapBuffers() { GLWindowPrivate *prv = (GLWindowPrivate*)m_pData; - if (prv->context) + if (WindowContext) pfnglXSwapBuffers(GDK_WINDOW_XDISPLAY(prv->widget->window), GDK_WINDOW_XWINDOW(prv->widget->window)); } diff --git a/linux/toolbar.cpp b/linux/toolbar.cpp index 0a418f00..e4918b47 100644 --- a/linux/toolbar.cpp +++ b/linux/toolbar.cpp @@ -10,7 +10,7 @@ #include "opengl.h" #include "gtktools.h" #include "main.h" -#include "globals.h" +#include "globals.h" #include "project.h" #include "pieceinf.h" #include "toolbar.h" @@ -199,46 +199,46 @@ void create_toolbars(GtkWidget *window, GtkWidget *vbox) gtk_container_add (GTK_CONTAINER (tool_toolbar.handle_box), tool_toolbar.toolbar); gtk_widget_show (tool_toolbar.toolbar); - tool_toolbar.brick = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.brick = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL, "Piece", "Insert Piece", "", new_pixmap (window, ac_brick), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_INSERT); - tool_toolbar.light = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), - GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Light", "Insert Light", "", + tool_toolbar.light = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Light", "Insert Light", "", new_pixmap (window, ac_light), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_LIGHT); - tool_toolbar.spot = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.spot = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Spot", "Insert Spotlight", "", new_pixmap (window, ac_spot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SPOTLIGHT); - tool_toolbar.camera = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.camera = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Camera", "Insert Camera", "", new_pixmap (window, ac_cam), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_CAMERA); - tool_toolbar.select = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.select = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Select", "Select Objects", "", new_pixmap (window, ac_sel), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SELECT); - tool_toolbar.move = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.move = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Move", "Move Objects", "", new_pixmap (window, ac_move), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_MOVE); - tool_toolbar.rotate = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.rotate = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rotate", "Rotate Pieces", "", new_pixmap (window, ac_rot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE); - tool_toolbar.erase = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.erase = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Delete", "Remove Objects", "", new_pixmap (window, ac_erase), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ERASER); - tool_toolbar.paint = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.paint = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Paint", "Paint Bricks", "", new_pixmap (window, ac_paint), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAINT); - tool_toolbar.zoom = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.zoom = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom", "Zoom", "", new_pixmap (window, ac_zoom), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM); - tool_toolbar.pan = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.pan = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Pan", "Pan", "", new_pixmap (window, ac_pan), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAN); - tool_toolbar.rotview = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.rotview = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rot. View", "Rotate View", "", new_pixmap (window, ac_rotv), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE_VIEW); - tool_toolbar.roll = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.roll = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Roll", "Roll", "", new_pixmap (window, ac_roll), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROLL); - tool_toolbar.zoomreg = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), + tool_toolbar.zoomreg = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom Box", "Zoom Region", "", new_pixmap (window, ac_zoomr), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM_REGION); gtk_toolbar_append_item (GTK_TOOLBAR (tool_toolbar.toolbar), "Zoom Ext.", "Zoom Extents", "", @@ -260,7 +260,7 @@ void create_toolbars(GtkWidget *window, GtkWidget *vbox) gtk_widget_show (anim_toolbar.toolbar); anim_toolbar.first = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar), - "First", "Go to the Start", "", new_pixmap (window, an_first), + "First", "Go to the Start", "", new_pixmap (window, an_first), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_FIRST); anim_toolbar.prev = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar), "Previous", "Go Back", "", new_pixmap (window, an_prev), @@ -367,7 +367,7 @@ void fill_piecetree() gtk_tree_store_append(model, &pat, &entry); gtk_tree_store_set(model, &pat, 0, desc, 1, child, -1); - } + } } } } @@ -504,7 +504,7 @@ static gint piececombo_key(GtkWidget* widget, GdkEventKey* event) // Remove all children. while (gtk_tree_model_iter_children(model, &child, &iter)) - gtk_tree_store_remove(GTK_TREE_STORE(model), &child); + gtk_tree_store_remove(GTK_TREE_STORE(model), &child); // Perform search. PtrArray SinglePieces, GroupedPieces; @@ -720,7 +720,7 @@ static gboolean colorlist_expose(GtkWidget *widget, GdkEventExpose *event, gpoin PangoContext *context; PangoLayout *layout; ColorListData* Data; - + Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist"); Data->UpdateLayout(widget); @@ -779,7 +779,7 @@ static gboolean colorlist_expose(GtkWidget *widget, GdkEventExpose *event, gpoin static gboolean colorlist_realize(GtkWidget* widget, gpointer user) { ColorListData* Data; - + Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist"); delete Data; @@ -795,7 +795,7 @@ static gboolean colorlist_realize(GtkWidget* widget, gpointer user) static gboolean colorlist_unrealize(GtkWidget* widget, gpointer user) { ColorListData* Data; - + Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist"); delete Data; @@ -921,7 +921,7 @@ static gboolean colorlist_tooltip(GtkWidget *widget, gint x, gint y, gboolean ke { if (keyboard_mode) return FALSE; - + ColorListData* Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist"); for (int CellIdx = 0; CellIdx < Data->mCells.GetSize(); CellIdx++) @@ -954,8 +954,12 @@ void colorlist_set(int new_color) if (new_color != cur_color) { cur_color = new_color; - gtk_widget_draw(colorlist, NULL); - preview->Redraw(); + + if (colorlist) + gtk_widget_draw(colorlist, NULL); + + if (preview) + preview->Redraw(); } } @@ -966,7 +970,7 @@ GtkWidget* create_piecebar(GtkWidget *window, GLWindow *share) frame = gtk_frame_new(NULL); gtk_widget_show(frame); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); vbox1 = gtk_vbox_new(FALSE, 0); gtk_widget_show(vbox1);