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 "w32_common.h"
#include "sub/osd.h"
#include "bitmap_packer.h"
// shaders generated by fxc.exe from d3d_shader_yuv.hlsl
#include "d3d_shader_420p.h"
@ -105,7 +104,6 @@ struct osdpart {
struct d3dtex texture;
int num_vertices;
vertex_osd *vertices;
struct bitmap_packer *packer;
};
enum shaders {
@ -1215,13 +1213,8 @@ static int preinit(struct vo *vo)
priv->vo = vo;
priv->log = vo->log;
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct osdpart *osd = talloc_ptrtype(priv, osd);
*osd = (struct osdpart) {
.packer = talloc_zero(osd, struct bitmap_packer),
};
priv->osd[n] = osd;
}
for (int n = 0; n < MAX_OSD_PARTS; n++)
priv->osd[n] = talloc_zero(priv, struct osdpart);
priv->d3d9_dll = LoadLibraryA("d3d9.dll");
if (!priv->d3d9_dll) {
@ -1536,34 +1529,45 @@ error_exit:
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,
struct sub_bitmaps *imgs)
{
D3DFORMAT fmt = priv->osd_fmt_table[imgs->format];
osd->packer->w_max = priv->max_texture_width;
osd->packer->h_max = priv->max_texture_height;
assert(imgs->packed);
osd->packer->padding = imgs->scaled; // assume 2x2 filter on scaling
int r = packer_pack_from_subbitmaps(osd->packer, imgs);
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;
}
osd->change_id = imgs->change_id;
osd->num_vertices = 0;
if (osd->packer->w > osd->texture.tex_w
|| osd->packer->h > osd->texture.tex_h
if (imgs->packed_w > osd->texture.tex_w
|| imgs->packed_h > osd->texture.tex_h
|| osd->format != imgs->format)
{
osd->format = imgs->format;
int new_w = osd->packer->w;
int new_h = osd->packer->h;
int new_w = next_pow2(imgs->packed_w);
int new_h = next_pow2(imgs->packed_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_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
}
struct pos bb[2];
packer_get_bb(osd->packer, bb);
RECT dirty_rc = { bb[0].x, bb[0].y, bb[1].x, bb[1].y };
RECT dirty_rc = { 0, 0, imgs->packed_w, imgs->packed_h };
D3DLOCKED_RECT locked_rect;
@ -1586,15 +1588,50 @@ static bool upload_osd(d3d_priv *priv, struct osdpart *osd,
}
int ps = fmt == D3DFMT_A8 ? 1 : 4;
packer_copy_subbitmaps(osd->packer, imgs, locked_rect.pBits, ps,
locked_rect.Pitch);
memcpy_pic(locked_rect.pBits, imgs->packed->planes[0], ps * imgs->packed_w,
imgs->packed_h, locked_rect.Pitch, imgs->packed->stride[0]);
if (FAILED(IDirect3DTexture9_UnlockRect(osd->texture.system, 0))) {
MP_ERR(priv, "OSD texture unlock failed.\n");
return false;
}
return d3dtex_update(priv, &osd->texture);
if (!d3dtex_update(priv, &osd->texture))
return false;
// We need 2 primitives per quad which makes 6 vertices.
osd->num_vertices = imgs->num_parts * 6;
MP_TARRAY_GROW(osd, osd->vertices, osd->num_vertices);
float tex_w = osd->texture.tex_w;
float tex_h = osd->texture.tex_h;
for (int n = 0; n < imgs->num_parts; n++) {
struct sub_bitmap *b = &imgs->parts[n];
D3DCOLOR color = imgs->format == SUBBITMAP_LIBASS
? ass_to_d3d_color(b->libass.color)
: D3DCOLOR_ARGB(255, 255, 255, 255);
float x0 = b->x;
float y0 = b->y;
float x1 = b->x + b->dw;
float y1 = b->y + b->dh;
float tx0 = b->src_x / tex_w;
float ty0 = b->src_y / tex_h;
float tx1 = (b->src_x + b->w) / tex_w;
float ty1 = (b->src_y + b->h) / tex_h;
vertex_osd *v = &osd->vertices[n * 6];
v[0] = (vertex_osd) { x0, y0, 0, color, tx0, ty0 };
v[1] = (vertex_osd) { x1, y0, 0, color, tx1, ty0 };
v[2] = (vertex_osd) { x0, y1, 0, color, tx0, ty1 };
v[3] = (vertex_osd) { x1, y1, 0, color, tx1, ty1 };
v[4] = v[2];
v[5] = v[1];
}
return true;
}
static struct osdpart *generate_osd(d3d_priv *priv, struct sub_bitmaps *imgs)
@ -1604,24 +1641,10 @@ static struct osdpart *generate_osd(d3d_priv *priv, struct sub_bitmaps *imgs)
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;
if (imgs->change_id != osd->change_id)
upload_osd(priv, osd, imgs);
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);
return osd->num_vertices ? osd : NULL;
}
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
@ -1632,44 +1655,6 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *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_h = osd->texture.tex_h;
for (int n = 0; n < osd->packer->count; n++) {
struct sub_bitmap *b = &imgs->parts[n];
struct pos p = osd->packer->result[n];
D3DCOLOR color = imgs->format == SUBBITMAP_LIBASS
? ass_to_d3d_color(b->libass.color)
: D3DCOLOR_ARGB(255, 255, 255, 255);
float x0 = b->x;
float y0 = b->y;
float x1 = b->x + b->dw;
float y1 = b->y + b->dh;
float tx0 = p.x / tex_w;
float ty0 = p.y / tex_h;
float tx1 = (p.x + b->w) / tex_w;
float ty1 = (p.y + b->h) / tex_h;
vertex_osd *v = &osd->vertices[n * 6];
v[0] = (vertex_osd) { x0, y0, 0, color, tx0, ty0 };
v[1] = (vertex_osd) { x1, y0, 0, color, tx1, ty0 };
v[2] = (vertex_osd) { x0, y1, 0, color, tx0, ty1 };
v[3] = (vertex_osd) { x1, y1, 0, color, tx1, ty1 };
v[4] = v[2];
v[5] = v[1];
}
}
d3d_begin_scene(priv);
IDirect3DDevice9_SetRenderState(priv->d3d_device,