From: Henri Verbeet Subject: [PATCH 2/3] d2d1: Store separate bezier vertices. Message-Id: <1481203920-29345-2-git-send-email-hverbeet@codeweavers.com> Date: Thu, 8 Dec 2016 14:31:59 +0100 Signed-off-by: Henri Verbeet --- dlls/d2d1/d2d1_private.h | 15 +++++------- dlls/d2d1/geometry.c | 62 ++++++++++++++++++++++------------------------- dlls/d2d1/render_target.c | 10 ++++---- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 6704ec5..2e05b80 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -285,16 +285,13 @@ enum d2d_geometry_state D2D_GEOMETRY_STATE_FIGURE, }; -struct d2d_bezier +struct d2d_bezier_vertex { + D2D1_POINT_2F position; struct { - D2D1_POINT_2F position; - struct - { - float u, v, sign; - } texcoord; - } v[3]; + float u, v, sign; + } texcoord; }; struct d2d_face @@ -320,8 +317,8 @@ struct d2d_geometry size_t faces_size; size_t face_count; - struct d2d_bezier *beziers; - size_t bezier_count; + struct d2d_bezier_vertex *bezier_vertices; + size_t bezier_vertex_count; } fill; union diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index a04a003..8bdd818 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -118,6 +118,15 @@ struct d2d_fp_fin size_t length; }; +static void d2d_bezier_vertex_set(struct d2d_bezier_vertex *b, + const D2D1_POINT_2F *p, float u, float v, float sign) +{ + b->position = *p; + b->texcoord.u = u; + b->texcoord.v = v; + b->texcoord.sign = sign; +} + static void d2d_fp_two_sum(float *out, float a, float b) { float a_virt, a_round, b_virt, b_round; @@ -1679,7 +1688,7 @@ static BOOL d2d_path_geometry_add_figure(struct d2d_geometry *geometry) static void d2d_geometry_cleanup(struct d2d_geometry *geometry) { - HeapFree(GetProcessHeap(), 0, geometry->fill.beziers); + HeapFree(GetProcessHeap(), 0, geometry->fill.bezier_vertices); HeapFree(GetProcessHeap(), 0, geometry->fill.faces); HeapFree(GetProcessHeap(), 0, geometry->fill.vertices); ID2D1Factory_Release(geometry->factory); @@ -1900,14 +1909,14 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) for (i = 0; i < geometry->u.path.figure_count; ++i) { - geometry->fill.bezier_count += geometry->u.path.figures[i].bezier_control_count; + geometry->fill.bezier_vertex_count += 3 * geometry->u.path.figures[i].bezier_control_count; } - if (!(geometry->fill.beziers = HeapAlloc(GetProcessHeap(), 0, - geometry->fill.bezier_count * sizeof(*geometry->fill.beziers)))) + if (!(geometry->fill.bezier_vertices = HeapAlloc(GetProcessHeap(), 0, + geometry->fill.bezier_vertex_count * sizeof(*geometry->fill.bezier_vertices)))) { - ERR("Failed to allocate beziers array.\n"); - geometry->fill.bezier_count = 0; + ERR("Failed to allocate bezier vertices array.\n"); + geometry->fill.bezier_vertex_count = 0; return E_OUTOFMEMORY; } @@ -1919,44 +1928,31 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) for (j = 0, control_idx = 0; j < figure->vertex_count; ++j) { const D2D1_POINT_2F *p0, *p1, *p2; - struct d2d_bezier *b; + struct d2d_bezier_vertex *b; + float sign = -1.0f; if (figure->vertex_types[j] != D2D_VERTEX_TYPE_BEZIER) continue; - b = &geometry->fill.beziers[bezier_idx]; + b = &geometry->fill.bezier_vertices[bezier_idx * 3]; p0 = &figure->vertices[j]; p1 = &figure->bezier_controls[control_idx++]; - if (j == figure->vertex_count - 1) - p2 = &figure->vertices[0]; - else - p2 = &figure->vertices[j + 1]; - - b->v[0].position = *p0; - b->v[0].texcoord.u = 0.0f; - b->v[0].texcoord.v = 0.0f; - b->v[1].position = *p1; - b->v[1].texcoord.u = 0.5f; - b->v[1].texcoord.v = 0.0f; - b->v[2].position = *p2; - b->v[2].texcoord.u = 1.0f; - b->v[2].texcoord.v = 1.0f; if (d2d_path_geometry_point_inside(geometry, p1, FALSE)) { - b->v[0].texcoord.sign = 1.0f; - b->v[1].texcoord.sign = 1.0f; - b->v[2].texcoord.sign = 1.0f; + sign = 1.0f; d2d_figure_insert_vertex(figure, j + 1, *p1); ++j; } + + if (j == figure->vertex_count - 1) + p2 = &figure->vertices[0]; else - { - b->v[0].texcoord.sign = -1.0f; - b->v[1].texcoord.sign = -1.0f; - b->v[2].texcoord.sign = -1.0f; - } + p2 = &figure->vertices[j + 1]; + d2d_bezier_vertex_set(&b[0], p0, 0.0f, 0.0f, sign); + d2d_bezier_vertex_set(&b[1], p1, 0.5f, 0.0f, sign); + d2d_bezier_vertex_set(&b[2], p2, 1.0f, 1.0f, sign); ++bezier_idx; } } @@ -1990,8 +1986,8 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac done: if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, geometry->fill.beziers); - geometry->fill.bezier_count = 0; + HeapFree(GetProcessHeap(), 0, geometry->fill.bezier_vertices); + geometry->fill.bezier_vertex_count = 0; d2d_path_geometry_free_figures(geometry); geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; } @@ -2685,7 +2681,7 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed if (!refcount) { - geometry->fill.beziers = NULL; + geometry->fill.bezier_vertices = NULL; geometry->fill.faces = NULL; geometry->fill.vertices = NULL; ID2D1Geometry_Release(geometry->u.transformed.src_geometry); diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 40ddecb..74dbfb7 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -717,10 +717,10 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target, ID3D10Buffer_Release(ib); } - if (geometry->fill.bezier_count) + if (geometry->fill.bezier_vertex_count) { - buffer_desc.ByteWidth = geometry->fill.bezier_count * sizeof(*geometry->fill.beziers); - buffer_data.pSysMem = geometry->fill.beziers; + buffer_desc.ByteWidth = geometry->fill.bezier_vertex_count * sizeof(*geometry->fill.bezier_vertices); + buffer_data.pSysMem = geometry->fill.bezier_vertices; if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb))) { @@ -728,8 +728,8 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target, goto done; } - d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, 3 * geometry->fill.bezier_count, vb, - sizeof(*geometry->fill.beziers->v), vs_cb, ps_cb, brush, opacity_brush); + d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, geometry->fill.bezier_vertex_count, vb, + sizeof(*geometry->fill.bezier_vertices), vs_cb, ps_cb, brush, opacity_brush); ID3D10Buffer_Release(vb); } -- 2.1.4