summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/render')
-rw-r--r--src/osd/modules/render/bgfx/fs_line.sc11
-rw-r--r--src/osd/modules/render/bgfx/fs_quad.sc11
-rw-r--r--src/osd/modules/render/bgfx/fs_quad_texture.sc14
-rw-r--r--src/osd/modules/render/bgfx/makefile13
-rw-r--r--src/osd/modules/render/bgfx/varying.def.sc7
-rw-r--r--src/osd/modules/render/bgfx/vs_line.sc13
-rw-r--r--src/osd/modules/render/bgfx/vs_quad.sc13
-rw-r--r--src/osd/modules/render/bgfx/vs_quad_texture.sc14
-rw-r--r--src/osd/modules/render/binpacker.cpp195
-rw-r--r--src/osd/modules/render/binpacker.h183
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp6
-rw-r--r--src/osd/modules/render/draw13.cpp36
-rw-r--r--src/osd/modules/render/drawbgfx.cpp1187
-rw-r--r--src/osd/modules/render/drawbgfx.h108
-rw-r--r--src/osd/modules/render/drawdd.cpp1317
-rw-r--r--src/osd/modules/render/drawogl.cpp66
-rw-r--r--src/osd/modules/render/drawsdl.cpp235
17 files changed, 1599 insertions, 1830 deletions
diff --git a/src/osd/modules/render/bgfx/fs_line.sc b/src/osd/modules/render/bgfx/fs_line.sc
new file mode 100644
index 00000000000..1fcd3b27284
--- /dev/null
+++ b/src/osd/modules/render/bgfx/fs_line.sc
@@ -0,0 +1,11 @@
+$input v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+void main()
+{
+ gl_FragColor = v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/fs_quad.sc b/src/osd/modules/render/bgfx/fs_quad.sc
new file mode 100644
index 00000000000..1fcd3b27284
--- /dev/null
+++ b/src/osd/modules/render/bgfx/fs_quad.sc
@@ -0,0 +1,11 @@
+$input v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+void main()
+{
+ gl_FragColor = v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/fs_quad_texture.sc b/src/osd/modules/render/bgfx/fs_quad_texture.sc
new file mode 100644
index 00000000000..5a45a056171
--- /dev/null
+++ b/src/osd/modules/render/bgfx/fs_quad_texture.sc
@@ -0,0 +1,14 @@
+$input v_color0, v_texcoord0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+SAMPLER2D(s_tex, 0);
+
+void main()
+{
+ vec4 texel = texture2D(s_tex, v_texcoord0);
+ gl_FragColor = texel * v_color0;
+}
diff --git a/src/osd/modules/render/bgfx/makefile b/src/osd/modules/render/bgfx/makefile
new file mode 100644
index 00000000000..86735a61c38
--- /dev/null
+++ b/src/osd/modules/render/bgfx/makefile
@@ -0,0 +1,13 @@
+BGFX_DIR=../../../../../3rdparty/bgfx
+RUNTIME_DIR=../../../../..
+BUILD_DIR=../../../../../build
+
+include $(BGFX_DIR)/scripts/shader.mk
+
+rebuild:
+ @make -s --no-print-directory TARGET=0 clean all
+ @make -s --no-print-directory TARGET=1 clean all
+ @make -s --no-print-directory TARGET=2 clean all
+ @make -s --no-print-directory TARGET=3 clean all
+ @make -s --no-print-directory TARGET=4 clean all
+ @make -s --no-print-directory TARGET=5 clean all
diff --git a/src/osd/modules/render/bgfx/varying.def.sc b/src/osd/modules/render/bgfx/varying.def.sc
new file mode 100644
index 00000000000..4745725e015
--- /dev/null
+++ b/src/osd/modules/render/bgfx/varying.def.sc
@@ -0,0 +1,7 @@
+vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
+vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
+vec3 v_pos : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
+
+vec3 a_position : POSITION;
+vec4 a_color0 : COLOR0;
+vec2 a_texcoord0 : TEXCOORD0;
diff --git a/src/osd/modules/render/bgfx/vs_line.sc b/src/osd/modules/render/bgfx/vs_line.sc
new file mode 100644
index 00000000000..874ffcf46ac
--- /dev/null
+++ b/src/osd/modules/render/bgfx/vs_line.sc
@@ -0,0 +1,13 @@
+$input a_position, a_color0
+$output v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+void main()
+{
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ v_color0 = a_color0;
+}
diff --git a/src/osd/modules/render/bgfx/vs_quad.sc b/src/osd/modules/render/bgfx/vs_quad.sc
new file mode 100644
index 00000000000..84e23c5a09b
--- /dev/null
+++ b/src/osd/modules/render/bgfx/vs_quad.sc
@@ -0,0 +1,13 @@
+$input a_position, a_color0
+$output v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+void main()
+{
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ v_color0 = a_color0;
+}
diff --git a/src/osd/modules/render/bgfx/vs_quad_texture.sc b/src/osd/modules/render/bgfx/vs_quad_texture.sc
new file mode 100644
index 00000000000..c3699f6fbd9
--- /dev/null
+++ b/src/osd/modules/render/bgfx/vs_quad_texture.sc
@@ -0,0 +1,14 @@
+$input a_position, a_texcoord0, a_color0
+$output v_texcoord0, v_color0
+
+// license:BSD-3-Clause
+// copyright-holders:Dario Manesku
+
+#include "../../../../../3rdparty/bgfx/examples/common/common.sh"
+
+void main()
+{
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ v_texcoord0 = a_texcoord0;
+ v_color0 = a_color0;
+}
diff --git a/src/osd/modules/render/binpacker.cpp b/src/osd/modules/render/binpacker.cpp
new file mode 100644
index 00000000000..2054dfa54cf
--- /dev/null
+++ b/src/osd/modules/render/binpacker.cpp
@@ -0,0 +1,195 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+//============================================================
+//
+// binpacker.cpp - Simple texture packer for dynamic atlasing
+//
+//============================================================
+
+#include "binpacker.h"
+#include <algorithm>
+
+bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size)
+{
+ clear();
+
+ m_pack_size = pack_size;
+
+ // Add rects to member array, and check to make sure none is too big
+ for (size_t rect = 0; rect < rects.size(); rect++)
+ {
+ m_rects.push_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
+ }
+
+ // Sort from greatest to least area
+ std::sort(m_rects.rbegin(), m_rects.rend());
+
+ // Pack
+ while (m_num_packed < (int)m_rects.size())
+ {
+ int i = m_packs.size();
+ m_packs.push_back(rectangle(m_pack_size));
+ m_roots.push_back(i);
+ if (!fill(i))
+ {
+ return false;
+ }
+ }
+
+ // Write out
+ packs.resize(m_roots.size());
+ for (size_t i = 0; i < m_roots.size(); ++i)
+ {
+ packs[i].clear();
+ add_pack_to_array(m_roots[i], packs[i]);
+ }
+
+ return true;
+}
+
+void rectangle_packer::clear()
+{
+ m_pack_size = 0;
+ m_num_packed = 0;
+ m_rects.clear();
+ m_packs.clear();
+ m_roots.clear();
+}
+
+bool rectangle_packer::fill(int pack)
+{
+ // For each rect
+ for (size_t rect = 0; rect < m_rects.size(); ++rect)
+ {
+ // If it's not already packed
+ if (!m_rects[rect].packed)
+ {
+ // If it fits in the current working area
+ if (fits(m_rects[rect], m_packs[pack]))
+ {
+ // Store in lower-left of working area, split, and recurse
+ m_num_packed++;
+ split(pack, rect);
+ fill(m_packs[pack].children[0]);
+ fill(m_packs[pack].children[1]);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void rectangle_packer::split(int pack, int rect)
+{
+ // Split the working area either horizontally or vertically with respect
+ // to the rect we're storing, such that we get the largest possible child
+ // area.
+
+ rectangle left = m_packs[pack];
+ rectangle right = m_packs[pack];
+ rectangle bottom = m_packs[pack];
+ rectangle top = m_packs[pack];
+
+ left.y += m_rects[rect].h;
+ left.w = m_rects[rect].w;
+ left.h -= m_rects[rect].h;
+
+ right.x += m_rects[rect].w;
+ right.w -= m_rects[rect].w;
+
+ bottom.x += m_rects[rect].w;
+ bottom.h = m_rects[rect].h;
+ bottom.w -= m_rects[rect].w;
+
+ top.y += m_rects[rect].h;
+ top.h -= m_rects[rect].h;
+
+ int max_lr_area = left.get_area();
+ if (right.get_area() > max_lr_area)
+ {
+ max_lr_area = right.get_area();
+ }
+
+ int max_bt_area = bottom.get_area();
+ if (top.get_area() > max_bt_area)
+ {
+ max_bt_area = top.get_area();
+ }
+
+ if (max_lr_area > max_bt_area)
+ {
+ if (left.get_area() > right.get_area())
+ {
+ m_packs.push_back(left);
+ m_packs.push_back(right);
+ }
+ else
+ {
+ m_packs.push_back(right);
+ m_packs.push_back(left);
+ }
+ }
+ else
+ {
+ if (bottom.get_area() > top.get_area())
+ {
+ m_packs.push_back(bottom);
+ m_packs.push_back(top);
+ }
+ else
+ {
+ m_packs.push_back(top);
+ m_packs.push_back(bottom);
+ }
+ }
+
+ // This pack area now represents the rect we've just stored, so save the
+ // relevant info to it, and assign children.
+ m_packs[pack].w = m_rects[rect].w;
+ m_packs[pack].h = m_rects[rect].h;
+ m_packs[pack].hash = m_rects[rect].hash;
+ m_packs[pack].format = m_rects[rect].format;
+ m_packs[pack].rowpixels = m_rects[rect].rowpixels;
+ m_packs[pack].palette = m_rects[rect].palette;
+ m_packs[pack].base = m_rects[rect].base;
+ m_packs[pack].children[0] = m_packs.size() - 2;
+ m_packs[pack].children[1] = m_packs.size() - 1;
+
+ // Done with the rect
+ m_rects[rect].packed = true;
+
+}
+
+bool rectangle_packer::fits(rectangle& rect1, const rectangle& rect2)
+{
+ // Check to see if rect1 fits in rect2
+
+ if (rect1.w <= rect2.w && rect1.h <= rect2.h)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void rectangle_packer::add_pack_to_array(int pack, std::vector<packed_rectangle>& array) const
+{
+ if (m_packs[pack].hash != 0)
+ {
+ array.push_back(packed_rectangle(m_packs[pack].hash, m_packs[pack].format,
+ m_packs[pack].w, m_packs[pack].h, m_packs[pack].x, m_packs[pack].y,
+ m_packs[pack].rowpixels, m_packs[pack].palette, m_packs[pack].base));
+
+ if (m_packs[pack].children[0] != -1)
+ {
+ add_pack_to_array(m_packs[pack].children[0], array);
+ }
+
+ if (m_packs[pack].children[1] != -1)
+ {
+ add_pack_to_array(m_packs[pack].children[1], array);
+ }
+ }
+}
diff --git a/src/osd/modules/render/binpacker.h b/src/osd/modules/render/binpacker.h
new file mode 100644
index 00000000000..677083b5c09
--- /dev/null
+++ b/src/osd/modules/render/binpacker.h
@@ -0,0 +1,183 @@
+#pragma once
+
+#ifndef __RECTPACKER_H__
+#define __RECTPACKER_H__
+
+#include "emu.h"
+
+#include <vector>
+
+class rectangle_packer
+{
+public:
+ // The input and output are in terms of vectors of ints to avoid
+ // dependencies (although I suppose a public member struct could have been
+ // used). The parameters are:
+
+ // packs : After packing, the outer array contains the packs (therefore
+ // the number of packs is packs.size()). Each inner array contains a
+ // sequence of sets of 3 ints. Each set represents a rectangle in the
+ // pack. The elements in the set are 1) the rect ID, 2) the x position
+ // of the rect with respect to the pack, and 3) the y position of the rect
+ // with respect to the pack. The widths and heights of the rects are not
+ // included, as it's assumed they are stored on the caller's side (they
+ // were after all the input to the function).
+
+ class packable_rectangle
+ {
+ public:
+ packable_rectangle() : m_hash(0), m_width(-1), m_height(-1) { }
+ packable_rectangle(UINT32 hash, UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
+ : m_hash(hash)
+ , m_format(format)
+ , m_width(width)
+ , m_height(height)
+ , m_rowpixels(rowpixels)
+ , m_palette(palette)
+ , m_base(base)
+ {
+ }
+
+ UINT32 hash() const { return m_hash; }
+ UINT32 format() const { return m_format; }
+ int width() const { return m_width; }
+ int height() const { return m_height; }
+ int rowpixels() const { return m_rowpixels; }
+ const rgb_t* palette() const { return m_palette; }
+ void* base() const { return m_base; }
+
+ private:
+ UINT32 m_hash;
+ UINT32 m_format;
+ int m_width;
+ int m_height;
+ int m_rowpixels;
+ const rgb_t* m_palette;
+ void* m_base;
+ };
+
+ class packed_rectangle
+ {
+ public:
+ packed_rectangle() : m_hash(0), m_format(0), m_width(-1), m_height(-1), m_x(-1), m_y(-1), m_rowpixels(0), m_palette(nullptr), m_base(nullptr) { }
+ packed_rectangle(const packed_rectangle& rect)
+ : m_hash(rect.m_hash)
+ , m_format(rect.m_format)
+ , m_width(rect.m_width)
+ , m_height(rect.m_height)
+ , m_x(rect.m_x)
+ , m_y(rect.m_y)
+ , m_rowpixels(rect.m_rowpixels)
+ , m_palette(rect.m_palette)
+ , m_base(rect.m_base)
+ {
+ }
+ packed_rectangle(UINT32 hash, UINT32 format, int width, int height, int x, int y, int rowpixels, const rgb_t *palette, void *base)
+ : m_hash(hash)
+ , m_format(format)
+ , m_width(width)
+ , m_height(height)
+ , m_x(x)
+ , m_y(y)
+ , m_rowpixels(rowpixels)
+ , m_palette(palette)
+ , m_base(base)
+ {
+ }
+
+ UINT32 hash() const { return m_hash; }
+ UINT32 format() const { return m_format; }
+ int width() const { return m_width; }
+ int height() const { return m_height; }
+ int x() const { return m_x; }
+ int y() const { return m_y; }
+ int rowpixels() const { return m_rowpixels; }
+ const rgb_t* palette() const { return m_palette; }
+ void* base() const { return m_base; }
+
+ private:
+ UINT32 m_hash;
+ UINT32 m_format;
+ int m_width;
+ int m_height;
+ int m_x;
+ int m_y;
+ int m_rowpixels;
+ const rgb_t* m_palette;
+ void* m_base;
+ };
+
+ bool pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size);
+
+private:
+ struct rectangle
+ {
+ rectangle(int size)
+ : x(0)
+ , y(0)
+ , w(size)
+ , h(size)
+ , hash(-1)
+ , format(0)
+ , rowpixels(0)
+ , palette(nullptr)
+ , base(nullptr)
+ , packed(false)
+ {
+ children[0] = -1;
+ children[1] = -1;
+ }
+
+ rectangle(int x, int y, int w, int h, int hash, UINT32 format, int rowpixels, const rgb_t *palette, void *base)
+ : x(x)
+ , y(y)
+ , w(w)
+ , h(h)
+ , hash(hash)
+ , format(format)
+ , rowpixels(rowpixels)
+ , palette(palette)
+ , base(base)
+ , packed(false)
+ {
+ children[0] = -1;
+ children[1] = -1;
+ }
+
+ int get_area() const
+ {
+ return w * h;
+ }
+
+ bool operator<(const rectangle& rect) const
+ {
+ return get_area() < rect.get_area();
+ }
+
+ int x;
+ int y;
+ int w;
+ int h;
+ int hash;
+ UINT32 format;
+ int rowpixels;
+ const rgb_t* palette;
+ void* base;
+ int children[2];
+ bool packed;
+ };
+
+ void clear();
+ bool fill(int pack);
+ void split(int pack, int rect);
+ bool fits(rectangle& rect1, const rectangle& rect2);
+ void add_pack_to_array(int pack, std::vector<packed_rectangle>& array) const;
+
+ int m_pack_size;
+ int m_num_packed;
+ std::vector<rectangle> m_rects;
+ std::vector<rectangle> m_packs;
+ std::vector<int> m_roots;
+};
+
+#endif // __RECTPACKER_H__ \ No newline at end of file
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 7284eaabaa6..3ffcee44707 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -1457,9 +1457,9 @@ int shaders::downsample_pass(render_target *rt, int source_index, poly_info *pol
curr_effect->update_uniforms();
int bloom_index = 0;
- float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
- float bloom_width = d3d->get_width();
- float bloom_height = d3d->get_height();
+ float bloom_width = rt->target_width;
+ float bloom_height = rt->target_height;
+ float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height;
for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
{
bloom_dims[bloom_index][0] = (float)(int)bloom_width;
diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp
index f357d567e71..320cc9f3a62 100644
--- a/src/osd/modules/render/draw13.cpp
+++ b/src/osd/modules/render/draw13.cpp
@@ -203,12 +203,6 @@ private:
INT32 m_blittimer;
-#if (SDLMAME_SDL2)
- //SDL_GLContext m_gl_context_id;
-#else
- // SDL surface
- SDL_Surface *m_sdlsurf;
-#endif
simple_list<texture_info> m_texlist; // list of active textures
@@ -601,32 +595,6 @@ static void drawsdl2_exit(void)
//============================================================
// sdl_info::create
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
//============================================================
static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
@@ -661,7 +629,6 @@ static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
int sdl_info13::create()
{
-#if (SDLMAME_SDL2)
// create renderer
/* Enable bilinear filtering in case it is supported.
@@ -699,9 +666,6 @@ int sdl_info13::create()
SDL_GetRendererInfo(m_sdl_renderer, &render_info);
drawsdl_show_info(&render_info);
-#else
-
-#endif
return 0;
}
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index ee808bfc197..9d751c9f816 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
-// copyright-holders:Miodrag Milanovic
+// copyright-holders:Miodrag Milanovic,Ryan Holtz,Dario Manesku,Branimir Karadzic,Aaron Giles
//============================================================
//
-// drawbgfx.c - BGFX drawer
+// drawbgfx.cpp - BGFX renderer
//
//============================================================
#define __STDC_LIMIT_MACROS
@@ -14,11 +14,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#if defined(SDLMAME_WIN32)
-#if (SDLMAME_SDL2)
#include <SDL2/SDL_syswm.h>
-#else
-#include <SDL/SDL_syswm.h>
-#endif
#endif
#else
#include "sdlinc.h"
@@ -30,6 +26,11 @@
#include <bgfx/bgfxplatform.h>
#include <bgfx/bgfx.h>
+#include <bx/fpumath.h>
+#include <bx/readerwriter.h>
+#include <algorithm>
+
+#include "drawbgfx.h"
//============================================================
// DEBUGGING
@@ -43,6 +44,8 @@
// MACROS
//============================================================
+#define GIBBERISH (0)
+
//============================================================
// INLINES
//============================================================
@@ -53,67 +56,6 @@
//============================================================
-/* sdl_info is the information about SDL for the current screen */
-class renderer_bgfx : public osd_renderer
-{
-public:
- renderer_bgfx(osd_window *w)
- : osd_renderer(w, FLAG_NONE), m_blittimer(0),
- m_blit_dim(0, 0),
- m_last_hofs(0), m_last_vofs(0),
- m_last_blit_time(0), m_last_blit_pixels(0)
- {}
-
- virtual int create() override;
- virtual int draw(const int update) override;
-#ifdef OSD_SDL
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
-#else
- virtual void save() override { }
- virtual void record() override { }
- virtual void toggle_fsfx() override { }
-#endif
- virtual void destroy() override;
- virtual render_primitive_list *get_primitives() override
- {
-#ifdef OSD_WINDOWS
- RECT client;
- GetClientRect(window().m_hwnd, &client);
- window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
- return &window().target()->get_primitives();
-#else
- osd_dim nd = window().blit_surface_size();
- if (nd != m_blit_dim)
- {
- m_blit_dim = nd;
- notify_changed();
- }
- window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
- return &window().target()->get_primitives();
-#endif
- }
-
- // void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y);
-
- //texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
- //texture_info *texture_update(const render_primitive &prim);
-
- INT32 m_blittimer;
-
- //simple_list<texture_info> m_texlist; // list of active textures
-
- osd_dim m_blit_dim;
- float m_last_hofs;
- float m_last_vofs;
-
- // Stats
- INT64 m_last_blit_time;
- INT64 m_last_blit_pixels;
-
- // Original display_mode
-};
-
-
//============================================================
// PROTOTYPES
//============================================================
@@ -150,36 +92,85 @@ int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks)
static void drawbgfx_exit(void)
{
+ // Shutdown bgfx.
+ bgfx::shutdown();
}
//============================================================
// renderer_bgfx::create
//============================================================
+bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName);
+
+
+#ifdef OSD_SDL
+static void* sdlNativeWindowHandle(SDL_Window* _window)
+{
+ SDL_SysWMinfo wmi;
+ SDL_VERSION(&wmi.version);
+ if (!SDL_GetWindowWMInfo(_window, &wmi))
+ {
+ return nullptr;
+ }
+
+# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
+ return (void*)wmi.info.x11.window;
+# elif BX_PLATFORM_OSX
+ return wmi.info.cocoa.window;
+# elif BX_PLATFORM_WINDOWS
+ return wmi.info.win.window;
+# elif BX_PLATFORM_STEAMLINK
+ return wmi.info.vivante.window;
+# elif BX_PLATFORM_EMSCRIPTEN
+ return nullptr;
+# endif // BX_PLATFORM_
+}
+#endif
int renderer_bgfx::create()
{
// create renderer
+ osd_dim wdim = window().get_size();
+ if (window().m_index == 0)
+ {
#ifdef OSD_WINDOWS
- RECT client;
- GetClientRect(window().m_hwnd, &client);
-
- bgfx::winSetHwnd(window().m_hwnd);
- bgfx::init();
- bgfx::reset(rect_width(&client), rect_height(&client), BGFX_RESET_VSYNC);
+ bgfx::winSetHwnd(window().m_hwnd);
#else
- osd_dim d = window().get_size();
- m_blittimer = 3;
-
- bgfx::sdlSetWindow(window().sdl_window());
- bgfx::init();
- bgfx::reset(d.width(), d.height(), BGFX_RESET_VSYNC);
+ bgfx::sdlSetWindow(window().sdl_window());
+#endif
+ bgfx::init();
+ bgfx::reset(wdim.width(), wdim.height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ // Enable debug text.
+ bgfx::setDebug(BGFX_DEBUG_TEXT); //BGFX_DEBUG_STATS
+ m_dimensions = osd_dim(wdim.width(), wdim.height());
+ }
+ else
+ {
+#ifdef OSD_WINDOWS
+ fbh = bgfx::createFrameBuffer(window().m_hwnd, wdim.width(), wdim.height());
+#else
+ fbh = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), wdim.width(), wdim.height());
#endif
+ bgfx::touch(window().m_index);
+ }
+
+ ScreenVertex::init();
+
+ // Create program from shaders.
+ m_progQuad = loadProgram("vs_quad", "fs_quad");
+ m_progQuadTexture = loadProgram("vs_quad_texture", "fs_quad_texture");
+ m_s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
+
+ uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
+ m_texture_cache = bgfx::createTexture2D(CACHE_SIZE, CACHE_SIZE, 1, bgfx::TextureFormat::RGBA8, flags);
+
+ const bgfx::Memory* memory = bgfx::alloc(sizeof(uint32_t) * CACHE_SIZE * CACHE_SIZE);
+ memset(memory->data, 0, sizeof(uint32_t) * CACHE_SIZE * CACHE_SIZE);
+ bgfx::updateTexture2D(m_texture_cache, 0, 0, 0, CACHE_SIZE, CACHE_SIZE, memory, CACHE_SIZE * sizeof(uint32_t));
- // Enable debug text.
- bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT);
+ memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16);
+ m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
- osd_printf_verbose("Leave drawsdl2_window_create\n");
return 0;
}
@@ -189,12 +180,14 @@ int renderer_bgfx::create()
void renderer_bgfx::destroy()
{
- // free the memory in the window
-
- // destroy_all_textures();
-
- // Shutdown bgfx.
- bgfx::shutdown();
+ if (window().m_index > 0)
+ {
+ bgfx::destroyFrameBuffer(fbh);
+ }
+ bgfx::destroyUniform(m_s_texColor);
+ // Cleanup.
+ bgfx::destroyProgram(m_progQuad);
+ bgfx::destroyProgram(m_progQuadTexture);
}
@@ -205,133 +198,973 @@ void renderer_bgfx::destroy()
#ifdef OSD_SDL
int renderer_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt)
{
- *xt = x - m_last_hofs;
- *yt = y - m_last_vofs;
- if (*xt<0 || *xt >= m_blit_dim.width())
+ *xt = x;
+ *yt = y;
+ if (*xt<0 || *xt >= m_dimensions.width())
return 0;
- if (*yt<0 || *yt >= m_blit_dim.height())
+ if (*yt<0 || *yt >= m_dimensions.height())
return 0;
return 1;
}
#endif
+static const bgfx::Memory* loadMem(bx::FileReaderI* _reader, const char* _filePath)
+{
+ if (bx::open(_reader, _filePath))
+ {
+ uint32_t size = (uint32_t)bx::getSize(_reader);
+ const bgfx::Memory* mem = bgfx::alloc(size + 1);
+ bx::read(_reader, mem->data, size);
+ bx::close(_reader);
+ mem->data[mem->size - 1] = '\0';
+ return mem;
+ }
+
+ return nullptr;
+}
+static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name)
+{
+ char filePath[512];
+
+ const char* shaderPath = "shaders/dx9/";
+
+ switch (bgfx::getRendererType())
+ {
+ case bgfx::RendererType::Direct3D11:
+ case bgfx::RendererType::Direct3D12:
+ shaderPath = "shaders/dx11/";
+ break;
+
+ case bgfx::RendererType::OpenGL:
+ shaderPath = "shaders/glsl/";
+ break;
+
+ case bgfx::RendererType::Metal:
+ shaderPath = "shaders/metal/";
+ break;
+
+ case bgfx::RendererType::OpenGLES:
+ shaderPath = "shaders/gles/";
+ break;
+
+ default:
+ break;
+ }
+
+ strcpy(filePath, shaderPath);
+ strcat(filePath, _name);
+ strcat(filePath, ".bin");
+
+ return bgfx::createShader(loadMem(_reader, filePath));
+}
+
+bgfx::ProgramHandle renderer_bgfx::loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName)
+{
+ bgfx::ShaderHandle vsh = loadShader(_reader, _vsName);
+ bgfx::ShaderHandle fsh = BGFX_INVALID_HANDLE;
+ if (nullptr != _fsName)
+ {
+ fsh = loadShader(_reader, _fsName);
+ }
+
+ return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
+}
+static auto s_fileReader = new bx::CrtFileReader;
+
+bgfx::ProgramHandle renderer_bgfx::loadProgram(const char* _vsName, const char* _fsName)
+{
+ return loadProgram(s_fileReader, _vsName, _fsName);
+}
+
//============================================================
// drawbgfx_window_draw
//============================================================
+bgfx::VertexDecl renderer_bgfx::ScreenVertex::ms_decl;
+
+void renderer_bgfx::put_packed_quad(render_primitive *prim, UINT32 hash, ScreenVertex* vertex)
+{
+ rectangle_packer::packed_rectangle& rect = m_hash_to_entry[hash];
+ float u0 = float(rect.x()) / float(CACHE_SIZE);
+ float v0 = float(rect.y()) / float(CACHE_SIZE);
+ float u1 = u0 + float(rect.width()) / float(CACHE_SIZE);
+ float v1 = v0 + float(rect.height()) / float(CACHE_SIZE);
+ u1 -= 0.5f / float(CACHE_SIZE);
+ v1 -= 0.5f / float(CACHE_SIZE);
+ u0 += 0.5f / float(CACHE_SIZE);
+ v0 += 0.5f / float(CACHE_SIZE);
+ UINT32 rgba = u32Color(prim->color.r * 255, prim->color.g * 255, prim->color.b * 255, prim->color.a * 255);
+
+ float x[4] = { prim->bounds.x0, prim->bounds.x1, prim->bounds.x0, prim->bounds.x1 };
+ float y[4] = { prim->bounds.y0, prim->bounds.y0, prim->bounds.y1, prim->bounds.y1 };
+ float u[4] = { u0, u1, u0, u1 };
+ float v[4] = { v0, v0, v1, v1 };
+
+ if (PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_SWAP_XY)
+ {
+ std::swap(u[1], u[2]);
+ std::swap(v[1], v[2]);
+ }
+
+ if (PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_FLIP_X)
+ {
+ std::swap(u[0], u[1]);
+ std::swap(v[0], v[1]);
+ std::swap(u[2], u[3]);
+ std::swap(v[2], v[3]);
+ }
+
+ if (PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_FLIP_Y)
+ {
+ std::swap(u[0], u[2]);
+ std::swap(v[0], v[2]);
+ std::swap(u[1], u[3]);
+ std::swap(v[1], v[3]);
+ }
+
+ vertex[0].m_x = x[0]; // 0
+ vertex[0].m_y = y[0];
+ vertex[0].m_z = 0;
+ vertex[0].m_rgba = rgba;
+ vertex[0].m_u = u[0];
+ vertex[0].m_v = v[0];
+
+ vertex[1].m_x = x[1]; // 1
+ vertex[1].m_y = y[1];
+ vertex[1].m_z = 0;
+ vertex[1].m_rgba = rgba;
+ vertex[1].m_u = u[1];
+ vertex[1].m_v = v[1];
+
+ vertex[2].m_x = x[3]; // 3
+ vertex[2].m_y = y[3];
+ vertex[2].m_z = 0;
+ vertex[2].m_rgba = rgba;
+ vertex[2].m_u = u[3];
+ vertex[2].m_v = v[3];
+
+ vertex[3].m_x = x[3]; // 3
+ vertex[3].m_y = y[3];
+ vertex[3].m_z = 0;
+ vertex[3].m_rgba = rgba;
+ vertex[3].m_u = u[3];
+ vertex[3].m_v = v[3];
+
+ vertex[4].m_x = x[2]; // 2
+ vertex[4].m_y = y[2];
+ vertex[4].m_z = 0;
+ vertex[4].m_rgba = rgba;
+ vertex[4].m_u = u[2];
+ vertex[4].m_v = v[2];
+
+ vertex[5].m_x = x[0]; // 0
+ vertex[5].m_y = y[0];
+ vertex[5].m_z = 0;
+ vertex[5].m_rgba = rgba;
+ vertex[5].m_u = u[0];
+ vertex[5].m_v = v[0];
+}
+
+void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer)
+{
+ ScreenVertex* vertex = (ScreenVertex*)buffer->data;
+
+ UINT32 rgba = u32Color(prim->color.r * 255, prim->color.g * 255, prim->color.b * 255, prim->color.a * 255);
+
+ vertex[0].m_x = prim->bounds.x0;
+ vertex[0].m_y = prim->bounds.y0;
+ vertex[0].m_z = 0;
+ vertex[0].m_rgba = rgba;
+ vertex[0].m_u = prim->texcoords.tl.u;
+ vertex[0].m_v = prim->texcoords.tl.v;
+
+ vertex[1].m_x = prim->bounds.x1;
+ vertex[1].m_y = prim->bounds.y0;
+ vertex[1].m_z = 0;
+ vertex[1].m_rgba = rgba;
+ vertex[1].m_u = prim->texcoords.tr.u;
+ vertex[1].m_v = prim->texcoords.tr.v;
+
+ vertex[2].m_x = prim->bounds.x1;
+ vertex[2].m_y = prim->bounds.y1;
+ vertex[2].m_z = 0;
+ vertex[2].m_rgba = rgba;
+ vertex[2].m_u = prim->texcoords.br.u;
+ vertex[2].m_v = prim->texcoords.br.v;
+
+ vertex[3].m_x = prim->bounds.x1;
+ vertex[3].m_y = prim->bounds.y1;
+ vertex[3].m_z = 0;
+ vertex[3].m_rgba = rgba;
+ vertex[3].m_u = prim->texcoords.br.u;
+ vertex[3].m_v = prim->texcoords.br.v;
+
+ vertex[4].m_x = prim->bounds.x0;
+ vertex[4].m_y = prim->bounds.y1;
+ vertex[4].m_z = 0;
+ vertex[4].m_rgba = rgba;
+ vertex[4].m_u = prim->texcoords.bl.u;
+ vertex[4].m_v = prim->texcoords.bl.v;
+
+ vertex[5].m_x = prim->bounds.x0;
+ vertex[5].m_y = prim->bounds.y0;
+ vertex[5].m_z = 0;
+ vertex[5].m_rgba = rgba;
+ vertex[5].m_u = prim->texcoords.tl.u;
+ vertex[5].m_v = prim->texcoords.tl.v;
+ bgfx::setVertexBuffer(buffer);
+
+ uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
+ if (video_config.filter == 0)
+ {
+ texture_flags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
+ }
+
+ const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK,
+ prim->texture.width, prim->texture.height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
+
+ bgfx::TextureHandle texture = bgfx::createTexture2D((uint16_t)prim->texture.width, (uint16_t)prim->texture.height, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem);
+
+ bgfx::setTexture(0, m_s_texColor, texture);
+
+ set_bgfx_state(PRIMFLAG_GET_BLENDMODE(prim->flags));
+ bgfx::submit(view, m_progQuadTexture);
+
+ bgfx::destroyTexture(texture);
+}
+
+#define MAX_TEMP_COORDS 100
+
+void renderer_bgfx::put_polygon(const float* coords, UINT32 num_coords, float r, UINT32 rgba, ScreenVertex* vertex)
+{
+ float tempCoords[MAX_TEMP_COORDS * 3];
+ float tempNormals[MAX_TEMP_COORDS * 2];
+
+ rectangle_packer::packed_rectangle& rect = m_hash_to_entry[WHITE_HASH];
+ float u0 = float(rect.x()) / float(CACHE_SIZE);
+ float v0 = float(rect.y()) / float(CACHE_SIZE);
+
+ num_coords = num_coords < MAX_TEMP_COORDS ? num_coords : MAX_TEMP_COORDS;
+
+ for (uint32_t ii = 0, jj = num_coords - 1; ii < num_coords; jj = ii++)
+ {
+ const float* v0 = &coords[jj * 3];
+ const float* v1 = &coords[ii * 3];
+ float dx = v1[0] - v0[0];
+ float dy = v1[1] - v0[1];
+ float d = sqrtf(dx * dx + dy * dy);
+ if (d > 0)
+ {
+ d = 1.0f / d;
+ dx *= d;
+ dy *= d;
+ }
+
+ tempNormals[jj * 2 + 0] = dy;
+ tempNormals[jj * 2 + 1] = -dx;
+ }
+
+ for (uint32_t ii = 0, jj = num_coords - 1; ii < num_coords; jj = ii++)
+ {
+ float dlx0 = tempNormals[jj * 2 + 0];
+ float dly0 = tempNormals[jj * 2 + 1];
+ float dlx1 = tempNormals[ii * 2 + 0];
+ float dly1 = tempNormals[ii * 2 + 1];
+ float dmx = (dlx0 + dlx1) * 0.5f;
+ float dmy = (dly0 + dly1) * 0.5f;
+ float dmr2 = dmx * dmx + dmy * dmy;
+ if (dmr2 > 0.000001f)
+ {
+ float scale = 1.0f / dmr2;
+ if (scale > 10.0f)
+ {
+ scale = 10.0f;
+ }
+
+ dmx *= scale;
+ dmy *= scale;
+ }
+
+ tempCoords[ii * 3 + 0] = coords[ii * 3 + 0] + dmx * r;
+ tempCoords[ii * 3 + 1] = coords[ii * 3 + 1] + dmy * r;
+ tempCoords[ii * 3 + 2] = coords[ii * 3 + 2];
+ }
+
+ int vertIndex = 0;
+ UINT32 trans = rgba & 0x00ffffff;
+ for (uint32_t ii = 0, jj = num_coords - 1; ii < num_coords; jj = ii++)
+ {
+ vertex[vertIndex].m_x = coords[ii * 3 + 0];
+ vertex[vertIndex].m_y = coords[ii * 3 + 1];
+ vertex[vertIndex].m_z = coords[ii * 3 + 2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = coords[jj * 3 + 0];
+ vertex[vertIndex].m_y = coords[jj * 3 + 1];
+ vertex[vertIndex].m_z = coords[jj * 3 + 2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = tempCoords[jj * 3 + 0];
+ vertex[vertIndex].m_y = tempCoords[jj * 3 + 1];
+ vertex[vertIndex].m_z = tempCoords[jj * 3 + 2];
+ vertex[vertIndex].m_rgba = trans;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = tempCoords[jj * 3 + 0];
+ vertex[vertIndex].m_y = tempCoords[jj * 3 + 1];
+ vertex[vertIndex].m_z = tempCoords[jj * 3 + 2];
+ vertex[vertIndex].m_rgba = trans;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = tempCoords[ii * 3 + 0];
+ vertex[vertIndex].m_y = tempCoords[ii * 3 + 1];
+ vertex[vertIndex].m_z = tempCoords[ii * 3 + 2];
+ vertex[vertIndex].m_rgba = trans;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = coords[ii * 3 + 0];
+ vertex[vertIndex].m_y = coords[ii * 3 + 1];
+ vertex[vertIndex].m_z = coords[ii * 3 + 2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+ }
+
+ for (uint32_t ii = 2; ii < num_coords; ++ii)
+ {
+ vertex[vertIndex].m_x = coords[0];
+ vertex[vertIndex].m_y = coords[1];
+ vertex[vertIndex].m_z = coords[2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = coords[(ii - 1) * 3 + 0];
+ vertex[vertIndex].m_y = coords[(ii - 1) * 3 + 1];
+ vertex[vertIndex].m_z = coords[(ii - 1) * 3 + 2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+
+ vertex[vertIndex].m_x = coords[ii * 3 + 0];
+ vertex[vertIndex].m_y = coords[ii * 3 + 1];
+ vertex[vertIndex].m_z = coords[ii * 3 + 2];
+ vertex[vertIndex].m_rgba = rgba;
+ vertex[vertIndex].m_u = u0;
+ vertex[vertIndex].m_v = v0;
+ vertIndex++;
+ }
+}
+
+void renderer_bgfx::put_line(float x0, float y0, float x1, float y1, float r, UINT32 rgba, ScreenVertex* vertex, float fth)
+{
+ float dx = x1 - x0;
+ float dy = y1 - y0;
+ float d = sqrtf(dx * dx + dy * dy);
+ if (d > 0.0001f)
+ {
+ d = 1.0f / d;
+ dx *= d;
+ dy *= d;
+ }
+
+ float nx = dy;
+ float ny = -dx;
+ float verts[4 * 3];
+ r -= fth;
+ r *= 0.5f;
+ if (r < 0.01f)
+ {
+ r = 0.01f;
+ }
+
+ dx *= r;
+ dy *= r;
+ nx *= r;
+ ny *= r;
+
+ verts[0] = x0 - dx - nx;
+ verts[1] = y0 - dy - ny;
+ verts[2] = 0;
+
+ verts[3] = x0 - dx + nx;
+ verts[4] = y0 - dy + ny;
+ verts[5] = 0;
+
+ verts[6] = x1 + dx + nx;
+ verts[7] = y1 + dy + ny;
+ verts[8] = 0;
+
+ verts[9] = x1 + dx - nx;
+ verts[10] = y1 + dy - ny;
+ verts[11] = 0;
+
+ put_polygon(verts, 4, fth, rgba, vertex);
+}
+
+uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a = 255)
+{
+ return (a << 24) | (b << 16) | (g << 8) | r;
+}
+
+//============================================================
+// copyline_palette16
+//============================================================
+
+static inline void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette)
+{
+ for (int x = 0; x < width; x++)
+ {
+ rgb_t srcpixel = palette[*src++];
+ *dst++ = 0xff000000 | (srcpixel.b() << 16) | (srcpixel.g() << 8) | srcpixel.r();
+ }
+}
+
+
+//============================================================
+// copyline_palettea16
+//============================================================
+
+static inline void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette)
+{
+ for (int x = 0; x < width; x++)
+ {
+ rgb_t srcpixel = palette[*src++];
+ *dst++ = (srcpixel.a() << 24) | (srcpixel.b() << 16) | (srcpixel.g() << 8) | srcpixel.r();
+ }
+}
+
+
+//============================================================
+// copyline_rgb32
+//============================================================
+
+static inline void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette)
+{
+ int x;
+
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = 0xff000000 | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = 0xff000000 | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r();
+ }
+ }
+}
+
+
+//============================================================
+// copyline_argb32
+//============================================================
+
+static inline void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette)
+{
+ int x;
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (x = 0; x < width; x++)
+ {
+ rgb_t srcpix = *src++;
+ *dst++ = (srcpix.a() << 24) | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r();
+ }
+ }
+}
+
+static inline UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
+{
+ /* original equations:
+
+ C = Y - 16
+ D = Cb - 128
+ E = Cr - 128
+
+ R = clip(( 298 * C + 409 * E + 128) >> 8)
+ G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
+ B = clip(( 298 * C + 516 * D + 128) >> 8)
+
+ R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8)
+ G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
+ B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8)
+
+ R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8)
+ G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
+ B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8)
+
+ R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8)
+ G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
+ B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8)
+ */
+ int r, g, b, common;
+
+ common = 298 * y - 298 * 16;
+ r = (common + 409 * cr - 409 * 128 + 128) >> 8;
+ g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
+ b = (common + 516 * cb - 516 * 128 + 128) >> 8;
+
+ if (r < 0) r = 0;
+ else if (r > 255) r = 255;
+ if (g < 0) g = 0;
+ else if (g > 255) g = 255;
+ if (b < 0) b = 0;
+ else if (b > 255) b = 255;
+
+ return 0xff000000 | (b << 16) | (g << 8) | r;
+}
+
+//============================================================
+// copyline_yuy16_to_argb
+//============================================================
+
+static inline void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xprescale)
+{
+ int x;
+
+ assert(width % 2 == 0);
+
+ // palette (really RGB map) case
+ if (palette != nullptr)
+ {
+ for (x = 0; x < width / 2; x++)
+ {
+ UINT16 srcpix0 = *src++;
+ UINT16 srcpix1 = *src++;
+ UINT8 cb = srcpix0 & 0xff;
+ UINT8 cr = srcpix1 & 0xff;
+ for (int x2 = 0; x2 < xprescale; x2++)
+ *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
+ for (int x2 = 0; x2 < xprescale; x2++)
+ *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
+ }
+ }
+
+ // direct case
+ else
+ {
+ for (x = 0; x < width; x += 2)
+ {
+ UINT16 srcpix0 = *src++;
+ UINT16 srcpix1 = *src++;
+ UINT8 cb = srcpix0 & 0xff;
+ UINT8 cr = srcpix1 & 0xff;
+ for (int x2 = 0; x2 < xprescale; x2++)
+ *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
+ for (int x2 = 0; x2 < xprescale; x2++)
+ *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
+ }
+ }
+}
+
+const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
+{
+ const bgfx::Memory* mem = bgfx::alloc(width * height * 4);
+ for (int y = 0; y < height; y++)
+ {
+ switch (format)
+ {
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
+ copyline_palette16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette);
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTEA16):
+ copyline_palettea16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette);
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
+ copyline_yuy16_to_argb((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette, 1);
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
+ copyline_argb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette);
+ break;
+ case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
+ copyline_rgb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette);
+ break;
+ default:
+ break;
+ }
+ }
+ return mem;
+}
+
int renderer_bgfx::draw(int update)
{
- //if (has_flags(FI_CHANGED) || (window().width() != m_last_width) || (window().height() != m_last_height))
- // do something
- //clear_flags(FI_CHANGED);
+ int index = window().m_index;
+ // Set view 0 default viewport.
+ osd_dim wdim = window().get_size();
+ int width = wdim.width();
+ int height = wdim.height();
+ if (index == 0)
+ {
+ if ((m_dimensions != osd_dim(width, height))) {
+ bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ m_dimensions = osd_dim(width, height);
+ }
+ }
+ else {
+ if ((m_dimensions != osd_dim(width, height))) {
+ bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ if (bgfx::isValid(fbh))
+ {
+ bgfx::destroyFrameBuffer(fbh);
+ }
+#ifdef OSD_WINDOWS
+ fbh = bgfx::createFrameBuffer(window().m_hwnd, width, height);
+#else
+ fbh = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), width, height);
+#endif
+ bgfx::setViewFrameBuffer(index, fbh);
+ m_dimensions = osd_dim(width, height);
+ bgfx::setViewClear(index
+ , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+ , 0x000000ff
+ , 1.0f
+ , 0
+ );
+ bgfx::touch(index);
+ bgfx::frame();
+ return 0;
+ }
+ }
+ if (index != 0) bgfx::setViewFrameBuffer(index, fbh);
+ bgfx::setViewSeq(index, true);
+ bgfx::setViewRect(index, 0, 0, width, height);
+
+ // Setup view transform.
+ {
+ float view[16];
+ bx::mtxIdentity(view);
- bgfx::setViewClear(0
- , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
+ float left = 0.0f;
+ float top = 0.0f;
+ float right = width;
+ float bottom = height;
+ float proj[16];
+ bx::mtxOrtho(proj, left, right, bottom, top, 0.0f, 100.0f);
+ bgfx::setViewTransform(index, view, proj);
+ }
+ bgfx::setViewClear(index
+ , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x000000ff
, 1.0f
, 0
);
- // Set view 0 default viewport.
-#ifdef OSD_WINDOWS
- RECT client;
- GetClientRect(window().m_hwnd, &client);
- bgfx::setViewRect(0, 0, 0, rect_width(&client), rect_height(&client));
-#else
- bgfx::setViewRect(0, 0, 0, m_blit_dim.width(), m_blit_dim.height());
-#endif
+
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
- bgfx::touch(0);
+ bgfx::touch(index);
window().m_primlist->acquire_lock();
- // now draw
- for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
+ // Mark our texture atlas as dirty if we need to do so
+ bool atlas_valid = update_atlas();
+
+ render_primitive *prim = window().m_primlist->first();
+ while (prim != nullptr)
{
- switch (prim->type)
+ UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
+
+ bgfx::TransientVertexBuffer buffer;
+ allocate_buffer(prim, blend, &buffer);
+
+ buffer_status status = buffer_primitives(index, atlas_valid, &prim, &buffer);
+
+ if (status != BUFFER_EMPTY)
+ {
+ set_bgfx_state(blend);
+ bgfx::setVertexBuffer(&buffer);
+ bgfx::setTexture(0, m_s_texColor, m_texture_cache);
+ bgfx::submit(index, m_progQuadTexture);
+ }
+
+ if (status != BUFFER_DONE && status != BUFFER_PRE_FLUSH)
+ {
+ prim = prim->next();
+ }
+ }
+
+ window().m_primlist->release_lock();
+ // Advance to next frame. Rendering thread will be kicked to
+ // process submitted rendering primitives.
+ if (index==0) bgfx::frame();
+
+ return 0;
+}
+
+renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer)
+{
+ int vertices = 0;
+
+ UINT32 blend = PRIMFLAG_GET_BLENDMODE((*prim)->flags);
+ while (*prim != nullptr)
+ {
+ switch ((*prim)->type)
{
- /**
- * Try to stay in one Begin/End block as long as possible,
- * since entering and leaving one is most expensive..
- */
case render_primitive::LINE:
- // check if it's really a point
-/*
- if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0))
- {
- curPrimitive=GL_POINTS;
- } else {
- curPrimitive=GL_LINES;
- }
-
- if(pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
- {
- glEnd();
- pendingPrimitive=GL_NO_PRIMITIVE;
- }
-
- if ( pendingPrimitive==GL_NO_PRIMITIVE )
- {
- set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
- }
-
- glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
-
- if(pendingPrimitive!=curPrimitive)
- {
- glBegin(curPrimitive);
- pendingPrimitive=curPrimitive;
- }
-
- // check if it's really a point
- if (curPrimitive==GL_POINTS)
- {
- glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
- }
- else
- {
- glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
- glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs);
- }*/
+ put_line((*prim)->bounds.x0, (*prim)->bounds.y0, (*prim)->bounds.x1, (*prim)->bounds.y1, 1.0f, u32Color((*prim)->color.r * 255, (*prim)->color.g * 255, (*prim)->color.b * 255, (*prim)->color.a * 255), (ScreenVertex*)buffer->data + vertices, 1.0f);
+ vertices += 30;
break;
case render_primitive::QUAD:
-/*
- if(pendingPrimitive!=GL_NO_PRIMITIVE)
- {
- glEnd();
- pendingPrimitive=GL_NO_PRIMITIVE;
- }
+ if ((*prim)->texture.base == nullptr)
+ {
+ put_packed_quad(*prim, WHITE_HASH, (ScreenVertex*)buffer->data + vertices);
+ vertices += 6;
+ }
+ else
+ {
+ const UINT32 hash = get_texture_hash(*prim);
+ if (atlas_valid && (*prim)->packable(PACKABLE_SIZE) && hash != 0 && m_hash_to_entry[hash].hash())
+ {
+ put_packed_quad(*prim, hash, (ScreenVertex*)buffer->data + vertices);
+ vertices += 6;
+ }
+ else
+ {
+ if (vertices > 0)
+ {
+ return BUFFER_PRE_FLUSH;
+ }
+ render_textured_quad(view, *prim, buffer);
+ return BUFFER_EMPTY;
+ }
+ }
+ break;
+
+ default:
+ // Unhandled
+ break;
+ }
+
+ if ((*prim)->next() != nullptr && PRIMFLAG_GET_BLENDMODE((*prim)->next()->flags) != blend)
+ {
+ break;
+ }
+
+ *prim = (*prim)->next();
+ }
+
+ if (*prim == nullptr)
+ {
+ return BUFFER_DONE;
+ }
+ if (vertices == 0)
+ {
+ return BUFFER_EMPTY;
+ }
+ return BUFFER_FLUSH;
+}
+
+void renderer_bgfx::set_bgfx_state(UINT32 blend)
+{
+ uint64_t flags = BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_ALWAYS;
+
+ switch (blend)
+ {
+ case BLENDMODE_NONE:
+ bgfx::setState(flags);
+ break;
+ case BLENDMODE_ALPHA:
+ bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA));
+ break;
+ case BLENDMODE_RGB_MULTIPLY:
+ bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO));
+ break;
+ case BLENDMODE_ADD:
+ bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE));
+ break;
+ }
+}
- glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
+bool renderer_bgfx::update_atlas()
+{
+ bool atlas_dirty = check_for_dirty_atlas();
+
+ if (atlas_dirty)
+ {
+ m_hash_to_entry.clear();
- set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
+ std::vector<std::vector<rectangle_packer::packed_rectangle>> packed;
+ if (m_packer.pack(m_texinfo, packed, CACHE_SIZE))
+ {
+ process_atlas_packs(packed);
+ }
+ else
+ {
+ packed.clear();
- texture = texture_update(window, prim, 0);
+ m_texinfo.clear();
+ m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
+ m_packer.pack(m_texinfo, packed, CACHE_SIZE);
+ process_atlas_packs(packed);
- sdl->texVerticex[0]=prim->bounds.x0 + hofs;
- sdl->texVerticex[1]=prim->bounds.y0 + vofs;
- sdl->texVerticex[2]=prim->bounds.x1 + hofs;
- sdl->texVerticex[3]=prim->bounds.y0 + vofs;
- sdl->texVerticex[4]=prim->bounds.x1 + hofs;
- sdl->texVerticex[5]=prim->bounds.y1 + vofs;
- sdl->texVerticex[6]=prim->bounds.x0 + hofs;
- sdl->texVerticex[7]=prim->bounds.y1 + vofs;
+ return false;
+ }
+ }
+ return true;
+}
- glDrawArrays(GL_QUADS, 0, 4);
-*/
+void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed)
+{
+ for (std::vector<rectangle_packer::packed_rectangle> pack : packed)
+ {
+ for (rectangle_packer::packed_rectangle rect : pack)
+ {
+ if (rect.hash() == 0xffffffff)
+ {
+ continue;
+ }
+ m_hash_to_entry[rect.hash()] = rect;
+ const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base());
+ bgfx::updateTexture2D(m_texture_cache, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem);
+ }
+ }
+}
+
+UINT32 renderer_bgfx::get_texture_hash(render_primitive *prim)
+{
+#if GIBBERISH
+ UINT32 xor_value = 0x87;
+ UINT32 hash = 0xdabeefed;
+
+ int bpp = 2;
+ UINT32 format = PRIMFLAG_GET_TEXFORMAT(prim->flags);
+ if (format == TEXFORMAT_ARGB32 || format == TEXFORMAT_RGB32)
+ {
+ bpp = 4;
+ }
+
+ for (int y = 0; y < prim->texture.height; y++)
+ {
+ UINT8 *base = reinterpret_cast<UINT8*>(prim->texture.base) + prim->texture.rowpixels * y;
+ for (int x = 0; x < prim->texture.width * bpp; x++)
+ {
+ hash += base[x] ^ xor_value;
+ }
+ }
+ return hash;
+#else
+ return (reinterpret_cast<size_t>(prim->texture.base)) & 0xffffffff;
+#endif
+}
+
+bool renderer_bgfx::check_for_dirty_atlas()
+{
+ bool atlas_dirty = false;
+
+ std::map<UINT32, rectangle_packer::packable_rectangle> acquired_infos;
+ for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next())
+ {
+ bool pack = prim->packable(PACKABLE_SIZE);
+ if (prim->type == render_primitive::QUAD && prim->texture.base != nullptr && pack)
+ {
+ const UINT32 hash = get_texture_hash(prim);
+ // If this texture is packable and not currently in the atlas, prepare the texture for putting in the atlas
+ if ((hash != 0 && m_hash_to_entry[hash].hash() == 0 && acquired_infos[hash].hash() == 0)
+ || (hash != 0 && m_hash_to_entry[hash].hash() != hash && acquired_infos[hash].hash() == 0))
+ { // Create create the texture and mark the atlas dirty
+ atlas_dirty = true;
+
+ m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim->flags & PRIMFLAG_TEXFORMAT_MASK,
+ prim->texture.width, prim->texture.height,
+ prim->texture.rowpixels, prim->texture.palette, prim->texture.base));
+ acquired_infos[hash] = m_texinfo[m_texinfo.size() - 1];
+ }
+ }
+ }
+
+ if (m_texinfo.size() == 1)
+ {
+ atlas_dirty = true;
+ }
+
+ return atlas_dirty;
+}
+
+void renderer_bgfx::allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer)
+{
+ int vertices = 0;
+
+ bool mode_switched = false;
+ while (prim != nullptr && !mode_switched)
+ {
+ switch (prim->type)
+ {
+ case render_primitive::LINE:
+ vertices += 30;
break;
+ case render_primitive::QUAD:
+ if (!prim->packable(PACKABLE_SIZE))
+ {
+ if (prim->texture.base == nullptr)
+ {
+ vertices += 6;
+ }
+ else
+ {
+ mode_switched = true;
+ if (vertices == 0)
+ {
+ vertices += 6;
+ }
+ }
+ }
+ else
+ {
+ vertices += 6;
+ }
+ break;
default:
- throw emu_fatalerror("Unexpected render_primitive type");
+ // Do nothing
+ break;
}
- }
- window().m_primlist->release_lock();
- // Advance to next frame. Rendering thread will be kicked to
- // process submitted rendering primitives.
- bgfx::frame();
+ prim = prim->next();
- return 0;
+ if (prim != nullptr && PRIMFLAG_GET_BLENDMODE(prim->flags) != blend)
+ {
+ mode_switched = true;
+ }
+ }
+
+ if (vertices > 0 && bgfx::checkAvailTransientVertexBuffer(vertices, ScreenVertex::ms_decl))
+ {
+ bgfx::allocTransientVertexBuffer(buffer, vertices, ScreenVertex::ms_decl);
+ }
}
diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h
new file mode 100644
index 00000000000..86619eab718
--- /dev/null
+++ b/src/osd/modules/render/drawbgfx.h
@@ -0,0 +1,108 @@
+#pragma once
+
+#ifndef __RENDER_BGFX__
+#define __RENDER_BGFX__
+
+#include <map>
+#include <vector>
+
+#include "binpacker.h"
+
+/* sdl_info is the information about SDL for the current screen */
+class renderer_bgfx : public osd_renderer
+{
+public:
+ renderer_bgfx(osd_window *w)
+ : osd_renderer(w, FLAG_NONE)
+ , m_dimensions(0, 0)
+ {
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+#ifdef OSD_SDL
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+#else
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+#endif
+ virtual void destroy() override;
+ virtual render_primitive_list *get_primitives() override
+ {
+ osd_dim wdim = window().get_size();
+ window().target()->set_bounds(wdim.width(), wdim.height(), window().aspect());
+ return &window().target()->get_primitives();
+ }
+
+private:
+ struct ScreenVertex
+ {
+ float m_x;
+ float m_y;
+ float m_z;
+ UINT32 m_rgba;
+ float m_u;
+ float m_v;
+
+ static void init()
+ {
+ ms_decl.begin()
+ .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
+ .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
+ .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+ .end();
+ }
+
+ static bgfx::VertexDecl ms_decl;
+ };
+
+ void allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer);
+ enum buffer_status
+ {
+ BUFFER_PRE_FLUSH,
+ BUFFER_FLUSH,
+ BUFFER_EMPTY,
+ BUFFER_DONE
+ };
+ buffer_status buffer_primitives(int view, bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer);
+
+ void render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer);
+
+ void put_packed_quad(render_primitive *prim, UINT32 hash, ScreenVertex* vertex);
+ void put_polygon(const float* coords, UINT32 num_coords, float r, UINT32 rgba, ScreenVertex* vertex);
+ void put_line(float x0, float y0, float x1, float y1, float r, UINT32 rgba, ScreenVertex* vertex, float fth = 1.0f);
+
+ void set_bgfx_state(UINT32 blend);
+
+ uint32_t u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a);
+
+ bool check_for_dirty_atlas();
+ bool update_atlas();
+ void process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed);
+ const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
+ UINT32 get_texture_hash(render_primitive *prim);
+
+ bgfx::ProgramHandle loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName);
+ bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName);
+
+ bgfx::ProgramHandle m_progQuad;
+ bgfx::ProgramHandle m_progQuadTexture;
+ bgfx::UniformHandle m_s_texColor;
+ bgfx::FrameBufferHandle fbh;
+ bgfx::TextureHandle m_texture_cache;
+
+ // Original display_mode
+ osd_dim m_dimensions;
+
+ std::map<UINT32, rectangle_packer::packed_rectangle> m_hash_to_entry;
+ std::vector<rectangle_packer::packable_rectangle> m_texinfo;
+ rectangle_packer m_packer;
+
+ uint32_t m_white[16*16];
+ enum : uint16_t { CACHE_SIZE = 1024 };
+ enum : uint32_t { PACKABLE_SIZE = 128 };
+ enum : UINT32 { WHITE_HASH = 0x87654321 };
+};
+
+#endif
diff --git a/src/osd/modules/render/drawdd.cpp b/src/osd/modules/render/drawdd.cpp
deleted file mode 100644
index fb82dff3c1f..00000000000
--- a/src/osd/modules/render/drawdd.cpp
+++ /dev/null
@@ -1,1317 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// drawdd.c - Win32 DirectDraw implementation
-//
-//============================================================
-
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <mmsystem.h>
-#include <ddraw.h>
-#undef interface
-
-// MAME headers
-#include "emu.h"
-#include "render.h"
-#include "rendutil.h"
-#include "rendersw.inc"
-
-// MAMEOS headers
-#include "winmain.h"
-#include "window.h"
-
-
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-typedef HRESULT (WINAPI *directdrawcreateex_ptr)(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter);
-typedef HRESULT (WINAPI *directdrawenumerateex_ptr)(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
-
-
-/* dd_info is the information about DirectDraw for the current screen */
-class renderer_dd : public osd_renderer
-{
-public:
- renderer_dd(osd_window *window)
- : osd_renderer(window, FLAG_NONE),
- width(0),
- height(0),
- refresh(0),
- //adapter(0),
- adapter_ptr(NULL),
- clearouter(0),
- blitwidth(0), blitheight(0),
- //lastdest
- ddraw(NULL),
- primary(NULL),
- back(NULL),
- blit(NULL),
- clipper(NULL),
- gamma(NULL),
- //DDSURFACEDESC2 primarydesc;
- //DDSURFACEDESC2 blitdesc;
- //DDSURFACEDESC2 origmode;
- //ddcaps(0),
- //helcaps(0),
- membuffer(NULL),
- membuffersize(0)
- { }
-
- virtual ~renderer_dd() { }
-
- virtual int create() override;
- virtual render_primitive_list *get_primitives() override;
- virtual int draw(const int update) override;
- virtual void save() override {};
- virtual void record() override {};
- virtual void toggle_fsfx() override {};
- virtual void destroy() override;
-
- int width, height; // current width, height
- int refresh; // current refresh rate
-
-private:
-
- inline void update_outer_rects();
-
- // surface management
- int ddraw_create();
- int ddraw_create_surfaces();
- void ddraw_delete();
- void ddraw_delete_surfaces();
- int ddraw_verify_caps();
- int ddraw_test_cooperative();
- HRESULT create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type);
- int create_clipper();
-
- // drawing helpers
- void compute_blit_surface_size();
- void blit_to_primary(int srcwidth, int srcheight);
-
- // video modes
- int config_adapter_mode();
- void get_adapter_for_monitor(osd_monitor_info *monitor);
- void pick_best_mode();
-
- // various
- void calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins);
-
-
- GUID adapter; // current display adapter
- GUID * adapter_ptr; // pointer to current display adapter
- int clearouter; // clear the outer areas?
-
- INT32 blitwidth, blitheight; // current blit width/height values
- RECT lastdest; // last destination rectangle
-
- IDirectDraw7 * ddraw; // pointer to the DirectDraw object
- IDirectDrawSurface7 * primary; // pointer to the primary surface object
- IDirectDrawSurface7 * back; // pointer to the back buffer surface object
- IDirectDrawSurface7 * blit; // pointer to the blit surface object
- IDirectDrawClipper * clipper; // pointer to the clipper object
- IDirectDrawGammaControl *gamma; // pointer to the gamma control object
-
- DDSURFACEDESC2 primarydesc; // description of the primary surface
- DDSURFACEDESC2 blitdesc; // description of the blitting surface
- DDSURFACEDESC2 origmode; // original video mode
-
- DDCAPS ddcaps; // capabilities of the device
- DDCAPS helcaps; // capabilities of the hardware
-
- UINT8 * membuffer; // memory buffer for complex rendering
- UINT32 membuffersize; // current size of the memory buffer
-};
-
-
-/* monitor_enum_info holds information during a monitor enumeration */
-struct monitor_enum_info
-{
- osd_monitor_info * monitor; // pointer to monitor we want
- GUID guid; // GUID of the one we found
- GUID * guid_ptr; // pointer to our GUID
- int foundit; // TRUE if we found what we wanted
-};
-
-
-/* mode_enum_info holds information during a display mode enumeration */
-struct mode_enum_info
-{
- renderer_dd * renderer;
- osd_window * window;
- INT32 minimum_width, minimum_height;
- INT32 target_width, target_height;
- double target_refresh;
- float best_score;
-};
-
-
-
-//============================================================
-// GLOBALS
-//============================================================
-
-static HINSTANCE dllhandle;
-static directdrawcreateex_ptr directdrawcreateex;
-static directdrawenumerateex_ptr directdrawenumerateex;
-
-
-
-//============================================================
-// INLINES
-//============================================================
-
-inline void renderer_dd::update_outer_rects()
-{
- clearouter = (back != NULL) ? 3 : 1;
-}
-
-
-static inline int better_mode(int width0, int height0, int width1, int height1, float desired_aspect)
-{
- float aspect0 = (float)width0 / (float)height0;
- float aspect1 = (float)width1 / (float)height1;
- return (fabs(desired_aspect - aspect0) < fabs(desired_aspect - aspect1)) ? 0 : 1;
-}
-
-
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-// core functions
-static void drawdd_exit(void);
-
-
-
-//============================================================
-// drawnone_create
-//============================================================
-
-static osd_renderer *drawdd_create(osd_window *window)
-{
- return global_alloc(renderer_dd(window));
-}
-
-
-//============================================================
-// drawdd_init
-//============================================================
-
-int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks)
-{
- // dynamically grab the create function from ddraw.dll
- dllhandle = LoadLibrary(TEXT("ddraw.dll"));
- if (dllhandle == NULL)
- {
- osd_printf_verbose("DirectDraw: Unable to access ddraw.dll\n");
- return 1;
- }
-
- // import the create function
- directdrawcreateex = (directdrawcreateex_ptr)GetProcAddress(dllhandle, "DirectDrawCreateEx");
- if (directdrawcreateex == NULL)
- {
- osd_printf_verbose("DirectDraw: Unable to find DirectDrawCreateEx\n");
- FreeLibrary(dllhandle);
- dllhandle = NULL;
- return 1;
- }
-
- // import the enumerate function
- directdrawenumerateex = (directdrawenumerateex_ptr)GetProcAddress(dllhandle, "DirectDrawEnumerateExA");
- if (directdrawenumerateex == NULL)
- {
- osd_printf_verbose("DirectDraw: Unable to find DirectDrawEnumerateExA\n");
- FreeLibrary(dllhandle);
- dllhandle = NULL;
- return 1;
- }
-
- // fill in the callbacks
- memset(callbacks, 0, sizeof(*callbacks));
- callbacks->exit = drawdd_exit;
- callbacks->create = drawdd_create;
-
- osd_printf_verbose("DirectDraw: Using DirectDraw 7\n");
- return 0;
-}
-
-
-
-//============================================================
-// drawdd_exit
-//============================================================
-
-static void drawdd_exit(void)
-{
- if (dllhandle != NULL)
- FreeLibrary(dllhandle);
-}
-
-
-
-//============================================================
-// drawdd_window_init
-//============================================================
-
-int renderer_dd::create()
-{
- // configure the adapter for the mode we want
- if (config_adapter_mode())
- {
- osd_printf_error("Unable to configure adapter.\n");
- goto error;
- }
-
- // create the ddraw object
- if (ddraw_create())
- {
- osd_printf_error("Unable to create ddraw object.\n");
- goto error;
- }
-
- return 0;
-
-error:
- destroy();
- osd_printf_error("Unable to initialize DirectDraw.\n");
- return 1;
-}
-
-
-
-//============================================================
-// drawdd_window_destroy
-//============================================================
-
-void renderer_dd::destroy()
-{
- // delete the ddraw object
- ddraw_delete();
-}
-
-
-
-//============================================================
-// drawdd_window_get_primitives
-//============================================================
-
-render_primitive_list *renderer_dd::get_primitives()
-{
- compute_blit_surface_size();
- window().target()->set_bounds(blitwidth, blitheight, 0);
- window().target()->set_max_update_rate((refresh == 0) ? origmode.dwRefreshRate : refresh);
-
- return &window().target()->get_primitives();
-}
-
-
-
-//============================================================
-// drawdd_window_draw
-//============================================================
-
-int renderer_dd::draw(const int update)
-{
- render_primitive *prim;
- int usemembuffer = FALSE;
- HRESULT result;
-
- // if we're updating, remember to erase the outer stuff
- if (update)
- update_outer_rects();
-
- // if we have a ddraw object, check the cooperative level
- if (ddraw_test_cooperative())
- return 1;
-
- // get the size; if we're too small, delete the existing surfaces
- if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight)
- ddraw_delete_surfaces();
-
- // if we need to create surfaces, do it now
- if (blit == NULL && ddraw_create_surfaces() != 0)
- return 1;
-
- // select our surface and lock it
- result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL);
- if (result == DDERR_SURFACELOST)
- {
- osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
- ddraw_delete_surfaces();
- return 1;
- }
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
- return 1;
- }
-
- // render to it
- window().m_primlist->acquire_lock();
-
- // scan the list of primitives for tricky stuff
- for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
- if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
- (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
- {
- usemembuffer = TRUE;
- break;
- }
-
- // if we're using the memory buffer, draw offscreen first and then copy
- if (usemembuffer)
- {
- int x, y;
-
- // based on the target format, use one of our standard renderers
- switch (blitdesc.ddpfPixelFormat.dwRBitMask)
- {
- case 0x00ff0000: software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break;
- case 0x000000ff: software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break;
- case 0xf800: software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break;
- case 0x7c00: software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break;
- default:
- osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
- break;
- }
-
- // handle copying to both 16bpp and 32bpp destinations
- for (y = 0; y < blitheight; y++)
- {
- if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
- {
- UINT32 *src = (UINT32 *)membuffer + y * blitwidth;
- UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
- for (x = 0; x < blitwidth; x++)
- *dst++ = *src++;
- }
- else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
- {
- UINT16 *src = (UINT16 *)membuffer + y * blitwidth;
- UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
- for (x = 0; x < blitwidth; x++)
- *dst++ = *src++;
- }
- }
-
- }
-
- // otherwise, draw directly
- else
- {
- // based on the target format, use one of our standard renderers
- switch (blitdesc.ddpfPixelFormat.dwRBitMask)
- {
- case 0x00ff0000: software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
- case 0x000000ff: software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
- case 0xf800: software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
- case 0x7c00: software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
- default:
- osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
- break;
- }
- }
- window().m_primlist->release_lock();
-
- // unlock and blit
- result = IDirectDrawSurface7_Unlock(blit, NULL);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);
-
- // sync to VBLANK
- if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL))
- {
- result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
- }
-
- // complete the blitting
- blit_to_primary(blitwidth, blitheight);
- return 0;
-}
-
-
-
-//============================================================
-// ddraw_create
-//============================================================
-
-int renderer_dd::ddraw_create()
-{
- HRESULT result;
- int verify;
-
- // if a device exists, free it
- if (ddraw != NULL)
- ddraw_delete();
-
- // create the DirectDraw object
- result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
- goto error;
- }
-
- // verify the caps
- verify = ddraw_verify_caps();
- if (verify == 2)
- {
- osd_printf_error("DirectDraw: Error - Device does not meet minimum requirements for DirectDraw rendering\n");
- goto error;
- }
- if (verify == 1)
- osd_printf_verbose("DirectDraw: Warning - Device may not perform well for DirectDraw rendering\n");
-
- // set the cooperative level
- // for non-window modes, we will use full screen here
- result = IDirectDraw7_SetCooperativeLevel(ddraw, win_window_list->m_hwnd, DDSCL_SETFOCUSWINDOW);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(FOCUSWINDOW) call\n", (int)result);
- goto error;
- }
- result = IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_SETDEVICEWINDOW | (window().fullscreen() ? DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE : DDSCL_NORMAL));
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(DEVICEWINDOW) call\n", (int)result);
- goto error;
- }
-
- // full screen mode: set the resolution
- if (window().fullscreen() && video_config.switchres)
- {
- result = IDirectDraw7_SetDisplayMode(ddraw, width, height, 32, refresh, 0);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X attempting to set video mode %dx%d@%d call\n", (int)result, width, height, refresh);
- goto error;
- }
- }
-
- return ddraw_create_surfaces();
-
-error:
- ddraw_delete();
- return 1;
-}
-
-
-
-//============================================================
-// ddraw_create_surfaces
-//============================================================
-
-int renderer_dd::ddraw_create_surfaces()
-{
- HRESULT result;
-
- // make a description of the primary surface
- memset(&primarydesc, 0, sizeof(primarydesc));
- primarydesc.dwSize = sizeof(primarydesc);
- primarydesc.dwFlags = DDSD_CAPS;
- primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- // for triple-buffered full screen mode, allocate flipping surfaces
- if (window().fullscreen() && video_config.triplebuf)
- {
- primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
- primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
- primarydesc.dwBackBufferCount = 2;
- }
-
- // create the primary surface and report errors
- result = create_surface(&primarydesc, &primary, "primary");
- if (result != DD_OK) goto error;
-
- // full screen mode: get the back surface
- back = NULL;
- if (window().fullscreen() && video_config.triplebuf)
- {
- DDSCAPS2 caps = { DDSCAPS_BACKBUFFER };
- result = IDirectDrawSurface7_GetAttachedSurface(primary, &caps, &back);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result);
- goto error;
- }
- }
-
- // now make a description of our blit surface, based on the primary surface
- if (blitwidth == 0 || blitheight == 0)
- compute_blit_surface_size();
- blitdesc = primarydesc;
- blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
- blitdesc.dwWidth = blitwidth;
- blitdesc.dwHeight = blitheight;
- blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
-
- // then create the blit surface, fall back to system memory if video mem doesn't work
- result = create_surface(&blitdesc, &blit, "blit");
- if (result != DD_OK)
- {
- blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
- result = create_surface(&blitdesc, &blit, "blit");
- }
- if (result != DD_OK) goto error;
-
- // create a memory buffer for offscreen drawing
- if (membuffersize < blitwidth * blitheight * 4)
- {
- membuffersize = blitwidth * blitheight * 4;
- global_free_array(membuffer);
- membuffer = global_alloc_array(UINT8, membuffersize);
- }
- if (membuffer == NULL)
- goto error;
-
- // create a clipper for windowed mode
- if (!window().fullscreen() && create_clipper())
- goto error;
-
- // full screen mode: set the gamma
- if (window().fullscreen())
- {
- // only set the gamma if it's not 1.0f
- windows_options &options = downcast<windows_options &>(window().machine().options());
- float brightness = options.full_screen_brightness();
- float contrast = options.full_screen_contrast();
- float fgamma = options.full_screen_gamma();
- if (brightness != 1.0f || contrast != 1.0f || fgamma != 1.0f)
- {
- // see if we can get a GammaControl object
- result = IDirectDrawSurface_QueryInterface(primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&gamma);
- if (result != DD_OK)
- {
- osd_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n");
- this->gamma = NULL;
- }
-
- // proceed if we can
- if (this->gamma != NULL)
- {
- DDGAMMARAMP ramp;
- int i;
-
- // create a standard ramp and set it
- for (i = 0; i < 256; i++)
- ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, fgamma) << 8;
-
- // attempt to set it
- result = IDirectDrawGammaControl_SetGammaRamp(this->gamma, 0, &ramp);
- if (result != DD_OK)
- osd_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result);
- }
- }
- }
-
- // force some updates
- update_outer_rects();
- return 0;
-
-error:
- ddraw_delete_surfaces();
- return 1;
-}
-
-
-
-//============================================================
-// ddraw_delete
-//============================================================
-
-void renderer_dd::ddraw_delete()
-{
- // free surfaces
- ddraw_delete_surfaces();
-
- // restore resolutions
- if (ddraw != NULL)
- IDirectDraw7_RestoreDisplayMode(ddraw);
-
- // reset cooperative level
- if (ddraw != NULL && window().m_hwnd != NULL)
- IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_NORMAL);
-
- // release the DirectDraw object itself
- if (ddraw != NULL)
- IDirectDraw7_Release(ddraw);
- ddraw = NULL;
-}
-
-
-
-//============================================================
-// ddraw_delete_surfaces
-//============================================================
-
-void renderer_dd::ddraw_delete_surfaces()
-{
- // release the gamma control
- if (gamma != NULL)
- IDirectDrawGammaControl_Release(gamma);
- gamma = NULL;
-
- // release the clipper
- if (clipper != NULL)
- IDirectDrawClipper_Release(clipper);
- clipper = NULL;
-
- // free the memory buffer
- global_free_array(membuffer);
- membuffer = NULL;
- membuffersize = 0;
-
- // release the blit surface
- if (blit != NULL)
- IDirectDrawSurface7_Release(blit);
- blit = NULL;
-
- // release the back surface
- if (back != NULL)
- IDirectDrawSurface7_Release(back);
- back = NULL;
-
- // release the primary surface
- if (primary != NULL)
- IDirectDrawSurface7_Release(primary);
- primary = NULL;
-}
-
-
-
-//============================================================
-// ddraw_verify_caps
-//============================================================
-
-int renderer_dd::ddraw_verify_caps()
-{
- int retval = 0;
- HRESULT result;
-
- // get the capabilities
- ddcaps.dwSize = sizeof(ddcaps);
- helcaps.dwSize = sizeof(helcaps);
- result = IDirectDraw7_GetCaps(ddraw, &ddcaps, &helcaps);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_GetCaps call\n", (int)result);
- return 1;
- }
-
- // determine if hardware stretching is available
- if ((ddcaps.dwCaps & DDCAPS_BLTSTRETCH) == 0)
- {
- osd_printf_verbose("DirectDraw: Warning - Device does not support hardware stretching\n");
- retval = 1;
- }
-
- return retval;
-}
-
-
-
-//============================================================
-// ddraw_test_cooperative
-//============================================================
-
-int renderer_dd::ddraw_test_cooperative()
-{
- HRESULT result;
-
- // check our current status; if we lost the device, punt to GDI
- result = IDirectDraw7_TestCooperativeLevel(ddraw);
- switch (result)
- {
- // punt to GDI if someone else has exclusive mode
- case DDERR_NOEXCLUSIVEMODE:
- case DDERR_EXCLUSIVEMODEALREADYSET:
- ddraw_delete_surfaces();
- return 1;
-
- // if we're ok, but we don't have a primary surface, create one
- default:
- case DD_OK:
- if (primary == NULL)
- return ddraw_create_surfaces();
- return 0;
- }
-}
-
-
-
-//============================================================
-// create_surface
-//============================================================
-
-HRESULT renderer_dd::create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type)
-{
- HRESULT result;
-
- // create the surface as requested
- result = IDirectDraw7_CreateSurface(ddraw, desc, surface, NULL);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X creating %s surface\n", (int)result, type);
- return result;
- }
-
- // get a description of the primary surface
- result = IDirectDrawSurface7_GetSurfaceDesc(*surface, desc);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X getting %s surface desciption\n", (int)result, type);
- IDirectDrawSurface7_Release(*surface);
- *surface = NULL;
- return result;
- }
-
- // print out the good stuff
- osd_printf_verbose("DirectDraw: %s surface created: %dx%dx%d (R=%08X G=%08X B=%08X)\n",
- type,
- (int)desc->dwWidth,
- (int)desc->dwHeight,
- (int)desc->ddpfPixelFormat.dwRGBBitCount,
- (UINT32)desc->ddpfPixelFormat.dwRBitMask,
- (UINT32)desc->ddpfPixelFormat.dwGBitMask,
- (UINT32)desc->ddpfPixelFormat.dwBBitMask);
- return result;
-}
-
-
-
-//============================================================
-// create_clipper
-//============================================================
-
-int renderer_dd::create_clipper()
-{
- HRESULT result;
-
- // create a clipper for the primary surface
- result = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X creating clipper\n", (int)result);
- return 1;
- }
-
- // set the clipper's hwnd
- result = IDirectDrawClipper_SetHWnd(clipper, 0, window().m_hwnd);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X setting clipper hwnd\n", (int)result);
- return 1;
- }
-
- // set the clipper on the primary surface
- result = IDirectDrawSurface7_SetClipper(primary, clipper);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X setting clipper on primary surface\n", (int)result);
- return 1;
- }
- return 0;
-}
-
-
-
-//============================================================
-// compute_blit_surface_size
-//============================================================
-
-void renderer_dd::compute_blit_surface_size()
-{
- INT32 newwidth, newheight;
- int xscale, yscale;
- RECT client;
-
- // start with the minimum size
- window().target()->compute_minimum_size(newwidth, newheight);
-
- // get the window's client rectangle
- GetClientRect(window().m_hwnd, &client);
-
- // hardware stretch case: apply prescale
- if (video_config.hwstretch)
- {
- int prescale = (window().prescale() < 1) ? 1 : window().prescale();
-
- // clamp the prescale to something smaller than the target bounds
- xscale = prescale;
- while (xscale > 1 && newwidth * xscale > rect_width(&client))
- xscale--;
- yscale = prescale;
- while (yscale > 1 && newheight * yscale > rect_height(&client))
- yscale--;
- }
-
- // non stretch case
- else
- {
- INT32 target_width = rect_width(&client);
- INT32 target_height = rect_height(&client);
- float desired_aspect = 1.0f;
-
- // compute the appropriate visible area if we're trying to keepaspect
- if (video_config.keepaspect)
- {
- osd_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
- window().target()->compute_visible_area(target_width, target_height, monitor->aspect(), window().target()->orientation(), target_width, target_height);
- desired_aspect = (float)target_width / (float)target_height;
- }
-
- // compute maximum integral scaling to fit the window
- xscale = (target_width + 2) / newwidth;
- yscale = (target_height + 2) / newheight;
-
- // try a little harder to keep the aspect ratio if desired
- if (video_config.keepaspect)
- {
- // if we could stretch more in the X direction, and that makes a better fit, bump the xscale
- while (newwidth * (xscale + 1) <= rect_width(&client) &&
- better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
- xscale++;
-
- // if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
- while (newheight * (yscale + 1) <= rect_height(&client) &&
- better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
- yscale++;
-
- // now that we've maxed out, see if backing off the maximally stretched one makes a better fit
- if (rect_width(&client) - newwidth * xscale < rect_height(&client) - newheight * yscale)
- {
- while (xscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect))
- xscale--;
- }
- else
- {
- while (yscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect))
- yscale--;
- }
- }
- }
-
- // ensure at least a scale factor of 1
- if (xscale == 0) xscale = 1;
- if (yscale == 0) yscale = 1;
-
- // apply the final scale
- newwidth *= xscale;
- newheight *= yscale;
- if (newwidth != blitwidth || newheight != blitheight)
- {
- // force some updates
- update_outer_rects();
- osd_printf_verbose("DirectDraw: New blit size = %dx%d\n", newwidth, newheight);
- }
- blitwidth = newwidth;
- blitheight = newheight;
-}
-
-
-
-//============================================================
-// calc_fullscreen_margins
-//============================================================
-
-void renderer_dd::calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins)
-{
- margins->left = 0;
- margins->top = 0;
- margins->right = desc_width;
- margins->bottom = desc_height;
-
- if (window().win_has_menu())
- {
- static int height_with_menubar = 0;
- if (height_with_menubar == 0)
- {
- RECT with_menu = { 100, 100, 200, 200 };
- RECT without_menu = { 100, 100, 200, 200 };
- AdjustWindowRect(&with_menu, WS_OVERLAPPED, TRUE);
- AdjustWindowRect(&without_menu, WS_OVERLAPPED, FALSE);
- height_with_menubar = (with_menu.bottom - with_menu.top) - (without_menu.bottom - without_menu.top);
- }
- margins->top = height_with_menubar;
- }
-}
-
-
-
-//============================================================
-// blit_to_primary
-//============================================================
-
-void renderer_dd::blit_to_primary(int srcwidth, int srcheight)
-{
- IDirectDrawSurface7 *target = (back != NULL) ? back : primary;
- osd_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
- DDBLTFX blitfx = { sizeof(DDBLTFX) };
- RECT clear, outer, dest, source;
- INT32 dstwidth, dstheight;
- HRESULT result;
-
- // compute source rect
- source.left = source.top = 0;
- source.right = srcwidth;
- source.bottom = srcheight;
-
- // compute outer rect -- windowed version
- if (!window().fullscreen())
- {
- GetClientRect(window().m_hwnd, &outer);
- ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[0]);
- ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[1]);
-
- // adjust to be relative to the monitor
- osd_rect pos = monitor->position_size();
- outer.left -= pos.left();
- outer.right -= pos.left();
- outer.top -= pos.top();
- outer.bottom -= pos.top();
- }
-
- // compute outer rect -- full screen version
- else
- {
- calc_fullscreen_margins(primarydesc.dwWidth, primarydesc.dwHeight, &outer);
- }
-
- // if we're respecting the aspect ratio, we need to adjust to fit
- dstwidth = rect_width(&outer);
- dstheight = rect_height(&outer);
- if (!video_config.hwstretch)
- {
- // trim the source if necessary
- if (rect_width(&outer) < srcwidth)
- {
- source.left += (srcwidth - rect_width(&outer)) / 2;
- source.right = source.left + rect_width(&outer);
- }
- if (rect_height(&outer) < srcheight)
- {
- source.top += (srcheight - rect_height(&outer)) / 2;
- source.bottom = source.top + rect_height(&outer);
- }
-
- // match the destination and source sizes
- dstwidth = srcwidth = source.right - source.left;
- dstheight = srcheight = source.bottom - source.top;
- }
- else if (video_config.keepaspect)
- {
- // compute the appropriate visible area
- window().target()->compute_visible_area(rect_width(&outer), rect_height(&outer), monitor->aspect(), window().target()->orientation(), dstwidth, dstheight);
- }
-
- // center within
- dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2;
- dest.right = dest.left + dstwidth;
- dest.top = outer.top + (rect_height(&outer) - dstheight) / 2;
- dest.bottom = dest.top + dstheight;
-
- // compare against last destination; if different, force a redraw
- if (dest.left != lastdest.left || dest.right != lastdest.right || dest.top != lastdest.top || dest.bottom != lastdest.bottom)
- {
- lastdest = dest;
- update_outer_rects();
- }
-
- // clear outer rects if we need to
- if (clearouter != 0)
- {
- clearouter--;
-
- // clear the left edge
- if (dest.left > outer.left)
- {
- clear = outer;
- clear.right = dest.left;
- result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
- }
-
- // clear the right edge
- if (dest.right < outer.right)
- {
- clear = outer;
- clear.left = dest.right;
- result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
- }
-
- // clear the top edge
- if (dest.top > outer.top)
- {
- clear = outer;
- clear.bottom = dest.top;
- result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
- }
-
- // clear the bottom edge
- if (dest.bottom < outer.bottom)
- {
- clear = outer;
- clear.top = dest.bottom;
- result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
- }
- }
-
- // do the blit
- result = IDirectDrawSurface7_Blt(target, &dest, blit, &source, DDBLT_WAIT, NULL);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X blitting to the screen\n", (int)result);
-
- // page flip if triple buffered
- if (window().fullscreen() && back != NULL)
- {
- result = IDirectDrawSurface7_Flip(primary, NULL, DDFLIP_WAIT);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
- }
-}
-
-
-
-//============================================================
-// config_adapter_mode
-//============================================================
-
-int renderer_dd::config_adapter_mode()
-{
- DDDEVICEIDENTIFIER2 identifier;
- HRESULT result;
-
- // choose the monitor number
- get_adapter_for_monitor(window().monitor());
-
- // create a temporary DirectDraw object
- result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
- return 1;
- }
-
- // get the identifier
- result = IDirectDraw7_GetDeviceIdentifier(ddraw, &identifier, 0);
- if (result != DD_OK)
- {
- osd_printf_error("Error getting identifier for device\n");
- return 1;
- }
- osd_printf_verbose("DirectDraw: Configuring device %s\n", identifier.szDescription);
-
- // get the current display mode
- memset(&origmode, 0, sizeof(origmode));
- origmode.dwSize = sizeof(origmode);
- result = IDirectDraw7_GetDisplayMode(ddraw, &origmode);
- if (result != DD_OK)
- {
- osd_printf_verbose("DirectDraw: Error %08X getting current display mode\n", (int)result);
- IDirectDraw7_Release(ddraw);
- return 1;
- }
-
- // choose a resolution: full screen mode case
- if (window().fullscreen())
- {
- // default to the current mode exactly
- width = origmode.dwWidth;
- height = origmode.dwHeight;
- refresh = origmode.dwRefreshRate;
-
- // if we're allowed to switch resolutions, override with something better
- if (video_config.switchres)
- pick_best_mode();
- }
-
- // release the DirectDraw object
- IDirectDraw7_Release(ddraw);
- ddraw = NULL;
-
- // if we're not changing resolutions, make sure we have a resolution we can handle
- if (!window().fullscreen() || !video_config.switchres)
- {
- switch (origmode.ddpfPixelFormat.dwRBitMask)
- {
- case 0x00ff0000:
- case 0x000000ff:
- case 0xf800:
- case 0x7c00:
- break;
-
- default:
- osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)origmode.ddpfPixelFormat.dwRBitMask, (int)origmode.ddpfPixelFormat.dwGBitMask, (int)origmode.ddpfPixelFormat.dwBBitMask);
- return 1;
- }
- }
-
- return 0;
-}
-
-
-
-//============================================================
-// monitor_enum_callback
-//============================================================
-
-static BOOL WINAPI monitor_enum_callback(GUID FAR *guid, LPSTR description, LPSTR name, LPVOID context, HMONITOR hmonitor)
-{
- monitor_enum_info *einfo = (monitor_enum_info *)context;
-
- // do we match the desired monitor?
- if (hmonitor == *((HMONITOR *)einfo->monitor->oshandle()) || (hmonitor == NULL && einfo->monitor->is_primary()))
- {
- einfo->guid_ptr = (guid != NULL) ? &einfo->guid : NULL;
- if (guid != NULL)
- einfo->guid = *guid;
- einfo->foundit = TRUE;
- }
- return 1;
-}
-
-
-
-//============================================================
-// get_adapter_for_monitor
-//============================================================
-
-void renderer_dd::get_adapter_for_monitor(osd_monitor_info *monitor)
-{
- monitor_enum_info einfo;
- HRESULT result;
-
- // try to find our monitor
- memset(&einfo, 0, sizeof(einfo));
- einfo.monitor = monitor;
- result = (*directdrawenumerateex)(monitor_enum_callback, &einfo, DDENUM_ATTACHEDSECONDARYDEVICES);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during DirectDrawEnumerateEx call\n", (int)result);
-
- // set up the adapter
- if (einfo.foundit && einfo.guid_ptr != NULL)
- {
- adapter = einfo.guid;
- adapter_ptr = &adapter;
- }
- else
- adapter_ptr = NULL;
-}
-
-
-
-//============================================================
-// enum_modes_callback
-//============================================================
-
-static HRESULT WINAPI enum_modes_callback(LPDDSURFACEDESC2 desc, LPVOID context)
-{
- float size_score, refresh_score, final_score;
- mode_enum_info *einfo = (mode_enum_info *)context;
- renderer_dd *dd = einfo->renderer;
-
- // skip non-32 bit modes
- if (desc->ddpfPixelFormat.dwRGBBitCount != 32)
- return DDENUMRET_OK;
-
- // compute initial score based on difference between target and current
- size_score = 1.0f / (1.0f + fabs((float)((INT32)desc->dwWidth - einfo->target_width)) + fabs((float)((INT32)desc->dwHeight - einfo->target_height)));
-
- // if the mode is too small, give a big penalty
- if (desc->dwWidth < einfo->minimum_width || desc->dwHeight < einfo->minimum_height)
- size_score *= 0.01f;
-
- // if mode is smaller than we'd like, it only scores up to 0.1
- if (desc->dwWidth < einfo->target_width || desc->dwHeight < einfo->target_height)
- size_score *= 0.1f;
-
- // if we're looking for a particular mode, that's a winner
- if (desc->dwWidth == einfo->window->m_win_config.width && desc->dwHeight == einfo->window->m_win_config.height)
- size_score = 2.0f;
-
- // compute refresh score
- refresh_score = 1.0f / (1.0f + fabs((double)desc->dwRefreshRate - einfo->target_refresh));
-
- // if refresh is smaller than we'd like, it only scores up to 0.1
- if ((double)desc->dwRefreshRate < einfo->target_refresh)
- refresh_score *= 0.1f;
-
- // if we're looking for a particular refresh, make sure it matches
- if (desc->dwRefreshRate == einfo->window->m_win_config.refresh)
- refresh_score = 2.0f;
-
- // weight size and refresh equally
- final_score = size_score + refresh_score;
-
- // best so far?
- osd_printf_verbose(" %4dx%4d@%3dHz -> %f\n", (int)desc->dwWidth, (int)desc->dwHeight, (int)desc->dwRefreshRate, final_score * 1000.0f);
- if (final_score > einfo->best_score)
- {
- einfo->best_score = final_score;
- dd->width = desc->dwWidth;
- dd->height = desc->dwHeight;
- dd->refresh = desc->dwRefreshRate;
- }
- return DDENUMRET_OK;
-}
-
-
-
-//============================================================
-// pick_best_mode
-//============================================================
-
-void renderer_dd::pick_best_mode()
-{
- mode_enum_info einfo;
- HRESULT result;
-
- // determine the minimum width/height for the selected target
- // note: technically we should not be calling this from an alternate window
- // thread; however, it is only done during init time, and the init code on
- // the main thread is waiting for us to finish, so it is safe to do so here
- window().target()->compute_minimum_size(einfo.minimum_width, einfo.minimum_height);
-
- // use those as the target for now
- einfo.target_width = einfo.minimum_width * MAX(1, window().prescale());
- einfo.target_height = einfo.minimum_height * MAX(1, window().prescale());
-
- // determine the refresh rate of the primary screen
- einfo.target_refresh = 60.0;
- const screen_device *primary_screen = window().machine().config().first_screen();
- if (primary_screen != NULL)
- einfo.target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
- printf("Target refresh = %f\n", einfo.target_refresh);
-
- // if we're not stretching, allow some slop on the minimum since we can handle it
- if (!video_config.hwstretch)
- {
- einfo.minimum_width -= 4;
- einfo.minimum_height -= 4;
- }
-
- // if we are stretching, aim for a mode approximately 2x the game's resolution
- else if (window().prescale() <= 1)
- {
- einfo.target_width *= 2;
- einfo.target_height *= 2;
- }
-
- // fill in the rest of the data
- einfo.window = &window();
- einfo.renderer = this;
- einfo.best_score = 0.0f;
-
- // enumerate the modes
- osd_printf_verbose("DirectDraw: Selecting video mode...\n");
- result = IDirectDraw7_EnumDisplayModes(ddraw, DDEDM_REFRESHRATES, NULL, &einfo, enum_modes_callback);
- if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during EnumDisplayModes call\n", (int)result);
- osd_printf_verbose("DirectDraw: Mode selected = %4dx%4d@%3dHz\n", width, height, refresh);
-}
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 4a2744e4068..728b0810290 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -30,10 +30,6 @@
#include "modules/lib/osdlib.h"
#include "modules/lib/osdobj_common.h"
-#if defined(OSD_WINDOWS) && !defined(SDLMAME_SDL2)
-#define SDLMAME_SDL2 0
-#endif
-
// OpenGL headers
#include "modules/opengl/osd_opengl.h"
@@ -344,7 +340,7 @@ private:
HMODULE win_gl_context::m_module;
-#elif SDLMAME_SDL2
+#else
class sdl_gl_context : public osd_gl_context
{
@@ -395,51 +391,6 @@ private:
char m_error[256];
};
-#else
-// SDL 1.2
-class sdl12_gl_context : public osd_gl_context
-{
-public:
- sdl12_gl_context(SDL_Surface *window) : osd_gl_context(), m_window(window)
- {
- m_error[0] = 0;
- }
- virtual ~sdl12_gl_context()
- {
- }
- virtual void MakeCurrent()
- {
- }
-
- virtual int SetSwapInterval(const int swap)
- {
- // Not supported on 1.2
- return 0;
- }
-
- virtual const char *LastErrorMsg()
- {
- if (m_error[0] == 0)
- return NULL;
- else
- return m_error;
- }
-
- virtual void *getProcAddress(const char *proc)
- {
- return SDL_GL_GetProcAddress(proc);
- }
-
- virtual void SwapBuffer()
- {
- SDL_GL_SwapBuffers();
- }
-
-private:
- SDL_Surface *m_window;
- char m_error[256];
-};
-
#endif
//============================================================
@@ -766,10 +717,8 @@ int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks)
load_gl_lib(machine);
#if defined(OSD_WINDOWS)
osd_printf_verbose("Using Windows OpenGL driver\n");
-#elif SDLMAME_SDL2
- osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
#else
- osd_printf_verbose("Using SDL single-window OpenGL driver (SDL 1.2)\n");
+ osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
#endif
return 0;
@@ -1035,10 +984,8 @@ int sdl_info_ogl::create()
// create renderer
#if defined(OSD_WINDOWS)
m_gl_context = global_alloc(win_gl_context(window().m_hwnd));
-#elif SDLMAME_SDL2
- m_gl_context = global_alloc(sdl_gl_context(window().sdl_window()));
#else
- m_gl_context = global_alloc(sdl12_gl_context(window().sdl_surface()));
+ m_gl_context = global_alloc(sdl_gl_context(window().sdl_window()));
#endif
if (m_gl_context->LastErrorMsg() != NULL)
{
@@ -1530,11 +1477,9 @@ int sdl_info_ogl::draw(const int update)
if (m_init_context)
{
// do some one-time OpenGL setup
-#if SDLMAME_SDL2
// FIXME: SRGB conversion is working on SDL2, may be of use
// when we eventually target gamma and monitor profiles.
//glEnable(GL_FRAMEBUFFER_SRGB);
-#endif
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
@@ -1560,11 +1505,6 @@ int sdl_info_ogl::draw(const int update)
loadGLExtensions();
}
-#if !defined(OSD_WINDOWS) && !SDLMAME_SDL2
- // force all textures to be regenerated
- destroy_all_textures();
-#endif
-
m_surf_w = m_width;
m_surf_h = m_height;
diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp
index 221ac79ef4d..b9a40038082 100644
--- a/src/osd/modules/render/drawsdl.cpp
+++ b/src/osd/modules/render/drawsdl.cpp
@@ -40,11 +40,9 @@
struct sdl_scale_mode;
-#if (SDLMAME_SDL2)
#define DRAW2_SCALEMODE_NEAREST "0"
#define DRAW2_SCALEMODE_LINEAR "1"
#define DRAW2_SCALEMODE_BEST "2"
-#endif
/* sdl_info is the information about SDL for the current screen */
class sdl_info : public osd_renderer
@@ -53,12 +51,8 @@ public:
sdl_info(osd_window *w, int extra_flags)
: osd_renderer(w, extra_flags),
- #if (SDLMAME_SDL2)
m_sdl_renderer(NULL),
m_texture_id(NULL),
- #else
- m_yuvsurf(NULL),
- #endif
m_yuv_lookup(NULL),
m_yuv_bitmap(NULL),
//m_hw_scale_width(0),
@@ -88,24 +82,14 @@ public:
private:
void destroy_all_textures();
void yuv_init();
-#if (SDLMAME_SDL2)
void setup_texture(const osd_dim &size);
-#endif
void yuv_lookup_set(unsigned int pen, unsigned char red,
unsigned char green, unsigned char blue);
-#if (!SDLMAME_SDL2)
- void yuv_overlay_init();
-#endif
-
INT32 m_blittimer;
-#if (SDLMAME_SDL2)
SDL_Renderer *m_sdl_renderer;
SDL_Texture *m_texture_id;
-#else
- SDL_Overlay *m_yuvsurf;
-#endif
// YUV overlay
UINT32 *m_yuv_lookup;
@@ -127,11 +111,7 @@ struct sdl_scale_mode
int is_yuv; /* Yuv mode? */
int mult_w; /* Width multiplier */
int mult_h; /* Height multiplier */
-#if (!SDLMAME_SDL2)
- int m_extra_flags; /* Texture/surface flags */
-#else
const char *sdl_scale_mode_hint; /* what to use as a hint ? */
-#endif
int pixel_format; /* Pixel/Overlay format */
void (*yuv_blit)(const UINT16 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height);
};
@@ -160,20 +140,6 @@ static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch,
// Static declarations
-#if (!SDLMAME_SDL2)
-static int shown_video_info = 0;
-
-static const sdl_scale_mode scale_modes[] =
-{
- { "none", 0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF, 0, 0 },
- { "async", 0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF | osd_renderer::FLAG_NEEDS_ASYNCBLIT, 0, 0 },
- { "yv12", 1, 1, 1, 1, 0, SDL_YV12_OVERLAY, yuv_RGB_to_YV12 },
- { "yv12x2", 1, 1, 2, 2, 0, SDL_YV12_OVERLAY, yuv_RGB_to_YV12X2 },
- { "yuy2", 1, 1, 1, 1, 0, SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2 },
- { "yuy2x2", 1, 1, 2, 1, 0, SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2X2 },
- { NULL }
-};
-#else
static const sdl_scale_mode scale_modes[] =
{
{ "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, 0 },
@@ -186,7 +152,6 @@ static const sdl_scale_mode scale_modes[] =
{ "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
{ NULL }
};
-#endif
//============================================================
// drawsdl_scale_mode
@@ -226,12 +191,7 @@ int drawsdl_scale_mode(const char *s)
static osd_renderer *drawsdl_create(osd_window *window)
{
// FIXME: QUALITY HINTS
-#if (SDLMAME_SDL2)
return global_alloc(sdl_info(window, osd_renderer::FLAG_NONE));
-#else
- const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
- return global_alloc(sdl_info(window, sm->m_extra_flags));
-#endif
}
//============================================================
@@ -244,11 +204,7 @@ int drawsdl_init(osd_draw_callbacks *callbacks)
callbacks->create = drawsdl_create;
callbacks->exit = drawsdl_exit;
- if (SDLMAME_SDL2)
- osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
- else
- osd_printf_verbose("Using SDL single-window soft driver (SDL 1.2)\n");
-
+ osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
return 0;
}
@@ -264,7 +220,6 @@ static void drawsdl_exit(void)
// setup_texture for window
//============================================================
-#if (SDLMAME_SDL2)
void sdl_info::setup_texture(const osd_dim &size)
{
const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
@@ -311,64 +266,11 @@ void sdl_info::setup_texture(const osd_dim &size)
size.width(), size.height());
}
}
-#endif
-
-//============================================================
-// yuv_overlay_init
-//============================================================
-
-#if (!SDLMAME_SDL2)
-void sdl_info::yuv_overlay_init()
-{
- const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
- int minimum_width, minimum_height;
-
- window().target()->compute_minimum_size(minimum_width, minimum_height);
-
- if (window().prescale())
- {
- minimum_width *= window().prescale();
- minimum_height *= window().prescale();
- }
-
- if (m_yuvsurf != NULL)
- {
- SDL_FreeYUVOverlay(m_yuvsurf);
- m_yuvsurf = NULL;
- }
-
- if (m_yuv_bitmap != NULL)
- {
- global_free_array(m_yuv_bitmap);
- }
-
- osd_printf_verbose("SDL: Creating %d x %d YUV-Overlay ...\n", minimum_width, minimum_height);
-
- m_yuv_bitmap = global_alloc_array(UINT16, minimum_width*minimum_height);
-
- m_yuvsurf = SDL_CreateYUVOverlay(minimum_width * sdl_sm->mult_w, minimum_height * sdl_sm->mult_h,
- sdl_sm->pixel_format, window().sdl_surface());
-
- if ( m_yuvsurf == NULL ) {
- osd_printf_error("SDL: Couldn't create SDL_yuv_overlay: %s\n", SDL_GetError());
- //return 1;
- }
-
- if (!shown_video_info)
- {
- osd_printf_verbose("YUV Mode : %s\n", sdl_sm->name);
- osd_printf_verbose("YUV Overlay Size : %d x %d\n", minimum_width, minimum_height);
- osd_printf_verbose("YUV Acceleration : %s\n", m_yuvsurf->hw_overlay ? "Hardware" : "Software");
- shown_video_info = 1;
- }
-}
-#endif
//============================================================
// drawsdl_show_info
//============================================================
-#if (SDLMAME_SDL2)
static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
{
#define RF_ENTRY(x) {x, #x }
@@ -395,42 +297,14 @@ static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
if (render_info->flags & rflist[i].flag)
osd_printf_verbose("renderer: flag %s\n", rflist[i].name);
}
-#endif
//============================================================
// sdl_info::create
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
-// a
//============================================================
int sdl_info::create()
{
-#if (SDLMAME_SDL2)
const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
// create renderer
@@ -486,8 +360,6 @@ int sdl_info::create()
window().get_size(w, h);
setup_texture(w, h);
#endif
-#else
-#endif
m_yuv_lookup = NULL;
m_blittimer = 0;
@@ -517,9 +389,7 @@ void sdl_info::destroy()
global_free_array(m_yuv_bitmap);
m_yuv_bitmap = NULL;
}
-#if (SDLMAME_SDL2)
SDL_DestroyRenderer(m_sdl_renderer);
-#endif
}
//============================================================
@@ -543,16 +413,8 @@ int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt)
void sdl_info::destroy_all_textures()
{
-#if (SDLMAME_SDL2)
SDL_DestroyTexture(m_texture_id);
m_texture_id = NULL;
-#else
- if (m_yuvsurf != NULL)
- {
- SDL_FreeYUVOverlay(m_yuvsurf);
- m_yuvsurf = NULL;
- }
-#endif
}
@@ -566,9 +428,7 @@ int sdl_info::draw(int update)
UINT8 *surfptr;
INT32 pitch;
Uint32 rmask, gmask, bmask;
-#if (SDLMAME_SDL2)
Uint32 amask;
-#endif
INT32 vofs, hofs, blitwidth, blitheight, ch, cw;
int bpp;
@@ -584,68 +444,14 @@ int sdl_info::draw(int update)
clear_flags(FI_CHANGED);
m_blittimer = 3;
m_last_dim = wdim;
-#if (SDLMAME_SDL2)
SDL_RenderSetViewport(m_sdl_renderer, NULL);
if (m_texture_id != NULL)
SDL_DestroyTexture(m_texture_id);
setup_texture(m_blit_dim);
m_blittimer = 3;
-#else
- const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
- if (sdl_sm->is_yuv)
- {
- yuv_overlay_init();
- }
-#endif
}
// lock it if we need it
-#if (!SDLMAME_SDL2)
-
- pitch = window().sdl_surface()->pitch;
- bpp = window().sdl_surface()->format->BytesPerPixel;
- rmask = window().sdl_surface()->format->Rmask;
- gmask = window().sdl_surface()->format->Gmask;
- bmask = window().sdl_surface()->format->Bmask;
-// amask = sdlsurf->format->Amask;
-#if 0
- if (window().blitwidth() != m_old_blitwidth || window().blitheight() != m_old_blitheight)
- {
- if (sm->is_yuv)
- yuv_overlay_init();
- m_old_blitwidth = window().blitwidth();
- m_old_blitheight = window().blitheight();
- m_blittimer = 3;
- }
-#endif
- if (SDL_MUSTLOCK(window().sdl_surface()))
- SDL_LockSurface(window().sdl_surface());
-
- // Clear if necessary
- if (m_blittimer > 0)
- {
- memset(window().sdl_surface()->pixels, 0, wdim.height() * window().sdl_surface()->pitch);
- m_blittimer--;
- }
-
-
- if (sm->is_yuv)
- {
- SDL_LockYUVOverlay(m_yuvsurf);
- surfptr = m_yuvsurf->pixels[0]; // (UINT8 *) m_yuv_bitmap;
- pitch = m_yuvsurf->pitches[0]; // (UINT8 *) m_yuv_bitmap;
-#if 0
- printf("abcd %d\n", m_yuvsurf->h);
- printf("abcd %d %d %d\n", m_yuvsurf->pitches[0], m_yuvsurf->pitches[1], m_yuvsurf->pitches[2]);
- printf("abcd %p %p %p\n", m_yuvsurf->pixels[0], m_yuvsurf->pixels[1], m_yuvsurf->pixels[2]);
- printf("abcd %ld %ld\n", m_yuvsurf->pixels[1] - m_yuvsurf->pixels[0], m_yuvsurf->pixels[2] - m_yuvsurf->pixels[1]);
-#endif
- }
- else
- surfptr = (UINT8 *)window().sdl_surface()->pixels;
-#else
- //SDL_SelectRenderer(window().sdl_window);
-
{
Uint32 format;
@@ -668,7 +474,6 @@ int sdl_info::draw(int update)
SDL_LockTexture(m_texture_id, NULL, (void **) &surfptr, &pitch);
-#endif
// get ready to center the image
vofs = hofs = 0;
blitwidth = m_blit_dim.width();
@@ -703,25 +508,11 @@ int sdl_info::draw(int update)
int mamewidth, mameheight;
-#if !SDLMAME_SDL2
- if (!sm->is_yuv)
- {
- surfptr += ((vofs * pitch) + (hofs * bpp));
- mamewidth = blitwidth; //sdl_surface()->w;
- mameheight = blitheight; //sdl_surface()->h;
- }
- else
- {
- mamewidth = m_yuvsurf->w / sm->mult_w;
- mameheight = m_yuvsurf->h / sm->mult_h;
- }
-#else
Uint32 fmt = 0;
int access = 0;
SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
mamewidth /= sm->mult_w;
mameheight /= sm->mult_h;
-#endif
//printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
// rescale bounds
@@ -780,24 +571,6 @@ int sdl_info::draw(int update)
window().m_primlist->release_lock();
// unlock and flip
-#if (!SDLMAME_SDL2)
- if (SDL_MUSTLOCK(window().sdl_surface())) SDL_UnlockSurface(window().sdl_surface());
- if (!sm->is_yuv)
- {
- SDL_Flip(window().sdl_surface());
- }
- else
- {
- SDL_Rect r;
-
- SDL_UnlockYUVOverlay(m_yuvsurf);
- r.x = hofs;
- r.y = vofs;
- r.w = blitwidth;
- r.h = blitheight;
- SDL_DisplayYUVOverlay(m_yuvsurf, &r);
- }
-#else
SDL_UnlockTexture(m_texture_id);
{
SDL_Rect r;
@@ -811,7 +584,6 @@ int sdl_info::draw(int update)
SDL_RenderCopy(m_sdl_renderer,m_texture_id, NULL, &r);
SDL_RenderPresent(m_sdl_renderer);
}
-#endif
return 0;
}
//============================================================
@@ -950,12 +722,7 @@ static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch,
pixels[0] = ptr;
pixels[1] = ptr + pitch * height * 2;
-#if (SDLMAME_SDL2)
int p2 = (pitch >> 1);
-#else
- int p2 = (pitch + 7) & ~ 7;;
- p2 = (p2 >> 1);
-#endif
pixels[2] = pixels[1] + p2 * height;
for(y=0;y<height;y++)