Move read_viewport and viewport_info to render_chain_gl_legacy.c

This commit is contained in:
twinaphex 2017-04-19 01:25:19 +02:00
parent faafa2def0
commit 32c91baca6
6 changed files with 144 additions and 121 deletions

View File

@ -1493,7 +1493,7 @@ static bool d3d_read_viewport(void *data, uint8_t *buffer, bool is_idle)
!d3d->renderchain_driver->read_viewport)
return false;
return d3d->renderchain_driver->read_viewport(d3d, buffer);
return d3d->renderchain_driver->read_viewport(d3d, buffer, false);
}
static bool d3d_set_shader(void *data,

View File

@ -910,9 +910,12 @@ static bool renderchain_set_pass_size(cg_renderchain_t *chain,
}
static void cg_d3d9_renderchain_convert_geometry(
void *data, const void *info_data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height,
void *data,
const void *info_data,
unsigned *out_width,
unsigned *out_height,
unsigned width,
unsigned height,
void *final_viewport_data)
{
const LinkInfo *info = (const LinkInfo*)info_data;
@ -998,8 +1001,10 @@ static void d3d_recompute_pass_sizes(cg_renderchain_t *chain,
}
}
static void cg_d3d9_renderchain_set_final_viewport(void *data,
void *renderchain_data, const void *viewport_data)
static void cg_d3d9_renderchain_set_final_viewport(
void *data,
void *renderchain_data,
const void *viewport_data)
{
d3d_video_t *d3d = (d3d_video_t*)data;
cg_renderchain_t *chain = (cg_renderchain_t*)renderchain_data;
@ -1011,7 +1016,9 @@ static void cg_d3d9_renderchain_set_final_viewport(void *data,
d3d_recompute_pass_sizes(chain, d3d);
}
static bool cg_d3d9_renderchain_add_pass(void *data, const void *info_data)
static bool cg_d3d9_renderchain_add_pass(
void *data,
const void *info_data)
{
Pass pass;
const LinkInfo *info = (const LinkInfo*)info_data;
@ -1482,7 +1489,9 @@ static bool cg_d3d9_renderchain_render(
return true;
}
static void cg_d3d9_renderchain_set_font_rect(void *data, const void *font_data)
static void cg_d3d9_renderchain_set_font_rect(
void *data,
const void *font_data)
{
settings_t *settings = config_get_ptr();
d3d_video_t *d3d = (d3d_video_t*)data;
@ -1516,7 +1525,7 @@ static void cg_d3d9_renderchain_set_font_rect(void *data, const void *font_data)
d3d->font_rect_shifted.bottom += 2;
}
static bool cg_d3d9_renderchain_read_viewport(void *data, uint8_t *buffer)
static bool cg_d3d9_renderchain_read_viewport(void *data, uint8_t *buffer, bool is_idle)
{
unsigned width, height;
D3DLOCKED_RECT rect;

View File

@ -66,7 +66,7 @@ typedef struct renderchain_driver
unsigned width, unsigned height,
void *final_viewport);
void (*set_font_rect)(void *data, const void *param_data);
bool (*read_viewport)(void *data, uint8_t *buffer);
bool (*read_viewport)(void *data, uint8_t *buffer, bool is_idle);
void (*viewport_info)(void *data, struct video_viewport *vp);
const char *ident;
} renderchain_driver_t;

View File

@ -2338,121 +2338,12 @@ error:
static void gl_viewport_info(void *data, struct video_viewport *vp)
{
unsigned width, height;
unsigned top_y, top_dist;
gl_t *gl = (gl_t*)data;
video_driver_get_size(&width, &height);
*vp = gl->vp;
vp->full_width = width;
vp->full_height = height;
/* Adjust as GL viewport is bottom-up. */
top_y = vp->y + vp->height;
top_dist = height - top_y;
vp->y = top_dist;
gl_renderchain_viewport_info(data, vp);
}
static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle)
{
#ifndef NO_GL_READ_PIXELS
unsigned num_pixels = 0;
gl_t *gl = (gl_t*)data;
if (!gl)
return false;
context_bind_hw_render(false);
num_pixels = gl->vp.width * gl->vp.height;
#ifdef HAVE_GL_ASYNC_READBACK
if (gl->pbo_readback_enable)
{
const uint8_t *ptr = NULL;
/* Don't readback if we're in menu mode.
* We haven't buffered up enough frames yet, come back later. */
if (!gl->pbo_readback_valid[gl->pbo_readback_index])
goto error;
gl->pbo_readback_valid[gl->pbo_readback_index] = false;
glBindBuffer(GL_PIXEL_PACK_BUFFER,
gl->pbo_readback[gl->pbo_readback_index]);
#ifdef HAVE_OPENGLES3
/* Slower path, but should work on all implementations at least. */
ptr = (const uint8_t*)glMapBufferRange(GL_PIXEL_PACK_BUFFER,
0, num_pixels * sizeof(uint32_t), GL_MAP_READ_BIT);
if (ptr)
{
unsigned y;
for (y = 0; y < gl->vp.height; y++)
{
video_frame_convert_rgba_to_bgr(
(const void*)ptr,
buffer,
gl->vp.width);
}
}
#else
ptr = (const uint8_t*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (ptr)
{
struct scaler_ctx *ctx = &gl->pbo_readback_scaler;
scaler_ctx_scale_direct(ctx, buffer, ptr);
}
#endif
if (!ptr)
{
RARCH_ERR("[GL]: Failed to map pixel unpack buffer.\n");
goto error;
}
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
else /* Use slow synchronous readbacks. Use this with plain screenshots
as we don't really care about performance in this case. */
#endif
{
/* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
* readbacks so do just that.
* GLES2 also doesn't support reading back data
* from front buffer, so render a cached frame
* and have gl_frame() do the readback while it's
* in the back buffer.
*
* Keep codepath similar for GLES and desktop GL.
*/
gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t));
if (!gl->readback_buffer_screenshot)
goto error;
if (!is_idle)
video_driver_cached_frame();
video_frame_convert_rgba_to_bgr(
(const void*)gl->readback_buffer_screenshot,
buffer,
num_pixels);
free(gl->readback_buffer_screenshot);
gl->readback_buffer_screenshot = NULL;
}
context_bind_hw_render(true);
return true;
error:
context_bind_hw_render(true);
#endif
return false;
return gl_renderchain_read_viewport(data, buffer, is_idle);
}
#if 0

View File

@ -78,6 +78,10 @@ void gl_renderchain_free(gl_t *gl);
bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height);
void gl_renderchain_viewport_info(void *data, struct video_viewport *vp);
bool gl_renderchain_read_viewport(void *data, uint8_t *buffer, bool is_idle);
void context_bind_hw_render(bool enable);
RETRO_END_DECLS

View File

@ -995,3 +995,122 @@ bool gl_renderchain_add_lut(const struct video_shader *shader,
return true;
}
void gl_renderchain_viewport_info(void *data, struct video_viewport *vp)
{
unsigned width, height;
unsigned top_y, top_dist;
gl_t *gl = (gl_t*)data;
video_driver_get_size(&width, &height);
*vp = gl->vp;
vp->full_width = width;
vp->full_height = height;
/* Adjust as GL viewport is bottom-up. */
top_y = vp->y + vp->height;
top_dist = height - top_y;
vp->y = top_dist;
}
bool gl_renderchain_read_viewport(void *data, uint8_t *buffer, bool is_idle)
{
#ifndef NO_GL_READ_PIXELS
unsigned num_pixels = 0;
gl_t *gl = (gl_t*)data;
if (!gl)
return false;
context_bind_hw_render(false);
num_pixels = gl->vp.width * gl->vp.height;
#ifdef HAVE_GL_ASYNC_READBACK
if (gl->pbo_readback_enable)
{
const uint8_t *ptr = NULL;
/* Don't readback if we're in menu mode.
* We haven't buffered up enough frames yet, come back later. */
if (!gl->pbo_readback_valid[gl->pbo_readback_index])
goto error;
gl->pbo_readback_valid[gl->pbo_readback_index] = false;
glBindBuffer(GL_PIXEL_PACK_BUFFER,
gl->pbo_readback[gl->pbo_readback_index]);
#ifdef HAVE_OPENGLES3
/* Slower path, but should work on all implementations at least. */
ptr = (const uint8_t*)glMapBufferRange(GL_PIXEL_PACK_BUFFER,
0, num_pixels * sizeof(uint32_t), GL_MAP_READ_BIT);
if (ptr)
{
unsigned y;
for (y = 0; y < gl->vp.height; y++)
{
video_frame_convert_rgba_to_bgr(
(const void*)ptr,
buffer,
gl->vp.width);
}
}
#else
ptr = (const uint8_t*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (ptr)
{
struct scaler_ctx *ctx = &gl->pbo_readback_scaler;
scaler_ctx_scale_direct(ctx, buffer, ptr);
}
#endif
if (!ptr)
{
RARCH_ERR("[GL]: Failed to map pixel unpack buffer.\n");
goto error;
}
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
else /* Use slow synchronous readbacks. Use this with plain screenshots
as we don't really care about performance in this case. */
#endif
{
/* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
* readbacks so do just that.
* GLES2 also doesn't support reading back data
* from front buffer, so render a cached frame
* and have gl_frame() do the readback while it's
* in the back buffer.
*
* Keep codepath similar for GLES and desktop GL.
*/
gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t));
if (!gl->readback_buffer_screenshot)
goto error;
if (!is_idle)
video_driver_cached_frame();
video_frame_convert_rgba_to_bgr(
(const void*)gl->readback_buffer_screenshot,
buffer,
num_pixels);
free(gl->readback_buffer_screenshot);
gl->readback_buffer_screenshot = NULL;
}
context_bind_hw_render(true);
return true;
error:
context_bind_hw_render(true);
#endif
return false;
}