mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Move read_viewport and viewport_info to render_chain_gl_legacy.c
This commit is contained in:
parent
faafa2def0
commit
32c91baca6
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
113
gfx/drivers/gl.c
113
gfx/drivers/gl.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user