From 47d8fd0713226a72e0ab69b0a8856b0a3d3193e0 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 28 Mar 2013 20:40:19 +0100 Subject: gl_video: move video image fields into a struct This is a bit cleaner. Also don't repeat the chroma shift calculations over and over, but store the image size instead, which is simpler and will give us a chance to fix display of non-mod-2 image sizes. --- video/out/gl_video.c | 110 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 42 deletions(-) (limited to 'video') diff --git a/video/out/gl_video.c b/video/out/gl_video.c index c14612be61..2cdf1f597a 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -91,13 +91,19 @@ struct vertex { #define VERTICES_PER_QUAD 6 struct texplane { - int shift_x, shift_y; + int w, h; + int tex_w, tex_h; GLuint gl_texture; int gl_buffer; int buffer_size; void *buffer_ptr; }; +struct video_image { + struct texplane planes[3]; + bool image_flipped; +}; + struct scaler { int index; const char *name; @@ -146,20 +152,20 @@ struct gl_video { uint32_t image_format; int texture_w, texture_h; + struct mp_imgfmt_desc image_desc; + bool is_yuv; bool is_linear_rgb; // per pixel (full pixel when packed, each component when planar) - int plane_bytes; int plane_bits; + int plane_count; GLint gl_internal_format; GLenum gl_format; GLenum gl_type; - int plane_count; - struct texplane planes[3]; - bool image_flipped; + struct video_image image; struct fbotex indirect_fbo; // RGB target struct fbotex scale_sep_fbo; // first pass when doing 2 pass scaling @@ -456,8 +462,7 @@ static void update_uniforms(struct gl_video *p, GLuint program) gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n); gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n), - p->texture_w >> p->planes[n].shift_x, - p->texture_h >> p->planes[n].shift_y); + p->image.planes[n].w, p->image.planes[n].h); } gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"), @@ -637,7 +642,7 @@ static void shader_setup_scaler(char **shader, struct scaler *scaler, int pass) static bool input_is_subsampled(struct gl_video *p) { for (int i = 0; i < p->plane_count; i++) - if (p->planes[i].shift_x || p->planes[i].shift_y) + if (p->image_desc.xs[i] || p->image_desc.ys[i]) return true; return false; } @@ -931,7 +936,7 @@ static void reinit_rendering(struct gl_video *p) uninit_rendering(p); - if (!p->planes[0].gl_texture) + if (!p->image.planes[0].gl_texture) return; init_dither(p); @@ -994,6 +999,19 @@ void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d) debug_check_gl(p, "after 3d lut creation"); } +static void set_image_textures(struct gl_video *p, struct video_image *vimg) +{ + GL *gl = p->gl; + + for (int n = 0; n < p->plane_count; n++) { + struct texplane *plane = &vimg->planes[n]; + + gl->ActiveTexture(GL_TEXTURE0 + n); + gl->BindTexture(GL_TEXTURE_2D, plane->gl_texture); + } + gl->ActiveTexture(GL_TEXTURE0); +} + static void init_video(struct gl_video *p) { GL *gl = p->gl; @@ -1012,27 +1030,34 @@ static void init_video(struct gl_video *p) debug_check_gl(p, "before video texture creation"); - tex_size(p, p->image_w, p->image_h, - &p->texture_w, &p->texture_h); + struct video_image *vimg = &p->image; for (int n = 0; n < p->plane_count; n++) { - struct texplane *plane = &p->planes[n]; + struct texplane *plane = &vimg->planes[n]; + + plane->w = p->image_w >> p->image_desc.xs[n]; + plane->h = p->image_h >> p->image_desc.ys[n]; - int w = p->texture_w >> plane->shift_x; - int h = p->texture_h >> plane->shift_y; + tex_size(p, plane->w, plane->h, + &plane->tex_w, &plane->tex_h); - mp_msg(MSGT_VO, MSGL_V, "[gl] Texture for plane %d: %dx%d\n", n, w, h); + mp_msg(MSGT_VO, MSGL_V, "[gl] Texture for plane %d: %dx%d\n", + n, plane->tex_w, plane->tex_h); gl->ActiveTexture(GL_TEXTURE0 + n); gl->GenTextures(1, &plane->gl_texture); gl->BindTexture(GL_TEXTURE_2D, plane->gl_texture); - gl->TexImage2D(GL_TEXTURE_2D, 0, p->gl_internal_format, w, h, 0, - p->gl_format, p->gl_type, NULL); + gl->TexImage2D(GL_TEXTURE_2D, 0, p->gl_internal_format, + plane->tex_w, plane->tex_h, 0, + p->gl_format, p->gl_type, NULL); default_tex_params(gl, GL_TEXTURE_2D, GL_LINEAR); } gl->ActiveTexture(GL_TEXTURE0); + p->texture_w = p->image.planes[0].tex_w; + p->texture_h = p->image.planes[0].tex_h; + debug_check_gl(p, "after video texture creation"); reinit_rendering(p); @@ -1044,8 +1069,10 @@ static void uninit_video(struct gl_video *p) uninit_rendering(p); + struct video_image *vimg = &p->image; + for (int n = 0; n < 3; n++) { - struct texplane *plane = &p->planes[n]; + struct texplane *plane = &vimg->planes[n]; gl->DeleteTextures(1, &plane->gl_texture); plane->gl_texture = 0; @@ -1098,7 +1125,8 @@ void gl_video_render_frame(struct gl_video *p) { GL *gl = p->gl; struct vertex vb[VERTICES_PER_QUAD]; - bool is_flipped = p->image_flipped; + struct video_image *vimg = &p->image; + bool is_flipped = vimg->image_flipped; if (p->dst_rect.x0 > p->vp_x || p->dst_rect.y0 > p->vp_y || p->dst_rect.x1 < p->vp_x + p->vp_w @@ -1110,10 +1138,12 @@ void gl_video_render_frame(struct gl_video *p) // Order of processing: // [indirect -> [scale_sep ->]] final + set_image_textures(p, vimg); + struct fbotex dummy = { .vp_w = p->image_w, .vp_h = p->image_h, .tex_w = p->texture_w, .tex_h = p->texture_h, - .texture = p->planes[0].gl_texture, + .texture = vimg->planes[0].gl_texture, }; struct fbotex *source = &dummy; @@ -1245,10 +1275,12 @@ static bool get_image(struct gl_video *p, struct mp_image *mpi) if (mpi->num_planes != p->plane_count) return false; + struct video_image *vimg = &p->image; + for (int n = 0; n < p->plane_count; n++) { - struct texplane *plane = &p->planes[n]; - mpi->stride[n] = (mpi->w >> plane->shift_x) * p->plane_bytes; - int needed_size = (mpi->h >> plane->shift_y) * mpi->stride[n]; + struct texplane *plane = &vimg->planes[n]; + mpi->stride[n] = mpi->plane_w[n] * p->image_desc.bytes[n]; + int needed_size = mpi->plane_h[n] * mpi->stride[n]; if (!plane->gl_buffer) gl->GenBuffers(1, &plane->gl_buffer); gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, plane->gl_buffer); @@ -1273,24 +1305,22 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi) assert(mpi->num_planes >= p->plane_count); + struct video_image *vimg = &p->image; + mp_image_t mpi2 = *mpi; - int w = mpi->w, h = mpi->h; bool pbo = false; - if (!p->planes[0].buffer_ptr && get_image(p, &mpi2)) { + if (!vimg->planes[0].buffer_ptr && get_image(p, &mpi2)) { for (n = 0; n < p->plane_count; n++) { - struct texplane *plane = &p->planes[n]; - int xs = plane->shift_x, ys = plane->shift_y; - int line_bytes = (mpi->w >> xs) * p->plane_bytes; - memcpy_pic(mpi2.planes[n], mpi->planes[n], line_bytes, mpi->h >> ys, + int line_bytes = mpi->plane_w[n] * p->image_desc.bytes[n]; + memcpy_pic(mpi2.planes[n], mpi->planes[n], line_bytes, mpi->plane_h[n], mpi2.stride[n], mpi->stride[n]); } mpi = &mpi2; pbo = true; } - p->image_flipped = mpi->stride[0] < 0; + vimg->image_flipped = mpi->stride[0] < 0; for (n = 0; n < p->plane_count; n++) { - struct texplane *plane = &p->planes[n]; - int xs = plane->shift_x, ys = plane->shift_y; + struct texplane *plane = &vimg->planes[n]; void *plane_ptr = mpi->planes[n]; if (pbo) { gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, plane->gl_buffer); @@ -1303,7 +1333,7 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi) gl->ActiveTexture(GL_TEXTURE0 + n); gl->BindTexture(GL_TEXTURE_2D, plane->gl_texture); glUploadTex(gl, GL_TEXTURE_2D, p->gl_format, p->gl_type, plane_ptr, - mpi->stride[n], 0, 0, w >> xs, h >> ys, 0); + mpi->stride[n], 0, 0, plane->w, plane->h, 0); } gl->ActiveTexture(GL_TEXTURE0); gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -1313,7 +1343,9 @@ struct mp_image *gl_video_download_image(struct gl_video *p) { GL *gl = p->gl; - if (!p->planes[0].gl_texture) + struct video_image *vimg = &p->image; + + if (!vimg->planes[0].gl_texture) return NULL; mp_image_t *image = mp_image_alloc(p->image_format, p->texture_w, @@ -1328,7 +1360,7 @@ struct mp_image *gl_video_download_image(struct gl_video *p) for (int n = 0; n < p->plane_count; n++) { gl->ActiveTexture(GL_TEXTURE0 + n); - gl->BindTexture(GL_TEXTURE_2D, p->planes[n].gl_texture); + gl->BindTexture(GL_TEXTURE_2D, vimg->planes[n].gl_texture); glDownloadTex(gl, GL_TEXTURE_2D, p->gl_format, p->gl_type, image->planes[n], image->stride[n]); } @@ -1587,7 +1619,6 @@ static bool init_format(int fmt, struct gl_video *init) if (!supported) return false; - init->plane_bytes = (init->plane_bits + 7) / 8; init->is_yuv = desc.flags & MP_IMGFLAG_YUV; init->is_linear_rgb = false; @@ -1596,12 +1627,7 @@ static bool init_format(int fmt, struct gl_video *init) assert(desc.num_planes >= init->plane_count); assert(desc.num_planes <= init->plane_count + 1); - for (int n = 0; n < init->plane_count; n++) { - struct texplane *plane = &init->planes[n]; - - plane->shift_x = desc.xs[n]; - plane->shift_y = desc.ys[n]; - } + init->image_desc = desc; return true; } -- cgit v1.2.3