[retro-gtk] retro-core: Implement RETRO_ENVIRONMENT_SET_HW_RENDER
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] retro-core: Implement RETRO_ENVIRONMENT_SET_HW_RENDER
- Date: Mon, 23 Mar 2020 13:55:02 +0000 (UTC)
commit 71d106405ea69f3b8e55c6650b22fcf2c98845ee
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Fri Jan 31 22:49:15 2020 +0500
retro-core: Implement RETRO_ENVIRONMENT_SET_HW_RENDER
Use RetroGLRenderer to support hardware rendering for OpenGL.
retro-runner/retro-core-private.h | 2 +
retro-runner/retro-core.c | 5 +++
retro-runner/retro-environment.c | 80 +++++++++++++++++++++++++++++++++++++--
3 files changed, 84 insertions(+), 3 deletions(-)
---
diff --git a/retro-runner/retro-core-private.h b/retro-runner/retro-core-private.h
index 435010b..34b2c33 100644
--- a/retro-runner/retro-core-private.h
+++ b/retro-runner/retro-core-private.h
@@ -14,6 +14,7 @@
#include "retro-input-descriptor-private.h"
#include "retro-module-private.h"
#include "retro-pixel-format-private.h"
+#include "retro-renderer-private.h"
#include "retro-rotation-private.h"
#include "retro-variable-private.h"
@@ -47,6 +48,7 @@ struct _RetroCore
gdouble sample_rate;
RetroFramebuffer *framebuffer;
+ RetroRenderer *renderer;
RetroKeyboardCallback keyboard_callback;
RetroControllerState *default_controller;
GHashTable *controllers;
diff --git a/retro-runner/retro-core.c b/retro-runner/retro-core.c
index 80f5d6a..4bb01d6 100644
--- a/retro-runner/retro-core.c
+++ b/retro-runner/retro-core.c
@@ -132,6 +132,7 @@ retro_core_finalize (GObject *object)
g_free (self->libretro_path);
g_free (self->content_directory);
g_free (self->save_directory);
+ g_clear_object (&self->renderer);
G_OBJECT_CLASS (retro_core_parent_class)->finalize (object);
}
@@ -918,6 +919,8 @@ load_game (RetroCore *self,
get_system_av_info = retro_module_get_get_system_av_info (self->module);
get_system_av_info (&info);
retro_core_set_system_av_info (self, &info);
+ if (self->renderer)
+ retro_renderer_realize (self->renderer, info.geometry.max_width, info.geometry.max_height);
return game_loaded;
}
@@ -935,6 +938,8 @@ prepare (RetroCore *self) {
get_system_av_info = retro_module_get_get_system_av_info (self->module);
get_system_av_info (&info);
retro_core_set_system_av_info (self, &info);
+ if (self->renderer)
+ retro_renderer_realize (self->renderer, info.geometry.max_width, info.geometry.max_height);
return game_loaded;
}
diff --git a/retro-runner/retro-environment.c b/retro-runner/retro-environment.c
index 409f351..ac22075 100644
--- a/retro-runner/retro-environment.c
+++ b/retro-runner/retro-environment.c
@@ -4,6 +4,8 @@
#include <stdbool.h>
#include "retro-input-private.h"
+#include "retro-gl-renderer-private.h"
+#include "retro-hw-render-callback-private.h"
#include "retro-rumble-effect.h"
#define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000
@@ -303,6 +305,51 @@ get_variable_update (RetroCore *self,
return TRUE;
}
+static RetroProcAddress
+hw_rendering_callback_get_proc_address (const gchar *sym)
+{
+ RetroCore *self = retro_core_get_instance ();
+
+ return retro_renderer_get_proc_address (self->renderer, sym);
+}
+
+static guintptr
+hw_rendering_callback_get_current_framebuffer ()
+{
+ RetroCore *self = retro_core_get_instance ();
+
+ return retro_renderer_get_current_framebuffer (self->renderer);
+}
+
+static gboolean
+set_hw_render (RetroCore *self,
+ RetroHWRenderCallback *callback)
+{
+ switch (callback->context_type) {
+ case RETRO_HW_CONTEXT_OPENGL:
+ case RETRO_HW_CONTEXT_OPENGL_CORE:
+ case RETRO_HW_CONTEXT_OPENGLES2:
+ case RETRO_HW_CONTEXT_OPENGLES3:
+ case RETRO_HW_CONTEXT_OPENGLES_VERSION:
+ self->renderer = retro_gl_renderer_new (self, callback);
+ break;
+
+ case RETRO_HW_CONTEXT_VULKAN:
+ g_critical ("Vulkan support isn't implemented");
+
+ return FALSE;
+ default:
+ g_critical ("Unknown context type: %d", callback->context_type);
+
+ return FALSE;
+ }
+
+ callback->get_current_framebuffer = hw_rendering_callback_get_current_framebuffer;
+ callback->get_proc_address = hw_rendering_callback_get_proc_address;
+
+ return TRUE;
+}
+
static gboolean
set_disk_control_interface (RetroCore *self,
RetroDiskControlCallback *callback)
@@ -460,6 +507,9 @@ environment_core_command (RetroCore *self,
case RETRO_ENVIRONMENT_SET_GEOMETRY:
return set_geometry (self, (RetroGameGeometry *) data);
+ case RETRO_ENVIRONMENT_SET_HW_RENDER:
+ return set_hw_render (self, (RetroHWRenderCallback *) data);
+
case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS:
return set_input_descriptors (self, (RetroInputDescriptor *) data);
@@ -497,7 +547,6 @@ environment_core_command (RetroCore *self,
case RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK:
case RETRO_ENVIRONMENT_SET_CONTROLLER_INFO:
case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK:
- case RETRO_ENVIRONMENT_SET_HW_RENDER:
case RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE:
case RETRO_ENVIRONMENT_SET_MEMORY_MAPS:
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
@@ -536,8 +585,33 @@ video_refresh_cb (guint8 *data,
return;
retro_framebuffer_lock (self->framebuffer);
- retro_framebuffer_set_data (self->framebuffer, self->pixel_format, pitch,
- width, height, self->aspect_ratio, data);
+
+ if (self->renderer) {
+ gint pixel_size;
+
+ if (data && data != RETRO_HW_FRAME_BUFFER_VALID) {
+ g_critical ("Video data must be NULL or RETRO_HW_FRAME_BUFFER_VALID if "
+ "rendering to hardware.");
+
+ return;
+ }
+
+ if (!retro_pixel_format_to_gl (self->pixel_format, NULL, NULL, &pixel_size))
+ return;
+
+ pitch = width * pixel_size;
+
+ retro_framebuffer_set_data (self->framebuffer, self->pixel_format, pitch,
+ width, height, self->aspect_ratio, NULL);
+
+ data = retro_framebuffer_get_pixels (self->framebuffer);
+
+ retro_renderer_snapshot (self->renderer, self->pixel_format, width, height, pitch, data);
+ }
+ else
+ retro_framebuffer_set_data (self->framebuffer, self->pixel_format, pitch,
+ width, height, self->aspect_ratio, data);
+
retro_framebuffer_unlock (self->framebuffer);
if (!self->block_video_signal)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]