Merge pull request #1512 from aliaspider/master

add a read_frame_raw callback to the video_driver_t structure.
This commit is contained in:
Twinaphex 2015-03-16 14:38:05 +01:00
commit 7af188185a
17 changed files with 88 additions and 5 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
{