diff options
Diffstat (limited to 'libvo/vo_opengl_old.c')
-rw-r--r-- | libvo/vo_opengl_old.c | 411 |
1 files changed, 49 insertions, 362 deletions
diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c index dcb1103b8e..b8b1fd4813 100644 --- a/libvo/vo_opengl_old.c +++ b/libvo/vo_opengl_old.c @@ -26,6 +26,7 @@ #include <string.h> #include <math.h> #include <stdbool.h> +#include <assert.h> #include "config.h" #include "talloc.h" @@ -35,29 +36,18 @@ #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" #include "geometry.h" -#include "osd.h" #include "sub/sub.h" -#include "eosd_packer.h" #include "gl_common.h" +#include "gl_osd.h" #include "aspect.h" #include "fastmemcpy.h" -#include "sub/ass_mp.h" - -//! How many parts the OSD may consist of at most -#define MAX_OSD_PARTS 20 //for gl_priv.use_yuv #define MASK_ALL_YUV (~(1 << YUV_CONVERSION_NONE)) #define MASK_NOT_COMBINERS (~((1 << YUV_CONVERSION_NONE) | (1 << YUV_CONVERSION_COMBINERS))) #define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT)) -struct vertex_eosd { - float x, y; - uint8_t color[4]; - float u, v; -}; - struct gl_priv { MPGLContext *glctx; GL *gl; @@ -66,19 +56,7 @@ struct gl_priv { int use_osd; int scaled_osd; - //! Textures for OSD - GLuint osdtex[MAX_OSD_PARTS]; - //! Alpha textures for OSD - GLuint osdatex[MAX_OSD_PARTS]; - GLuint eosd_texture; - int eosd_texture_width, eosd_texture_height; - struct eosd_packer *eosd; - struct vertex_eosd *eosd_va; - //! Display lists that draw the OSD parts - GLuint osdDispList[MAX_OSD_PARTS]; - GLuint osdaDispList[MAX_OSD_PARTS]; - //! How many parts the OSD currently consists of - int osdtexCnt; + struct mpgl_osd *osd; int osd_color; int use_ycbcr; @@ -137,13 +115,7 @@ static void resize(struct vo *vo, int x, int y) GL *gl = p->gl; mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n", x, y); - if (WinID >= 0) { - int left = 0, top = 0, w = x, h = y; - geometry(&left, &top, &w, &h, vo->dwidth, vo->dheight); - top = y - h - top; - gl->Viewport(left, top, w, h); - } else - gl->Viewport(0, 0, x, y); + gl->Viewport(0, 0, x, y); gl->MatrixMode(GL_PROJECTION); gl->LoadIdentity(); @@ -166,7 +138,6 @@ static void resize(struct vo *vo, int x, int y) gl->MatrixMode(GL_MODELVIEW); gl->LoadIdentity(); - vo_osd_resized(); gl->Clear(GL_COLOR_BUFFER_BIT); vo->want_redraw = true; } @@ -251,133 +222,43 @@ static void update_yuvconv(struct vo *vo) } } -/** - * \brief remove all OSD textures and display-lists, thus clearing it. - */ -static void clearOSD(struct vo *vo) -{ - struct gl_priv *p = vo->priv; - GL *gl = p->gl; - - int i; - if (!p->osdtexCnt) - return; - gl->DeleteTextures(p->osdtexCnt, p->osdtex); - gl->DeleteTextures(p->osdtexCnt, p->osdatex); - for (i = 0; i < p->osdtexCnt; i++) - gl->DeleteLists(p->osdaDispList[i], 1); - for (i = 0; i < p->osdtexCnt; i++) - gl->DeleteLists(p->osdDispList[i], 1); - p->osdtexCnt = 0; -} - -/** - * \brief construct display list from ass image list - * \param img image list to create OSD from. - */ -static void genEOSD(struct vo *vo, mp_eosd_images_t *imgs) +static void draw_osd(struct vo *vo, struct osd_state *osd) { struct gl_priv *p = vo->priv; GL *gl = p->gl; + assert(p->osd); - bool need_repos, need_upload, need_allocate; - eosd_packer_generate(p->eosd, imgs, &need_repos, &need_upload, - &need_allocate); - - if (!need_repos) + if (!p->use_osd) return; - if (!p->eosd_texture) - gl->GenTextures(1, &p->eosd_texture); - - gl->BindTexture(p->target, p->eosd_texture); - - if (need_allocate) { - texSize(vo, p->eosd->surface.w, p->eosd->surface.h, - &p->eosd_texture_width, &p->eosd_texture_height); - // xxx it doesn't need to be cleared, that's a waste of time - glCreateClearTex(gl, p->target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, - GL_NEAREST, p->eosd_texture_width, - p->eosd_texture_height, 0); + if (!p->scaled_osd) { + gl->MatrixMode(GL_PROJECTION); + gl->PushMatrix(); + gl->LoadIdentity(); + gl->Ortho(0, vo->dwidth, vo->dheight, 0, -1, 1); } - // 2 triangles primitives per quad = 6 vertices per quad - // not using GL_QUADS, as it is deprecated in OpenGL 3.x and later - p->eosd_va = talloc_realloc_size(p->eosd, p->eosd_va, - p->eosd->targets_count - * sizeof(struct vertex_eosd) * 6); - - float eosd_w = p->eosd_texture_width; - float eosd_h = p->eosd_texture_height; - - if (p->use_rectangle == 1) - eosd_w = eosd_h = 1.0f; - - for (int n = 0; n < p->eosd->targets_count; n++) { - struct eosd_target *target = &p->eosd->targets[n]; - ASS_Image *i = target->ass_img; + gl->Color4ub((p->osd_color >> 16) & 0xff, (p->osd_color >> 8) & 0xff, + p->osd_color & 0xff, 0xff - (p->osd_color >> 24)); - if (need_upload) { - glUploadTex(gl, p->target, GL_ALPHA, GL_UNSIGNED_BYTE, i->bitmap, - i->stride, target->source.x0, target->source.y0, - i->w, i->h, 0); - } - - uint8_t color[4] = { i->color >> 24, (i->color >> 16) & 0xff, - (i->color >> 8) & 0xff, 255 - (i->color & 0xff) }; - - float x0 = target->dest.x0; - float y0 = target->dest.y0; - float x1 = target->dest.x1; - float y1 = target->dest.y1; - float tx0 = target->source.x0 / eosd_w; - float ty0 = target->source.y0 / eosd_h; - float tx1 = target->source.x1 / eosd_w; - float ty1 = target->source.y1 / eosd_h; - -#define COLOR_INIT {color[0], color[1], color[2], color[3]} - struct vertex_eosd *va = &p->eosd_va[n * 6]; - va[0] = (struct vertex_eosd) { x0, y0, COLOR_INIT, tx0, ty0 }; - va[1] = (struct vertex_eosd) { x0, y1, COLOR_INIT, tx0, ty1 }; - va[2] = (struct vertex_eosd) { x1, y0, COLOR_INIT, tx1, ty0 }; - va[3] = (struct vertex_eosd) { x1, y1, COLOR_INIT, tx1, ty1 }; - va[4] = va[2]; - va[5] = va[1]; -#undef COLOR_INIT + struct mp_osd_res res = { + .w = vo->dwidth, + .h = vo->dheight, + .display_par = vo->monitor_par, + .video_par = vo->aspdat.par, + }; + if (p->scaled_osd) { + res.w = p->image_width; + res.h = p->image_height; + } else if (aspect_scaling()) { + res.ml = res.mr = p->ass_border_x; + res.mt = res.mb = p->ass_border_y; } - gl->BindTexture(p->target, 0); -} - -// Note: relies on state being setup, like projection matrix and blending -static void drawEOSD(struct vo *vo) -{ - struct gl_priv *p = vo->priv; - GL *gl = p->gl; - - if (p->eosd->targets_count == 0) - return; - - gl->BindTexture(p->target, p->eosd_texture); + mpgl_osd_draw_legacy(p->osd, osd, res); - struct vertex_eosd *va = p->eosd_va; - size_t stride = sizeof(struct vertex_eosd); - - gl->VertexPointer(2, GL_FLOAT, stride, &va[0].x); - gl->ColorPointer(4, GL_UNSIGNED_BYTE, stride, &va[0].color[0]); - gl->TexCoordPointer(2, GL_FLOAT, stride, &va[0].u); - - gl->EnableClientState(GL_VERTEX_ARRAY); - gl->EnableClientState(GL_TEXTURE_COORD_ARRAY); - gl->EnableClientState(GL_COLOR_ARRAY); - - gl->DrawArrays(GL_TRIANGLES, 0, p->eosd->targets_count * 6); - - gl->DisableClientState(GL_VERTEX_ARRAY); - gl->DisableClientState(GL_TEXTURE_COORD_ARRAY); - gl->DisableClientState(GL_COLOR_ARRAY); - - gl->BindTexture(p->target, 0); + if (!p->scaled_osd) + gl->PopMatrix(); } /** @@ -400,13 +281,9 @@ static void uninitGl(struct vo *vo) if (i) gl->DeleteTextures(i, p->default_texs); p->default_texs[0] = 0; - clearOSD(vo); - if (p->eosd_texture) - gl->DeleteTextures(1, &p->eosd_texture); - eosd_packer_reinit(p->eosd, 0, 0); - p->eosd_texture = 0; - if (gl->DeleteBuffers && p->buffer) - gl->DeleteBuffers(1, &p->buffer); + if (p->osd) + mpgl_osd_destroy(p->osd); + p->osd = NULL; p->buffer = 0; p->buffersize = 0; p->bufferptr = NULL; @@ -519,7 +396,7 @@ static int initGl(struct vo *vo, uint32_t d_width, uint32_t d_height) gl->DepthMask(GL_FALSE); gl->Disable(GL_CULL_FACE); gl->Enable(p->target); - gl->DrawBuffer(vo_doublebuffering ? GL_BACK : GL_FRONT); + gl->DrawBuffer(GL_BACK); gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n", @@ -576,9 +453,8 @@ static int initGl(struct vo *vo, uint32_t d_width, uint32_t d_height) update_yuvconv(vo); } - GLint max_texture_size; - gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - eosd_packer_reinit(p->eosd, max_texture_size, max_texture_size); + p->osd = mpgl_osd_init(gl, true); + p->osd->scaled = p->scaled_osd; resize(vo, d_width, d_height); @@ -646,141 +522,6 @@ static void check_events(struct vo *vo) vo->want_redraw = true; } -/** - * Creates the textures and the display list needed for displaying - * an OSD part. - * Callback function for osd_draw_text_ext(). - */ -static void create_osd_texture(void *ctx, int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride) -{ - struct vo *vo = ctx; - struct gl_priv *p = vo->priv; - GL *gl = p->gl; - - // initialize to 8 to avoid special-casing on alignment - int sx = 8, sy = 8; - GLint scale_type = p->scaled_osd ? GL_LINEAR : GL_NEAREST; - - if (w <= 0 || h <= 0 || stride < w) { - mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n"); - return; - } - texSize(vo, w, h, &sx, &sy); - - if (p->osdtexCnt >= MAX_OSD_PARTS) { - mp_msg(MSGT_VO, MSGL_ERR, "Too many OSD parts, contact the developers!\n"); - return; - } - - // create Textures for OSD part - gl->GenTextures(1, &p->osdtex[p->osdtexCnt]); - gl->BindTexture(p->target, p->osdtex[p->osdtexCnt]); - glCreateClearTex(gl, p->target, GL_LUMINANCE, GL_LUMINANCE, - GL_UNSIGNED_BYTE, scale_type, sx, sy, 0); - glUploadTex(gl, p->target, GL_LUMINANCE, GL_UNSIGNED_BYTE, src, stride, - 0, 0, w, h, 0); - - gl->GenTextures(1, &p->osdatex[p->osdtexCnt]); - gl->BindTexture(p->target, p->osdatex[p->osdtexCnt]); - glCreateClearTex(gl, p->target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, - scale_type, sx, sy, 0); - { - int i; - char *tmp = malloc(stride * h); - // convert alpha from weird MPlayer scale. - // in-place is not possible since it is reused for future OSDs - for (i = h * stride - 1; i >= 0; i--) - tmp[i] = -srca[i]; - glUploadTex(gl, p->target, GL_ALPHA, GL_UNSIGNED_BYTE, tmp, stride, - 0, 0, w, h, 0); - free(tmp); - } - - gl->BindTexture(p->target, 0); - - // Create a list for rendering this OSD part - p->osdaDispList[p->osdtexCnt] = gl->GenLists(1); - gl->NewList(p->osdaDispList[p->osdtexCnt], GL_COMPILE); - // render alpha - gl->BindTexture(p->target, p->osdatex[p->osdtexCnt]); - glDrawTex(gl, x0, y0, w, h, 0, 0, w, h, sx, sy, p->use_rectangle == 1, 0, 0); - gl->EndList(); - - p->osdDispList[p->osdtexCnt] = gl->GenLists(1); - gl->NewList(p->osdDispList[p->osdtexCnt], GL_COMPILE); - // render OSD - gl->BindTexture(p->target, p->osdtex[p->osdtexCnt]); - glDrawTex(gl, x0, y0, w, h, 0, 0, w, h, sx, sy, p->use_rectangle == 1, 0, 0); - gl->EndList(); - - p->osdtexCnt++; -} - -#define RENDER_OSD 1 -#define RENDER_EOSD 2 - -/** - * \param type bit 0: render OSD, bit 1: render EOSD - */ -static void do_render_osd(struct vo *vo, int type) -{ - struct gl_priv *p = vo->priv; - GL *gl = p->gl; - - int draw_osd = (type & RENDER_OSD) && p->osdtexCnt > 0; - int draw_eosd = (type & RENDER_EOSD); - if (!draw_osd && !draw_eosd) - return; - // set special rendering parameters - if (!p->scaled_osd) { - gl->MatrixMode(GL_PROJECTION); - gl->PushMatrix(); - gl->LoadIdentity(); - gl->Ortho(0, vo->dwidth, vo->dheight, 0, -1, 1); - } - gl->Enable(GL_BLEND); - if (draw_eosd) { - gl->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - drawEOSD(vo); - } - if (draw_osd) { - gl->Color4ub((p->osd_color >> 16) & 0xff, (p->osd_color >> 8) & 0xff, - p->osd_color & 0xff, 0xff - (p->osd_color >> 24)); - // draw OSD - gl->BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); - gl->CallLists(p->osdtexCnt, GL_UNSIGNED_INT, p->osdaDispList); - gl->BlendFunc(GL_SRC_ALPHA, GL_ONE); - gl->CallLists(p->osdtexCnt, GL_UNSIGNED_INT, p->osdDispList); - } - // set rendering parameters back to defaults - gl->Disable(GL_BLEND); - if (!p->scaled_osd) - gl->PopMatrix(); - gl->BindTexture(p->target, 0); -} - -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct gl_priv *p = vo->priv; - - if (!p->use_osd) - return; - if (vo_osd_has_changed(osd)) { - int osd_h, osd_w; - clearOSD(vo); - osd_w = p->scaled_osd ? p->image_width : vo->dwidth; - osd_h = p->scaled_osd ? p->image_height : vo->dheight; - osd_draw_text_ext(osd, osd_w, osd_h, p->ass_border_x, - p->ass_border_y, p->ass_border_x, - p->ass_border_y, p->image_width, - p->image_height, create_osd_texture, vo); - } - if (vo_doublebuffering) - do_render_osd(vo, RENDER_OSD); -} - static void do_render(struct vo *vo) { struct gl_priv *p = vo->priv; @@ -822,20 +563,11 @@ static void flip_page(struct vo *vo) struct gl_priv *p = vo->priv; GL *gl = p->gl; - if (vo_doublebuffering) { - if (p->use_glFinish) - gl->Finish(); - p->glctx->swapGlBuffers(p->glctx); - if (aspect_scaling()) - gl->Clear(GL_COLOR_BUFFER_BIT); - } else { - do_render(vo); - do_render_osd(vo, RENDER_OSD | RENDER_EOSD); - if (p->use_glFinish) - gl->Finish(); - else - gl->Flush(); - } + if (p->use_glFinish) + gl->Finish(); + p->glctx->swapGlBuffers(p->glctx); + if (aspect_scaling()) + gl->Clear(GL_COLOR_BUFFER_BIT); } static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, @@ -1059,8 +791,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } skip_upload: - if (vo_doublebuffering) - do_render(vo); + do_render(vo); return VO_TRUE; } @@ -1085,36 +816,16 @@ static mp_image_t *get_screenshot(struct vo *vo) gl->ActiveTexture(GL_TEXTURE0); } - image->width = p->image_width; - image->height = p->image_height; + image->w = p->image_width; + image->h = p->image_height; + image->display_w = vo->aspdat.prew; + image->display_h = vo->aspdat.preh; - image->w = vo->aspdat.prew; - image->h = vo->aspdat.preh; + mp_image_set_colorspace_details(image, &p->colorspace); return image; } -static mp_image_t *get_window_screenshot(struct vo *vo) -{ - struct gl_priv *p = vo->priv; - GL *gl = p->gl; - - GLint vp[4]; //x, y, w, h - gl->GetIntegerv(GL_VIEWPORT, vp); - mp_image_t *image = alloc_mpi(vp[2], vp[3], IMGFMT_RGB24); - gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - gl->PixelStorei(GL_PACK_ALIGNMENT, 0); - gl->PixelStorei(GL_PACK_ROW_LENGTH, 0); - gl->ReadBuffer(GL_FRONT); - //flip image while reading - 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, - image->planes[0] + y * image->stride[0]); - } - return image; -} - static int query_format(struct vo *vo, uint32_t format) { struct gl_priv *p = vo->priv; @@ -1123,7 +834,7 @@ static int query_format(struct vo *vo, uint32_t format) int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIP | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; if (p->use_osd) - caps |= VFCAP_OSD | VFCAP_EOSD | (p->scaled_osd ? 0 : VFCAP_EOSD_UNSCALED); + caps |= VFCAP_OSD; if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA) return caps; if (p->use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) && @@ -1182,8 +893,6 @@ static int preinit(struct vo *vo, const char *arg) .osd_color = 0xffffff, }; - p->eosd = eosd_packer_create(vo); - char *backend_arg = NULL; //essentially unused; for legacy warnings only @@ -1359,27 +1068,6 @@ static int control(struct vo *vo, uint32_t request, void *data) return query_format(vo, *(uint32_t *)data); case VOCTRL_DRAW_IMAGE: return draw_image(vo, data); - case VOCTRL_DRAW_EOSD: - if (!data) - return VO_FALSE; - genEOSD(vo, data); - if (vo_doublebuffering) - do_render_osd(vo, RENDER_EOSD); - return VO_TRUE; - case VOCTRL_GET_EOSD_RES: { - mp_eosd_res_t *r = data; - r->w = vo->dwidth; - r->h = vo->dheight; - r->mt = r->mb = r->ml = r->mr = 0; - if (p->scaled_osd) { - r->w = p->image_width; - r->h = p->image_height; - } else if (aspect_scaling()) { - r->ml = r->mr = p->ass_border_x; - r->mt = r->mb = p->ass_border_y; - } - return VO_TRUE; - } case VOCTRL_ONTOP: if (!p->glctx->ontop) break; @@ -1435,8 +1123,7 @@ static int control(struct vo *vo, uint32_t request, void *data) p->glctx->update_xinerama_info(vo); return VO_TRUE; case VOCTRL_REDRAW_FRAME: - if (vo_doublebuffering) - do_render(vo); + do_render(vo); return true; case VOCTRL_PAUSE: if (!p->glctx->pause) @@ -1451,7 +1138,7 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; if (args->full_window) - args->out_image = get_window_screenshot(vo); + args->out_image = glGetWindowScreenshot(p->gl); else args->out_image = get_screenshot(vo); return true; |