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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>