Commit Graph

33 Commits

Author SHA1 Message Date
Elias Naur f86703e4b0 op: introduce Defer for deferring CallOps
Updates gio#164

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-14 15:53:49 +01:00
Elias Naur d331dd2de8 op: rename StackOp/Push/Pop to StateOp/Save/Load
The semantics were relaxed in a previous commit; this change renames
to operations accordingly.

API change. Use gofmt to adjust your code accordingly:

gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 21:28:59 +01:00
Sebastien Binet 8676a73a91 internal/rendertest: use a YIQ-based algorithm to compare images
This PR implements an image comparison algorithm in the NTSC YIQ color
space, as described in:

  Measuring perceived color difference using YIQ NTSC
  transmission color space in mobile applications.
  Yuriy Kotsarenko, Fernando Ramos.

An electronic version is available at:

- http://www.progmat.uaem.mx:8080/artVol2Num2/Articulo3Vol2Num2.pdf

This should allow the image comparison to be a tad more robust than
comparing plain uint8 pixel values.

Signed-off-by: Sebastien Binet <s@sbinet.org>
2021-01-02 12:54:29 +01:00
Elias Naur cb075ea9cf app/headless,internal/rendertest: relax tests
The Mesa software OpenGL implementation strays enough from the
reference values that tests fail. Relax the tests to make them
pass again.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-17 20:48:30 +01:00
Walter Werner SCHNEIDER fd2d96adfc all: fix spelling errors
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-17 08:55:23 +01:00
Walter Werner SCHNEIDER 83d23ab507 all: sort and group imports
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
2020-12-17 08:55:09 +01:00
Sebastien Binet e71bf13c9a gpu,op/clip: implement dashed stroked paths
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-12-09 11:23:13 +01:00
Sebastien Binet be89f8b945 all: introduce Outline and Stroke builders
This CL introduces 2 new path builders:
- Outline which takes a PathSpec to be outlined
- Stroke which takes a PathSpec and a stroke style, to stroke a path.

typically, code like this:

  var p clip.Path
  ...
  p.Outline().Add(o)

should be replaced with:

  var p clip.Path
  ...
  clip.Outline{Path: p.End()}.Op().Add(o)

similarly, stroking should be modified from:

  var p clip.Path
  ...
  p.Stroke(width, clip.StrokeStyle{...}).Add(o)

to:

  var p clip.Path
  ...
  clip.Stroke{Path: p.End(), Style: clip.StrokeStyle{Width:...}}.Op().Add(o)

here are tentative 'rf' scripts (see rsc.io/rf for more details):

  ```
  ex {
  	import "gioui.org/op";
  	import "gioui.org/op/clip";

  	var p clip.Path;
  	var o *op.Ops;

  	p.Outline().Add(o) -> clip.Outline{Path:p.End()}.Op().Add(o);
  }

  ex {
  	import "gioui.org/op";
  	import "gioui.org/op/clip";

  	var o *op.Ops;
  	var p clip.Path;
  	var sty clip.StrokeStyle;
  	var width float32;

  	p.Stroke(width, sty).Add(o) ->   \
	    clip.Stroke{                 \
		Path:p.End(),            \
		Style: clip.StrokeStyle{ \
		    Width: width,        \
	    }}.Op().Add(o);
  }
  ```

Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-12-09 09:44:15 +01:00
Egon Elbre 1899104536 op/clip: expose LineTo and QuadTo
Using delta position with Line and Quad can drift over successive calls.
Also, in some cases it's much more convenient to use absolute
coordinates rather than relative.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-21 22:46:03 +01:00
Egon Elbre 21ef492cc9 all: use color.NRGBA in public API
color.RGBA has two problems with regards to using it.

First the color values need to be premultiplied, whereas most APIs
have non-premultiplied values. This is mainly to preserve color components
with low alpha values.

Second there are two ways to premultiply with sRGB. One is to premultiply
after sRGB conversion, the other is before. This makes using the API more
confusing.

Using color.NRGBA in sRGB makes it align with CSS.e

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-19 11:30:11 +01:00
Sebastien Binet 7eb32360e5 gpu,op/clip: implement stroked paths with miter joins
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 16:14:49 +01:00
Elias Naur 7de8ce51a5 gpu: fix off-by-a-half clipping
I don't know why the 1/2 factor is there, but it leads to images being
rendered with a 0.5 pixel offset.

Remove the other useless checks while here: clipping 1px images shouldn't
be a problem and the destination rectangle is always non-zero (otherwise
it wouldn't be rendered).

Update the reference images that are subtly changed because of this fix.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-11 15:14:39 +01:00
Sebastien Binet 700cec440e gpu,op/clip: implement stroked paths with round joins
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 14:03:30 +01:00
Sebastien Binet 1106d90f11 gpu,op/clip: implement stroked paths with round caps
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 12:25:24 +01:00
Sebastien Binet 33c5fb63db gpu,op/clip: implement stroked paths
Flat and Square caps are implemented.
Bevel joins are implemented.

Round caps, Round joins and Miter joins are left for another PR.

Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-10 15:58:10 +01:00
Sebastien Binet 936eb52b7e all: rename clip.Path.End into clip.Path.Outline
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-10 15:58:07 +01:00
Elias Naur 94d242d18c op/paint: remove support for PaintOp.Rect
PaintOp.Rect is the wrong abstraction; it implies a clip operation
better handled by package clip, and not all paints need it (colors).
Furthermore, it's awkward to specify a PaintOp that fills up the
current clip area, regardless of its size.

Redefine PathOp to mean "fill current clip area".

API change. Replace uses of PaintOp.Rect with a TransformOp applied
before the PaintOp.

Leave a TODO for the PathOp infinity area.

Fixes gio#167

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 16:32:19 +01:00
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
Egon Elbre f00f3a3359 gpu: add linear gradient
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-03 15:39:06 +01:00
Elias Naur 0641a34b24 internal/rendertest: lower test tolerances
Egon Elbre pointed out that a difference of 20 means a 10% difference.
Lowering the tolerance to 5 didn't work on my setup; leave it at 10.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-03 15:39:06 +01: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 7054ba622a op/clip: implement arc path
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-27 14:46:02 +02:00
Elias Naur 6ab43aba3e all: implement staticcheck suggestions
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-19 10:47:17 +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 30ad63283b app/headless,internal/rendertest: report errors from headless renders
Updates gio#144

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-04 16:36:03 +02:00
Elias Naur 8bd0e85f2e internal/rendertest: dump bad images immediately
Updates gio#144

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-04 14:50:43 +02:00
Elias Naur dff037a84e internal/rendertest: release GPU resources after test completion
Updates gio#144

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-07-04 14:29:41 +02:00
Viktor Ogeman 7ff17453dd gpu: fix negative intersections
Fixes a bug due to that f32.Rect.Intersect will not return the
empty rectangle for non intersecting rectangles - but instead
a swapped rectangle. By removing the .Canon() call in gpu.go we
ensure that non overlapping clipping rects and paint rects will
lead to no painting.

The Canon() call is not needed since boundsForTransformedRect()
was previously updated to always return a canonical rectangle.

Test case added.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-25 15:52:55 +02:00
Elias Naur b664d68a7c internal/rendertest: tolerate lack of headless suppport
Fixes the builders.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-22 17:28:12 +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 cee045bf92 gpu: build gpu data also when outside window
This commit fixes a bug where a shape first drawn off-screen
and later moved into screen would not display properly. Since we
cache CPU operations (vertex transform / construction) we need to
upload the constructed data to the GPU after it was build, or a later
frame will use non-initialized memory for it's draw call.

Note that this fix removes the optimization of not processing clip
paths outside the screen - but this is assumed to be uncommon except
when it is first drawn off screen to later be moved in (e.g. in a scrolling list)
in which case we do want to upload the data and prepare for that later
call.

This commit also does a few minor clean ups and adds a test case.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor e3bb94ebb0 internal/rendertest: create test suit for drawing operations
Uses app/headless to create a set of test cases for drawing operations, including clipping
textures and transforms. This commit tests for approximate pixel matches, if future changes affect
local drawing operations it will be easy to change the reference images, it thus becomes and
should be an intentional operation if changes lead to local changes in drawn results.

Ideally we should be able to make the tests check for exact pixel matches down the line to ensure
consistent results between platforms.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:19:12 +02:00
Viktor ef70b9252e internal/rendertest: create new standard benchmark
Create a standard, representative set of benchmarks for the
rendering pipeline to allow for measurement of performance
improvement/regressions due to changes.

The benchmarks are intended to be representative of the types
of drawing different gio uses should encounter.

BenchmarkDrawUI:
Draw text, instanced shaped and unique shapes in a mix that is
reasonable for a simple UI.

BenchmarkDrawUICached:
Same as BenchmarkDrawUI but not reset between iterations to
benchmark the rendering pipeline when using maximum caching.

Benchmark1000Circles:
Draw 1000 circles individually to benchmark the rendering performance
with no caching. Represents usages such as animating shapes or
drawing complex shapes.

Benchmark1000CirclesInstanced:
Draw 1000 circles by calling a Macro op, each one with an offset
transform. Represents cases such as drawing spirits etc.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:17:11 +02:00