OpenTTD Source  12.0-beta2
sdl2_opengl_v.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 /* XXX -- Temporary hack for Windows compile */
11 #define WINGDIAPI
12 #define APIENTRY
13 
14 #include "../stdafx.h"
15 #include "../openttd.h"
16 #include "../gfx_func.h"
17 #include "../rev.h"
18 #include "../blitter/factory.hpp"
19 #include "../network/network.h"
20 #include "../thread.h"
21 #include "../progress.h"
22 #include "../core/random_func.hpp"
23 #include "../core/math_func.hpp"
24 #include "../core/mem_func.hpp"
25 #include "../core/geometry_func.hpp"
26 #include "../fileio_func.h"
27 #include "../framerate_type.h"
28 #include "../window_func.h"
29 #include "sdl2_opengl_v.h"
30 #include <SDL.h>
31 #include <mutex>
32 #include <condition_variable>
33 #include <GL/gl.h>
34 #include "../3rdparty/opengl/glext.h"
35 #include "opengl.h"
36 #ifdef __EMSCRIPTEN__
37 # include <emscripten.h>
38 # include <emscripten/html5.h>
39 #endif
40 
41 #include "../safeguards.h"
42 
43 static FVideoDriver_SDL_OpenGL iFVideoDriver_SDL_OpenGL;
44 
46 static OGLProc GetOGLProcAddressCallback(const char *proc)
47 {
48  return reinterpret_cast<OGLProc>(SDL_GL_GetProcAddress(proc));
49 }
50 
51 bool VideoDriver_SDL_OpenGL::CreateMainWindow(uint w, uint h, uint flags)
52 {
53  return this->VideoDriver_SDL_Base::CreateMainWindow(w, h, SDL_WINDOW_OPENGL);
54 }
55 
56 const char *VideoDriver_SDL_OpenGL::Start(const StringList &param)
57 {
58  const char *error = VideoDriver_SDL_Base::Start(param);
59  if (error != nullptr) return error;
60 
61  error = this->AllocateContext();
62  if (error != nullptr) {
63  this->Stop();
64  return error;
65  }
66 
67  /* Now we have a OpenGL context, force a client-size-changed event,
68  * so all buffers are allocated correctly. */
69  int w, h;
70  SDL_GetWindowSize(this->sdl_window, &w, &h);
71  this->ClientSizeChanged(w, h, true);
72  /* We should have a valid screen buffer now. If not, something went wrong and we should abort. */
73  if (_screen.dst_ptr == nullptr) {
74  this->Stop();
75  return "Can't get pointer to screen buffer";
76  }
77  /* Main loop expects to start with the buffer unmapped. */
78  this->ReleaseVideoPointer();
79 
80  return nullptr;
81 }
82 
84 {
85  this->DestroyContext();
87 }
88 
89 void VideoDriver_SDL_OpenGL::DestroyContext()
90 {
92 
93  if (this->gl_context != nullptr) {
94  SDL_GL_DeleteContext(this->gl_context);
95  this->gl_context = nullptr;
96  }
97 }
98 
100 {
101  SDL_GL_SetSwapInterval(vsync);
102 }
103 
104 const char *VideoDriver_SDL_OpenGL::AllocateContext()
105 {
106  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
107  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
108  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
109  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
110  SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
111  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
112 
113  if (_debug_driver_level >= 8) {
114  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
115  }
116 
117  this->gl_context = SDL_GL_CreateContext(this->sdl_window);
118  if (this->gl_context == nullptr) return "SDL2: Can't active GL context";
119 
121 
123 }
124 
126 {
127  OpenGLBackend::Get()->PopulateCursorCache();
128 }
129 
131 {
133 }
134 
135 bool VideoDriver_SDL_OpenGL::AllocateBackingStore(int w, int h, bool force)
136 {
137  if (this->gl_context == nullptr) return false;
138 
139  if (_screen.dst_ptr != nullptr) this->ReleaseVideoPointer();
140 
141  w = std::max(w, 64);
142  h = std::max(h, 64);
143  MemSetT(&this->dirty_rect, 0);
144 
145  bool res = OpenGLBackend::Get()->Resize(w, h, force);
146  SDL_GL_SwapWindow(this->sdl_window);
147  _screen.dst_ptr = this->GetVideoPointer();
148 
149  CopyPalette(this->local_palette, true);
150 
151  return res;
152 }
153 
155 {
156  if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
158  }
160 }
161 
163 {
164  if (this->anim_buffer != nullptr) OpenGLBackend::Get()->ReleaseAnimBuffer(this->dirty_rect);
166  MemSetT(&this->dirty_rect, 0);
167  this->anim_buffer = nullptr;
168 }
169 
171 {
172  PerformanceMeasurer framerate(PFE_VIDEO);
173 
174  if (this->local_palette.count_dirty != 0) {
176 
177  /* Always push a changed palette to OpenGL. */
178  OpenGLBackend::Get()->UpdatePalette(this->local_palette.palette, this->local_palette.first_dirty, this->local_palette.count_dirty);
180  blitter->PaletteAnimate(this->local_palette);
181  }
182 
183  this->local_palette.count_dirty = 0;
184  }
185 
188 
189  SDL_GL_SwapWindow(this->sdl_window);
190 }
VideoDriver_SDL_OpenGL::AllocateBackingStore
bool AllocateBackingStore(int w, int h, bool force=false) override
(Re-)create the backing store.
Definition: sdl2_opengl_v.cpp:135
PFE_VIDEO
@ PFE_VIDEO
Speed of painting drawn video buffer.
Definition: framerate_type.h:59
Blitter::UsePaletteAnimation
virtual Blitter::PaletteAnimation UsePaletteAnimation()=0
Check if the blitter uses palette animation at all.
Blitter
How all blitters should look like.
Definition: base.hpp:28
VideoDriver_SDL_OpenGL::Stop
void Stop() override
Stop this driver.
Definition: sdl2_opengl_v.cpp:83
VideoDriver_SDL_OpenGL::CreateMainWindow
bool CreateMainWindow(uint w, uint h, uint flags) override
Create the main window.
Definition: sdl2_opengl_v.cpp:51
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition: framerate_type.h:92
VideoDriver_SDL_OpenGL::PopulateSystemSprites
void PopulateSystemSprites() override
Populate all sprites in cache.
Definition: sdl2_opengl_v.cpp:125
OpenGLBackend::Get
static OpenGLBackend * Get()
Get singleton instance of this class.
Definition: opengl.h:86
OpenGLBackend::DrawMouseCursor
void DrawMouseCursor()
Draw mouse cursor on screen.
Definition: opengl.cpp:1068
VideoDriver_SDL_Base::Stop
void Stop() override
Stop this driver.
Definition: sdl2_v.cpp:557
VideoDriver_SDL_OpenGL::Paint
void Paint() override
Paint the window.
Definition: sdl2_opengl_v.cpp:170
Palette::palette
Colour palette[256]
Current palette. Entry 0 has to be always fully transparent!
Definition: gfx_type.h:314
OpenGLBackend::ReleaseVideoBuffer
void ReleaseVideoBuffer(const Rect &update_rect)
Update video buffer texture after the video buffer was filled.
Definition: opengl.cpp:1196
VideoDriver_SDL_Base::local_palette
Palette local_palette
Current palette to use for drawing.
Definition: sdl2_v.h:48
BlitterFactory::GetCurrentBlitter
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition: factory.hpp:141
OpenGLBackend::GetVideoBuffer
void * GetVideoBuffer()
Get a pointer to the memory for the video driver to draw to.
Definition: opengl.cpp:1151
StringList
std::vector< std::string > StringList
Type for a list of strings.
Definition: string_type.h:58
OpenGLBackend::Create
static const char * Create(GetOGLProcAddressProc get_proc, const Dimension &screen_res)
Create and initialize the singleton back-end class.
Definition: opengl.cpp:471
OpenGLBackend::Destroy
static void Destroy()
Free resources and destroy singleton back-end class.
Definition: opengl.cpp:484
VideoDriver_SDL_Base::CreateMainWindow
virtual bool CreateMainWindow(uint w, uint h, uint flags=0)
Create the main window.
Definition: sdl2_v.cpp:135
Palette::count_dirty
int count_dirty
The number of dirty elements.
Definition: gfx_type.h:316
VideoDriver_SDL_OpenGL::ToggleVsync
void ToggleVsync(bool vsync) override
Change the vsync setting.
Definition: sdl2_opengl_v.cpp:99
VideoDriver_SDL_OpenGL::Start
const char * Start(const StringList &param) override
Start this driver.
Definition: sdl2_opengl_v.cpp:56
OpenGLBackend::ClearCursorCache
void ClearCursorCache()
Queue a request for cursor cache clear.
Definition: opengl.cpp:1138
VideoDriver_SDL_OpenGL::ReleaseVideoPointer
void ReleaseVideoPointer() override
Hand video buffer back to the painting backend.
Definition: sdl2_opengl_v.cpp:162
VideoDriver_SDL_Base::ClientSizeChanged
void ClientSizeChanged(int w, int h, bool force)
Indicate to the driver the client-side might have changed.
Definition: sdl2_v.cpp:123
VideoDriver_SDL_OpenGL::GetVideoPointer
void * GetVideoPointer() override
Get a pointer to the video buffer.
Definition: sdl2_opengl_v.cpp:154
GetOGLProcAddressCallback
static OGLProc GetOGLProcAddressCallback(const char *proc)
Platform-specific callback to get an OpenGL funtion pointer.
Definition: sdl2_opengl_v.cpp:46
CopyPalette
bool CopyPalette(Palette &local_palette, bool force_copy)
Copy the current palette if the palette was updated.
Definition: gfx.cpp:1216
VideoDriver_SDL_Base::dirty_rect
Rect dirty_rect
Rectangle encompassing the dirty area of the video buffer.
Definition: sdl2_v.h:50
opengl.h
OpenGLBackend::Paint
void Paint()
Render video buffer to the screen.
Definition: opengl.cpp:1036
FVideoDriver_SDL_OpenGL
The factory for SDL' OpenGL video driver.
Definition: sdl2_opengl_v.h:52
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:132
_video_vsync
bool _video_vsync
Whether we should use vsync (only if _video_hw_accel is enabled).
Definition: video_driver.cpp:24
OpenGLBackend::UpdatePalette
void UpdatePalette(const Colour *pal, uint first, uint length)
Update the stored palette.
Definition: opengl.cpp:1022
Blitter::PaletteAnimate
virtual void PaletteAnimate(const Palette &palette)=0
Called when the 8bpp palette is changed; you should redraw all pixels on the screen that are equal to...
sdl2_opengl_v.h
Blitter::PALETTE_ANIMATION_BLITTER
@ PALETTE_ANIMATION_BLITTER
The blitter takes care of the palette animation.
Definition: base.hpp:52
MemSetT
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
VideoDriver_SDL_OpenGL::ClearSystemSprites
void ClearSystemSprites() override
Clear all cached sprites.
Definition: sdl2_opengl_v.cpp:130
OpenGLBackend::ReleaseAnimBuffer
void ReleaseAnimBuffer(const Rect &update_rect)
Update animation buffer texture after the animation buffer was filled.
Definition: opengl.cpp:1238
VideoDriver_SDL_Base::GetScreenSize
Dimension GetScreenSize() const override
Get the resolution of the main screen.
Definition: sdl2_v.cpp:683
VideoDriver_SDL_OpenGL::gl_context
void * gl_context
OpenGL context.
Definition: sdl2_opengl_v.h:44
OpenGLBackend::Resize
bool Resize(int w, int h, bool force=false)
Change the size of the drawing window and allocate matching resources.
Definition: opengl.cpp:907
OpenGLBackend::GetAnimBuffer
uint8 * GetAnimBuffer()
Get a pointer to the memory for the separate animation buffer.
Definition: opengl.cpp:1173
VideoDriver_SDL_OpenGL::anim_buffer
uint8 * anim_buffer
Animation buffer from OpenGL back-end.
Definition: sdl2_opengl_v.h:45
VideoDriver_SDL_Base::sdl_window
struct SDL_Window * sdl_window
Main SDL window.
Definition: sdl2_v.h:47
VideoDriver_SDL_Base::Start
const char * Start(const StringList &param) override
Start this driver.
Definition: sdl2_v.cpp:527