Cleanup: remove redundant doxygen \file argument
[blender.git] / intern / ghost / intern / GHOST_ContextSDL.cpp
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
20 /** \file \ingroup GHOST
21  *
22  * Definition of GHOST_ContextSDL class.
23  */
24
25 #include "GHOST_ContextSDL.h"
26
27 #include <vector>
28
29 #include <cassert>
30 #include <cstdio>
31 #include <cstring>
32
33
34 SDL_GLContext GHOST_ContextSDL::s_sharedContext = NULL;
35 int           GHOST_ContextSDL::s_sharedCount   = 0;
36
37
38 GHOST_ContextSDL::GHOST_ContextSDL(
39         bool stereoVisual,
40         GHOST_TUns16 numOfAASamples,
41         SDL_Window *window,
42         int contextProfileMask,
43         int contextMajorVersion,
44         int contextMinorVersion,
45         int contextFlags,
46         int contextResetNotificationStrategy)
47     : GHOST_Context(stereoVisual, numOfAASamples),
48       m_window(window),
49       m_hidden_window(NULL),
50       m_contextProfileMask(contextProfileMask),
51       m_contextMajorVersion(contextMajorVersion),
52       m_contextMinorVersion(contextMinorVersion),
53       m_contextFlags(contextFlags),
54       m_contextResetNotificationStrategy(contextResetNotificationStrategy),
55       m_context(NULL)
56 {
57         // assert(m_window  != NULL);
58 }
59
60
61 GHOST_ContextSDL::~GHOST_ContextSDL()
62 {
63         if (m_context != NULL) {
64                 if (m_window != NULL && m_context == SDL_GL_GetCurrentContext())
65                         SDL_GL_MakeCurrent(m_window, NULL);
66
67                 if (m_context != s_sharedContext || s_sharedCount == 1) {
68                         assert(s_sharedCount > 0);
69
70                         s_sharedCount--;
71
72                         if (s_sharedCount == 0)
73                                 s_sharedContext = NULL;
74
75                         SDL_GL_DeleteContext(m_context);
76                 }
77
78                 if (m_hidden_window != NULL)
79                         SDL_DestroyWindow(m_hidden_window);
80         }
81 }
82
83
84 GHOST_TSuccess GHOST_ContextSDL::swapBuffers()
85 {
86         SDL_GL_SwapWindow(m_window);
87
88         return GHOST_kSuccess;
89 }
90
91
92 GHOST_TSuccess GHOST_ContextSDL::activateDrawingContext()
93 {
94         if (m_context) {
95                 return SDL_GL_MakeCurrent(m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
96         }
97         else {
98                 return GHOST_kFailure;
99         }
100 }
101
102
103 GHOST_TSuccess GHOST_ContextSDL::releaseDrawingContext()
104 {
105         if (m_context) {
106                 /* Untested, may not work */
107                 return SDL_GL_MakeCurrent(NULL, NULL) ? GHOST_kSuccess : GHOST_kFailure;
108         }
109         else {
110                 return GHOST_kFailure;
111         }
112 }
113
114
115 GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext()
116 {
117 #ifdef GHOST_OPENGL_ALPHA
118         const bool needAlpha   = true;
119 #else
120         const bool needAlpha   = false;
121 #endif
122
123 #ifdef GHOST_OPENGL_STENCIL
124         const bool needStencil = true;
125 #else
126         const bool needStencil = false;
127 #endif
128
129         SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, m_contextProfileMask);
130         SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, m_contextMajorVersion);
131         SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, m_contextMinorVersion);
132         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, m_contextFlags);
133
134         SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
135         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
136         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
137         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
138         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
139         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
140
141         if (needAlpha) {
142                 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
143         }
144
145         if (needStencil) {
146                 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
147         }
148
149         if (m_stereoVisual) {
150                 SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
151         }
152
153         if (m_numOfAASamples) {
154                 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
155                 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples);
156         }
157
158         if (m_window == NULL) {
159                 m_hidden_window = SDL_CreateWindow(
160                     "Offscreen Context Windows",
161                     SDL_WINDOWPOS_UNDEFINED,
162                     SDL_WINDOWPOS_UNDEFINED,
163                     1, 1,
164                     SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN
165                 );
166
167                 m_window = m_hidden_window;
168         }
169
170         m_context = SDL_GL_CreateContext(m_window);
171
172         GHOST_TSuccess success;
173
174         if (m_context != NULL) {
175                 if (!s_sharedContext)
176                         s_sharedContext = m_context;
177
178                 s_sharedCount++;
179
180                 success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ?
181                            GHOST_kFailure : GHOST_kSuccess;
182
183                 initContextGLEW();
184
185                 initClearGL();
186                 SDL_GL_SwapWindow(m_window);
187
188                 success = GHOST_kSuccess;
189         }
190         else {
191                 success = GHOST_kFailure;
192         }
193
194         return success;
195 }
196
197
198 GHOST_TSuccess GHOST_ContextSDL::releaseNativeHandles()
199 {
200         m_window = NULL;
201
202         return GHOST_kSuccess;
203 }
204
205
206 GHOST_TSuccess GHOST_ContextSDL::setSwapInterval(int interval)
207 {
208         if (SDL_GL_SetSwapInterval(interval) != -1) {
209                 return GHOST_kSuccess;
210         }
211         else {
212                 return GHOST_kFailure;
213         }
214 }
215
216
217 GHOST_TSuccess GHOST_ContextSDL::getSwapInterval(int &intervalOut)
218 {
219         intervalOut = SDL_GL_GetSwapInterval();
220         return GHOST_kSuccess;
221 }