summaryrefslogtreecommitdiffstats
path: root/libvo/vo_opengl_old.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/vo_opengl_old.c')
-rw-r--r--libvo/vo_opengl_old.c411
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;