| 
									
										
										
										
											2017-12-14 17:48:08 +11:00
										 |  |  | /*
 | 
					
						
							|  |  |  | Looking Glass - KVM FrameRelay (KVMFR) Client | 
					
						
							| 
									
										
										
										
											2019-02-22 22:16:14 +11:00
										 |  |  | Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com> | 
					
						
							| 
									
										
										
										
											2017-12-14 17:48:08 +11:00
										 |  |  | https://looking-glass.hostfission.com
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This program 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; either version 2 of the License, or (at your option) any later | 
					
						
							|  |  |  | version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This program 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. See the GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You should have received a copy of the GNU General Public License along with | 
					
						
							|  |  |  | this program; if not, write to the Free Software Foundation, Inc., 59 Temple | 
					
						
							|  |  |  | Place, Suite 330, Boston, MA 02111-1307 USA | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-28 11:02:36 +11:00
										 |  |  | #include "interface/renderer.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | #include <stdint.h>
 | 
					
						
							|  |  |  | #include <stdbool.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | #include <malloc.h>
 | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 16:09:39 +11:00
										 |  |  | #include <SDL2/SDL_ttf.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <GL/gl.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-11 03:02:45 +11:00
										 |  |  | #include <GL/glx.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 11:12:59 +10:00
										 |  |  | #include "common/debug.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  | #include "common/option.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  | #include "common/framebuffer.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-17 14:35:08 +11:00
										 |  |  | #include "common/locking.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-28 19:56:14 +11:00
										 |  |  | #include "dynamic/fonts.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | #include "ll.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 17:58:36 +10:00
										 |  |  | #define BUFFER_COUNT       2
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | #define FPS_TEXTURE        0
 | 
					
						
							|  |  |  | #define MOUSE_TEXTURE      1
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | #define ALERT_TEXTURE      2
 | 
					
						
							|  |  |  | #define TEXTURE_COUNT      3
 | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  | #define ALERT_TIMEOUT_FLAG ((uint64_t)-1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  | #define FADE_TIME 1000000
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  | static struct Option opengl_options[] = | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     .module       = "opengl", | 
					
						
							|  |  |  |     .name         = "mipmap", | 
					
						
							|  |  |  |     .description  = "Enable mipmapping", | 
					
						
							|  |  |  |     .type         = OPTION_TYPE_BOOL, | 
					
						
							|  |  |  |     .value.x_bool = true | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     .module       = "opengl", | 
					
						
							|  |  |  |     .name         = "vsync", | 
					
						
							|  |  |  |     .description  = "Enable vsync", | 
					
						
							|  |  |  |     .type         = OPTION_TYPE_BOOL, | 
					
						
							| 
									
										
											  
											
												[client] fix hang in eglSwapBuffers when exiting while not visible
eglSwapBuffers is allowed to block when called with a nonzero interval
parameter. On Wayland, Mesa will block until a frame callback arrives.
If an application is not visible, a compositor is free to not schedule
frame callbacks (in order to save CPU time rendering something that is
entirely invisible).
Currently, starting Looking Glass from a terminal, hiding it
entirely, and sending ^C will cause Looking Glass to hang joining the
render thread until the window is made visible again.
Calling eglDestroySurface is insufficient to unblock eglSwapBuffers, as
it attempts to grab the same underlying mutex.
Instead, this commit makes it so that we pass a 0 interval to
eglSwapBuffers when running on Wayland, such that we don't block waiting
for a frame callback. This is not entirely ideal as it *does* mean
Looking Glass submits buffers while hidden, but it seems better than
hanging on exit.
It also forces opengl:vsync and egl:vsync flags to off when running on
Wayland, as they are meaningless there.
											
										 
											2021-01-03 21:09:55 -05:00
										 |  |  |     .value.x_bool = false, | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     .module       = "opengl", | 
					
						
							|  |  |  |     .name         = "preventBuffer", | 
					
						
							|  |  |  |     .description  = "Prevent the driver from buffering frames", | 
					
						
							|  |  |  |     .type         = OPTION_TYPE_BOOL, | 
					
						
							|  |  |  |     .value.x_bool = true | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     .module       = "opengl", | 
					
						
							|  |  |  |     .name         = "amdPinnedMem", | 
					
						
							|  |  |  |     .description  = "Use GL_AMD_pinned_memory if it is available", | 
					
						
							|  |  |  |     .type         = OPTION_TYPE_BOOL, | 
					
						
							|  |  |  |     .value.x_bool = true | 
					
						
							| 
									
										
										
										
											2020-03-28 15:24:05 -05:00
										 |  |  |   }, | 
					
						
							|  |  |  |   {0} | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct OpenGL_Options | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   bool mipmap; | 
					
						
							|  |  |  |   bool vsync; | 
					
						
							| 
									
										
										
										
											2017-12-19 11:02:35 +11:00
										 |  |  |   bool preventBuffer; | 
					
						
							| 
									
										
										
										
											2018-05-16 17:58:36 +10:00
										 |  |  |   bool amdPinnedMem; | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | struct Alert | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   bool          ready; | 
					
						
							|  |  |  |   bool          useCloseFlag; | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   LG_FontBitmap *text; | 
					
						
							|  |  |  |   float         r, g, b, a; | 
					
						
							|  |  |  |   uint64_t      timeout; | 
					
						
							|  |  |  |   bool          closeFlag; | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | struct Inst | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  |   LG_RendererParams     params; | 
					
						
							|  |  |  |   struct OpenGL_Options opt; | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |   bool              amdPinnedMemSupport; | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   bool              renderStarted; | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   bool              configured; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   bool              reconfigure; | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  |   SDL_GLContext     glContext; | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   SDL_Point         window; | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   bool              frameUpdate; | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   const LG_Font   * font; | 
					
						
							|  |  |  |   LG_FontObj        fontObj, alertFontObj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 19:30:49 +11:00
										 |  |  |   LG_Lock             formatLock; | 
					
						
							|  |  |  |   LG_RendererFormat   format; | 
					
						
							|  |  |  |   GLuint              intFormat; | 
					
						
							|  |  |  |   GLuint              vboFormat; | 
					
						
							|  |  |  |   GLuint              dataFormat; | 
					
						
							|  |  |  |   size_t              texSize; | 
					
						
							|  |  |  |   size_t              texPos; | 
					
						
							|  |  |  |   const FrameBuffer * frame; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  |   uint64_t          drawStart; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   bool              hasBuffers; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   GLuint            vboID[BUFFER_COUNT]; | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  |   uint8_t         * texPixels[BUFFER_COUNT]; | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_Lock           syncLock; | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  |   bool              texReady; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   int               texIndex; | 
					
						
							| 
									
										
										
										
											2017-12-11 03:47:07 +11:00
										 |  |  |   int               texList; | 
					
						
							|  |  |  |   int               fpsList; | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |   int               mouseList; | 
					
						
							| 
									
										
										
										
											2017-12-11 03:47:07 +11:00
										 |  |  |   LG_RendererRect   destRect; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   bool              hasTextures, hasFrames; | 
					
						
							|  |  |  |   GLuint            frames[BUFFER_COUNT]; | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |   GLsync            fences[BUFFER_COUNT]; | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   GLuint            textures[TEXTURE_COUNT]; | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   struct ll       * alerts; | 
					
						
							|  |  |  |   int               alertList; | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   bool              waiting; | 
					
						
							|  |  |  |   uint64_t          waitFadeTime; | 
					
						
							|  |  |  |   bool              waitDone; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  |   bool              fpsTexture; | 
					
						
							|  |  |  |   SDL_Rect          fpsRect; | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_Lock           mouseLock; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   LG_RendererCursor mouseCursor; | 
					
						
							|  |  |  |   int               mouseWidth; | 
					
						
							|  |  |  |   int               mouseHeight; | 
					
						
							|  |  |  |   int               mousePitch; | 
					
						
							|  |  |  |   uint8_t *         mouseData; | 
					
						
							|  |  |  |   size_t            mouseDataSize; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 04:18:30 +11:00
										 |  |  |   bool              mouseUpdate; | 
					
						
							| 
									
										
										
										
											2017-12-15 16:53:26 +11:00
										 |  |  |   bool              newShape; | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |   LG_RendererCursor mouseType; | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   bool              mouseVisible; | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |   SDL_Rect          mousePos; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static bool _check_gl_error(unsigned int line, const char * name); | 
					
						
							|  |  |  | #define check_gl_error(name) _check_gl_error(__LINE__, name)
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  | enum ConfigStatus | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   CONFIG_STATUS_OK, | 
					
						
							|  |  |  |   CONFIG_STATUS_ERROR, | 
					
						
							|  |  |  |   CONFIG_STATUS_NOOP | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void deconfigure(struct Inst * this); | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | static enum ConfigStatus configure(struct Inst * this); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void update_mouse_shape(struct Inst * this, bool * newShape); | 
					
						
							| 
									
										
										
										
											2017-12-23 17:37:56 +11:00
										 |  |  | static bool draw_frame(struct Inst * this); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void draw_mouse(struct Inst * this); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  | static void render_wait(struct Inst * this); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 01:05:26 -05:00
										 |  |  | const char * opengl_get_name(void) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   return "OpenGL"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 01:05:26 -05:00
										 |  |  | static void opengl_setup(void) | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   option_register(opengl_options); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | bool opengl_create(void ** opaque, const LG_RendererParams params) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   // create our local storage
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   *opaque = malloc(sizeof(struct Inst)); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   if (!*opaque) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |     DEBUG_INFO("Failed to allocate %lu bytes", sizeof(struct Inst)); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   memset(*opaque, 0, sizeof(struct Inst)); | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   struct Inst * this = (struct Inst *)*opaque; | 
					
						
							| 
									
										
										
										
											2019-05-21 15:03:59 +10:00
										 |  |  |   memcpy(&this->params, ¶ms, sizeof(LG_RendererParams)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->opt.mipmap        = option_get_bool("opengl", "mipmap"       ); | 
					
						
							|  |  |  |   this->opt.vsync         = option_get_bool("opengl", "vsync"        ); | 
					
						
							|  |  |  |   this->opt.preventBuffer = option_get_bool("opengl", "preventBuffer"); | 
					
						
							|  |  |  |   this->opt.amdPinnedMem  = option_get_bool("opengl", "amdPinnedMem" ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_LOCK_INIT(this->formatLock); | 
					
						
							|  |  |  |   LG_LOCK_INIT(this->syncLock  ); | 
					
						
							|  |  |  |   LG_LOCK_INIT(this->mouseLock ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   this->font = LG_Fonts[0]; | 
					
						
							|  |  |  |   if (!this->font->create(&this->fontObj, NULL, 14)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Unable to create the font renderer"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!this->font->create(&this->alertFontObj, NULL, 18)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Unable to create the font renderer"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   this->alerts = ll_new(); | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | bool opengl_initialize(void * opaque) | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |   //FIXME
 | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  |   if (!this) | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   this->waiting  = true; | 
					
						
							|  |  |  |   this->waitDone = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   *sdlFlags = SDL_WINDOW_OPENGL; | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:26 +10:00
										 |  |  |   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER      , 1); | 
					
						
							|  |  |  |   SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); | 
					
						
							|  |  |  |   SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); | 
					
						
							| 
									
										
										
										
											2021-01-03 23:29:34 -05:00
										 |  |  |   SDL_GL_SetAttribute(SDL_GL_RED_SIZE          , 8); | 
					
						
							|  |  |  |   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE        , 8); | 
					
						
							|  |  |  |   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE         , 8); | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | void opengl_deinitialize(void * opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   if (!this) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   if (this->renderStarted) | 
					
						
							| 
									
										
										
										
											2018-07-20 00:10:29 +10:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |     glDeleteLists(this->texList  , BUFFER_COUNT); | 
					
						
							|  |  |  |     glDeleteLists(this->mouseList, 1); | 
					
						
							| 
									
										
										
										
											2018-07-20 00:10:29 +10:00
										 |  |  |     glDeleteLists(this->fpsList  , 1); | 
					
						
							|  |  |  |     glDeleteLists(this->alertList, 1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   deconfigure(this); | 
					
						
							|  |  |  |   if (this->mouseData) | 
					
						
							|  |  |  |     free(this->mouseData); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 18:54:29 +10:00
										 |  |  |   if (this->glContext) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     SDL_GL_DeleteContext(this->glContext); | 
					
						
							|  |  |  |     this->glContext = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 01:23:25 +11:00
										 |  |  |   LG_LOCK_FREE(this->formatLock); | 
					
						
							|  |  |  |   LG_LOCK_FREE(this->syncLock  ); | 
					
						
							|  |  |  |   LG_LOCK_FREE(this->mouseLock ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   struct Alert * alert; | 
					
						
							|  |  |  |   while(ll_shift(this->alerts, (void **)&alert)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (alert->text) | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |       this->font->release(this->alertFontObj, alert->text); | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     free(alert); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   ll_free(this->alerts); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   if (this->font && this->fontObj) | 
					
						
							|  |  |  |     this->font->destroy(this->fontObj); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   free(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-11 14:30:44 +10:00
										 |  |  | void opengl_on_restart(void * opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   this->waiting = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 02:44:56 +11:00
										 |  |  | void opengl_on_resize(void * opaque, const int width, const int height, | 
					
						
							|  |  |  |     const LG_RendererRect destRect, LG_RendererRotate rotate) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->window.x = width; | 
					
						
							|  |  |  |   this->window.y = height; | 
					
						
							| 
									
										
										
										
											2018-07-19 23:32:42 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (destRect.valid) | 
					
						
							|  |  |  |     memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect)); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   // setup the projection matrix
 | 
					
						
							|  |  |  |   glViewport(0, 0, this->window.x, this->window.y); | 
					
						
							|  |  |  |   glMatrixMode(GL_PROJECTION); | 
					
						
							|  |  |  |   glLoadIdentity(); | 
					
						
							| 
									
										
										
										
											2021-02-18 21:40:05 -05:00
										 |  |  |   glOrtho(0, this->window.x, this->window.y, 0, -1, 1); | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   glMatrixMode(GL_MODELVIEW); | 
					
						
							|  |  |  |   glLoadIdentity(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (this->destRect.valid) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     glTranslatef(this->destRect.x, this->destRect.y, 0.0f); | 
					
						
							|  |  |  |     glScalef( | 
					
						
							|  |  |  |       (float)this->destRect.w / (float)this->format.width, | 
					
						
							|  |  |  |       (float)this->destRect.h / (float)this->format.height, | 
					
						
							|  |  |  |       1.0f | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 02:44:56 +11:00
										 |  |  | bool opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, | 
					
						
							|  |  |  |     const int width, const int height, const int pitch, const uint8_t * data) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   if (!this) | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_LOCK(this->mouseLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   this->mouseCursor = cursor; | 
					
						
							|  |  |  |   this->mouseWidth  = width; | 
					
						
							|  |  |  |   this->mouseHeight = height; | 
					
						
							|  |  |  |   this->mousePitch  = pitch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const size_t size = height * pitch; | 
					
						
							|  |  |  |   if (size > this->mouseDataSize) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |     if (this->mouseData) | 
					
						
							|  |  |  |       free(this->mouseData); | 
					
						
							|  |  |  |     this->mouseData     = (uint8_t *)malloc(size); | 
					
						
							|  |  |  |     this->mouseDataSize = size; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   memcpy(this->mouseData, data, size); | 
					
						
							|  |  |  |   this->newShape = true; | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_UNLOCK(this->mouseLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool opengl_on_mouse_event(void * opaque, const bool visible, const int x, const int y) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   if (!this) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (this->mousePos.x == x && this->mousePos.y == y && this->mouseVisible == visible) | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->mouseVisible = visible; | 
					
						
							|  |  |  |   this->mousePos.x   = x; | 
					
						
							|  |  |  |   this->mousePos.y   = y; | 
					
						
							|  |  |  |   this->mouseUpdate  = true; | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-30 02:32:25 +11:00
										 |  |  | bool opengl_on_frame_format(void * opaque, const LG_RendererFormat format, bool useDMA) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_LOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2020-10-12 19:43:29 +11:00
										 |  |  |   memcpy(&this->format, &format, sizeof(LG_RendererFormat)); | 
					
						
							|  |  |  |   this->reconfigure = true; | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2020-10-12 19:43:29 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 22:57:04 +11:00
										 |  |  | bool opengl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd) | 
					
						
							| 
									
										
										
										
											2020-10-12 19:43:29 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_LOCK(this->syncLock); | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   this->frame       = frame; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   this->frameUpdate = true; | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_UNLOCK(this->syncLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   if (this->waiting) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-19 00:29:29 -04:00
										 |  |  |     this->waiting = false; | 
					
						
							|  |  |  |     if (!this->params.quickSplash) | 
					
						
							|  |  |  |       this->waitFadeTime = microtime() + FADE_TIME; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       glDisable(GL_MULTISAMPLE); | 
					
						
							|  |  |  |       this->waitDone = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 12:26:06 +11:00
										 |  |  | void opengl_on_alert(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag) | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   struct Alert * a = malloc(sizeof(struct Alert)); | 
					
						
							|  |  |  |   memset(a, 0, sizeof(struct Alert)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch(alert) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     case LG_ALERT_INFO: | 
					
						
							|  |  |  |       a->r = 0.0f; | 
					
						
							|  |  |  |       a->g = 0.0f; | 
					
						
							|  |  |  |       a->b = 0.8f; | 
					
						
							|  |  |  |       a->a = 0.8f; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case LG_ALERT_SUCCESS: | 
					
						
							|  |  |  |       a->r = 0.0f; | 
					
						
							|  |  |  |       a->g = 0.8f; | 
					
						
							|  |  |  |       a->b = 0.0f; | 
					
						
							|  |  |  |       a->a = 0.8f; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case LG_ALERT_WARNING: | 
					
						
							|  |  |  |       a->r = 0.8f; | 
					
						
							|  |  |  |       a->g = 0.5f; | 
					
						
							|  |  |  |       a->b = 0.0f; | 
					
						
							|  |  |  |       a->a = 0.8f; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case LG_ALERT_ERROR: | 
					
						
							|  |  |  |       a->r = 1.0f; | 
					
						
							|  |  |  |       a->g = 0.0f; | 
					
						
							|  |  |  |       a->b = 0.0f; | 
					
						
							|  |  |  |       a->a = 0.8f; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 05:50:22 +11:00
										 |  |  |   if (!(a->text = this->font->render(this->alertFontObj, 0xffffff00, message))) | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to render alert text: %s", TTF_GetError()); | 
					
						
							|  |  |  |     free(a); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |   if (closeFlag) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     a->useCloseFlag = true; | 
					
						
							|  |  |  |     *closeFlag = &a->closeFlag; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   ll_push(this->alerts, a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  | void bitmap_to_texture(LG_FontBitmap * bitmap, GLuint texture) | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |   glBindTexture(GL_TEXTURE_2D       , texture      ); | 
					
						
							|  |  |  |   glPixelStorei(GL_UNPACK_ALIGNMENT , 4            ); | 
					
						
							|  |  |  |   glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->width); | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   glTexImage2D( | 
					
						
							|  |  |  |     GL_TEXTURE_2D, | 
					
						
							|  |  |  |     0, | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |     bitmap->bpp, | 
					
						
							|  |  |  |     bitmap->width, | 
					
						
							|  |  |  |     bitmap->height, | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     0, | 
					
						
							|  |  |  |     GL_BGRA, | 
					
						
							|  |  |  |     GL_UNSIGNED_BYTE, | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |     bitmap->pixels | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | bool opengl_render_startup(void * opaque) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |   //FIXME
 | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |   this->glContext = app_getGLContext(); | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   if (!this->glContext) | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   DEBUG_INFO("Vendor  : %s", glGetString(GL_VENDOR  )); | 
					
						
							|  |  |  |   DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); | 
					
						
							|  |  |  |   DEBUG_INFO("Version : %s", glGetString(GL_VERSION )); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:32:42 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   GLint n; | 
					
						
							|  |  |  |   glGetIntegerv(GL_NUM_EXTENSIONS, &n); | 
					
						
							|  |  |  |   for(GLint i = 0; i < n; ++i) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i); | 
					
						
							|  |  |  |     if (strcmp((const char *)ext, "GL_AMD_pinned_memory") == 0) | 
					
						
							| 
									
										
										
										
											2018-07-19 23:32:42 +10:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |       if (this->opt.amdPinnedMem) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         this->amdPinnedMemSupport = true; | 
					
						
							|  |  |  |         DEBUG_INFO("Using GL_AMD_pinned_memory"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         DEBUG_INFO("GL_AMD_pinned_memory is available but not in use"); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2018-07-19 23:32:42 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   glEnable(GL_TEXTURE_2D); | 
					
						
							|  |  |  |   glEnable(GL_COLOR_MATERIAL); | 
					
						
							|  |  |  |   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
					
						
							|  |  |  |   glBlendEquation(GL_FUNC_ADD); | 
					
						
							|  |  |  |   glEnable(GL_MULTISAMPLE); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   // generate lists for drawing
 | 
					
						
							|  |  |  |   this->texList   = glGenLists(BUFFER_COUNT); | 
					
						
							|  |  |  |   this->mouseList = glGenLists(1); | 
					
						
							|  |  |  |   this->fpsList   = glGenLists(1); | 
					
						
							|  |  |  |   this->alertList = glGenLists(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // create the overlay textures
 | 
					
						
							|  |  |  |   glGenTextures(TEXTURE_COUNT, this->textures); | 
					
						
							|  |  |  |   if (check_gl_error("glGenTextures")) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     LG_UNLOCK(this->formatLock); | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   this->hasTextures = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); | 
					
						
							|  |  |  |   this->renderStarted = true; | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | bool opengl_render(void * opaque, LG_RendererRotate rotate) | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   if (!this) | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |   switch(configure(this)) | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |   { | 
					
						
							|  |  |  |     case CONFIG_STATUS_ERROR: | 
					
						
							|  |  |  |       DEBUG_ERROR("configure failed"); | 
					
						
							| 
									
										
										
										
											2018-07-20 00:10:29 +10:00
										 |  |  |       return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |     case CONFIG_STATUS_NOOP : | 
					
						
							|  |  |  |     case CONFIG_STATUS_OK   : | 
					
						
							|  |  |  |      if (!draw_frame(this)) | 
					
						
							|  |  |  |        return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 
					
						
							|  |  |  |   glClear(GL_COLOR_BUFFER_BIT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (this->waiting) | 
					
						
							|  |  |  |     render_wait(this); | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2018-07-20 00:10:29 +10:00
										 |  |  |   { | 
					
						
							|  |  |  |     bool newShape; | 
					
						
							|  |  |  |     update_mouse_shape(this, &newShape); | 
					
						
							|  |  |  |     glCallList(this->texList + this->texIndex); | 
					
						
							|  |  |  |     draw_mouse(this); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!this->waitDone) | 
					
						
							|  |  |  |       render_wait(this); | 
					
						
							| 
									
										
										
										
											2018-07-20 00:10:29 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (this->fpsTexture) | 
					
						
							|  |  |  |     glCallList(this->fpsList); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |   struct Alert * alert; | 
					
						
							|  |  |  |   while(ll_peek_head(this->alerts, (void **)&alert)) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |     if (!alert->ready) | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |       bitmap_to_texture(alert->text, this->textures[ALERT_TEXTURE]); | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |       glNewList(this->alertList, GL_COMPILE); | 
					
						
							|  |  |  |         const int p = 4; | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |         const int w = alert->text->width  + p * 2; | 
					
						
							|  |  |  |         const int h = alert->text->height + p * 2; | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |         glTranslatef(-(w / 2), -(h / 2), 0.0f); | 
					
						
							|  |  |  |         glEnable(GL_BLEND); | 
					
						
							|  |  |  |         glDisable(GL_TEXTURE_2D); | 
					
						
							|  |  |  |         glColor4f(alert->r, alert->g, alert->b, alert->a); | 
					
						
							|  |  |  |         glBegin(GL_TRIANGLE_STRIP); | 
					
						
							|  |  |  |           glVertex2i(0, 0); | 
					
						
							|  |  |  |           glVertex2i(w, 0); | 
					
						
							|  |  |  |           glVertex2i(0, h); | 
					
						
							|  |  |  |           glVertex2i(w, h); | 
					
						
							|  |  |  |         glEnd(); | 
					
						
							|  |  |  |         glEnable(GL_TEXTURE_2D); | 
					
						
							|  |  |  |         glBindTexture(GL_TEXTURE_2D, this->textures[ALERT_TEXTURE]); | 
					
						
							|  |  |  |         glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 
					
						
							|  |  |  |         glTranslatef(p, p, 0.0f); | 
					
						
							|  |  |  |         glBegin(GL_TRIANGLE_STRIP); | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |           glTexCoord2f(0.0f, 0.0f); glVertex2i(0                 , 0                  ); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 0.0f); glVertex2i(alert->text->width, 0                  ); | 
					
						
							|  |  |  |           glTexCoord2f(0.0f, 1.0f); glVertex2i(0                 , alert->text->height); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 1.0f); glVertex2i(alert->text->width, alert->text->height); | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |         glEnd(); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |         glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |         glDisable(GL_BLEND); | 
					
						
							|  |  |  |       glEndList(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |       if (!alert->useCloseFlag) | 
					
						
							|  |  |  |         alert->timeout = microtime() + 2*1000000; | 
					
						
							|  |  |  |       alert->ready   = true; | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 04:38:11 +11:00
										 |  |  |       this->font->release(this->fontObj, alert->text); | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |       alert->text  = NULL; | 
					
						
							|  |  |  |       alert->ready = true; | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-07-24 01:09:53 +10:00
										 |  |  |       bool close = false; | 
					
						
							|  |  |  |       if (alert->useCloseFlag) | 
					
						
							|  |  |  |         close = alert->closeFlag; | 
					
						
							|  |  |  |       else if (alert->timeout < microtime()) | 
					
						
							|  |  |  |         close = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (close) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         free(alert); | 
					
						
							|  |  |  |         ll_shift(this->alerts, NULL); | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-05-29 11:08:25 +10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glPushMatrix(); | 
					
						
							|  |  |  |       glLoadIdentity(); | 
					
						
							|  |  |  |       glTranslatef(this->window.x / 2, this->window.y / 2, 0.0f); | 
					
						
							|  |  |  |       glCallList(this->alertList); | 
					
						
							|  |  |  |     glPopMatrix(); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   if (this->opt.preventBuffer) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |     app_glSwapBuffers(); | 
					
						
							| 
									
										
										
										
											2018-05-21 23:16:16 +10:00
										 |  |  |     glFinish(); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  |     app_glSwapBuffers(); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 05:26:51 +11:00
										 |  |  |   this->mouseUpdate = false; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 23:59:22 +11:00
										 |  |  | void opengl_update_fps(void * opaque, const float avgUPS, const float avgFPS) | 
					
						
							| 
									
										
										
										
											2018-11-20 05:26:51 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  |   if (!this->params.showFPS) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   char str[128]; | 
					
						
							| 
									
										
										
										
											2018-12-12 23:59:22 +11:00
										 |  |  |   snprintf(str, sizeof(str), "UPS: %8.4f, FPS: %8.4f", avgUPS, avgFPS); | 
					
						
							| 
									
										
										
										
											2018-11-20 05:26:51 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   LG_FontBitmap *textSurface = NULL; | 
					
						
							| 
									
										
										
										
											2018-11-20 05:50:22 +11:00
										 |  |  |   if (!(textSurface = this->font->render(this->fontObj, 0xffffff00, str))) | 
					
						
							| 
									
										
										
										
											2018-11-20 05:26:51 +11:00
										 |  |  |     DEBUG_ERROR("Failed to render text"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bitmap_to_texture(textSurface, this->textures[FPS_TEXTURE]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->fpsRect.x = 5; | 
					
						
							|  |  |  |   this->fpsRect.y = 5; | 
					
						
							|  |  |  |   this->fpsRect.w = textSurface->width; | 
					
						
							|  |  |  |   this->fpsRect.h = textSurface->height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->font->release(this->fontObj, textSurface); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->fpsTexture  = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   glNewList(this->fpsList, GL_COMPILE); | 
					
						
							|  |  |  |     glPushMatrix(); | 
					
						
							|  |  |  |     glLoadIdentity(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glEnable(GL_BLEND); | 
					
						
							|  |  |  |     glDisable(GL_TEXTURE_2D); | 
					
						
							|  |  |  |     glColor4f(0.0f, 0.0f, 1.0f, 0.5f); | 
					
						
							|  |  |  |     glBegin(GL_TRIANGLE_STRIP); | 
					
						
							|  |  |  |       glVertex2i(this->fpsRect.x                  , this->fpsRect.y                  ); | 
					
						
							|  |  |  |       glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y                  ); | 
					
						
							|  |  |  |       glVertex2i(this->fpsRect.x                  , this->fpsRect.y + this->fpsRect.h); | 
					
						
							|  |  |  |       glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y + this->fpsRect.h); | 
					
						
							|  |  |  |     glEnd(); | 
					
						
							|  |  |  |     glEnable(GL_TEXTURE_2D); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glBindTexture(GL_TEXTURE_2D, this->textures[FPS_TEXTURE]); | 
					
						
							|  |  |  |     glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 
					
						
							|  |  |  |     glBegin(GL_TRIANGLE_STRIP); | 
					
						
							|  |  |  |       glTexCoord2f(0.0f , 0.0f); glVertex2i(this->fpsRect.x                  , this->fpsRect.y                  ); | 
					
						
							|  |  |  |       glTexCoord2f(1.0f , 0.0f); glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y                  ); | 
					
						
							|  |  |  |       glTexCoord2f(0.0f , 1.0f); glVertex2i(this->fpsRect.x                  , this->fpsRect.y + this->fpsRect.h); | 
					
						
							|  |  |  |       glTexCoord2f(1.0f,  1.0f); glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y + this->fpsRect.h); | 
					
						
							|  |  |  |     glEnd(); | 
					
						
							|  |  |  |     glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							|  |  |  |     glDisable(GL_BLEND); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glPopMatrix(); | 
					
						
							|  |  |  |   glEndList(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  | void draw_torus(float x, float y, float inner, float outer, unsigned int pts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   glBegin(GL_QUAD_STRIP); | 
					
						
							|  |  |  |   for (unsigned int i = 0; i <= pts; ++i) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     float angle = (i / (float)pts) * M_PI * 2.0f; | 
					
						
							|  |  |  |     glVertex2f(x + (inner * cos(angle)), y + (inner * sin(angle))); | 
					
						
							|  |  |  |     glVertex2f(x + (outer * cos(angle)), y + (outer * sin(angle))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   glEnd(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void draw_torus_arc(float x, float y, float inner, float outer, unsigned int pts, float s, float e) | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  |   glBegin(GL_QUAD_STRIP); | 
					
						
							|  |  |  |   for (unsigned int i = 0; i <= pts; ++i) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     float angle = s + ((i / (float)pts) * e); | 
					
						
							|  |  |  |     glVertex2f(x + (inner * cos(angle)), y + (inner * sin(angle))); | 
					
						
							|  |  |  |     glVertex2f(x + (outer * cos(angle)), y + (outer * sin(angle))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   glEnd(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void render_wait(struct Inst * this) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   float a; | 
					
						
							|  |  |  |   if (this->waiting) | 
					
						
							|  |  |  |     a = 1.0f; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     uint64_t t = microtime(); | 
					
						
							|  |  |  |     if (t > this->waitFadeTime) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-07-28 10:36:41 +10:00
										 |  |  |       glDisable(GL_MULTISAMPLE); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |       this->waitDone = true; | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint64_t delta = this->waitFadeTime - t; | 
					
						
							|  |  |  |     a = 1.0f / FADE_TIME * delta; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glEnable(GL_BLEND); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  |   glPushMatrix(); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glLoadIdentity(); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  |   glTranslatef(this->window.x / 2.0f, this->window.y / 2.0f, 0.0f); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:48:35 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   //draw the background gradient
 | 
					
						
							|  |  |  |   glBegin(GL_TRIANGLE_FAN); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glColor4f(0.234375f, 0.015625f, 0.425781f, a); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:48:35 +10:00
										 |  |  |   glVertex2f(0, 0); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glColor4f(0, 0, 0, a); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:48:35 +10:00
										 |  |  |   for (unsigned int i = 0; i <= 100; ++i) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     float angle = (i / (float)100) * M_PI * 2.0f; | 
					
						
							|  |  |  |     glVertex2f(cos(angle) * this->window.x, sin(angle) * this->window.y); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   glEnd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // draw the logo
 | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glColor4f(1.0f, 1.0f, 1.0f, a); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:48:35 +10:00
										 |  |  |   glScalef (2.0f, 2.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   draw_torus    (  0,  0, 40, 42, 60); | 
					
						
							|  |  |  |   draw_torus    (  0,  0, 32, 34, 60); | 
					
						
							|  |  |  |   draw_torus    (-50, -3,  2,  4, 30); | 
					
						
							|  |  |  |   draw_torus    ( 50, -3,  2,  4, 30); | 
					
						
							|  |  |  |   draw_torus_arc(  0,  0, 51, 49, 60, 0.0f, M_PI); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   glBegin(GL_QUADS); | 
					
						
							|  |  |  |     glVertex2f(-1 , 50); | 
					
						
							|  |  |  |     glVertex2f(-1 , 76); | 
					
						
							|  |  |  |     glVertex2f( 1 , 76); | 
					
						
							|  |  |  |     glVertex2f( 1 , 50); | 
					
						
							|  |  |  |     glVertex2f(-14, 76); | 
					
						
							|  |  |  |     glVertex2f(-14, 78); | 
					
						
							|  |  |  |     glVertex2f( 14, 78); | 
					
						
							|  |  |  |     glVertex2f( 14, 76); | 
					
						
							|  |  |  |     glVertex2f(-21, 83); | 
					
						
							|  |  |  |     glVertex2f(-21, 85); | 
					
						
							|  |  |  |     glVertex2f( 21, 85); | 
					
						
							|  |  |  |     glVertex2f( 21, 83); | 
					
						
							|  |  |  |   glEnd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   draw_torus_arc(-14, 83, 5, 7, 10, M_PI       , M_PI / 2.0f); | 
					
						
							|  |  |  |   draw_torus_arc( 14, 83, 5, 7, 10, M_PI * 1.5f, M_PI / 2.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 23:48:35 +10:00
										 |  |  |   //FIXME: draw the diagnoal marks on the circle
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 23:33:51 +10:00
										 |  |  |   glPopMatrix(); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |   glDisable(GL_BLEND); | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | const LG_Renderer LGR_OpenGL = | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-12 19:43:29 +11:00
										 |  |  |   .get_name        = opengl_get_name, | 
					
						
							|  |  |  |   .setup           = opengl_setup, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   .create          = opengl_create, | 
					
						
							|  |  |  |   .initialize      = opengl_initialize, | 
					
						
							|  |  |  |   .deinitialize    = opengl_deinitialize, | 
					
						
							|  |  |  |   .on_restart      = opengl_on_restart, | 
					
						
							|  |  |  |   .on_resize       = opengl_on_resize, | 
					
						
							|  |  |  |   .on_mouse_shape  = opengl_on_mouse_shape, | 
					
						
							|  |  |  |   .on_mouse_event  = opengl_on_mouse_event, | 
					
						
							|  |  |  |   .on_frame_format = opengl_on_frame_format, | 
					
						
							|  |  |  |   .on_frame        = opengl_on_frame, | 
					
						
							|  |  |  |   .on_alert        = opengl_on_alert, | 
					
						
							|  |  |  |   .render_startup  = opengl_render_startup, | 
					
						
							|  |  |  |   .render          = opengl_render, | 
					
						
							|  |  |  |   .update_fps      = opengl_update_fps | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool _check_gl_error(unsigned int line, const char * name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GLenum error = glGetError(); | 
					
						
							|  |  |  |   if (error == GL_NO_ERROR) | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 21:40:05 -05:00
										 |  |  |   const char * errStr; | 
					
						
							|  |  |  |   switch (error) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     case GL_INVALID_ENUM: | 
					
						
							|  |  |  |       errStr = "GL_INVALID_ENUM"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_INVALID_VALUE: | 
					
						
							|  |  |  |       errStr = "GL_INVALID_VALUE"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_INVALID_OPERATION: | 
					
						
							|  |  |  |       errStr = "GL_INVALID_OPERATION"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_STACK_OVERFLOW: | 
					
						
							|  |  |  |       errStr = "GL_STACK_OVERFLOW"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_STACK_UNDERFLOW: | 
					
						
							|  |  |  |       errStr = "GL_STACK_UNDERFLOW"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_OUT_OF_MEMORY: | 
					
						
							|  |  |  |       errStr = "GL_OUT_OF_MEMORY"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case GL_TABLE_TOO_LARGE: | 
					
						
							|  |  |  |       errStr = "GL_TABLE_TOO_LARGE"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       errStr = "unknown error"; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   DEBUG_ERROR("%d: %s = %d (%s)", line, name, error, errStr); | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 21:46:30 +11:00
										 |  |  | static enum ConfigStatus configure(struct Inst * this) | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   LG_LOCK(this->formatLock); | 
					
						
							|  |  |  |   if (!this->reconfigure) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |     return CONFIG_STATUS_NOOP; | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (this->configured) | 
					
						
							|  |  |  |     deconfigure(this); | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 08:41:15 +10:00
										 |  |  |   switch(this->format.type) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-12-04 21:23:28 +11:00
										 |  |  |     case FRAME_TYPE_BGRA: | 
					
						
							| 
									
										
										
										
											2018-12-12 10:55:18 +11:00
										 |  |  |       this->intFormat  = GL_RGBA8; | 
					
						
							|  |  |  |       this->vboFormat  = GL_BGRA; | 
					
						
							|  |  |  |       this->dataFormat = GL_UNSIGNED_BYTE; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     case FRAME_TYPE_RGBA: | 
					
						
							| 
									
										
										
										
											2018-12-12 10:55:18 +11:00
										 |  |  |       this->intFormat  = GL_RGBA8; | 
					
						
							|  |  |  |       this->vboFormat  = GL_RGBA; | 
					
						
							|  |  |  |       this->dataFormat = GL_UNSIGNED_BYTE; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     case FRAME_TYPE_RGBA10: | 
					
						
							| 
									
										
										
										
											2018-12-12 10:55:18 +11:00
										 |  |  |       this->intFormat  = GL_RGB10_A2; | 
					
						
							|  |  |  |       this->vboFormat  = GL_RGBA; | 
					
						
							|  |  |  |       this->dataFormat = GL_UNSIGNED_INT_2_10_10_10_REV; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 20:44:22 +11:00
										 |  |  |     case FRAME_TYPE_RGBA16F: | 
					
						
							|  |  |  |       this->intFormat  = GL_RGB16F; | 
					
						
							|  |  |  |       this->vboFormat  = GL_RGBA; | 
					
						
							|  |  |  |       this->dataFormat = GL_HALF_FLOAT; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       DEBUG_ERROR("Unknown/unsupported compression type"); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |       return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // calculate the texture size in bytes
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   this->texSize = this->format.height * this->format.pitch; | 
					
						
							|  |  |  |   this->texPos  = 0; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   glGenBuffers(BUFFER_COUNT, this->vboID); | 
					
						
							|  |  |  |   if (check_gl_error("glGenBuffers")) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     LG_UNLOCK(this->formatLock); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   this->hasBuffers = true; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   if (this->amdPinnedMemSupport) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int pagesize = getpagesize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(int i = 0; i < BUFFER_COUNT; ++i) | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |       this->texPixels[i] = aligned_alloc(pagesize, this->texSize); | 
					
						
							|  |  |  |       if (!this->texPixels[i]) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         DEBUG_ERROR("Failed to allocate memory for texture"); | 
					
						
							|  |  |  |         return CONFIG_STATUS_ERROR; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       memset(this->texPixels[i], 0, this->texSize); | 
					
						
							| 
									
										
										
										
											2018-05-15 19:23:57 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |       glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, this->vboID[i]); | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       if (check_gl_error("glBindBuffer")) | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |         LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |         return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       glBufferData( | 
					
						
							|  |  |  |         GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, | 
					
						
							|  |  |  |         this->texSize, | 
					
						
							|  |  |  |         this->texPixels[i], | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |         GL_STREAM_DRAW | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       if (check_gl_error("glBufferData")) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |         return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for(int i = 0; i < BUFFER_COUNT; ++i) | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[i]); | 
					
						
							|  |  |  |       if (check_gl_error("glBindBuffer")) | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |         LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |         return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       glBufferData( | 
					
						
							|  |  |  |         GL_PIXEL_UNPACK_BUFFER, | 
					
						
							|  |  |  |         this->texSize, | 
					
						
							|  |  |  |         NULL, | 
					
						
							|  |  |  |         GL_STREAM_DRAW | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       if (check_gl_error("glBufferData")) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |         return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   // create the frame textures
 | 
					
						
							|  |  |  |   glGenTextures(BUFFER_COUNT, this->frames); | 
					
						
							|  |  |  |   if (check_gl_error("glGenTextures")) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |     LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |     return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   this->hasFrames = true; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   for(int i = 0; i < BUFFER_COUNT; ++i) | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     // bind and create the new texture
 | 
					
						
							|  |  |  |     glBindTexture(GL_TEXTURE_2D, this->frames[i]); | 
					
						
							|  |  |  |     if (check_gl_error("glBindTexture")) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |       return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     glTexImage2D( | 
					
						
							|  |  |  |       GL_TEXTURE_2D, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |       this->intFormat, | 
					
						
							|  |  |  |       this->format.width, | 
					
						
							|  |  |  |       this->format.height, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |       this->vboFormat, | 
					
						
							| 
									
										
										
										
											2018-12-12 10:55:18 +11:00
										 |  |  |       this->dataFormat, | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |       (void*)0 | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     if (check_gl_error("glTexImage2D")) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |       return CONFIG_STATUS_ERROR; | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     // configure the texture
 | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S    , GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T    , GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |     // create the display lists
 | 
					
						
							|  |  |  |     glNewList(this->texList + i, GL_COMPILE); | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |       glBindTexture(GL_TEXTURE_2D, this->frames[i]); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |       glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 
					
						
							|  |  |  |       glBegin(GL_TRIANGLE_STRIP); | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |         glTexCoord2f(0.0f, 0.0f); glVertex2i(0                 , 0                  ); | 
					
						
							|  |  |  |         glTexCoord2f(1.0f, 0.0f); glVertex2i(this->format.width, 0                  ); | 
					
						
							|  |  |  |         glTexCoord2f(0.0f, 1.0f); glVertex2i(0                 , this->format.height); | 
					
						
							|  |  |  |         glTexCoord2f(1.0f, 1.0f); glVertex2i(this->format.width, this->format.height); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |      glEnd(); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |      glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |     glEndList(); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  |   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 14:49:37 +10:00
										 |  |  |   this->drawStart   = nanotime(); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   this->configured  = true; | 
					
						
							|  |  |  |   this->reconfigure = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  |   return CONFIG_STATUS_OK; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void deconfigure(struct Inst * this) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   if (!this->configured) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (this->hasTextures) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  |     glDeleteTextures(TEXTURE_COUNT, this->textures); | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |     this->hasTextures = false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   if (this->hasFrames) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     glDeleteTextures(BUFFER_COUNT, this->frames); | 
					
						
							|  |  |  |     this->hasFrames = false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   if (this->hasBuffers) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     glDeleteBuffers(BUFFER_COUNT, this->vboID); | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |     this->hasBuffers = false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |   if (this->amdPinnedMemSupport) | 
					
						
							| 
									
										
										
										
											2018-05-15 19:25:22 +10:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     for(int i = 0; i < BUFFER_COUNT; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (this->fences[i]) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         glDeleteSync(this->fences[i]); | 
					
						
							|  |  |  |         this->fences[i] = NULL; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-12-12 23:32:31 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (this->texPixels[i]) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         free(this->texPixels[i]); | 
					
						
							|  |  |  |         this->texPixels[i] = NULL; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-15 19:25:22 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   this->configured = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void update_mouse_shape(struct Inst * this, bool * newShape) | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_LOCK(this->mouseLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   *newShape = this->newShape; | 
					
						
							|  |  |  |   if (!this->newShape) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |     LG_UNLOCK(this->mouseLock); | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-11 01:31:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   const LG_RendererCursor cursor = this->mouseCursor; | 
					
						
							|  |  |  |   const int               width  = this->mouseWidth; | 
					
						
							|  |  |  |   const int               height = this->mouseHeight; | 
					
						
							|  |  |  |   const int               pitch  = this->mousePitch; | 
					
						
							|  |  |  |   const uint8_t *         data   = this->mouseData; | 
					
						
							| 
									
										
										
										
											2017-12-13 03:08:13 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:39:19 +10:00
										 |  |  |   // tmp buffer for masked colour
 | 
					
						
							|  |  |  |   uint32_t tmp[width * height]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |   this->mouseType = cursor; | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |   switch(cursor) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-28 11:39:19 +10:00
										 |  |  |     case LG_CURSOR_MASKED_COLOR: | 
					
						
							|  |  |  |       for(int i = 0; i < width * height; ++i) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         const uint32_t c = ((uint32_t *)data)[i]; | 
					
						
							|  |  |  |         tmp[i] = (c & ~0xFF000000) | (c & 0xFF000000 ? 0x0 : 0xFF000000); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       data = (uint8_t *)tmp; | 
					
						
							|  |  |  |       // fall through to LG_CURSOR_COLOR
 | 
					
						
							|  |  |  |       //
 | 
					
						
							|  |  |  |       // technically we should also create an XOR texture from the data but this
 | 
					
						
							|  |  |  |       // usage seems very rare in modern software.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |     case LG_CURSOR_COLOR: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       glBindTexture(GL_TEXTURE_2D, this->textures[MOUSE_TEXTURE]); | 
					
						
							|  |  |  |       glPixelStorei(GL_UNPACK_ALIGNMENT , 4    ); | 
					
						
							|  |  |  |       glPixelStorei(GL_UNPACK_ROW_LENGTH, width); | 
					
						
							|  |  |  |       glTexImage2D | 
					
						
							|  |  |  |       ( | 
					
						
							|  |  |  |         GL_TEXTURE_2D, | 
					
						
							|  |  |  |         0      , | 
					
						
							|  |  |  |         GL_RGBA, | 
					
						
							|  |  |  |         width  , | 
					
						
							|  |  |  |         height , | 
					
						
							|  |  |  |         0      , | 
					
						
							| 
									
										
										
										
											2017-12-15 10:20:20 +11:00
										 |  |  |         GL_BGRA, // windows cursors are in BGRA format
 | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |         GL_UNSIGNED_BYTE, | 
					
						
							|  |  |  |         data | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |       glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this->mousePos.w = width; | 
					
						
							|  |  |  |       this->mousePos.h = height; | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |       glNewList(this->mouseList, GL_COMPILE); | 
					
						
							|  |  |  |         glEnable(GL_BLEND); | 
					
						
							|  |  |  |         glBindTexture(GL_TEXTURE_2D, this->textures[MOUSE_TEXTURE]); | 
					
						
							|  |  |  |         glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 
					
						
							|  |  |  |         glBegin(GL_TRIANGLE_STRIP); | 
					
						
							|  |  |  |           glTexCoord2f(0.0f, 0.0f); glVertex2i(0    , 0     ); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 0.0f); glVertex2i(width, 0     ); | 
					
						
							|  |  |  |           glTexCoord2f(0.0f, 1.0f); glVertex2i(0    , height); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 1.0f); glVertex2i(width, height); | 
					
						
							|  |  |  |         glEnd(); | 
					
						
							|  |  |  |         glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							|  |  |  |         glDisable(GL_BLEND); | 
					
						
							|  |  |  |       glEndList(); | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case LG_CURSOR_MONOCHROME: | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |       const int hheight = height / 2; | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |       uint32_t d[width * height]; | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |       for(int y = 0; y < hheight; ++y) | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |         for(int x = 0; x < width; ++x) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const uint8_t  * srcAnd  = data + (pitch * y) + (x / 8); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |           const uint8_t  * srcXor  = srcAnd + pitch * hheight; | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |           const uint8_t    mask    = 0x80 >> (x % 8); | 
					
						
							|  |  |  |           const uint32_t   andMask = (*srcAnd & mask) ? 0xFFFFFFFF : 0xFF000000; | 
					
						
							|  |  |  |           const uint32_t   xorMask = (*srcXor & mask) ? 0x00FFFFFF : 0x00000000; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |           d[y * width + x                  ] = andMask; | 
					
						
							|  |  |  |           d[y * width + x + width * hheight] = xorMask; | 
					
						
							| 
									
										
										
										
											2017-12-13 04:49:43 +11:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       glBindTexture(GL_TEXTURE_2D, this->textures[MOUSE_TEXTURE]); | 
					
						
							|  |  |  |       glPixelStorei(GL_UNPACK_ALIGNMENT , 4    ); | 
					
						
							|  |  |  |       glPixelStorei(GL_UNPACK_ROW_LENGTH, width); | 
					
						
							|  |  |  |       glTexImage2D | 
					
						
							|  |  |  |       ( | 
					
						
							|  |  |  |         GL_TEXTURE_2D, | 
					
						
							|  |  |  |         0      , | 
					
						
							|  |  |  |         GL_RGBA, | 
					
						
							|  |  |  |         width  , | 
					
						
							|  |  |  |         height , | 
					
						
							|  |  |  |         0      , | 
					
						
							|  |  |  |         GL_RGBA, | 
					
						
							|  |  |  |         GL_UNSIGNED_BYTE, | 
					
						
							|  |  |  |         d | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |       glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this->mousePos.w = width; | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |       this->mousePos.h = hheight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       glNewList(this->mouseList, GL_COMPILE); | 
					
						
							|  |  |  |         glEnable(GL_COLOR_LOGIC_OP); | 
					
						
							|  |  |  |         glBindTexture(GL_TEXTURE_2D, this->textures[MOUSE_TEXTURE]); | 
					
						
							|  |  |  |         glLogicOp(GL_AND); | 
					
						
							|  |  |  |         glBegin(GL_TRIANGLE_STRIP); | 
					
						
							| 
									
										
										
										
											2017-12-13 20:44:58 +11:00
										 |  |  |           glTexCoord2f(0.0f, 0.0f); glVertex2i(0    , 0      ); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 0.0f); glVertex2i(width, 0      ); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |           glTexCoord2f(0.0f, 0.5f); glVertex2i(0    , hheight); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 0.5f); glVertex2i(width, hheight); | 
					
						
							|  |  |  |         glEnd(); | 
					
						
							|  |  |  |         glLogicOp(GL_XOR); | 
					
						
							|  |  |  |         glBegin(GL_TRIANGLE_STRIP); | 
					
						
							| 
									
										
										
										
											2017-12-13 20:44:58 +11:00
										 |  |  |           glTexCoord2f(0.0f, 0.5f); glVertex2i(0    , 0      ); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 0.5f); glVertex2i(width, 0      ); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |           glTexCoord2f(0.0f, 1.0f); glVertex2i(0    , hheight); | 
					
						
							|  |  |  |           glTexCoord2f(1.0f, 1.0f); glVertex2i(width, hheight); | 
					
						
							|  |  |  |         glEnd(); | 
					
						
							| 
									
										
										
										
											2018-07-20 01:01:16 +10:00
										 |  |  |         glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |         glDisable(GL_COLOR_LOGIC_OP); | 
					
						
							|  |  |  |       glEndList(); | 
					
						
							| 
									
										
										
										
											2017-12-13 03:51:25 +11:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 04:18:30 +11:00
										 |  |  |   this->mouseUpdate = true; | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_UNLOCK(this->mouseLock); | 
					
						
							| 
									
										
										
										
											2017-12-13 03:08:13 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  | static bool opengl_buffer_fn(void * opaque, const void * data, size_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct Inst * this = (struct Inst *)opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // update the buffer, this performs a DMA transfer if possible
 | 
					
						
							|  |  |  |   glBufferSubData( | 
					
						
							|  |  |  |     GL_PIXEL_UNPACK_BUFFER, | 
					
						
							|  |  |  |     this->texPos, | 
					
						
							|  |  |  |     size, | 
					
						
							|  |  |  |     data | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   check_gl_error("glBufferSubData"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this->texPos += size; | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 17:37:56 +11:00
										 |  |  | static bool draw_frame(struct Inst * this) | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_LOCK(this->syncLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   if (!this->frameUpdate) | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |     LG_UNLOCK(this->syncLock); | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2017-12-14 17:42:16 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   if (++this->texIndex == BUFFER_COUNT) | 
					
						
							|  |  |  |     this->texIndex = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  |   this->frameUpdate = false; | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_UNLOCK(this->syncLock); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 00:57:27 +11:00
										 |  |  |   LG_LOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   if (glIsSync(this->fences[this->texIndex])) | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     switch(glClientWaitSync(this->fences[this->texIndex], 0, GL_TIMEOUT_IGNORED)) | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       case GL_ALREADY_SIGNALED: | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2017-12-11 03:02:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       case GL_CONDITION_SATISFIED: | 
					
						
							|  |  |  |         DEBUG_WARN("Had to wait for the sync"); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       case GL_TIMEOUT_EXPIRED: | 
					
						
							|  |  |  |         DEBUG_WARN("Timeout expired, DMA transfers are too slow!"); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |       case GL_WAIT_FAILED: | 
					
						
							| 
									
										
										
										
											2021-02-18 21:40:05 -05:00
										 |  |  |         DEBUG_ERROR("Wait failed %d", glGetError()); | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     glDeleteSync(this->fences[this->texIndex]); | 
					
						
							|  |  |  |     this->fences[this->texIndex] = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   glBindTexture(GL_TEXTURE_2D, this->frames[this->texIndex]); | 
					
						
							|  |  |  |   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[this->texIndex]); | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 13:27:07 +10:00
										 |  |  |   const int bpp = this->format.bpp / 8; | 
					
						
							|  |  |  |   glPixelStorei(GL_UNPACK_ALIGNMENT , bpp); | 
					
						
							|  |  |  |   glPixelStorei(GL_UNPACK_ROW_LENGTH, this->format.width); | 
					
						
							| 
									
										
										
										
											2018-05-15 13:23:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   this->texPos = 0; | 
					
						
							| 
									
										
										
										
											2020-04-14 13:27:07 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   framebuffer_read_fn( | 
					
						
							|  |  |  |     this->frame, | 
					
						
							| 
									
										
										
										
											2020-04-14 13:27:07 +10:00
										 |  |  |     this->format.height, | 
					
						
							|  |  |  |     this->format.width, | 
					
						
							|  |  |  |     bpp, | 
					
						
							|  |  |  |     this->format.pitch, | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |     opengl_buffer_fn, | 
					
						
							|  |  |  |     this | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   // update the texture
 | 
					
						
							|  |  |  |   glTexSubImage2D( | 
					
						
							|  |  |  |     GL_TEXTURE_2D, | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     this->format.width , | 
					
						
							|  |  |  |     this->format.height, | 
					
						
							|  |  |  |     this->vboFormat, | 
					
						
							|  |  |  |     this->dataFormat, | 
					
						
							|  |  |  |     (void*)0 | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   if (check_gl_error("glTexSubImage2D")) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("texIndex: %u, width: %u, height: %u, vboFormat: %x, texSize: %lu", | 
					
						
							|  |  |  |       this->texIndex, this->format.width, this->format.height, this->vboFormat, this->texSize | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   // set a fence so we don't overwrite a buffer in use
 | 
					
						
							|  |  |  |   this->fences[this->texIndex] = | 
					
						
							|  |  |  |     glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | 
					
						
							| 
									
										
										
										
											2018-05-16 17:58:36 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 23:17:20 +10:00
										 |  |  |   // unbind the buffer
 | 
					
						
							|  |  |  |   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 22:21:59 +11:00
										 |  |  |   const bool mipmap = this->opt.mipmap && ( | 
					
						
							| 
									
										
										
										
											2017-12-11 03:47:07 +11:00
										 |  |  |     (this->format.width  > this->destRect.w) || | 
					
						
							|  |  |  |     (this->format.height > this->destRect.h)); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  |   glBindTexture(GL_TEXTURE_2D, this->frames[this->texIndex]); | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |   if (mipmap) | 
					
						
							| 
									
										
										
										
											2017-12-16 11:25:01 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  |     glGenerateMipmap(GL_TEXTURE_2D); | 
					
						
							| 
									
										
										
										
											2017-12-16 11:25:01 +11:00
										 |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  |   glBindTexture(GL_TEXTURE_2D, 0); | 
					
						
							| 
									
										
										
										
											2017-12-31 00:27:26 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 01:03:21 +11:00
										 |  |  |   LG_UNLOCK(this->formatLock); | 
					
						
							| 
									
										
										
										
											2018-05-28 15:30:04 +10:00
										 |  |  |   this->texReady = true; | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 00:53:45 +11:00
										 |  |  | static void draw_mouse(struct Inst * this) | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   if (!this->mouseVisible) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-12-05 20:33:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   glPushMatrix(); | 
					
						
							| 
									
										
										
										
											2017-12-14 06:54:53 +11:00
										 |  |  |   glTranslatef(this->mousePos.x, this->mousePos.y, 0.0f); | 
					
						
							| 
									
										
										
										
											2017-12-13 13:10:32 +11:00
										 |  |  |   glCallList(this->mouseList); | 
					
						
							| 
									
										
										
										
											2017-12-13 02:22:47 +11:00
										 |  |  |   glPopMatrix(); | 
					
						
							| 
									
										
										
										
											2020-01-17 14:35:08 +11:00
										 |  |  | } |