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::allocatorGeom::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