vo_direct3d: remove bitmap packer

See previous comments.
This commit is contained in:
wm4 2016-07-01 20:21:15 +02:00
parent c0f272fcd1
commit fd5098a409
1 changed files with 70 additions and 85 deletions

View File

@ -38,7 +38,6 @@
#include "common/common.h" #include "common/common.h"
#include "w32_common.h" #include "w32_common.h"
#include "sub/osd.h" #include "sub/osd.h"
#include "bitmap_packer.h"
// shaders generated by fxc.exe from d3d_shader_yuv.hlsl // shaders generated by fxc.exe from d3d_shader_yuv.hlsl
#include "d3d_shader_420p.h" #include "d3d_shader_420p.h"
@ -105,7 +104,6 @@ struct osdpart {
struct d3dtex texture; struct d3dtex texture;
int num_vertices; int num_vertices;
vertex_osd *vertices; vertex_osd *vertices;
struct bitmap_packer *packer;
}; };
enum shaders { enum shaders {
@ -1215,13 +1213,8 @@ static int preinit(struct vo *vo)
priv->vo = vo; priv->vo = vo;
priv->log = vo->log; priv->log = vo->log;
for (int n = 0; n < MAX_OSD_PARTS; n++) { for (int n = 0; n < MAX_OSD_PARTS; n++)
struct osdpart *osd = talloc_ptrtype(priv, osd); priv->osd[n] = talloc_zero(priv, struct osdpart);
*osd = (struct osdpart) {
.packer = talloc_zero(osd, struct bitmap_packer),
};
priv->osd[n] = osd;
}
priv->d3d9_dll = LoadLibraryA("d3d9.dll"); priv->d3d9_dll = LoadLibraryA("d3d9.dll");
if (!priv->d3d9_dll) { if (!priv->d3d9_dll) {
@ -1536,34 +1529,45 @@ error_exit:
return NULL; return NULL;
} }
static D3DCOLOR ass_to_d3d_color(uint32_t color)
{
uint32_t r = (color >> 24) & 0xff;
uint32_t g = (color >> 16) & 0xff;
uint32_t b = (color >> 8) & 0xff;
uint32_t a = 0xff - (color & 0xff);
return D3DCOLOR_ARGB(a, r, g, b);
}
static int next_pow2(int v)
{
for (int x = 0; x < 30; x++) {
if ((1 << x) >= v)
return 1 << x;
}
return INT_MAX;
}
static bool upload_osd(d3d_priv *priv, struct osdpart *osd, static bool upload_osd(d3d_priv *priv, struct osdpart *osd,
struct sub_bitmaps *imgs) struct sub_bitmaps *imgs)
{ {
D3DFORMAT fmt = priv->osd_fmt_table[imgs->format]; D3DFORMAT fmt = priv->osd_fmt_table[imgs->format];
osd->packer->w_max = priv->max_texture_width; assert(imgs->packed);
osd->packer->h_max = priv->max_texture_height;
osd->packer->padding = imgs->scaled; // assume 2x2 filter on scaling osd->change_id = imgs->change_id;
int r = packer_pack_from_subbitmaps(osd->packer, imgs); osd->num_vertices = 0;
if (r < 0) {
MP_ERR(priv, "OSD bitmaps do not fit on "
"a surface with the maximum supported size %dx%d.\n",
osd->packer->w_max, osd->packer->h_max);
return false;
}
if (osd->packer->w > osd->texture.tex_w if (imgs->packed_w > osd->texture.tex_w
|| osd->packer->h > osd->texture.tex_h || imgs->packed_h > osd->texture.tex_h
|| osd->format != imgs->format) || osd->format != imgs->format)
{ {
osd->format = imgs->format; osd->format = imgs->format;
int new_w = osd->packer->w; int new_w = next_pow2(imgs->packed_w);
int new_h = osd->packer->h; int new_h = next_pow2(imgs->packed_h);
d3d_fix_texture_size(priv, &new_w, &new_h); d3d_fix_texture_size(priv, &new_w, &new_h);
MP_DBG(priv, "reallocate OSD surface.\n"); MP_DBG(priv, "reallocate OSD surface to %dx%d.\n", new_w, new_h);
d3dtex_release(priv, &osd->texture); d3dtex_release(priv, &osd->texture);
d3dtex_allocate(priv, &osd->texture, fmt, new_w, new_h); d3dtex_allocate(priv, &osd->texture, fmt, new_w, new_h);
@ -1572,9 +1576,7 @@ static bool upload_osd(d3d_priv *priv, struct osdpart *osd,
return false; // failed to allocate return false; // failed to allocate
} }
struct pos bb[2]; RECT dirty_rc = { 0, 0, imgs->packed_w, imgs->packed_h };
packer_get_bb(osd->packer, bb);
RECT dirty_rc = { bb[0].x, bb[0].y, bb[1].x, bb[1].y };
D3DLOCKED_RECT locked_rect; D3DLOCKED_RECT locked_rect;
@ -1586,66 +1588,26 @@ static bool upload_osd(d3d_priv *priv, struct osdpart *osd,
} }
int ps = fmt == D3DFMT_A8 ? 1 : 4; int ps = fmt == D3DFMT_A8 ? 1 : 4;
packer_copy_subbitmaps(osd->packer, imgs, locked_rect.pBits, ps, memcpy_pic(locked_rect.pBits, imgs->packed->planes[0], ps * imgs->packed_w,
locked_rect.Pitch); imgs->packed_h, locked_rect.Pitch, imgs->packed->stride[0]);
if (FAILED(IDirect3DTexture9_UnlockRect(osd->texture.system, 0))) { if (FAILED(IDirect3DTexture9_UnlockRect(osd->texture.system, 0))) {
MP_ERR(priv, "OSD texture unlock failed.\n"); MP_ERR(priv, "OSD texture unlock failed.\n");
return false; return false;
} }
return d3dtex_update(priv, &osd->texture); if (!d3dtex_update(priv, &osd->texture))
} return false;
static struct osdpart *generate_osd(d3d_priv *priv, struct sub_bitmaps *imgs) // We need 2 primitives per quad which makes 6 vertices.
{ osd->num_vertices = imgs->num_parts * 6;
if (imgs->num_parts == 0 || !priv->osd_fmt_table[imgs->format]) MP_TARRAY_GROW(osd, osd->vertices, osd->num_vertices);
return NULL;
struct osdpart *osd = priv->osd[imgs->render_index];
if (imgs->change_id != osd->change_id) {
if (!upload_osd(priv, osd, imgs))
osd->packer->count = 0;
osd->change_id = imgs->change_id;
osd->num_vertices = 0;
}
return osd->packer->count ? osd : NULL;
}
static D3DCOLOR ass_to_d3d_color(uint32_t color)
{
uint32_t r = (color >> 24) & 0xff;
uint32_t g = (color >> 16) & 0xff;
uint32_t b = (color >> 8) & 0xff;
uint32_t a = 0xff - (color & 0xff);
return D3DCOLOR_ARGB(a, r, g, b);
}
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
{
d3d_priv *priv = ctx;
struct osdpart *osd = generate_osd(priv, imgs);
if (!osd)
return;
if (osd->packer->count && !osd->num_vertices) {
// We need 2 primitives per quad which makes 6 vertices (we could reduce
// the number of vertices by using an indexed vertex array, but it's
// probably not worth doing)
osd->num_vertices = osd->packer->count * 6;
osd->vertices = talloc_realloc(osd, osd->vertices, vertex_osd,
osd->num_vertices);
float tex_w = osd->texture.tex_w; float tex_w = osd->texture.tex_w;
float tex_h = osd->texture.tex_h; float tex_h = osd->texture.tex_h;
for (int n = 0; n < osd->packer->count; n++) { for (int n = 0; n < imgs->num_parts; n++) {
struct sub_bitmap *b = &imgs->parts[n]; struct sub_bitmap *b = &imgs->parts[n];
struct pos p = osd->packer->result[n];
D3DCOLOR color = imgs->format == SUBBITMAP_LIBASS D3DCOLOR color = imgs->format == SUBBITMAP_LIBASS
? ass_to_d3d_color(b->libass.color) ? ass_to_d3d_color(b->libass.color)
@ -1655,10 +1617,10 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
float y0 = b->y; float y0 = b->y;
float x1 = b->x + b->dw; float x1 = b->x + b->dw;
float y1 = b->y + b->dh; float y1 = b->y + b->dh;
float tx0 = p.x / tex_w; float tx0 = b->src_x / tex_w;
float ty0 = p.y / tex_h; float ty0 = b->src_y / tex_h;
float tx1 = (p.x + b->w) / tex_w; float tx1 = (b->src_x + b->w) / tex_w;
float ty1 = (p.y + b->h) / tex_h; float ty1 = (b->src_y + b->h) / tex_h;
vertex_osd *v = &osd->vertices[n * 6]; vertex_osd *v = &osd->vertices[n * 6];
v[0] = (vertex_osd) { x0, y0, 0, color, tx0, ty0 }; v[0] = (vertex_osd) { x0, y0, 0, color, tx0, ty0 };
@ -1668,8 +1630,31 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
v[4] = v[2]; v[4] = v[2];
v[5] = v[1]; v[5] = v[1];
} }
return true;
} }
static struct osdpart *generate_osd(d3d_priv *priv, struct sub_bitmaps *imgs)
{
if (imgs->num_parts == 0 || !priv->osd_fmt_table[imgs->format])
return NULL;
struct osdpart *osd = priv->osd[imgs->render_index];
if (imgs->change_id != osd->change_id)
upload_osd(priv, osd, imgs);
return osd->num_vertices ? osd : NULL;
}
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
{
d3d_priv *priv = ctx;
struct osdpart *osd = generate_osd(priv, imgs);
if (!osd)
return;
d3d_begin_scene(priv); d3d_begin_scene(priv);
IDirect3DDevice9_SetRenderState(priv->d3d_device, IDirect3DDevice9_SetRenderState(priv->d3d_device,