Merge lp:~victored/noise/icon-view-optimizations-1 into lp:~elementary-apps/noise/trunk

Proposed by Victor Martinez
Status: Work in progress
Proposed branch: lp:~victored/noise/icon-view-optimizations-1
Merge into: lp:~elementary-apps/noise/trunk
Diff against target: 69 lines (+25/-11)
1 file modified
src/Widgets/FastView/TileView/TileView.vala (+25/-11)
To merge this branch: bzr merge lp:~victored/noise/icon-view-optimizations-1
Reviewer Review Type Date Requested Status
PerfectCarl (community) Needs Information
AnSukkal (community) testing Approve
elementary Apps team Pending
Review via email: mp+225761@code.launchpad.net

Commit message

Optimize Icon View: Set a fixed size for TileRenderer to avoid unnecessary calls to Gtk.CellRenderer.get_preferred_width and Gtk.CellRenderer.get_preferred_height_for_width.

Description of the change

I'm receiving many complaints about the current grid view being slow when resizing.

While I would always prefer a slow-to-resize view (we don't resize windows that often) over a fast grid that is permanently misaligned and looks ugly, I have to admit we can still try to do something about it.

This is the first optimization branch. TileRenderer.vala is fast at drawing, and no optimizations are really needed there. The size calculation methods (TileRenderer.get_preferred_*) were being called hundreds of times, as expected during drawing and layouting operations, wasting processor time since they always return the same result after size calculations.

To avoid this, this code calls Gtk.CellRenderer.set_fixed_size, so that successive size calculations are not ever required again. I've found this to smooth the drawing process a lot, but it's not totally smooth yet (see TODO).

TODO on next branch: As pointed out in the code, the current two operations slowing down resizing are Gtk.IconView.set_columns and Gtk.IconView.set_column_spacing, which trigger expensive functions. These are called from TileView.size_allocate to apply an ideal layout spacing to the grid.

To post a comment you must log in.
Revision history for this message
AnSukkal (ansukkal) :
review: Approve (testing)
Revision history for this message
PerfectCarl (name-is-carl) wrote :

What is the difference from this branch and https://code.launchpad.net/~victored/noise/grid-view-optimizations-2 ?

Could someone merge those two branches and test whether the result actually make any real difference?

review: Needs Information

Unmerged revisions

1634. By Victor Martinez

Optimize Icon View: Set a fixed size for TileRenderer to avoid unnecessary calls to Gtk.CellRenderer.get_preferred_width and Gtk.CellRenderer.get_preferred_height_for_width.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Widgets/FastView/TileView/TileView.vala'
2--- src/Widgets/FastView/TileView/TileView.vala 2014-05-03 22:20:19 +0000
3+++ src/Widgets/FastView/TileView/TileView.vala 2014-07-06 18:56:53 +0000
4@@ -7,6 +7,7 @@
5
6 public class Noise.Widgets.TileView : Gtk.IconView {
7 private const int MIN_HORIZONTAL_SPACING = 12;
8+ private const int MIN_ITEM_WIDTH = 100;
9
10 private const string STYLESHEET = """
11 /* general background color and texture */
12@@ -40,6 +41,7 @@
13 """;
14
15 private Gtk.CellRenderer cell_renderer = new TileRenderer ();
16+ private int sample_item_width = 0;
17
18 public int image_column {
19 set {
20@@ -80,25 +82,37 @@
21
22 public override void size_allocate (Gtk.Allocation alloc) {
23 // This assumes that the width of the sample is the width of every item
24- Gtk.Requisition minimum_size, natural_size;
25- cell_renderer.get_preferred_size (this, out minimum_size, out natural_size);
26- int item_width = minimum_size.width;
27+ if (sample_item_width < MIN_ITEM_WIDTH) {
28+ Gtk.Requisition minimum_size, natural_size;
29+ cell_renderer.get_preferred_size (this, out minimum_size, out natural_size);
30+ sample_item_width = minimum_size.width;
31
32- if (item_width <= 0)
33- base.size_allocate (alloc);
34+ // Once we detect a sane size for the renderer, set a fixed size
35+ // to avoid expensive calls to the get_preferred_width and
36+ // get_preferred_height_for_width from this point on. These are
37+ // always called multiple times when redrawing and waste a lot of
38+ // processor time.
39+ if (cell_renderer.width <= 0 && sample_item_width > MIN_ITEM_WIDTH)
40+ cell_renderer.set_fixed_size (natural_size.width, natural_size.height);
41+ }
42
43 int total_width = alloc.width;
44
45 // Find out how many items fit in a single row
46 double num = total_width + MIN_HORIZONTAL_SPACING - 2 * margin;
47- double denom = item_width + MIN_HORIZONTAL_SPACING;
48- columns = (int) (num / denom);
49+ double denom = sample_item_width + MIN_HORIZONTAL_SPACING;
50+ int n_columns = (int) (num / denom);
51
52 // Find ideal column spacing
53- num = total_width - columns * item_width - 2 * margin;
54- denom = columns - 1;
55- column_spacing = (int) (num / denom);
56+ num = total_width - n_columns * sample_item_width - 2 * margin;
57+ denom = n_columns - 1;
58+ int ideal_spacing = (int) (num / denom);
59+
60+ // These are expensive operations. Might be a good idea to run the very
61+ // last one from a main loop timeout callback for better performance.
62+ set_columns (n_columns);
63+ set_column_spacing (ideal_spacing);
64
65 base.size_allocate (alloc);
66 }
67-}
68\ No newline at end of file
69+}

Subscribers

People subscribed via source and target branches