I wanted to mention that I started a github fork of non, where I'll be
working on improving Non Sequencer, starting with optimizing the graphics
display.
Here is the URL:
https://github.com/Element-Green/non

I also wanted to post some of my analysis on the current system for
validation as well as offer up some ideas as to how to improve things.

My initial analysis is with the default pattern view.

>From what I can tell the current graphics rendering in canvas.C and tightly
coupled grid.C has very minimal optimization in regards to restricting the
area of redraws.  Most operations trigger a redraw of everything within the
canvas, which seems to include the ruler, background grid, row labels and
the note preview.  grid.C seems to be a class which manages the note data
and abstracts it as a grid, where canvas.C is responsible for the actual
display of this data.  The display is updated in reference to changes to
the grid.C note data via the signal_events_change signal, which in its
current implementation triggers a redraw of everything.  This means simple
operations like changing the velocity or duration of a note, consume lots
of CPU, and on my system at least, makes Non Sequencer pretty unusable in
its current "in development" form.

Some ideas for improving this, for which I would appreciate feedback and
comments:

Split the note canvas into 3 "layers":

Background Layer - Render as an off screen buffer, for the grid lines and
beat highlights.  Perhaps rendering a subset of the grid and tiling it
would make sense to cut down on memory, but not sure if that would be
faster or not.

Main Layer - Also drawn to an off screen buffer (but with alpha), contains
all the drawn note dashes.

Overlay Layer - Probably best to have this just be drawn as needed, rather
than double buffering it.  Contains the play head, box selections, loop
lines and perhaps also note dragging.


The signal_events_change signal could be modified to pass a start tick_t,
note and duration tick_t value, which would indicate what area of the grid
needs updating.  There would still be the ability to signal a complete
redraw (by passing a 0 duration perhaps or providing a different signal for
that purpose).  canvas.C could catch this signal and only redraw the part
of the grid that has changed.  For example, when changing the velocity of a
note, only the grid area of the note would signal.  If a duration was
changed, the larger of the old and new durations would be signaled.
 Operations which cause changes to multiple areas could do multiple updates
(for example selecting a new note, which causes an old note to become
unselected).

The draw_notes() function in grid.C could be updated to include a
restricted grid region, when redrawing notes.

The actual canvas draw() method could then accept regions from NTK and
simply composite the 3 layers for expose updates, etc.


Any thoughts on this line of thinking would be much appreciated.  I'd like
to start in on this work, but want to make sure I'm not totally off and
also to try and identify any obvious pitfalls I might be overlooking.

Cheers!

Element Green

Reply via email to