mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-24 12:15:08 +00:00
Merge pull request #1512 from aliaspider/master
add a read_frame_raw callback to the video_driver_t structure.
This commit is contained in:
commit
7af188185a
@ -1966,6 +1966,7 @@ video_driver_t video_d3d = {
|
||||
d3d_set_rotation,
|
||||
d3d_viewport_info,
|
||||
d3d_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
d3d_get_overlay_interface,
|
||||
#endif
|
||||
|
@ -769,6 +769,7 @@ video_driver_t video_dispmanx = {
|
||||
dispmanx_gfx_set_rotation,
|
||||
dispmanx_gfx_viewport_info,
|
||||
dispmanx_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -1673,6 +1673,7 @@ video_driver_t video_exynos = {
|
||||
exynos_gfx_set_rotation,
|
||||
exynos_gfx_viewport_info,
|
||||
exynos_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -2760,6 +2760,39 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define READ_RAW_GL_FRAME_TEST
|
||||
#endif
|
||||
|
||||
#if defined(READ_RAW_GL_FRAME_TEST)
|
||||
static void* gl_read_frame_raw(void *data, unsigned *width_p,
|
||||
unsigned *height_p, size_t *pitch_p)
|
||||
{
|
||||
int i;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
unsigned width = gl->last_width[gl->tex_index];
|
||||
unsigned height = gl->last_height[gl->tex_index];
|
||||
size_t pitch = gl->tex_w * gl->base_size;
|
||||
void* buffer = malloc(pitch * height);
|
||||
void* buffer_texture = malloc(pitch * gl->tex_h);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0,gl->texture_type, gl->texture_fmt, buffer_texture);
|
||||
|
||||
for(i = 0; i < height ; i++)
|
||||
memcpy((uint8_t*)buffer + i * pitch,
|
||||
(uint8_t*)buffer_texture + (height - 1 - i) * pitch, pitch);
|
||||
|
||||
*width_p = width;
|
||||
*height_p = height;
|
||||
*pitch_p = pitch;
|
||||
|
||||
free(buffer_texture);
|
||||
return buffer;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
static void gl_free_overlay(gl_t *gl);
|
||||
static bool gl_overlay_load(void *data,
|
||||
@ -3163,6 +3196,11 @@ video_driver_t video_gl = {
|
||||
gl_viewport_info,
|
||||
|
||||
gl_read_viewport,
|
||||
#if defined(READ_RAW_GL_FRAME_TEST)
|
||||
gl_read_frame_raw,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
gl_get_overlay_interface,
|
||||
|
@ -1503,6 +1503,7 @@ video_driver_t video_gx = {
|
||||
gx_set_rotation,
|
||||
gx_viewport_info,
|
||||
gx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
gx_get_overlay_interface,
|
||||
#endif
|
||||
|
@ -130,6 +130,7 @@ video_driver_t video_null = {
|
||||
null_gfx_set_rotation,
|
||||
null_gfx_viewport_info,
|
||||
null_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -1171,6 +1171,7 @@ video_driver_t video_omap = {
|
||||
omap_gfx_set_rotation,
|
||||
omap_gfx_viewport_info,
|
||||
omap_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -973,6 +973,7 @@ video_driver_t video_psp1 = {
|
||||
psp_set_rotation,
|
||||
psp_viewport_info,
|
||||
psp_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL,
|
||||
#endif
|
||||
|
@ -769,6 +769,7 @@ video_driver_t video_sdl2 = {
|
||||
sdl2_gfx_set_rotation,
|
||||
sdl2_gfx_viewport_info,
|
||||
sdl2_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL,
|
||||
#endif
|
||||
|
@ -570,6 +570,7 @@ video_driver_t video_sdl = {
|
||||
sdl_gfx_set_rotation,
|
||||
sdl_gfx_viewport_info,
|
||||
sdl_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL,
|
||||
#endif
|
||||
|
@ -1496,6 +1496,7 @@ video_driver_t video_sunxi = {
|
||||
sunxi_gfx_set_rotation,
|
||||
sunxi_gfx_viewport_info,
|
||||
NULL, /* read_viewport */
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -491,6 +491,7 @@ video_driver_t video_vg = {
|
||||
vg_set_rotation,
|
||||
vg_viewport_info,
|
||||
vg_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
|
@ -329,6 +329,7 @@ video_driver_t video_xenon360 = {
|
||||
xenon360_gfx_set_rotation,
|
||||
xenon360_gfx_viewport_info,
|
||||
xenon360_gfx_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
@ -937,6 +937,7 @@ video_driver_t video_xvideo = {
|
||||
xv_set_rotation,
|
||||
xv_viewport_info,
|
||||
xv_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
|
@ -167,6 +167,13 @@ typedef struct video_driver
|
||||
/* Reads out in BGR byte order (24bpp). */
|
||||
bool (*read_viewport)(void *data, uint8_t *buffer);
|
||||
|
||||
/* Returns a pointer to a newly allocated buffer that can
|
||||
* (and must) be passed to free() by the caller, containing a
|
||||
* copy of the current raw frame in the active pixel format
|
||||
* and sets width, height and pitch to the correct values. */
|
||||
void* (*read_frame_raw)(void *data, unsigned *width,
|
||||
unsigned *height, size_t *pitch);
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
void (*overlay_interface)(void *data, const video_overlay_interface_t **iface);
|
||||
#endif
|
||||
|
@ -977,6 +977,7 @@ static const video_driver_t video_thread = {
|
||||
thread_set_rotation,
|
||||
thread_viewport_info,
|
||||
thread_read_viewport,
|
||||
NULL, /* read_frame_raw */
|
||||
#ifdef HAVE_OVERLAY
|
||||
thread_get_overlay_interface, /* get_overlay_interface */
|
||||
#endif
|
||||
|
34
screenshot.c
34
screenshot.c
@ -254,9 +254,9 @@ bool take_screenshot(void)
|
||||
return false;
|
||||
|
||||
viewport_read = (g_settings.video.gpu_screenshot ||
|
||||
g_extern.system.hw_render_callback.context_type
|
||||
!= RETRO_HW_CONTEXT_NONE) && driver.video->read_viewport &&
|
||||
driver.video->viewport_info;
|
||||
((g_extern.system.hw_render_callback.context_type
|
||||
!= RETRO_HW_CONTEXT_NONE) && !driver.video->read_frame_raw))
|
||||
&& driver.video->read_viewport && driver.video->viewport_info;
|
||||
|
||||
if (viewport_read)
|
||||
{
|
||||
@ -276,8 +276,32 @@ bool take_screenshot(void)
|
||||
else if (g_extern.frame_cache.data &&
|
||||
(g_extern.frame_cache.data != RETRO_HW_FRAME_BUFFER_VALID))
|
||||
ret = take_screenshot_raw();
|
||||
else
|
||||
RARCH_ERR(RETRO_LOG_TAKE_SCREENSHOT_ERROR);
|
||||
else if (driver.video->read_frame_raw)
|
||||
{
|
||||
const void* old_data = g_extern.frame_cache.data;
|
||||
unsigned old_width = g_extern.frame_cache.width;
|
||||
unsigned old_height = g_extern.frame_cache.height;
|
||||
size_t old_pitch = g_extern.frame_cache.pitch;
|
||||
|
||||
void* frame_data = driver.video->read_frame_raw
|
||||
(driver.video_data, &g_extern.frame_cache.width,
|
||||
&g_extern.frame_cache.height, &g_extern.frame_cache.pitch);
|
||||
|
||||
if (frame_data)
|
||||
{
|
||||
g_extern.frame_cache.data = frame_data;
|
||||
ret = take_screenshot_raw();
|
||||
free(frame_data);
|
||||
}
|
||||
else
|
||||
RARCH_ERR(RETRO_LOG_TAKE_SCREENSHOT_ERROR);
|
||||
|
||||
g_extern.frame_cache.data = old_data;
|
||||
g_extern.frame_cache.width = old_width;
|
||||
g_extern.frame_cache.height = old_height;
|
||||
g_extern.frame_cache.pitch = old_pitch;
|
||||
}
|
||||
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user