~eliasnaur/gio

4 3

Drawing primitives and op.ImageOp

András Belicza
Details
Message ID
<CAP-HBqmZZ0_Nk5gm=HsXzDL+kmzjbTUbK28THGdiiYOmBXm5YA@mail.gmail.com>
DKIM signature
pass
Download raw message
First, thanks for all your work so far. It's a great initiative which
I hope will mature and grow.

I know gio doesn't support drawing primitives such as lines, curves,
circles. One way to do that would be to draw them on an off-screen
image either manually or using a lib like github.com/fogleman/gg,
and display that image using paint.ImageOp.

Is this the current best approach? How fast is it? I've read gio
caches images and does not send them in every frame (redraw). Does
gio detect if an image changed (e.g. the color of a pixel was
changed), and resend the image? My initial tests showed that image
changes were displayed properly. May I always create a new
paint.ImageOp and still leverage caching, or image caching only works
if the same paint.ImageOp is used in subsequent updates? And does it
send partial change (changed subimage) or the whole image?

Are there any plans to add direct (without drawing on an image first)
primitive drawing capabilities to gio?

Also there is op.InvalidateOp to trigger a frame (update) manually.
Are there plans to support partial updates? Often only small areas of
the window change, it would be efficient to not update the whole
window just some small parts of it (that did change).

Thanks again.
Details
Message ID
<BZOOCHQB7ECW.IV1WUAJW3KLX@testmac>
In-Reply-To
<CAP-HBqmZZ0_Nk5gm=HsXzDL+kmzjbTUbK28THGdiiYOmBXm5YA@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Mon Jan 6, 2020 at 12:13 PM, András Belicza wrote:
> 
> I know gio doesn't support drawing primitives such as lines, curves,
> circles. One way to do that would be to draw them on an off-screen
> image either manually or using a lib like github.com/fogleman/gg,
> and display that image using paint.ImageOp.
>
> 
> Is this the current best approach? How fast is it? I've read gio
> caches images and does not send them in every frame (redraw). Does
> gio detect if an image changed (e.g. the color of a pixel was
> changed), and resend the image? My initial tests showed that image
> changes were displayed properly. May I always create a new
> paint.ImageOp and still leverage caching, or image caching only works
> if the same paint.ImageOp is used in subsequent updates? And does it
> send partial change (changed subimage) or the whole image?
>

Updating an image.Image is the current best approach, but it is not very
efficient, except for static images where you only pay the generation
and transfer cost once. image.Image caching is keyed on paint.ImageOps:
each paint.NewImageOp result in a new texture; re-using an ImageOp will
re-use the cached texture. Unused textures are flushed every frame, so
your ImageOp will have to be used every frame for the caching to be
effective.

I hope to improve the caching algorithm so textures are kept around
based on video memory use, not whether they happened to be references in
the previous frame. But image.Image based approaches will never be fast.

> 
> Are there any plans to add direct (without drawing on an image first)
> primitive drawing capabilities to gio?
>

Yes. I want to replicate enough of the Rust Pathfinder library to
efficiently cover the common SVG primitives.

I also intend to expose the underlying GPU API (OpenGL, Vulkan etc.)
so games and other apps with specialized needs can have GPU access.
That's a non-portable and heavy-handed solution in your case, but
simplest to implement and therefore likely to come before general SVG
support.

> 
> Also there is op.InvalidateOp to trigger a frame (update) manually.
> Are there plans to support partial updates? Often only small areas of
> the window change, it would be efficient to not update the whole
> window just some small parts of it (that did change).
>

Yes, but (hopefully) not exposed to the app. I imagine a system where
not just images and paths are cached by the render backend, but entire
operation list fragments. Then, partial updates will naturally fall out
from diff'ing a frame's operation list with what is known to be in the
framebuffer from the previous frame.

-- elias
Details
Message ID
<CABN121iWWdnzcYOe6O6skXf0bVxJ6eVjxbi5RT4kP9=arqQTPA@mail.gmail.com>
In-Reply-To
<BZOOCHQB7ECW.IV1WUAJW3KLX@testmac> (view parent)
DKIM signature
missing
Download raw message
FYI, I've been working on a simple vector drawing module as part of my
foxtrot project.
It's still a work in progress and currently only supports drawing lines.
When it is done, and I am happy with the API, I can prepare a path to
add it to gio if you like.
Current situation is here:
https://github.com/wrnrlr/foxtrot/blob/master/test/draw/main.go


On Mon, Jan 6, 2020 at 12:47 PM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Mon Jan 6, 2020 at 12:13 PM, András Belicza wrote:
> >
> > I know gio doesn't support drawing primitives such as lines, curves,
> > circles. One way to do that would be to draw them on an off-screen
> > image either manually or using a lib like github.com/fogleman/gg,
> > and display that image using paint.ImageOp.
> >
> >
> > Is this the current best approach? How fast is it? I've read gio
> > caches images and does not send them in every frame (redraw). Does
> > gio detect if an image changed (e.g. the color of a pixel was
> > changed), and resend the image? My initial tests showed that image
> > changes were displayed properly. May I always create a new
> > paint.ImageOp and still leverage caching, or image caching only works
> > if the same paint.ImageOp is used in subsequent updates? And does it
> > send partial change (changed subimage) or the whole image?
> >
>
> Updating an image.Image is the current best approach, but it is not very
> efficient, except for static images where you only pay the generation
> and transfer cost once. image.Image caching is keyed on paint.ImageOps:
> each paint.NewImageOp result in a new texture; re-using an ImageOp will
> re-use the cached texture. Unused textures are flushed every frame, so
> your ImageOp will have to be used every frame for the caching to be
> effective.
>
> I hope to improve the caching algorithm so textures are kept around
> based on video memory use, not whether they happened to be references in
> the previous frame. But image.Image based approaches will never be fast.
>
> >
> > Are there any plans to add direct (without drawing on an image first)
> > primitive drawing capabilities to gio?
> >
>
> Yes. I want to replicate enough of the Rust Pathfinder library to
> efficiently cover the common SVG primitives.
>
> I also intend to expose the underlying GPU API (OpenGL, Vulkan etc.)
> so games and other apps with specialized needs can have GPU access.
> That's a non-portable and heavy-handed solution in your case, but
> simplest to implement and therefore likely to come before general SVG
> support.
>
> >
> > Also there is op.InvalidateOp to trigger a frame (update) manually.
> > Are there plans to support partial updates? Often only small areas of
> > the window change, it would be efficient to not update the whole
> > window just some small parts of it (that did change).
> >
>
> Yes, but (hopefully) not exposed to the app. I imagine a system where
> not just images and paths are cached by the render backend, but entire
> operation list fragments. Then, partial updates will naturally fall out
> from diff'ing a frame's operation list with what is known to be in the
> framebuffer from the previous frame.
>
> -- elias
Details
Message ID
<BZPNH8H7D1S0.1IJ1BXFLZQ1QM@testmac>
In-Reply-To
<CABN121iWWdnzcYOe6O6skXf0bVxJ6eVjxbi5RT4kP9=arqQTPA@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Tue Jan 7, 2020 at 3:26 PM, Werner Laurensse wrote:
> FYI, I've been working on a simple vector drawing module as part of my
> foxtrot project.
> It's still a work in progress and currently only supports drawing lines.
> When it is done, and I am happy with the API, I can prepare a path to
> add it to gio if you like.
> Current situation is here:
> https://github.com/wrnrlr/foxtrot/blob/master/test/draw/main.go
>
> 

Looks good. I would be interested in seeing the finished API for this.
It doesn't even have to be finished: just publish something that can
be used outside the package and I'll gladly link to it from the
newsletter and the Twitter account.

-- elias
Details
Message ID
<CAD1K+AKP9P91h=ft3UFQRwLxPiQj1rW=7qpReYwhoL-XkZgaCg@mail.gmail.com>
In-Reply-To
<BZPNH8H7D1S0.1IJ1BXFLZQ1QM@testmac> (view parent)
DKIM signature
pass
Download raw message
On Tue Jan 7, 2020 at 3:26 PM, Werner Laurensse wrote:
> FYI, I've been working on a simple vector drawing module as part of my
> foxtrot project.
> It's still a work in progress and currently only supports drawing lines.
> When it is done, and I am happy with the API, I can prepare a path to
> add it to gio if you like.

I have dreamed of a high-level text/image/vector API for in gio.
Some suggestions on the API:

The coordinate system is based on percentage (0-100) of the underlying
canvas, and attributes  like colors are named as strings ("black" or
"rgb(127,0,0)").  Opacity is specified as a variadic argument also
expressed as a percentage from (0 - invisible to 100 - fully opaque).

// Text places text left-aligned at (x,y), with specified font, size
and color. Opacity (0-100) is optional
Text(x, y float64, s, font string, size float64, color string, opacity
...float64)
TextMid(x, y float64, s, font string, size float64, color string,
opacity ...float64) // center text at (x,y)
TextEnd(x, y float64, s, font string, size float64, color string,
opacity ...float64) // end-align text at (x, y)

// Colored Rectangle centered at (x,y), with dimensions (w,h), with
optional opacity
Rect(x, y, w, h float64, color string, opacity ...float64)

// Colored Ellipse at centered at (x,y), with dimensions (w,h), with
optional opacity
Ellipse(x, y, w, h float64, color string, opacity ...float64)

// Colored Line from (x1, y1) to (x2, y2), with specified size
(thickness), with optional opacity
Line(x1, y1, x2, y2, size float64, color string, opacity ...float64)

// Colored Arc centered at (x,y), sized as (w,h), between angles a1
and a2, opacity is optional
Arc(x, y, w, h, size, a1, a2 float64, color string, opacity ...float64)

// Colored Bezier curve between (x1, y2) and (x3, y3), with control
points at (x2, y2), thickness is specified by size.
Curve(x1, y1, x2, y2, x3, y3, size float64, color string, opacity ...float64)

// Colored Polygon makes a polygon with the specified color (with
optional opacity), with coordinates in x and y slices.
Polygon(x, y []float64, color string, opacity ...float64)

// Place an image centered at (x,y), with dimensions (w,h), in file
specified by name
Image(x, y float64, w, h int, name string)


On Tue, Jan 7, 2020 at 10:06 AM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Tue Jan 7, 2020 at 3:26 PM, Werner Laurensse wrote:
> > FYI, I've been working on a simple vector drawing module as part of my
> > foxtrot project.
> > It's still a work in progress and currently only supports drawing lines.
> > When it is done, and I am happy with the API, I can prepare a path to
> > add it to gio if you like.
> > Current situation is here:
> > https://github.com/wrnrlr/foxtrot/blob/master/test/draw/main.go
> >
> >
>
> Looks good. I would be interested in seeing the finished API for this.
> It doesn't even have to be finished: just publish something that can
> be used outside the package and I'll gladly link to it from the
> newsletter and the Twitter account.
>
> -- elias