summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/drawogl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/render/drawogl.cpp')
-rw-r--r--src/osd/modules/render/drawogl.cpp1200
1 files changed, 743 insertions, 457 deletions
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 6837e63bbe3..f9f76946bf4 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -12,35 +12,63 @@
//
//============================================================
-// standard C headers
-#include <math.h>
-#include <stdio.h>
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if USE_OPENGL
-// MAME headers
+// will be picked up from specific OSD implementation
+#include "window.h"
+
+// OSD common headers
+#include "modules/lib/osdlib.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/opengl/gl_shader_mgr.h"
#include "osdcomm.h"
-#include "emu.h"
-#include "emuopts.h"
-#ifdef OSD_MAC
+// OSD headers
+#if defined(OSD_WINDOWS)
+typedef uint64_t HashT;
+#include "winglcontext.h"
+#elif defined(OSD_MAC)
#define GL_SILENCE_DEPRECATION (1)
+#include "osdmac.h"
+#else
+#include "osdsdl.h"
+#include "sdlglcontext.h"
#endif
+// emu
+#include "emucore.h"
+#include "emuopts.h"
+#include "render.h"
+
+
#if !defined(OSD_WINDOWS) && !defined(OSD_MAC)
+
// standard SDL headers
#define TOBEMIGRATED 1
#include <SDL2/SDL.h>
-#endif
-#include "modules/lib/osdlib.h"
-#include "modules/lib/osdobj_common.h"
+#endif // !defined(OSD_WINDOWS && !defined(OSD_MAC)
-// OpenGL headers
-#include "modules/opengl/osd_opengl.h"
-#include "modules/opengl/gl_shader_tool.h"
-#include "modules/opengl/gl_shader_mgr.h"
+// standard C headers
+#include <cmath>
+#include <cstdio>
+#include <memory>
+#include <utility>
+
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
+#include <cstring>
+#include <cstdio>
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
#ifndef APIENTRY
#define APIENTRY
#endif
@@ -67,7 +95,13 @@ typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum m_target, GLuint r
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum m_target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum m_target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
-#endif
+
+#endif // defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
+
+namespace osd {
+
+namespace {
// make sure the extensions compile OK everywhere
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
@@ -123,7 +157,283 @@ typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuin
#define GL_DEPTH_COMPONENT32 0x81A7
#endif
-#include "drawogl.h"
+
+//============================================================
+// Configuration
+//============================================================
+
+#define GLSL_SHADER_MAX 10
+
+struct ogl_video_config
+{
+ ogl_video_config() = default;
+
+ bool vbo = false;
+ bool pbo = false;
+ bool allowtexturerect = false; // allow GL_ARB_texture_rectangle, default: no
+ bool forcepow2texture = false; // force power of two textures, default: no
+ bool glsl = false;
+ int glsl_filter = 0; // glsl filtering, >0 disables filter
+ std::string glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
+ int glsl_shader_mamebm_num = 0; // custom glsl shader set number, mame bitmap
+ std::string glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
+ int glsl_shader_scrn_num = 0; // custom glsl shader number, screen bitmap
+};
+
+
+//============================================================
+// Textures
+//============================================================
+
+/* ogl_texture_info holds information about a texture */
+class ogl_texture_info
+{
+public:
+ ogl_texture_info(
+#if defined(USE_DISPATCH_GL)
+ osd_gl_dispatch *gld
+#endif
+ )
+#if defined(USE_DISPATCH_GL)
+ : gl_dispatch(gld)
+#endif
+ {
+ for (int i=0; i<2; i++)
+ {
+ mpass_textureunit[i] = 0;
+ mpass_texture_mamebm[i] = 0;
+ mpass_fbo_mamebm[i] = 0;
+ mpass_texture_scrn[i] = 0;
+ mpass_fbo_scrn[i] = 0;
+ }
+ for (int i=0; i<8; i++)
+ texCoord[i] = 0.0f;
+ }
+
+#if defined(USE_DISPATCH_GL)
+ osd_gl_dispatch *const gl_dispatch; // name is magic, can't be changed
+#endif
+ HashT hash = 0; // hash value for the texture (must be >= pointer size)
+ uint32_t flags = 0; // rendering flags
+ render_texinfo texinfo; // copy of the texture info
+ int rawwidth = 0, rawheight = 0; // raw width/height of the texture
+ int rawwidth_create = 0; // raw width/height, pow2 compatible, if needed
+ int rawheight_create = 0; // (create and initial set the texture, not for copy!)
+ int type = 0; // what type of texture are we?
+ int format = 0; // texture format
+ int borderpix = 0; // do we have a 1 pixel border?
+ int xprescale = 0; // what is our X prescale factor?
+ int yprescale = 0; // what is our Y prescale factor?
+ int nocopy = 0; // must the texture date be copied?
+
+ uint32_t texture = 0; // OpenGL texture "name"/ID
+
+ GLenum texTarget = 0; // OpenGL texture target
+ int texpow2 = 0; // Is this texture pow2
+
+ uint32_t mpass_dest_idx = 0; // Multipass dest idx [0..1]
+ uint32_t mpass_textureunit[2]; // texture unit names for GLSL
+
+ uint32_t mpass_texture_mamebm[2]; // Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
+ uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
+
+ uint32_t pbo = 0; // pixel buffer object for this texture (DYNAMIC only!)
+ uint32_t *data = nullptr; // pixels for the texture
+ bool data_own = false; // do we own / allocated it ?
+ GLfloat texCoord[8];
+ GLuint texCoordBufferName;
+
+};
+
+// renderer_ogl is the information about OpenGL for the current screen
+class renderer_ogl : public osd_renderer
+{
+public:
+ renderer_ogl(osd_window &window, ogl_video_config const &ogl_config)
+ : osd_renderer(window)
+ , m_ogl_config(ogl_config)
+ , m_blittimer(0)
+ , m_width(0)
+ , m_height(0)
+ , m_blit_dim(0, 0)
+ , m_initialized(0)
+ , m_last_blendmode(0)
+ , m_texture_max_width(0)
+ , m_texture_max_height(0)
+ , m_texpoweroftwo(0)
+ , m_usevbo(0)
+ , m_usepbo(0)
+ , m_usefbo(0)
+ , m_useglsl(0)
+ , m_glsl_program_num(0)
+ , m_glsl_program_mb2sc(0)
+ , m_usetexturerect(0)
+ , m_init_context(0)
+ , m_last_hofs(0.0f)
+ , m_last_vofs(0.0f)
+ , m_surf_w(0)
+ , m_surf_h(0)
+ {
+ for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
+ m_texhash[i] = nullptr;
+ for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
+ m_glsl_program[i] = 0;
+ for (int i=0; i < 8; i++)
+ m_texVerticex[i] = 0.0f;
+ }
+ virtual ~renderer_ogl()
+ {
+ // free the memory in the window
+ destroy_all_textures();
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+
+#ifndef OSD_WINDOWS
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+#endif
+ virtual render_primitive_list *get_primitives() override
+ {
+ osd_dim nd = window().get_size();
+ if (nd != m_blit_dim)
+ {
+ m_blit_dim = nd;
+ notify_changed();
+ }
+ if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
+ return nullptr;
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+ }
+
+#ifdef OSD_WINDOWS
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+#endif
+
+private:
+ static const uint32_t HASH_SIZE = ((1 << 18) + 1);
+ static const uint32_t OVERFLOW_SIZE = (1 << 12);
+
+ void destroy_all_textures();
+
+ void loadGLExtensions();
+ void loadgl_functions();
+ void initialize_gl();
+ void set_blendmode(int blendmode);
+ HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
+ void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
+ uint32_t width, uint32_t height,
+ int* p_width, int* p_height, int* p_width_create, int* p_height_create);
+ void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
+ int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_find(const render_primitive *prim);
+ void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
+ void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
+ void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
+ ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
+ void texture_disable(ogl_texture_info * texture);
+ void texture_all_disable();
+
+ int gl_checkFramebufferStatus() const;
+ int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const;
+ void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const;
+
+ int gl_check_error(bool log, const char *file, int line) const
+ {
+ GLenum const glerr = glGetError();
+ if (GL_NO_ERROR != glerr)
+ {
+ if (log)
+ osd_printf_warning("%s:%d: GL Error: %d 0x%X\n", file, line, int(glerr), unsigned(glerr));
+ }
+ return (GL_NO_ERROR != glerr) ? glerr : 0;
+ }
+
+#define GL_CHECK_ERROR_QUIET() gl_check_error(false, __FILE__, __LINE__)
+#define GL_CHECK_ERROR_NORMAL() gl_check_error(true, __FILE__, __LINE__)
+
+ ogl_video_config const &m_ogl_config;
+
+ int32_t m_blittimer;
+ int m_width;
+ int m_height;
+ osd_dim m_blit_dim;
+
+ std::unique_ptr<osd_gl_context> m_gl_context;
+ std::unique_ptr<glsl_shader_info> m_shader_tool;
+
+ int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
+ // 3D info (GL mode only)
+ ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
+ int m_last_blendmode; // previous blendmode
+ int32_t m_texture_max_width; // texture maximum width
+ int32_t m_texture_max_height; // texture maximum height
+ int m_texpoweroftwo; // must textures be power-of-2 sized?
+ int m_usevbo; // runtime check if VBO is available
+ int m_usepbo; // runtime check if PBO is available
+ int m_usefbo; // runtime check if FBO is available
+ int m_useglsl; // runtime check if GLSL is available
+
+ GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
+ int m_glsl_program_num; // number of GLSL programs
+ int m_glsl_program_mb2sc; // GLSL program idx, which transforms
+ // the mame-bitmap. screen-bitmap (size/rotation/..)
+ // All progs <= glsl_program_mb2sc using the mame bitmap
+ // as input, otherwise the screen bitmap.
+ // All progs >= glsl_program_mb2sc using the screen bitmap
+ // as output, otherwise the mame bitmap.
+ int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
+
+ int m_init_context; // initialize context before next draw
+
+ float m_last_hofs;
+ float m_last_vofs;
+
+ // Static vars from draogl_window_dra
+ int32_t m_surf_w;
+ int32_t m_surf_h;
+ GLfloat m_texVerticex[8];
+
+#if defined(USE_DISPATCH_GL)
+ std::unique_ptr<osd_gl_dispatch> gl_dispatch; // name is magic, can't be changed
+#endif
+
+ // OGL 1.3
+#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
+ PFNGLACTIVETEXTUREARBPROC m_glActiveTexture = nullptr;
+#else
+ PFNGLACTIVETEXTUREPROC m_glActiveTexture = nullptr;
+#endif
+
+ // VBO
+ PFNGLGENBUFFERSPROC m_glGenBuffers = nullptr;
+ PFNGLDELETEBUFFERSPROC m_glDeleteBuffers = nullptr;
+ PFNGLBINDBUFFERPROC m_glBindBuffer = nullptr;
+ PFNGLBUFFERDATAPROC m_glBufferData = nullptr;
+ PFNGLBUFFERSUBDATAPROC m_glBufferSubData = nullptr;
+
+ // PBO
+ PFNGLMAPBUFFERPROC m_glMapBuffer = nullptr;
+ PFNGLUNMAPBUFFERPROC m_glUnmapBuffer = nullptr;
+
+ // FBO
+ PFNGLISFRAMEBUFFEREXTPROC m_glIsFramebuffer = nullptr;
+ PFNGLBINDFRAMEBUFFEREXTPROC m_glBindFramebuffer = nullptr;
+ PFNGLDELETEFRAMEBUFFERSEXTPROC m_glDeleteFramebuffers = nullptr;
+ PFNGLGENFRAMEBUFFERSEXTPROC m_glGenFramebuffers = nullptr;
+ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC m_glCheckFramebufferStatus = nullptr;
+ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC m_glFramebufferTexture2D = nullptr;
+
+ static bool s_shown_video_info;
+};
+
//============================================================
// DEBUGGING
@@ -236,103 +546,22 @@ void renderer_ogl::set_blendmode(int blendmode)
}
}
-//============================================================
-// STATIC VARIABLES
-//============================================================
-
-// OGL 1.3
-#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
-static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = nullptr;
-#else
-static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = nullptr;
-#endif
-
-// VBO
-static PFNGLGENBUFFERSPROC pfn_glGenBuffers = nullptr;
-static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers = nullptr;
-static PFNGLBINDBUFFERPROC pfn_glBindBuffer = nullptr;
-static PFNGLBUFFERDATAPROC pfn_glBufferData = nullptr;
-static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData = nullptr;
-
-// PBO
-static PFNGLMAPBUFFERPROC pfn_glMapBuffer = nullptr;
-static PFNGLUNMAPBUFFERPROC pfn_glUnmapBuffer = nullptr;
-
-// FBO
-static PFNGLISFRAMEBUFFEREXTPROC pfn_glIsFramebuffer = nullptr;
-static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer = nullptr;
-static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers = nullptr;
-static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers = nullptr;
-static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus = nullptr;
-static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D = nullptr;
-
-static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
-
-//============================================================
-// Textures
-//============================================================
-
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags);
+static int glsl_shader_feature = glsl_shader_info::FEAT_PLAIN; // FIXME: why is this static?
//============================================================
// Static Variables
//============================================================
bool renderer_ogl::s_shown_video_info = false;
-bool renderer_ogl::s_dll_loaded = false;
-
-void renderer_ogl::init(running_machine &machine)
-{
- s_dll_loaded = false;
-
- load_gl_lib(machine);
-#if defined(OSD_WINDOWS)
- osd_printf_verbose("Using Windows OpenGL driver\n");
-#else
- osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
-#endif
-}
-
-//============================================================
-// CONSTRUCTOR & DESTRUCTOR
-//============================================================
-
-renderer_ogl::~renderer_ogl()
-{
- // free the memory in the window
- destroy_all_textures();
-
- global_free(m_gl_context);
- m_gl_context = nullptr;
-}
-
-void renderer_ogl::exit()
-{
- for (int i = 0; i < video_config.glsl_shader_mamebm_num; i++)
- {
- if (nullptr != video_config.glsl_shader_mamebm[i])
- {
- free(video_config.glsl_shader_mamebm[i]);
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
- for (int i =0; i < video_config.glsl_shader_scrn_num; i++)
- {
- if (nullptr != video_config.glsl_shader_scrn[i])
- {
- free(video_config.glsl_shader_scrn[i]);
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-}
//============================================================
// Load the OGL function addresses
//============================================================
-static void loadgl_functions(osd_gl_context *context)
+void renderer_ogl::loadgl_functions()
{
-#ifdef USE_DISPATCH_GL
+#if defined(USE_DISPATCH_GL)
+ gl_dispatch = std::make_unique<osd_gl_dispatch>();
int err_count = 0;
@@ -340,11 +569,11 @@ static void loadgl_functions(osd_gl_context *context)
* while func will be expanded to disp_p->glBegin
*/
- #define OSD_GL(ret,func,params) \
- if (!( func = (ret (APIENTRY *)params) context->getProcAddress( #func ) )) \
- { err_count++; osd_printf_error("GL function %s not found!\n", #func ); }
+ #define OSD_GL(ret, func, params) \
+ if (!m_gl_context->get_proc_address(func, #func)) \
+ { err_count++; osd_printf_error("GL function %s not found!\n", #func); }
- #define OSD_GL_UNUSED(ret,func,params)
+ #define OSD_GL_UNUSED(ret, func, params)
#define GET_GLFUNC 1
#include "modules/opengl/osd_opengl.h"
@@ -356,45 +585,6 @@ static void loadgl_functions(osd_gl_context *context)
#endif
}
-//============================================================
-// Load GL library
-//============================================================
-
-#ifdef USE_DISPATCH_GL
-osd_gl_dispatch *gl_dispatch;
-#endif
-
-void renderer_ogl::load_gl_lib(running_machine &machine)
-{
- if (!s_dll_loaded)
- {
-#ifndef OSD_WINDOWS
-#ifdef USE_DISPATCH_GL
- /*
- * directfb and and x11 use this env var
- * SDL_VIDEO_GL_DRIVER
- */
- const char *stemp;
-
- stemp = downcast<sdl_options &>(machine.options()).gl_lib();
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
- stemp = nullptr;
-
- if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
- {
- fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
- }
- osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
- /* FIXME: must be freed as well */
-#endif
-#endif
-#ifdef USE_DISPATCH_GL
- gl_dispatch = global_alloc(osd_gl_dispatch);
-#endif
- s_dll_loaded = true;
- }
-}
-
void renderer_ogl::initialize_gl()
{
int has_and_allow_texturerect = 0;
@@ -420,7 +610,7 @@ void renderer_ogl::initialize_gl()
m_usefbo = 0;
m_useglsl = 0;
- if (video_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
+ if (m_ogl_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
{
has_and_allow_texturerect = 1;
if (!s_shown_video_info)
@@ -430,7 +620,7 @@ void renderer_ogl::initialize_gl()
}
// does this card support non-power-of-two sized textures? (they're faster, so use them if possible)
- if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
+ if ( !m_ogl_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
{
if (!s_shown_video_info)
{
@@ -460,7 +650,7 @@ void renderer_ogl::initialize_gl()
if (strstr(extstr, "GL_ARB_vertex_buffer_object"))
{
- m_usevbo = video_config.vbo;
+ m_usevbo = m_ogl_config.vbo;
if (!s_shown_video_info)
{
if(m_usevbo)
@@ -474,7 +664,7 @@ void renderer_ogl::initialize_gl()
{
if( m_usevbo )
{
- m_usepbo = video_config.pbo;
+ m_usepbo = m_ogl_config.pbo;
if (!s_shown_video_info)
{
if(m_usepbo)
@@ -517,7 +707,7 @@ void renderer_ogl::initialize_gl()
strstr(extstr, "GL_ARB_fragment_shader")
)
{
- m_useglsl = video_config.glsl;
+ m_useglsl = m_ogl_config.glsl;
if (!s_shown_video_info)
{
if(m_useglsl)
@@ -557,24 +747,22 @@ void renderer_ogl::initialize_gl()
int renderer_ogl::create()
{
- auto win = assert_window();
-
// create renderer
#if defined(OSD_WINDOWS)
- m_gl_context = global_alloc(win_gl_context(std::static_pointer_cast<win_window_info>(win)->platform_window()));
+ m_gl_context.reset(new win_gl_context(dynamic_cast<win_window_info &>(window()).platform_window()));
#elif defined(OSD_MAC)
// TODO
-// m_gl_context = global_alloc(mac_gl_context(std::static_pointer_cast<mac_window_info>(win)->platform_window()));
+// m_gl_context.reset(new mac_gl_context(dynamic_cast<mac_window_info &>(window()).platform_window()));
#else
- m_gl_context = global_alloc(sdl_gl_context(std::static_pointer_cast<sdl_window_info>(win)->platform_window()));
+ m_gl_context.reset(new sdl_gl_context(dynamic_cast<sdl_window_info &>(window()).platform_window()));
#endif
- if (m_gl_context->LastErrorMsg() != nullptr)
+ if (!*m_gl_context)
{
- osd_printf_error("%s\n", m_gl_context->LastErrorMsg());
+ char const *const msg = m_gl_context->last_error_message();
+ osd_printf_error("Creating OpenGL context failed: %s\n", msg ? msg : "unknown error");
return 1;
}
- m_gl_context->SetSwapInterval(video_config.waitvsync ? 1 : 0);
-
+ m_gl_context->set_swap_interval(video_config.waitvsync ? 1 : 0);
m_blittimer = 0;
m_surf_w = 0;
@@ -590,10 +778,9 @@ int renderer_ogl::create()
/* load any GL function addresses
* this must be done here because we need a context
*/
- loadgl_functions(m_gl_context);
+ loadgl_functions();
initialize_gl();
-
m_init_context = 0;
osd_printf_verbose("Leave renderer_ogl::create\n");
@@ -623,27 +810,15 @@ int renderer_ogl::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_ogl::destroy_all_textures()
{
- ogl_texture_info *texture = nullptr;
- bool lock=false;
- int i;
-
- if ( !m_initialized )
- return;
-
- auto win = try_getwindow();
- // During destroy this can get called
- // and the window is no longer available
- if (win == nullptr)
+ if (!m_initialized)
return;
- m_gl_context->MakeCurrent();
+ m_gl_context->make_current();
- if(win->m_primlist)
- {
- lock=true;
- win->m_primlist->acquire_lock();
- }
+ bool const lock = bool(window().m_primlist);
+ if (lock)
+ window().m_primlist->acquire_lock();
glFinish();
@@ -651,60 +826,54 @@ void renderer_ogl::destroy_all_textures()
glFinish();
glDisableClientState(GL_VERTEX_ARRAY);
- i=0;
- while (i<HASH_SIZE+OVERFLOW_SIZE)
+ for (int i = 0; i < (HASH_SIZE + OVERFLOW_SIZE); ++i)
{
- texture = m_texhash[i];
- m_texhash[i] = nullptr;
- if (texture != nullptr)
+ ogl_texture_info *const texture = std::exchange(m_texhash[i], nullptr);
+ if (texture)
{
- if(m_usevbo)
+ if (m_usevbo)
{
- pfn_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
+ m_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
texture->texCoordBufferName=0;
}
- if(m_usepbo && texture->pbo)
+ if (m_usepbo && texture->pbo)
{
- pfn_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
+ m_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
texture->pbo=0;
}
- if( m_glsl_program_num > 1 )
+ if (m_glsl_program_num > 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
}
- if ( m_glsl_program_mb2sc < m_glsl_program_num - 1 )
+ if (m_glsl_program_mb2sc < m_glsl_program_num - 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
}
glDeleteTextures(1, (GLuint *)&texture->texture);
- if ( texture->data_own )
+ if (texture->data_own)
{
free(texture->data);
texture->data=nullptr;
texture->data_own=false;
}
- global_free(texture);
+ delete texture;
}
- i++;
- }
- if ( m_useglsl )
- {
- glsl_shader_free(m_glsl);
- m_glsl = nullptr;
}
+ m_shader_tool.reset();
+
m_initialized = 0;
if (lock)
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
}
//============================================================
// loadGLExtensions
@@ -740,178 +909,138 @@ void renderer_ogl::loadGLExtensions()
// Get Pointers To The GL Functions
// VBO:
- if( m_usevbo )
+ if (m_usevbo)
{
- pfn_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
- pfn_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
- pfn_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
- pfn_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
- pfn_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
+ m_gl_context->get_proc_address(m_glGenBuffers, "glGenBuffers");
+ m_gl_context->get_proc_address(m_glDeleteBuffers, "glDeleteBuffers");
+ m_gl_context->get_proc_address(m_glBindBuffer, "glBindBuffer");
+ m_gl_context->get_proc_address(m_glBufferData, "glBufferData");
+ m_gl_context->get_proc_address(m_glBufferSubData, "glBufferSubData");
}
// PBO:
- if ( m_usepbo )
+ if (m_usepbo)
{
- pfn_glMapBuffer = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
- pfn_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
+ m_gl_context->get_proc_address(m_glMapBuffer, "glMapBuffer");
+ m_gl_context->get_proc_address(m_glUnmapBuffer, "glUnmapBuffer");
}
// FBO:
- if ( m_usefbo )
+ if (m_usefbo)
{
- pfn_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
- pfn_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
- pfn_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
- pfn_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
- pfn_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
- pfn_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
+ m_gl_context->get_proc_address(m_glIsFramebuffer, "glIsFramebufferEXT");
+ m_gl_context->get_proc_address(m_glBindFramebuffer, "glBindFramebufferEXT");
+ m_gl_context->get_proc_address(m_glDeleteFramebuffers, "glDeleteFramebuffersEXT");
+ m_gl_context->get_proc_address(m_glGenFramebuffers, "glGenFramebuffersEXT");
+ m_gl_context->get_proc_address(m_glCheckFramebufferStatus, "glCheckFramebufferStatusEXT");
+ m_gl_context->get_proc_address(m_glFramebufferTexture2D, "glFramebufferTexture2DEXT");
}
- if ( m_usevbo &&
- ( !pfn_glGenBuffers || !pfn_glDeleteBuffers ||
- !pfn_glBindBuffer || !pfn_glBufferData || !pfn_glBufferSubData
- ) )
+ if (m_usevbo && (!m_glGenBuffers || !m_glDeleteBuffers || !m_glBindBuffer || !m_glBufferData || !m_glBufferSubData))
{
- m_usepbo=false;
+ m_usepbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: VBO not supported, missing: ");
- if (!pfn_glGenBuffers)
- {
- osd_printf_warning("glGenBuffers, ");
- }
- if (!pfn_glDeleteBuffers)
- {
- osd_printf_warning("glDeleteBuffers");
- }
- if (!pfn_glBindBuffer)
- {
- osd_printf_warning("glBindBuffer, ");
- }
- if (!pfn_glBufferData)
- {
- osd_printf_warning("glBufferData, ");
- }
- if (!pfn_glBufferSubData)
- {
- osd_printf_warning("glBufferSubData, ");
- }
+ osd_printf_warning("OpenGL: VBO not supported, missing:");
+ if (!m_glGenBuffers)
+ osd_printf_warning(" glGenBuffers");
+ if (!m_glDeleteBuffers)
+ osd_printf_warning(" glDeleteBuffers");
+ if (!m_glBindBuffer)
+ osd_printf_warning(" glBindBuffer");
+ if (!m_glBufferData)
+ osd_printf_warning(" glBufferData");
+ if (!m_glBufferSubData)
+ osd_printf_warning(" glBufferSubData");
osd_printf_warning("\n");
}
- if ( m_usevbo )
+ if (m_usevbo)
{
if (_once)
- {
osd_printf_warning("OpenGL: PBO not supported, no VBO support.\n");
- }
- m_usepbo=false;
+ m_usepbo = false;
}
}
- if ( m_usepbo && ( !pfn_glMapBuffer || !pfn_glUnmapBuffer ) )
+ if (m_usepbo && (!m_glMapBuffer || !m_glUnmapBuffer))
{
- m_usepbo=false;
+ m_usepbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: PBO not supported, missing: ");
- if (!pfn_glMapBuffer)
- {
- osd_printf_warning("glMapBuffer, ");
- }
- if (!pfn_glUnmapBuffer)
- {
- osd_printf_warning("glUnmapBuffer, ");
- }
+ osd_printf_warning("OpenGL: PBO not supported, missing:");
+ if (!m_glMapBuffer)
+ osd_printf_warning(" glMapBuffer");
+ if (!m_glUnmapBuffer)
+ osd_printf_warning(" glUnmapBuffer");
osd_printf_warning("\n");
}
}
if ( m_usefbo &&
- ( !pfn_glIsFramebuffer || !pfn_glBindFramebuffer || !pfn_glDeleteFramebuffers ||
- !pfn_glGenFramebuffers || !pfn_glCheckFramebufferStatus || !pfn_glFramebufferTexture2D
+ ( !m_glIsFramebuffer || !m_glBindFramebuffer || !m_glDeleteFramebuffers ||
+ !m_glGenFramebuffers || !m_glCheckFramebufferStatus || !m_glFramebufferTexture2D
))
{
- m_usefbo=false;
+ m_usefbo = false;
if (_once)
{
- osd_printf_warning("OpenGL: FBO not supported, missing: ");
- if (!pfn_glIsFramebuffer)
- {
- osd_printf_warning("pfn_glIsFramebuffer, ");
- }
- if (!pfn_glBindFramebuffer)
- {
- osd_printf_warning("pfn_glBindFramebuffer, ");
- }
- if (!pfn_glDeleteFramebuffers)
- {
- osd_printf_warning("pfn_glDeleteFramebuffers, ");
- }
- if (!pfn_glGenFramebuffers)
- {
- osd_printf_warning("pfn_glGenFramebuffers, ");
- }
- if (!pfn_glCheckFramebufferStatus)
- {
- osd_printf_warning("pfn_glCheckFramebufferStatus, ");
- }
- if (!pfn_glFramebufferTexture2D)
- {
- osd_printf_warning("pfn_glFramebufferTexture2D, ");
- }
+ osd_printf_warning("OpenGL: FBO not supported, missing:");
+ if (!m_glIsFramebuffer)
+ osd_printf_warning(" m_glIsFramebuffer");
+ if (!m_glBindFramebuffer)
+ osd_printf_warning(" m_glBindFramebuffer");
+ if (!m_glDeleteFramebuffers)
+ osd_printf_warning(" m_glDeleteFramebuffers");
+ if (!m_glGenFramebuffers)
+ osd_printf_warning(" m_glGenFramebuffers");
+ if (!m_glCheckFramebufferStatus)
+ osd_printf_warning(" m_glCheckFramebufferStatus");
+ if (!m_glFramebufferTexture2D)
+ osd_printf_warning(" m_glFramebufferTexture2D");
osd_printf_warning("\n");
}
}
if (_once)
{
- if ( m_usevbo )
- {
+ if (m_usevbo)
osd_printf_verbose("OpenGL: VBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: VBO not supported\n");
- }
- if ( m_usepbo )
- {
+ if (m_usepbo)
osd_printf_verbose("OpenGL: PBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: PBO not supported\n");
- }
- if ( m_usefbo )
- {
+ if (m_usefbo)
osd_printf_verbose("OpenGL: FBO supported\n");
- }
else
- {
osd_printf_warning("OpenGL: FBO not supported\n");
- }
}
- if ( m_useglsl )
+ if (m_useglsl)
{
#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
+ m_gl_context->get_proc_address(m_glActiveTexture, "glActiveTextureARB");
#else
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
+ m_gl_context->get_proc_address(m_glActiveTexture, "glActiveTexture");
#endif
- if (!pfn_glActiveTexture)
+ if (!m_glActiveTexture)
{
if (_once)
- {
osd_printf_warning("OpenGL: GLSL disabled, glActiveTexture(ARB) not supported\n");
- }
m_useglsl = 0;
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- m_glsl = glsl_shader_init(m_gl_context);
- m_useglsl = (m_glsl != nullptr ? 1 : 0);
+ m_shader_tool = glsl_shader_info::init(
+ *m_gl_context
+#if defined(USE_DISPATCH_GL)
+ , gl_dispatch.get()
+#endif
+ );
+ m_useglsl = (m_shader_tool ? 1 : 0);
if ( ! m_useglsl )
{
@@ -922,9 +1051,9 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- if (assert_window()->prescale() != 1 )
+ if (window().prescale() != 1 )
{
m_useglsl = 0;
if (_once)
@@ -934,15 +1063,14 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- int i;
video_config.filter = false;
- glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
+ glsl_shader_feature = glsl_shader_info::FEAT_PLAIN;
m_glsl_program_num = 0;
m_glsl_program_mb2sc = 0;
- for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
+ for (int i=0; i<m_ogl_config.glsl_shader_mamebm_num; i++)
{
if ( !m_usefbo && m_glsl_program_num==1 )
{
@@ -953,60 +1081,65 @@ void renderer_ogl::loadGLExtensions()
break;
}
- if ( glsl_shader_add_mamebm(m_glsl, video_config.glsl_shader_mamebm[i], m_glsl_program_num) )
+ if ( m_shader_tool->add_mamebm(m_ogl_config.glsl_shader_mamebm[i].c_str(), m_glsl_program_num) )
{
osd_printf_error("OpenGL: GLSL loading mame bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_mamebm[i]);
- } else {
- glsl_shader_feature = GLSL_SHADER_FEAT_CUSTOM;
+ i, m_ogl_config.glsl_shader_mamebm[i]);
+ }
+ else
+ {
+ glsl_shader_feature = glsl_shader_info::FEAT_CUSTOM;
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using mame bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_mamebm[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_mamebm[i]);
}
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
}
}
- if ( video_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
+ if ( m_ogl_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
{
osd_printf_verbose("OpenGL: GLSL cannot use screen bitmap shader without bitmap shader\n");
}
- for(i=0; m_usefbo && m_glsl_program_num>0 && i<video_config.glsl_shader_scrn_num; i++)
+ for(int i=0; m_usefbo && m_glsl_program_num>0 && i<m_ogl_config.glsl_shader_scrn_num; i++)
{
- if ( glsl_shader_add_scrn(m_glsl, video_config.glsl_shader_scrn[i],
- m_glsl_program_num-1-m_glsl_program_mb2sc) )
+ if ( m_shader_tool->add_scrn(m_ogl_config.glsl_shader_scrn[i].c_str(), m_glsl_program_num-1-m_glsl_program_mb2sc) )
{
osd_printf_error("OpenGL: GLSL loading screen bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_scrn[i]);
- } else {
+ i, m_ogl_config.glsl_shader_scrn[i]);
+ }
+ else
+ {
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using screen bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_scrn[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_scrn[i]);
}
m_glsl_program_num++;
}
}
if ( 0==m_glsl_program_num &&
- 0 <= video_config.glsl_filter && video_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
+ 0 <= m_ogl_config.glsl_filter && m_ogl_config.glsl_filter < glsl_shader_info::FEAT_INT_NUMBER )
{
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
- glsl_shader_feature = video_config.glsl_filter;
+ glsl_shader_feature = m_ogl_config.glsl_filter;
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using shader filter '%s', idx: %d, num %d (vid filter: %d)\n",
- glsl_shader_get_filter_name_mamebm(glsl_shader_feature),
+ m_shader_tool->get_filter_name_mamebm(glsl_shader_feature),
glsl_shader_feature, m_glsl_program_num, video_config.filter);
}
}
- } else {
+ }
+ else
+ {
if (_once)
{
osd_printf_verbose("OpenGL: using vid filter: %d\n", video_config.filter);
@@ -1026,16 +1159,7 @@ int renderer_ogl::draw(const int update)
float vofs, hofs;
int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE;
-#ifdef TOBEMIGRATED
- if (video_config.novideo)
- {
- return 0;
- }
-#endif
-
- auto win = assert_window();
-
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@@ -1047,7 +1171,7 @@ int renderer_ogl::draw(const int update)
clear_flags(FI_CHANGED);
}
- m_gl_context->MakeCurrent();
+ m_gl_context->make_current();
if (m_init_context)
{
@@ -1116,7 +1240,42 @@ int renderer_ogl::draw(const int update)
// |_________|
// (0,h) (w,h)
- glViewport(0.0, 0.0, (GLsizei) m_width, (GLsizei) m_height);
+ GLsizei iScale = 1;
+
+ /*
+ Mac hack: macOS version 10.15 and later flipped from assuming you don't support Retina to
+ assuming you do support Retina. SDL 2.0.11 is scheduled to fix this, but it's not out yet.
+ So we double-scale everything if you're on 10.15 or later and SDL is not at least version 2.0.11.
+ */
+ #if defined(SDLMAME_MACOSX) && !defined(OSD_MAC)
+ SDL_version sdlVers;
+ SDL_GetVersion(&sdlVers);
+ // Only do this if SDL is not at least 2.0.11.
+ if ((sdlVers.major == 2) && (sdlVers.minor == 0) && (sdlVers.patch < 11))
+ #endif
+ #if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+ {
+ // now get the Darwin kernel version
+ int dMaj, dMin, dPatch;
+ char versStr[64];
+ dMaj = dMin = dPatch = 0;
+ size_t size = sizeof(versStr);
+ int retVal = sysctlbyname("kern.osrelease", versStr, &size, NULL, 0);
+ if (retVal == 0)
+ {
+ sscanf(versStr, "%d.%d.%d", &dMaj, &dMin, &dPatch);
+ // 10.15 Catalina is Darwin version 19
+ if (dMaj >= 19)
+ {
+ // do the workaround for Retina being forced on
+ osd_printf_verbose("OpenGL: enabling Retina workaround\n");
+ iScale = 2;
+ }
+ }
+ }
+ #endif
+
+ glViewport(0.0, 0.0, (GLsizei) m_width * iScale, (GLsizei) m_height * iScale);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble) m_width, (GLdouble) m_height, 0.0, 0.0, -1.0);
@@ -1152,16 +1311,15 @@ int renderer_ogl::draw(const int update)
hofs = (cw - m_blit_dim.width()) / 2.0f;
}
}
-#else
#endif
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// now draw
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
int i;
@@ -1196,6 +1354,10 @@ int renderer_ogl::draw(const int update)
if(pendingPrimitive!=curPrimitive)
{
+ if (curPrimitive==GL_POINTS)
+ glPointSize(prim.width);
+ else
+ glLineWidth(prim.width);
glBegin(curPrimitive);
pendingPrimitive=curPrimitive;
}
@@ -1212,11 +1374,6 @@ int renderer_ogl::draw(const int update)
}
#else
{
- const line_aa_step *step = line_aa_4step;
- render_bounds b0, b1;
- float r, g, b, a;
- float effwidth;
-
// we're not gonna play fancy here. close anything pending and let's go.
if (pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
{
@@ -1227,12 +1384,10 @@ int renderer_ogl::draw(const int update)
set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim.flags));
// compute the effective width based on the direction of the line
- effwidth = prim.width();
- if (effwidth < 0.5f)
- effwidth = 0.5f;
+ float effwidth = std::max(prim.width(), 0.5f);
// determine the bounds of a quad to draw this line
- render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, 0.0f);
// fix window position
b0.x0 += hofs;
@@ -1245,7 +1400,7 @@ int renderer_ogl::draw(const int update)
b1.y1 += vofs;
// iterate over AA steps
- for (step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
+ for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
{
glBegin(GL_TRIANGLE_STRIP);
@@ -1262,14 +1417,10 @@ int renderer_ogl::draw(const int update)
glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs);
// determine the color of the line
- r = (prim.color.r * step->weight);
- g = (prim.color.g * step->weight);
- b = (prim.color.b * step->weight);
- a = (prim.color.a * 255.0f);
- if (r > 1.0) r = 1.0;
- if (g > 1.0) g = 1.0;
- if (b > 1.0) b = 1.0;
- if (a > 1.0) a = 1.0;
+ float r = std::min(prim.color.r * step->weight, 1.0f);
+ float g = std::min(prim.color.g * step->weight, 1.0f);
+ float b = std::min(prim.color.b * step->weight, 1.0f);
+ float a = std::min(prim.color.a * 255.0f, 1.0f);
glColor4f(r, g, b, a);
// texture = texture_update(window, &prim, 0);
@@ -1377,10 +1528,10 @@ int renderer_ogl::draw(const int update)
pendingPrimitive=GL_NO_PRIMITIVE;
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
m_init_context = 0;
- m_gl_context->SwapBuffer();
+ m_gl_context->swap_buffer();
return 0;
}
@@ -1513,9 +1664,8 @@ void renderer_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, ui
while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height)
texture->yprescale--;
- auto win = assert_window();
- if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != win->prescale() || texture->yprescale != win->prescale()))
- osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", win->prescale(), win->prescale(), texture->xprescale, texture->yprescale);
+ if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale()))
+ osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale);
width *= texture->xprescale;
height *= texture->yprescale;
@@ -1610,10 +1760,9 @@ void renderer_ogl::texture_compute_size_type(const render_texinfo *texsource, og
// texture_create
//============================================================
-static int gl_checkFramebufferStatus(void)
+int renderer_ogl::gl_checkFramebufferStatus() const
{
- GLenum status;
- status=(GLenum)pfn_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+ GLenum const status = (GLenum)m_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
return 0;
@@ -1653,14 +1802,14 @@ static int gl_checkFramebufferStatus(void)
return -1;
}
-static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height)
+int renderer_ogl::texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const
{
- pfn_glActiveTexture(text_unit);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
+ m_glActiveTexture(text_unit);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
glBindTexture(GL_TEXTURE_2D, text_name);
{
GLint _width, _height;
- if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
+ if ( m_shader_tool->texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &_width, &_height, 1) )
{
osd_printf_error("cannot create fbo texture, req: %dx%d, avail: %dx%d - bail out\n",
@@ -1675,10 +1824,10 @@ static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- pfn_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ m_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, text_name, 0);
if ( gl_checkFramebufferStatus() )
@@ -1715,51 +1864,49 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
for(i=0; i<m_glsl_program_num; i++)
{
if ( i<=m_glsl_program_mb2sc )
- {
- m_glsl_program[i] = glsl_shader_get_program_mamebm(glsl_shader_feature, i);
- } else {
- m_glsl_program[i] = glsl_shader_get_program_scrn(i-1-m_glsl_program_mb2sc);
- }
- pfn_glUseProgramObjectARB(m_glsl_program[i]);
+ m_glsl_program[i] = m_shader_tool->get_program_mamebm(glsl_shader_feature, i);
+ else
+ m_glsl_program[i] = m_shader_tool->get_program_scrn(i-1-m_glsl_program_mb2sc);
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[i]);
if ( i<=m_glsl_program_mb2sc )
{
// GL_TEXTURE0 GLSL Uniforms
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
- pfn_glUniform1iARB(uniform_location, 0);
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
+ m_shader_tool->pfn_glUniform1iARB(uniform_location, 0);
GL_CHECK_ERROR_NORMAL();
}
{
GLfloat color_texture_sz[2] = { (GLfloat)texture->rawwidth, (GLfloat)texture->rawheight };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
GL_CHECK_ERROR_NORMAL();
}
GLfloat color_texture_pow2_sz[2] = { (GLfloat)texture->rawwidth_create, (GLfloat)texture->rawheight_create };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
GL_CHECK_ERROR_NORMAL();
GLfloat screen_texture_sz[2] = { (GLfloat) m_blit_dim.width(), (GLfloat) m_blit_dim.height() };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
GL_CHECK_ERROR_NORMAL();
GLfloat screen_texture_pow2_sz[2] = { (GLfloat)surf_w_pow2, (GLfloat)surf_h_pow2 };
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
- pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
+ m_shader_tool->pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
GL_CHECK_ERROR_NORMAL();
}
- pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
if( m_glsl_program_num > 1 )
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
for (i=0; i<2; i++)
@@ -1773,7 +1920,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
}
}
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
osd_printf_verbose("GL texture: mpass mame-bmp 2x %dx%d (pow2 %dx%d)\n",
texture->rawwidth, texture->rawheight, texture->rawwidth_create, texture->rawheight_create);
@@ -1783,7 +1930,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
for (i=0; i<2; i++)
@@ -1804,14 +1951,14 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
// GL_TEXTURE0
// get a name for this texture
glGenTextures(1, (GLuint *)&texture->texture);
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->texture);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create);
uint32_t * dummy = nullptr;
GLint _width, _height;
- if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
+ if ( m_shader_tool->texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
texture->rawwidth_create, texture->rawheight_create,
0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
@@ -1833,7 +1980,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
{
- assert( glsl_shader_feature == GLSL_SHADER_FEAT_PLAIN );
+ assert( glsl_shader_feature == glsl_shader_info::FEAT_PLAIN );
// screen textures get the user's choice of filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -1854,8 +2001,8 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_CHECK_ERROR_NORMAL();
@@ -1868,7 +2015,11 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
ogl_texture_info *texture;
// allocate a new texture
- texture = global_alloc(ogl_texture_info);
+ texture = new ogl_texture_info(
+#if defined(USE_DISPATCH_GL)
+ gl_dispatch.get()
+#endif
+ );
// fill in the core data
texture->hash = texture_compute_hash(texsource, flags);
@@ -1877,9 +2028,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
texture->texinfo.seqid = -1; // force set data
if (PRIMFLAG_GET_SCREENTEX(flags))
{
- auto win = assert_window();
- texture->xprescale = win->prescale();
- texture->yprescale = win->prescale();
+ texture->xprescale = window().prescale();
+ texture->yprescale = window().prescale();
}
else
{
@@ -1933,14 +2083,14 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if ( texture->type != TEXTURE_TYPE_SHADER && m_useglsl)
{
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
}
if ( texture->type==TEXTURE_TYPE_SHADER )
{
if ( texture_shader_create(texsource, texture, flags) )
{
- global_free(texture);
+ delete texture;
return nullptr;
}
}
@@ -1976,8 +2126,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if( texture->texTarget==GL_TEXTURE_RECTANGLE_ARB )
{
// texture rectangles can't wrap
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else {
// set wrapping mode appropriately
if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
@@ -1987,8 +2137,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
}
@@ -1998,12 +2148,12 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
assert(m_usepbo);
// create the PBO
- pfn_glGenBuffers(1, (GLuint *)&texture->pbo);
+ m_glGenBuffers(1, (GLuint *)&texture->pbo);
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
// set up the PBO dimension, ..
- pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
+ m_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
texture->rawwidth * texture->rawheight * sizeof(uint32_t),
nullptr, GL_STREAM_DRAW);
}
@@ -2033,10 +2183,10 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if (m_usevbo)
{
// Generate And Bind The Texture Coordinate Buffer
- pfn_glGenBuffers( 1, &(texture->texCoordBufferName) );
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glGenBuffers( 1, &(texture->texCoordBufferName) );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
+ m_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2297,14 +2447,14 @@ static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, in
// texture_set_data
//============================================================
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags)
+void renderer_ogl::texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const
{
if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert(texture->pbo);
assert(!texture->nocopy);
- texture->data = (uint32_t *) pfn_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
+ texture->data = (uint32_t *) m_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
}
// note that nocopy and borderpix are mutually exclusive, IOW
@@ -2371,7 +2521,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
if ( texture->type == TEXTURE_TYPE_SHADER )
{
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, texture->texture);
if (texture->nocopy)
@@ -2390,7 +2540,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
// unmap the buffer from the CPU space so it can DMA
- pfn_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
+ m_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
// kick off the DMA
glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
@@ -2422,7 +2572,7 @@ static int compare_texture_primitive(const ogl_texture_info *texture, const rend
texture->texinfo.width == prim->texture.width &&
texture->texinfo.height == prim->texture.height &&
texture->texinfo.rowpixels == prim->texture.rowpixels &&
- /* texture->texinfo.palette == prim->texture.palette && */
+ texture->texinfo.palette == prim->texture.palette &&
((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
return 1;
else
@@ -2540,12 +2690,12 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
if ( shaderIdx>0 )
{
int uniform_location;
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
- pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
+ m_shader_tool->pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
if ( shaderIdx<=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[mpass_src_idx]);
@@ -2554,22 +2704,22 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[mpass_src_idx]);
}
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
glBindTexture(texture->texTarget, 0);
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
if ( shaderIdx<m_glsl_program_num-1 )
{
if ( shaderIdx>=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
}
else
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
}
if ( shaderIdx==0 )
@@ -2590,7 +2740,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
else
{
glBindTexture(texture->texTarget, 0);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
if ( m_glsl_program_mb2sc == m_glsl_program_num-1 )
{
@@ -2598,7 +2748,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, 0);
}
}
@@ -2610,8 +2760,7 @@ void renderer_ogl::texture_shader_update(ogl_texture_info *texture, render_conta
if (container!=nullptr)
{
- render_container::user_settings settings;
- container->get_user_settings(settings);
+ render_container::user_settings settings = container->get_user_settings();
/* FIXME: the code below is in just for illustration issue on
* how to set shader variables. gamma, contrast and brightness are
* handled already by the core
@@ -2620,8 +2769,8 @@ void renderer_ogl::texture_shader_update(ogl_texture_info *texture, render_conta
vid_attributes[1] = settings.m_contrast;
vid_attributes[2] = settings.m_brightness;
vid_attributes[3] = 0.0f;
- uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
- pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
+ uniform_location = m_shader_tool->pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
+ m_shader_tool->pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
if ( GL_CHECK_ERROR_QUIET() ) {
osd_printf_verbose("GLSL: could not set 'vid_attributes' for shader prog idx %d\n", shaderIdx);
}
@@ -2642,12 +2791,12 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
{
if ( texture->type == TEXTURE_TYPE_SHADER )
{
- pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
+ m_shader_tool->pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
}
else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert ( m_usepbo ) ;
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
glEnable(texture->texTarget);
}
else
@@ -2687,9 +2836,9 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
+ m_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2706,34 +2855,41 @@ void renderer_ogl::texture_disable(ogl_texture_info * texture)
if ( texture->type == TEXTURE_TYPE_SHADER )
{
assert ( m_useglsl );
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- } else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ }
+ else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDisable(texture->texTarget);
- } else {
+ }
+ else
+ {
glDisable(texture->texTarget);
}
}
void renderer_ogl::texture_all_disable()
{
- if ( m_useglsl )
+ if (m_useglsl)
{
- pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
+ m_shader_tool->pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- pfn_glActiveTexture(GL_TEXTURE3);
+ m_glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE2);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE1);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE0);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ if (m_usefbo)
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@@ -2746,10 +2902,140 @@ void renderer_ogl::texture_all_disable()
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
}
if ( m_usepbo )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
}
}
+
+
+class video_opengl : public osd_module, public render_module
+{
+public:
+ video_opengl()
+ : osd_module(OSD_RENDERER_PROVIDER, "opengl")
+#if defined(USE_DISPATCH_GL)
+ , m_dll_loaded(false)
+#endif
+ {
+ }
+ ~video_opengl() { exit(); }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ ogl_video_config m_ogl_config;
+#if defined(USE_DISPATCH_GL)
+ bool m_dll_loaded;
+#endif
+};
+
+int video_opengl::init(osd_interface &osd, osd_options const &options)
+{
+ m_ogl_config.vbo = options.gl_vbo();
+ m_ogl_config.pbo = options.gl_pbo();
+ m_ogl_config.allowtexturerect = !options.gl_no_texture_rect();
+ m_ogl_config.forcepow2texture = options.gl_force_pow2_texture();
+ m_ogl_config.glsl = options.gl_glsl();
+ if (m_ogl_config.glsl)
+ {
+ m_ogl_config.glsl_filter = options.glsl_filter();
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_mame(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_mamebm[m_ogl_config.glsl_shader_mamebm_num++] = stemp;
+ }
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_screen(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_scrn[m_ogl_config.glsl_shader_scrn_num++] = stemp;
+ }
+ }
+ else
+ {
+ m_ogl_config.glsl_filter = 0;
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_mamebm)
+ s.clear();
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_scrn)
+ s.clear();
+ }
+
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (!m_dll_loaded)
+ {
+ // directfb and and x11 use this env var: SDL_VIDEO_GL_DRIVER
+ char const *libname = dynamic_cast<sdl_options const &>(options).gl_lib();
+ if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
+ libname = nullptr;
+
+ if (SDL_GL_LoadLibrary(libname) != 0)
+ {
+ osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
+ return -1;
+ }
+
+ osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
+ }
+#endif // defined(OSD_SDL)
+ m_dll_loaded = true;
+#endif // defined(USE_DISPATCH_GL)
+
+#if defined(OSD_WINDOWS)
+ osd_printf_verbose("Using Windows OpenGL driver\n");
+#else // defined(OSD_WINDOWS)
+ osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
+#endif // defined(OSD_WINDOWS)
+
+ return 0;
+}
+
+void video_opengl::exit()
+{
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (m_dll_loaded)
+ SDL_GL_UnloadLibrary();
+#endif // defined(OSD_SDL)
+ m_dll_loaded = false;
+#endif // defined(USE_DISPATCH_GL)
+
+ m_ogl_config = ogl_video_config();
+}
+
+std::unique_ptr<osd_renderer> video_opengl::create(osd_window &window)
+{
+ return std::make_unique<renderer_ogl>(window, m_ogl_config);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // USE_OPENGL
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_opengl, OSD_RENDERER_PROVIDER, "opengl") } }
+
+#endif // USE_OPENGL
+
+
+MODULE_DEFINITION(RENDERER_OPENGL, osd::video_opengl)