Commit Graph

60 Commits

Author SHA1 Message Date
Elias Naur afb52194d1 app/headless,internal/rendertest: replace PaintOps with Fill/FillShape
We're about to remove PaintOp.Rect. Replacing PaintOps with Fill or
FillShape where possible will ease the transition.

Using Fill in tests exposed a problem with the infinity in paint.Fill.
Adjust it for now; it will be removed later.

Updates gio#167

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 16:12:39 +01:00
Elias Naur 852958f4b5 gpu,widget,op/paint,gpu: remove support for ImageOp.Rect
This is effectively a revert of commit gioui.org/commit/69dfd2e3a5541.

ImageOp.Rect is the wrong abstraction; it implies a clipping operation that is
better handled by package clip.

API change. Uses of ImageOp.Rect should apply a clip.Rect before the PaintOp,
or use image.RGBA.SubImage (or similar).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 13:36:36 +01:00
Elias Naur efdd5ae602 op/paint: make the shape argument last in FillShape
FillShape is a generalization of Fill, so it seems more natural to
have the extra argument last.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-03 18:57:25 +01:00
Elias Naur 3107c95757 op/clip: remove unused parameter from Rect.Op
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-03 18:57:25 +01:00
Egon Elbre f00f3a3359 gpu: add linear gradient
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-03 15:39:06 +01:00
Chris Waldon fc307c1e71 op/paint: add Fill helpers for painting an area with a solid color
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:47 +02:00
Chris Waldon 685e0772a3 op/clip: add UniformRRect to create rects with uniform corner radii
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:43 +02:00
Chris Waldon 8bdca84c56 op/clip: export Op method of clip shapes
This allows passing the resulting clip.Op types into functions that
draw shapes.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:40 +02:00
Sebastien Binet f2cd504a9f op/clip: smoother implementation of Arc for large angles
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-29 17:36:37 +02:00
Sebastien Binet 3fe0f62fa3 op/clip: export Path's current pen position
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-27 14:46:05 +02:00
Sebastien Binet 7054ba622a op/clip: implement arc path
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-27 14:46:02 +02:00
Elias Naur c76b42e486 op/clip,widget: add clip.Border and widget.Border
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-09 19:55:37 +02:00
Elias Naur d572aa23ac op/clip: split Rect into pixel-aligned Rect and rounded RRect
The pixel-aligned Rect is more efficient and easier to use in the common case
of layout clipping.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-09 18:33:00 +02:00
Elias Naur 4818538ef8 op/clip: unexport Rect.Op
It wasn't used anywhere outside Rect.Add.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-09 17:29:31 +02:00
Elias Naur 878131189b all: remove redundant op.TransformOp.Offset
Use op.Offset instead, or create and manipulate a f32.Affine2D.

API change. Update your code with a gofmt rule:

	gofmt -r 'op.TransformOp{}.Offset -> op.Offset'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-21 22:41:56 +02:00
Viktor 24951a7ee7 gpu, op, internal/ops: add affine transformations
Add support for affine transformations. The key changes are outlined
below.

- Painting/clipping with rectangles is handled by, for complex
  transforms, creating clipping paths representing the transformed
  rectangle and using a larger bounding box. Cover/Blit shaders updated
  correspondingly to correctly map texture cordinates from the new
  bounding boxes.
- Since path splitting must happen on CPU the transforms must happen CPU
  side as well - offsets removed from shaders.
- Complex transforms will lead to different path splitting which means
  that GPU arrays can no longer be cached if the transform has changed.
  Thus the current transform is added as a key to the cache.
- Add a public API to op for setting Affine transformations.

There are a number of optimizations that could be explored further but
which are left out now:
- Caching also of CPU operations (e.g path splitting & transforms) and
  not only caching the GPU arrays.
- Allow for re-use of cached GPU vertices if the transformation change
  is a pure offset / scaling since the splitting is then the same.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:17:53 +02:00
Viktor b247395c62 gpu, io/router, op: use f32.Affine2D instead of op.TransformOp for transforms
Encode TransformOp as an Affince2D matrix instead and use that in gpu and io transform handling.
There are no changes to user facing API and so far only the offset part of the matrix is used.

This patch is a step towards full affine transformations.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:17:42 +02:00
Viktor 5b277757cf op/clip, gpu: split complex curves in package gpu instead
This is a first step towards supporting affine drawing transforms.
The rendering algorithm relies on quadratic curves that do not cross
x = 0 more than once, thus curves must be split after any rotation/shear
transforms. Move this logic and the generation of vertices to package gpu.
Also close all curves and draw zero-width edges as preparation for
transform since the will no longer implicitly be vertical with no
effect.

This commit will severely affect performance since vertexes are now
transformed also for cached items, using cpu resources.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:17:27 +02:00
Elias Naur 1603a6f3ee op: add note that Ops.Reset invalidates recorded macros.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-17 09:59:15 +02:00
Elias Naur c19ed05342 op: change CallOp to be a return value from MacroOp.Stop
Converting

	macro := op.Record(ops)
	...
	macro.Stop()

	macro.Add()

to

	macro := op.Record(ops)
	...
	call := macro.Stop()

	call.Add(ops)

Which is more general (call.Add can take a different ops than the op.Record
that started it), and enforced the order between Stop and the subsequent Add.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-02 12:07:20 +02:00
Elias Naur acc23a5b3e op: make MacroOp methods take value receivers
The only mutable field is "recording", which is used for a sanity
check. THat check is performed (less generally) by Ops.macroStack.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-02 11:12:37 +02:00
Elias Naur 3e8c502550 op: return value StackOp from Push and make Pop use a value receiver
To match Record, we'd like Push to return a value. To do that and
support the one-line

	defer op.Push(ops).Pop()

Pop needs to use a value receiver as well. Drop the active field
and make it so. The field was only a sanity check, a check which is
already done by Ops.stackStack, albeit with a less specific panic.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-02 10:52:46 +02:00
Thomas Bruyelle ae8a377cda op: add op.Push and op.Record funcs
The funcs replace stack.Push and macro.Record, which become private.
This makes stack and macro faster to write, in particular for stacks
where you can just write the following line to save and restore the
state :

  defer op.Push(ops).Pop()

This usage requires Push to return a pointer (since Pop has a pointer
receiver), or else the code doesn't compile.

For consistancy, I tried to do the same for op.Record, but this implied
to turn all the MacroOp fields into pointers, and this caused some
panics. As a result, op.Record doesn't return a pointer.

An other side effect pointed by Larry Clapp: StackOp and MacroOp are not
re-usable any more, you have to allocate a new one for each usage, using
the described funcs above.

Signed-off-by: Thomas Bruyelle <thomas.bruyelle@gmail.com>
2020-06-02 10:39:56 +02:00
Elias Naur ac62e3a7ab op/clip: add Rect.Add shorthand
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-20 10:21:11 +02:00
Elias Naur 013ea395b4 all: use new rectangle and point convenience functions
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-19 11:03:30 +02:00
Elias Naur 31acd5451e op/paint: further clarify PaintOp documentation
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-14 13:44:36 +02:00
Elias Naur 29c9b06dab op/paint: document ImageOp gotcha
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-14 13:31:21 +02:00
Elias Naur b7ba809517 op/paint: rename material to brush
The "material" name clashes with the theme of the same name.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-14 13:19:15 +02:00
Elias Naur 81f474f5d7 op/paint,io/system: document ImageOp lifetime
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-14 13:15:05 +02:00
Elias Naur af68e17dd3 op/paint: set subimage Rect when converting image
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-03-12 18:42:20 +01:00
Elias Naur bfb50cef5d all: remove unused fields, functions and add missing error handling
Credit to staticcheck.io.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-02-27 22:26:54 +01:00
Elias Naur 591c89ab0a gpu: drop use of integer shader inputs
They're a pain to support. Encode the single integer value we have
as a float instead.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-02-27 21:22:59 +01:00
Elias Naur 69dfd2e3a5 op/paint: add support for efficient ImageOp subimages
The new field ImageOp.Rect is initialized to cover the entire source
image, but can be modified to draw only a section of it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-02-13 13:15:32 +01:00
axel paulander 2e66c90aee op/paint: correct image loading
Corrected the use of draw.Draw in paint.NewImageOp as the old use only works for images starting at the origin

Signed-off-by: Axel Paulander <axel.paulander@gmail.com>
2020-01-10 17:52:33 +01:00
Elias Naur edc81ea0bb op: remove operation list argument from MacroOp.Add
The ability to invoke other operation lists belongs in the new CallOp.

While we're here, make MacroOp.Add use a pointer receiver to match the
other methods.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-12 00:45:36 +01:00
Elias Naur 06217c5320 op: introduce CallOp
We'd like to improve the API of Flex, Stack and similar layouts
that use MacroOps internall. Unfortunately, the

  func (m MacroOp) Add(o *Ops)

method causes the MacroOp to be allocated on the heap, ruining the
nice garbage-free property of layouts.

Fortunately, layouts don't need the feature that caused the heap
allocation: invoking operation lists different than the current.

CallOp separates the invoke-different-list semantic from MacroOp,
in preparation for removing the feature from MacroOp.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-12 00:45:36 +01:00
Elias Naur 8102f63114 op: tighten stack checks
Assign (per-frame) unique ids to each MacroOp and StackOp operations
and ensure that the pairwise Push/Pop and Record/End match.

In a follow-up change the Flex and Stack layouts will rely on those
checks to avoid being overlapped.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-02 18:52:29 +01:00
Elias Naur 2486d46ab4 op: tighten documentation
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-02 17:55:26 +01:00
Elias Naur 7299d1c875 op/clip: replace Rect and RoundRect with Rect type
Remembering the order of the corners in the RoundRect is difficult,
which suggest that RoundRect should be a struct with named fields.

Do that, and make Rect the special case where corner radii are all
zero.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-18 14:33:28 +01:00
Elias Naur 65c783179d clip: change Rect argument to f32.Rectangle
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-09 19:42:19 +01:00
Elias Naur 4f30b985eb op/clip: add RoundRect
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-09 19:30:07 +01:00
Elias Naur e864ac3fc3 op/clip: split clip operations into its own package
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-09 19:07:00 +01:00
Elias Naur 560cf6054c op/paint: add note that ClipOp intersects the clip, not replace it
Updates #61

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-09 18:31:49 +01:00
Elias Naur 0dac972b25 app,os: update documentation to match changed API
Updates gio#61

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-09 18:25:28 +01:00
Elias Naur f1d971268e op/paint: guard against nil image in ImageOp.Size
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-07 21:08:01 +01:00
aarzilli 454b226404 op/paint: NewImageOp does not need to make copies of RGBA images
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-07 18:44:31 +01:00
Elias Naur 97299dc2f9 op/paint: make every ImageOp unique
The gioui.org/commit/74407a50d598bfd27e8f8e48b6832cc5df04de77
added a NewImageOp constructor that always copies the supplied
image. It does that for two reasons:

First, the image.Image reference is used in the image=>texture
map of cached textures. Without a copy, we wouldn't detect a
modified image even if a new ImageOp was created.

Second, we don't want the program to touch the image while the GPU
is uploading it.

The second reason was removed in a previous change that blocks
FrameEvent.Frame until we're done with the operations, including
uploading images to the GPU.

The first reason is easily fixed by using a unique per ImageOp,
as pointed out by Alessandro Arzilli.

This change switches to using the unique key. Alessandro's patch
avoids the copy when possible.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-11-07 18:27:06 +01:00
aarzilli 299e966816 op/paint: make documentation of Line clearer
The movement is not to an absolute coordinate but by a delta relative
to the current position of the pen.
2019-11-05 17:57:50 +01:00
Elias Naur 4da6c57d83 op: complete the MacroOp example
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-14 23:18:49 +02:00
Elias Naur fa00b53e13 op: change signature of Ops.Write
By returning the allocated data buffer, Ops can become an interface
in a future change without forcing operations to allocate.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-14 23:10:35 +02:00