mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 04:20:27 +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)
|
!d3d->renderchain_driver->read_viewport)
|
||||||
return false;
|
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,
|
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(
|
static void cg_d3d9_renderchain_convert_geometry(
|
||||||
void *data, const void *info_data,
|
void *data,
|
||||||
unsigned *out_width, unsigned *out_height,
|
const void *info_data,
|
||||||
unsigned width, unsigned height,
|
unsigned *out_width,
|
||||||
|
unsigned *out_height,
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
void *final_viewport_data)
|
void *final_viewport_data)
|
||||||
{
|
{
|
||||||
const LinkInfo *info = (const LinkInfo*)info_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,
|
static void cg_d3d9_renderchain_set_final_viewport(
|
||||||
void *renderchain_data, const void *viewport_data)
|
void *data,
|
||||||
|
void *renderchain_data,
|
||||||
|
const void *viewport_data)
|
||||||
{
|
{
|
||||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||||
cg_renderchain_t *chain = (cg_renderchain_t*)renderchain_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);
|
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;
|
Pass pass;
|
||||||
const LinkInfo *info = (const LinkInfo*)info_data;
|
const LinkInfo *info = (const LinkInfo*)info_data;
|
||||||
@ -1482,7 +1489,9 @@ static bool cg_d3d9_renderchain_render(
|
|||||||
return true;
|
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();
|
settings_t *settings = config_get_ptr();
|
||||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
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;
|
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;
|
unsigned width, height;
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
|
@ -66,7 +66,7 @@ typedef struct renderchain_driver
|
|||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
void *final_viewport);
|
void *final_viewport);
|
||||||
void (*set_font_rect)(void *data, const void *param_data);
|
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);
|
void (*viewport_info)(void *data, struct video_viewport *vp);
|
||||||
const char *ident;
|
const char *ident;
|
||||||
} renderchain_driver_t;
|
} 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)
|
static void gl_viewport_info(void *data, struct video_viewport *vp)
|
||||||
{
|
{
|
||||||
unsigned width, height;
|
gl_renderchain_viewport_info(data, vp);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle)
|
static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle)
|
||||||
{
|
{
|
||||||
#ifndef NO_GL_READ_PIXELS
|
return gl_renderchain_read_viewport(data, buffer, is_idle);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#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);
|
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);
|
void context_bind_hw_render(bool enable);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
@ -995,3 +995,122 @@ bool gl_renderchain_add_lut(const struct video_shader *shader,
|
|||||||
|
|
||||||
return true;
|
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