1 #include "GSH_OpenGL_Libretro.h"
2 #include "Log.h"
3 
4 #define LOG_NAME "LIBRETRO"
5 
6 extern int g_res_factor;
7 extern CGSHandler::PRESENTATION_MODE g_presentation_mode;
8 extern retro_video_refresh_t g_video_cb;
9 extern struct retro_hw_render_callback g_hw_render;
10 
CGSH_OpenGL_Libretro()11 CGSH_OpenGL_Libretro::CGSH_OpenGL_Libretro()
12     : CGSH_OpenGL(false)
13 {
14 }
15 
~CGSH_OpenGL_Libretro()16 CGSH_OpenGL_Libretro::~CGSH_OpenGL_Libretro()
17 {
18 }
19 
GetFactoryFunction()20 CGSH_OpenGL::FactoryFunction CGSH_OpenGL_Libretro::GetFactoryFunction()
21 {
22 	return []() { return new CGSH_OpenGL_Libretro(); };
23 }
24 
InitializeImpl()25 void CGSH_OpenGL_Libretro::InitializeImpl()
26 {
27 	fprintf(stderr, "%s\n", __FUNCTION__);
28 
29 #if defined(USE_GLEW)
30 	glewExperimental = GL_TRUE;
31 	auto result = glewInit();
32 	CLog::GetInstance().Warn(LOG_NAME, "glewInit %d\n", result == GLEW_OK);
33 	assert(result == GLEW_OK);
34 	if(result != GLEW_OK)
35 	{
36 		fprintf(stderr, "Error: %s\n", glewGetErrorString(result));
37 		CLog::GetInstance().Warn(LOG_NAME, "Error: %s\n", glewGetErrorString(result));
38 		return;
39 	}
40 
41 #endif
42 
43 	if(g_hw_render.get_current_framebuffer)
44 		m_presentFramebuffer = g_hw_render.get_current_framebuffer();
45 
46 	UpdatePresentationImpl();
47 
48 	CGSH_OpenGL::InitializeImpl();
49 }
50 
UpdatePresentation()51 void CGSH_OpenGL_Libretro::UpdatePresentation()
52 {
53 	SendGSCall([this]() { UpdatePresentationImpl(); });
54 }
55 
UpdatePresentationImpl()56 void CGSH_OpenGL_Libretro::UpdatePresentationImpl()
57 {
58 	PRESENTATION_PARAMS presentationParams;
59 	presentationParams.mode = g_presentation_mode;
60 	presentationParams.windowWidth = GetCrtWidth() * g_res_factor;
61 	presentationParams.windowHeight = GetCrtHeight() * g_res_factor;
62 
63 	SetPresentationParams(presentationParams);
64 	NotifyPreferencesChanged();
65 }
66 
FlushMailBox()67 void CGSH_OpenGL_Libretro::FlushMailBox()
68 {
69 	bool isFlushed = false;
70 	SendGSCall([&]() {
71 		isFlushed = true;
72 		m_flipped = true;
73 	},
74 	           true);
75 	while(!isFlushed)
76 	{
77 		// Wait for flush to complete
78 		ProcessSingleFrame();
79 	}
80 }
81 
Reset()82 void CGSH_OpenGL_Libretro::Reset()
83 {
84 	FlushMailBox();
85 	ResetBase();
86 	CGSH_OpenGL::ReleaseImpl();
87 	InitializeImpl();
88 }
89 
Release()90 void CGSH_OpenGL_Libretro::Release()
91 {
92 	FlushMailBox();
93 	ResetBase();
94 	CGSH_OpenGL::ReleaseImpl();
95 }
96 
FlipImpl()97 void CGSH_OpenGL_Libretro::FlipImpl()
98 {
99 	CLog::GetInstance().Print(LOG_NAME, "%s\n", __FUNCTION__);
100 
101 	if(g_hw_render.get_current_framebuffer)
102 		m_presentFramebuffer = g_hw_render.get_current_framebuffer();
103 	else
104 		return;
105 
106 	CGSH_OpenGL::FlipImpl();
107 }
108 
PresentBackbuffer()109 void CGSH_OpenGL_Libretro::PresentBackbuffer()
110 {
111 	CLog::GetInstance().Print(LOG_NAME, "%s\n", __FUNCTION__);
112 
113 	if(g_video_cb)
114 		g_video_cb(RETRO_HW_FRAME_BUFFER_VALID, GetCrtWidth() * g_res_factor, GetCrtHeight() * g_res_factor, 0);
115 }
116