Blender  V2.93
GHOST_ContextSDL.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include "GHOST_ContextSDL.h"
27 
28 #include <vector>
29 
30 #include <cassert>
31 #include <cstdio>
32 #include <cstring>
33 
34 SDL_GLContext GHOST_ContextSDL::s_sharedContext = NULL;
35 int GHOST_ContextSDL::s_sharedCount = 0;
36 
38  SDL_Window *window,
39  int contextProfileMask,
40  int contextMajorVersion,
41  int contextMinorVersion,
42  int contextFlags,
43  int contextResetNotificationStrategy)
44  : GHOST_Context(stereoVisual),
45  m_window(window),
46  m_hidden_window(NULL),
47  m_contextProfileMask(contextProfileMask),
48  m_contextMajorVersion(contextMajorVersion),
49  m_contextMinorVersion(contextMinorVersion),
50  m_contextFlags(contextFlags),
51  m_contextResetNotificationStrategy(contextResetNotificationStrategy),
52  m_context(NULL)
53 {
54  // assert(m_window != NULL);
55 }
56 
58 {
59  if (m_context != NULL) {
60  if (m_window != NULL && m_context == SDL_GL_GetCurrentContext())
61  SDL_GL_MakeCurrent(m_window, NULL);
62 
63  if (m_context != s_sharedContext || s_sharedCount == 1) {
64  assert(s_sharedCount > 0);
65 
66  s_sharedCount--;
67 
68  if (s_sharedCount == 0)
69  s_sharedContext = NULL;
70 
71  SDL_GL_DeleteContext(m_context);
72  }
73 
74  if (m_hidden_window != NULL)
75  SDL_DestroyWindow(m_hidden_window);
76  }
77 }
78 
80 {
81  SDL_GL_SwapWindow(m_window);
82 
83  return GHOST_kSuccess;
84 }
85 
87 {
88  if (m_context) {
89  return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
90  }
91  else {
92  return GHOST_kFailure;
93  }
94 }
95 
97 {
98  if (m_context) {
99  /* Untested, may not work */
100  return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure;
101  }
102  else {
103  return GHOST_kFailure;
104  }
105 }
106 
108 {
109 #ifdef GHOST_OPENGL_ALPHA
110  const bool needAlpha = true;
111 #else
112  const bool needAlpha = false;
113 #endif
114 
115  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask);
116  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion);
117  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion);
118  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags);
119 
120  SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
121  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
122  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
123  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
124  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
125 
126  if (needAlpha) {
127  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
128  }
129 
130  if (m_stereoVisual) {
131  SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
132  }
133 
134  if (m_window == NULL) {
135  m_hidden_window = SDL_CreateWindow("Offscreen Context Windows",
136  SDL_WINDOWPOS_UNDEFINED,
137  SDL_WINDOWPOS_UNDEFINED,
138  1,
139  1,
140  SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS |
141  SDL_WINDOW_HIDDEN);
142 
143  m_window = m_hidden_window;
144  }
145 
146  m_context = SDL_GL_CreateContext(m_window);
147 
148  GHOST_TSuccess success;
149 
150  if (m_context != NULL) {
151  if (!s_sharedContext)
152  s_sharedContext = m_context;
153 
154  s_sharedCount++;
155 
156  success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? GHOST_kFailure : GHOST_kSuccess;
157 
158  initContextGLEW();
159 
160  initClearGL();
161  SDL_GL_SwapWindow(m_window);
162 
163  success = GHOST_kSuccess;
164  }
165  else {
166  success = GHOST_kFailure;
167  }
168 
169  return success;
170 }
171 
173 {
174  m_window = NULL;
175 
176  return GHOST_kSuccess;
177 }
178 
180 {
181  if (SDL_GL_SetSwapInterval(interval) != -1) {
182  return GHOST_kSuccess;
183  }
184  else {
185  return GHOST_kFailure;
186  }
187 }
188 
190 {
191  intervalOut = SDL_GL_GetSwapInterval();
192  return GHOST_kSuccess;
193 }
GHOST_TSuccess
Definition: GHOST_Types.h:91
@ GHOST_kFailure
Definition: GHOST_Types.h:91
@ GHOST_kSuccess
Definition: GHOST_Types.h:91
GHOST_TSuccess swapBuffers()
GHOST_TSuccess initializeDrawingContext()
GHOST_TSuccess releaseNativeHandles()
GHOST_TSuccess getSwapInterval(int &intervalOut)
GHOST_ContextSDL(bool stereoVisual, SDL_Window *window, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, int contextFlags, int contextResetNotificationStrategy)
GHOST_TSuccess activateDrawingContext()
GHOST_TSuccess releaseDrawingContext()
GHOST_TSuccess setSwapInterval(int interval)
void initContextGLEW()
static void initClearGL()