This is copy/paste from PnlMultiPaned. The feature we want from
it is the ability to resize paned halves based on their natural
sizing up until the user has manually changed the paned handle
position.
When we find ourselves on a HiDPI display, we need to make sure
we setup the device scale factor properly and adjust our render
checks for valid surface sizes.
Generally we want this thing hidden, so only show it if we have
zoomed in enough to cause it to be useful.
We need to also find a way for the container to be able to
handle the change in size request and adjust the GtkPaned
to be non-ugly.
We don't want to cache all the datapoints from the underlying
capture, just the datapoints for the visible region (and some
at the edges so we get proper cairo_curve_to() x,y coordinates).
This isn't a major optimization yet until we start supporting
much larger capture sizes. But that will mostly be improved with
capture indexes anyway.
There are lots of little things that need fixing, such as the
ticks positioning, and reusing surfaces as much as possible, but
this gets our "MVP" panning in place.
If we don't have a minute worth of input, we should shrink the
visible area to exactly what we came across.
We still have the issue of the UI creating the capture file
before auth has completed, but we can fix that later so we
have a "semantically" correct start time.
These signals are emitted when a visualizer row has been added
or removed from the view. This might be handy if you want to
resize a paned based on the natural size of the visualizers.
This adds a new helper widget SpVisualizerView to simplify using
visualizers from applications using libsysprof-ui-2 such as
Builder.
We can manage the view range, zoom, etc from this widget going
forward.
We need a simple helper to choose colors for visualizers so
they do not overlap. This is just a simple cycle using some
predefined colors.
We should come up with something more unique in the future or
possibly do this with CSS and :nth-child(n) once we have access
to CSS nodes.
We need some sort of scale for content, so we will do this with
an overlay for now. However, we will also want something to be
able to do selections in the future.
This still needs some iteration for correctness, but this sort
of gets the ball rolling.
If we have not yet received our proper draw for the new size
allocation (likely right after the size allocate), then we can
just use the old surface but at a scaled value. This is handy
so that we don't block the main loop trying to do drawing of
lots of data points. Instead we just scale the image and wait
for the high-quality version to complete.
This starts getting the mechanics in place for off screen
rendering using a cairo image surface. We create our own
point cache for storing x,y pairs and then simplify our
drawing based on that.
When creating our private reader copy, we need to reset the
reader so that we start at the beginning. Otherwise, we are
likely to be at the end of the capture (especially for in
memory captures).
This is a simple cache that keeps x,y pairs for use when drawing
visualizers. To keep this generic, and save on memory, we simply
store the x,y coordinates as floats between 0.0 and 1.0. This
saves us roughly 50% on each data point over the 2 8-byte
numbers we would otherwise store.
Obviously, we could take this further and make some fancy index
storage with run-length-encode values, but this should work for
now and allow us to get more exotic later.
This provides the plumbing to do the threaded drawing, we just
need to write the capture cursor and draw operations from the
pixman/cairo worker thread (and do so safely).
This requires that both the left and right condition evaluate
to TRUE. We obviously will want to add more of these for things
like OR, NOT, etc. However, we can add them as necessary since
they are fairly self contained patches.
This lets us focus on the query of "show me all events related
to counter X" rather than the implementation details. Which
means later on, if we build a real index, we can optimize this
without changing user code.
This API helps us simplify some of the tooling to iterate
through a capture. In particular, we might want to setup a
bunch of matches and then just iterate through the items.
This can also allow delaying the iteration until the future
which might be handy for visualizers which won't want to block
the main loop.
I'm not jazzed about the 64k buffer created for every cursor
due to the SpCaptureReader copy, but it's probably not a big
deal in practice until we start doing more exotic things.