vo_opengl: don't rely on viewport to contain window dimensions

Apparently we don't always set the viewport to window dimensions
anymore, e.g. if nothing is actually rendered. This means the viewport
can contain old values.

The window screenshot code uses the viewport values to guess the default
framebuffer dimensions. With --force-window --idle --no-osc (which draws
nothing and issues a glClear() command only), taking a screenshot would
yield an image with the wrong size and possibly garbage in it. Fix this
by explicitly passing the currently known window dimensions. Abusing the
values stored in the viewport was questionable anyway.
This commit is contained in:
wm4 2016-12-02 15:26:45 +01:00
parent ec74a79e12
commit 09238a9bb5
3 changed files with 7 additions and 9 deletions

View File

@ -100,13 +100,11 @@ void gl_upload_tex(GL *gl, GLenum target, GLenum format, GLenum type,
gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
mp_image_t *gl_read_window_contents(GL *gl)
mp_image_t *gl_read_window_contents(GL *gl, int w, int h)
{
if (gl->es)
return NULL; // ES can't read from front buffer
GLint vp[4]; //x, y, w, h
gl->GetIntegerv(GL_VIEWPORT, vp);
mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, vp[2], vp[3]);
mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, w, h);
if (!image)
return NULL;
gl->BindFramebuffer(GL_FRAMEBUFFER, gl->main_fb);
@ -114,9 +112,8 @@ mp_image_t *gl_read_window_contents(GL *gl)
gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
gl->ReadBuffer(obj);
//flip image while reading (and also avoid stride-related trouble)
for (int y = 0; y < vp[3]; y++) {
gl->ReadPixels(vp[0], vp[1] + vp[3] - y - 1, vp[2], 1,
GL_RGB, GL_UNSIGNED_BYTE,
for (int y = 0; y < h; y++) {
gl->ReadPixels(0, h - y - 1, w, 1, GL_RGB, GL_UNSIGNED_BYTE,
image->planes[0] + y * image->stride[0]);
}
gl->PixelStorei(GL_PACK_ALIGNMENT, 4);

View File

@ -30,7 +30,7 @@ void gl_upload_tex(GL *gl, GLenum target, GLenum format, GLenum type,
const void *dataptr, int stride,
int x, int y, int w, int h);
mp_image_t *gl_read_window_contents(GL *gl);
mp_image_t *gl_read_window_contents(GL *gl, int w, int h);
const char* mp_sampler_type(GLenum texture_target);

View File

@ -272,7 +272,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
return VO_NOTIMPL;
}
case VOCTRL_SCREENSHOT_WIN: {
struct mp_image *screen = gl_read_window_contents(p->gl);
struct mp_image *screen =
gl_read_window_contents(p->gl, vo->dwidth, vo->dheight);
if (!screen)
break; // redirect to backend
// set image parameters according to the display, if possible