summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/drawogl.h
blob: 5444f2031413be4d6ab10576f9683852ddcb8664 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
//  drawogl.h - SDL software and OpenGL implementation
//
//  SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================

#pragma once

#ifndef __DRAWOGL__
#define __DRAWOGL__

// OSD headers
#ifndef OSD_WINDOWS
#include "osdsdl.h"
#include "window.h"
#else
#include "../windows/window.h"
typedef uint64_t HashT;
#endif

#if defined(OSD_WINDOWS)
#include "winglcontext.h"
#else
#include "sdlglcontext.h"
#endif

#include "modules/opengl/gl_shader_mgr.h"

//============================================================
//  Textures
//============================================================

/* ogl_texture_info holds information about a texture */
class ogl_texture_info
{
public:
	ogl_texture_info()
	:   hash(0), flags(0), rawwidth(0), rawheight(0),
		rawwidth_create(0), rawheight_create(0),
		type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
		texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(nullptr),
		data_own(0), texCoordBufferName(0)
	{
		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;
	}

	HashT               hash;               // hash value for the texture (must be >= pointer size)
	uint32_t              flags;              // rendering flags
	render_texinfo      texinfo;            // copy of the texture info
	int                 rawwidth, rawheight;    // raw width/height of the texture
	int                 rawwidth_create;    // raw width/height, pow2 compatible, if needed
	int                 rawheight_create;   // (create and initial set the texture, not for copy!)
	int                 type;               // what type of texture are we?
	int                 format;             // texture format
	int                 borderpix;          // do we have a 1 pixel border?
	int                 xprescale;          // what is our X prescale factor?
	int                 yprescale;          // what is our Y prescale factor?
	int                 nocopy;             // must the texture date be copied?

	uint32_t              texture;            // OpenGL texture "name"/ID

	GLenum              texTarget;          // OpenGL texture target
	int                 texpow2;            // Is this texture pow2

	uint32_t              mpass_dest_idx;         // 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;                    // pixel buffer object for this texture (DYNAMIC only!)
	uint32_t              *data;                  // pixels for the texture
	int                 data_own;               // 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(std::shared_ptr<osd_window> window)
		: osd_renderer(window, FLAG_NEEDS_OPENGL)
		, m_blittimer(0)
		, m_width(0)
		, m_height(0)
		, m_blit_dim(0, 0)
		, m_gl_context(nullptr)
		, 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(nullptr)
		, 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();

	static void init(running_machine &machine);
	static void exit();

	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
	{
		auto win = try_getwindow();
		if (win == nullptr)
			return nullptr;

		osd_dim nd = win->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;
		win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
		return &win->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 << 10) + 1);
	static const uint32_t OVERFLOW_SIZE = (1 << 10);

	void destroy_all_textures();

	static void load_gl_lib(running_machine &machine);
	void loadGLExtensions();
	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();

	int32_t           m_blittimer;
	int             m_width;
	int             m_height;
	osd_dim         m_blit_dim;

	osd_gl_context  *m_gl_context;

	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

	glsl_shader_info *m_glsl;             // glsl_shader_info

	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];

	static bool     s_shown_video_info;
	static bool     s_dll_loaded;
};

#endif // __DRAWOGL__