ManaPlus
glxhelper.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2014-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "utils/glxhelper.h"
23 
24 #if defined(USE_OPENGL) && defined(USE_X11)
25 
26 #include "logger.h"
27 
28 #include "render/opengl/mglcheck.h"
29 
30 #include "render/openglx/mglx.h"
31 
33 RENDER_OPENGL_MGLDEFINES_H
34 
35 #include "debug.h"
36 
37 static int ErrorHandler(Display *d A_UNUSED, XErrorEvent *e A_UNUSED)
38 {
39  return 0;
40 }
41 
42 void *GlxHelper::createContext(const unsigned long window,
43  void *const display0,
44  const int major,
45  const int minor,
46  const int profile)
47 {
48  Display *const display = static_cast<Display*>(display0);
49  XSync(display, false);
50  int (*handler)(Display *, XErrorEvent *) = XSetErrorHandler(ErrorHandler);
51  void *context = mglXGetCurrentContext();
52  if (!display)
53  return context;
54  if (isGLNull(mglXGetCurrentContext)
55  || isGLNull(mglXCreateContextAttribs)
56  || isGLNull(mglXChooseFBConfig))
57  {
58  logger->log("Can't change context, functions in driver "
59  "not implemented");
60  XSetErrorHandler(handler);
61  return context;
62  }
63  if (!context)
64  {
65  logger->log("Can't change context, because current "
66  "context not created");
67  XSetErrorHandler(handler);
68  return context;
69  }
70  int glxAttribs[] =
71  {
72  GLX_RENDER_TYPE, GLX_RGBA_BIT,
73  GLX_RED_SIZE, 3,
74  GLX_GREEN_SIZE, 3,
75  GLX_BLUE_SIZE, 2,
76  GLX_DOUBLEBUFFER, 1,
77  0
78  };
79 
80  int fbcount = 0;
81  GLXFBConfig *framebuffer_config = mglXChooseFBConfig(display,
82  DefaultScreen(display),
83  glxAttribs,
84  &fbcount);
85 
86  if (!framebuffer_config || !fbcount)
87  {
88  logger->log("No correct fb profile found");
89  XSetErrorHandler(handler);
90  return nullptr;
91  }
92  logger->log("Found %d frame buffer contexts.", fbcount);
93 
94  int attribs[] =
95  {
99  0, 0
100  };
101 
102  void *const context2 = mglXCreateContextAttribs(display,
103  framebuffer_config[0], context, true, attribs);
104  if (!context2)
105  {
106  logger->log("context %d.%d creation failed", major, minor);
107  XSetErrorHandler(handler);
108  return nullptr;
109  }
110 
111  XSync(display, false);
112  XSetErrorHandler(handler);
113 
114  if (!mglXMakeCurrent(display, window, context2))
115  {
116  mglXDestroyContext(display, context2);
117  logger->log("make current context %d.%d failed", major, minor);
118  return nullptr;
119  }
120 
121  if (mglXGetCurrentContext() != context2)
122  {
123  mglXDestroyContext(display, context2);
124  logger->log("context cant be changed to %d.%d.", major, minor);
125  return nullptr;
126  }
127 
128 // do not delete SDL context, because on exit it will crash
129 // mglXDestroyContext(display, context);
130  logger->log("Context for %d.%d created", major, minor);
131  return context2;
132 }
133 
134 bool GlxHelper::makeCurrent(const unsigned long window,
135  void *const display,
136  void *const context)
137 {
138  if (!display)
139  return false;
140  return mglXMakeCurrent(static_cast<Display*>(display), window, context);
141 }
142 
143 #endif // defined(USE_OPENGL) && defined(USE_X11)
void log(const char *const log_text,...)
Definition: logger.cpp:269
#define A_UNUSED
Definition: localconsts.h:160
Logger * logger
Definition: logger.cpp:89
#define isGLNull(func)
Definition: mglcheck.h:27
#define GLX_CONTEXT_MINOR_VERSION_ARB
Definition: mgldefines.h:127
#define GLX_CONTEXT_PROFILE_MASK_ARB
Definition: mgldefines.h:122
#define GLX_CONTEXT_MAJOR_VERSION_ARB
Definition: mgldefines.h:126