-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
SDLGLGraphicsContext.cpp
142 lines (126 loc) · 3.77 KB
/
SDLGLGraphicsContext.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "SDLGLGraphicsContext.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "base/NativeApp.h"
#include "base/display.h"
#include "gfx_es2/gpu_features.h"
class GLRenderManager;
// Returns 0 on success.
int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) {
struct GLVersionPair {
int major;
int minor;
};
GLVersionPair attemptVersions[] = {
#ifdef USING_GLES2
{3, 2}, {3, 1}, {3, 0}, {2, 0},
#else
{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0},
{3, 3}, {3, 2}, {3, 1}, {3, 0},
#endif
};
#ifdef USING_GLES2
mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
#else
mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
#endif
SDL_GLContext glContext = nullptr;
for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) {
const auto &ver = attemptVersions[i];
// Make sure to request a somewhat modern GL context at least - the
// latest supported by MacOS X (really, really sad...)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor);
#ifdef USING_GLES2
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SetGLCoreContext(false);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SetGLCoreContext(true);
#endif
window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode);
if (!window) {
NativeShutdown();
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
continue;
}
glContext = SDL_GL_CreateContext(window);
if (glContext != nullptr) {
// Victory, got one.
break;
}
// Let's keep trying. To be safe, destroy the window - docs say needed to change profile.
// in practice, it doesn't seem to matter, but maybe it differs by platform.
SDL_DestroyWindow(window);
}
if (glContext == nullptr) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SetGLCoreContext(false);
window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode);
if (window == nullptr) {
NativeShutdown();
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_Quit();
return 2;
}
glContext = SDL_GL_CreateContext(window);
if (glContext == nullptr) {
NativeShutdown();
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
SDL_Quit();
return 2;
}
}
#ifdef USING_EGL
EGL_Init();
#endif
#ifndef USING_GLES2
// Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc.
// glewExperimental allows us to force GLEW to search for the pointers anyway.
if (gl_extensions.IsCoreContext) {
glewExperimental = true;
}
if (GLEW_OK != glewInit()) {
printf("Failed to initialize glew!\n");
return 1;
}
// Unfortunately, glew will generate an invalid enum error, ignore.
if (gl_extensions.IsCoreContext)
glGetError();
if (GLEW_VERSION_2_0) {
printf("OpenGL 2.0 or higher.\n");
} else {
printf("Sorry, this program requires OpenGL 2.0.\n");
return 1;
}
#endif
// Finally we can do the regular initialization.
CheckGLExtensions();
draw_ = Draw::T3DCreateGLContext();
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
SetGPUBackend(GPUBackend::OPENGL);
bool success = draw_->CreatePresets();
assert(success);
renderManager_->SetSwapFunction([&]() {
#ifdef USING_EGL
eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
SDL_GL_SwapWindow(window_);
#endif
});
window_ = window;
return 0;
}
void SDLGLGraphicsContext::Shutdown() {
}
void SDLGLGraphicsContext::ShutdownFromRenderThread() {
delete draw_;
draw_ = nullptr;
#ifdef USING_EGL
EGL_Close();
#else
SDL_GL_DeleteContext(glContext);
#endif
}