In my quest for a more fluid experience with fewer distractions, I've
attempted to multithread the rendering. I see this has been a long
standing discussion:
https://bugs.launchpad.net/inkscape/+bug/200415
https://bugs.launchpad.net/inkscape/+bug/330271
I'm using a Lenovo P40 tablet and the total frame rendering time for a
simple piece is 80 to 100ms (1920x1080, a few hundred vertices on 2
layers with no filter effects - only alpha compositing). This slow
rendering speed makes the touchscreen zooming I recently implemented
very jerky.
So, I tried multithreading SPCanvas::paintRectInternal() with OpenMP
by splitting the rectangle into 2 and rendering them in ||.
I used mutual exclusion for some obviously thread unsafe code like the
call to markRect in SPCanvas::paintSingleBuffer(). The rendering would
work for a few frames before it freezes (waiting threads timeout and
then exit).
Then, I put other calls that I suspected were thread unsafe in
mutually exclusive blocks until I discovered _root->render() isn't
safe. No point in going further.
Excuse my naive attempt. Can anyone guess how feasible it is to
multithread the rendering? For now, I don't care if it's pixel
perfect. I just need something that's decent and doesn't crash/freeze.
I'm also wondering why the Cairo OpenGL backend isn't being used? GPU
rendering on integrated GPUs should give a nice speedup since there
should be no copying overhead.
The other place to optimize is pixman. I did some profiling (rapidly
zooming in and out with touchscreen) and >= 25% of the time is spent
in pixman rendering. I already went ahead and ported a few to AVX2 and
got ~1.3x speedup (should get more since my laptop is bottlenecked by
memory bandwidth owing to having only 1 memory channel).
Function Module
Samples
sse2_blt.part.0
libpixman-1-0.dll 4221
sse2_combine_in_u
libpixman-1-0.dll 2189
sse2_fill
libpixman-1-0.dll 1693
cairo_tor_scan_converter_generate
libcairo-2.dll 1494
sse2_composite_over_8888_8888
libpixman-1-0.dll 1424
bits_image_fetch_separable_convolution_affine_none_a8r8g8b8
libpixman-1-0.dll 1104
feed_curve_to_cairo(_cairo*Geom::Curve const&
libinkscape_base.dll 611
fast_composite_scaled_bilinear_sse2_8888_8888_cover_SRC
libpixman-1-0.dll 475
fill_xrgb32_lerp_opaque_spans
libcairo-2.dll 348
cairo_tor_scan_converter_add_polygon
libcairo-2.dll 260
compute_face
libcairo-2.dll 238
_dynamic_cast
libstdc++-6.dll 209
outer_join
libcairo-2.dll 179
cairo_polygon_add_edge
libcairo-2.dll 178
g_hash_table_lookup
libglib-2.0-0.dll 169
cairo_spline_decompose_into
libcairo-2.dll 153
g_slice_alloc
libglib-2.0-0.dll 138
cairo_spline_intersects
libcairo-2.dll 131
feed_pathvector_to_cairo(_cairo*Geom::PathVector const&)
libinkscape_base.dll 127
line_to
libcairo-2.dll 119
void std::vector<Geom::Pointstd::allocator<Geom::Point>
libinkscape_base.dll 116
cairo_matrix_transform_point
libcairo-2.dll 110
cell_list_render_edge
libcairo-2.dll 106
g_type_check_instance_is_a
libgobject-2.0-0.dll 106