Commit Graph

91 Commits

Author SHA1 Message Date
Elias Naur 57872856e8 internal/unsafe: fix SliceOf to return len equals to cap
Broken by gioui.org/commit/2dce8a0155ae192f54f74747d660b9f311e9e364,
found while debugging the dormant OpenGL backend for Windows.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-26 14:48:27 +01:00
Elias Naur 84b586ae6c gpu: don't automatically clear screen before rendering
Gio UI may be overlaid on top of custom graphics such as in the glfw example.
That will only work if Gio doesn't clear the screen (to white).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-22 18:33:34 +01:00
Elias Naur e70a16c345 io/router/key: add explicit tag to FocusOp; make last SoftKeyboardOp apply
The target of FocusOp is too subtle; be explicit instead and remove
any doubt.

Multiple SoftKeyboardOp in a single frame is rare, but if they do occur,
they should behave as if they were from separate frames: the last one
applies.

As a side-effect the key event router can be much simplified.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-22 16:34:51 +01:00
Elias Naur d0d6c6c38e internal/glimpl: hook up glTexStorage2D on iOS
The glTexStorage2D is part of OpenGL ES 3, but wasn't its function
pointer wasn't initialized on iOS.

Fixes a crash on startup on iOS devices and simulators.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-21 11:40:31 +01:00
Elias Naur d6886737a5 op: change Defer to only restore transformation state
It turns out restoring all operation state from the moment Defer
is executed is too much; for example, a right-click pop-up needs
the transformation, but not the current clip.

Change Defer to only restore the transformation, and reset all
other state.

Other combinations may be needed in future; we'll deal with them then,
possibly by exposing the load state mask.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-19 20:04:30 +01:00
Egon Elbre 468bd6f53a widget/material: add hover to Button
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-01-18 10:56:57 +01:00
Elias Naur 99bfa6a33c internal/f32color: revert incorrect NRGBA to linear color change
Egon Elbre convinced me commit 01d5e72291 was incorrect, because
in the NRGBA colorspace the alpha value is linear, not gamma adjusted.

Updates gio#192

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-16 09:58:04 +01:00
Elias Naur 01d5e72291 internal/f32color: correct pre-multipled color conversion
Tweak a test color to avoid an off-by-1 rounding error after changing
the conversion formula.

Fixes gio#192

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-15 16:02:39 +01:00
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
Elias Naur f7902f299b op: implement StackOp in terms of general save/load of state
Push/Pop only allows saving and restoring operation state in a
stack-like manner. We're going to need restoring arbitrary state
for implementing deferred operations.

Generalize state save/restore and implement Push and Pop on top of
that.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 20:53:25 +01:00
Egon Elbre f114acdb02 widget: use correct color in Icon
iconvg seems to expect a linear premultiplied color.

Fixes gio#132

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-01-11 14:32:28 +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 d23514fd58 gpu: add compute implementation
The old renderer is still the default, so the new compute renderer will only be
used in the rare case the old renderer is not supported but the new is. That
happens on the Samsung J2 Prime and Moto C Android phones. Or set the
GIORENDERER environment variable to "forcecompute" to disable the old renderer:

$ GIORENDERER=forcecompute go run ...

Missing features:
- Gradients are not supported yet, and render as a solid color.
- Draw timers are not added, and profile.Events are not emitted.
- Stroked paths may in some cases appear corrupted because their clip
  outlines are not continuous when generated by Gio. Sebastien is
  working on a fix.
- The new renderer shares most CPU-side logic with the old renderer,
  resulting in several inefficient conversion steps between the old
  operations representation and the new. This is slower, but minimizes
  divergence in features and bugs between the two renderers.

Roadmap:
- The compute renderer supports features that Gio does not yet
exploit: stroked paths with round caps, transformations, lines,
cubic beziér curves.
- More stroke styles and maybe dashed strokes natively in shaders.
- Metal and Direct3D ports.

The most important feature is porting the renderer to run on the CPU. A
CPU renderer will both support Gio on devices with insufficient GPU
support, and allow us to remove the old renderer. Two renderers is twice
the maintenance but the feature set of the weakest implementation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur b1ff179aa0 gpu,app,internal/glimpl: update GL backend for the compute renderer
Modern graphics APIs have immutable objects, with mutable data. For example,
a texture's dimensions are immutable, while the texture contents is not.
Change the GPU API abstraction to match.

Clearing a Texture is convenient to do with a plain []byte. Generalize
Texture.Upload to take a plain byte slice and introduce a helper function for
uploading *image.RGBA data.

Add TextureFormatRGBA8, a format for the linear RGB colorspace.

Add OpenGL ES 3.1 functions for compute programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur e9403d8b18 internal/unsafe: add StructView
Needed by the compute renderer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur 269e7e0d7b internal/cmd/convertshaders: add support for compute shaders
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur bfe2d04c60 gpu,app,internal/glimpl: update GL backend for the compute renderer
Modern graphics APIs have immutable objects, with mutable data. For example,
a texture's dimensions are immutable, while the texture contents is not.
Change the GPU API abstraction to match.

Clearing a Texture is convenient to do with a plain []byte. Generalize
Texture.Upload to take a plain byte slice and introduce a helper function for
uploading *image.RGBA data.

Add TextureFormatRGBA8 a format for the linear RGB colorspace.

Add OpenGL ES 3.1 functions for compute programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur e012c3f393 internal/glimpl: [wasm] pass correctly sized buffers to WebGL functions
Before this change, the entire byte buffer would be passed to WebGL, even
though its size may be (much) larger than the source data.
Remakably, this hasn't resulted in any problems until the use of
glBufferSubData, which require the passed data fits the buffer size.

As a bonus, this fix should speed up the wasm port by virtue of passing
much less data across the wasm<->js barrier.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 12:31:57 +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
Egon Elbre e383e6d6be widget/material: better disabled color calculation
Use desaturation in combination with alpha multiplication.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-12-16 19:15:17 +01:00
Elias Naur 2dce8a0155 internal/unsafe: fix vet warnings about SliceHeader use
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-10 18:33:02 +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
pierre 7c5bcd3db8 io/pointer: added CursorNameOp
The cursor can now be customized for a given area.

Signed-off-by: pierre <pierre.curto@gmail.com>
2020-12-09 09:38:31 +01:00
Egon Elbre 675e86b8e8 internal/unsafe: fix empty slice
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-12-09 09:36:07 +01:00
Inkeliz a76f816ae9 io/clipboard,app: add WriteOp, ReadOp
Previously, the only way to manipulate the clipboard (read or write) is
using the `app.Window`.

The new `clipboard.ReadOp` and `clipboard.WriteOp`makes possible to
read/write from the widget.

Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2020-12-06 22:15:16 +01:00
Inkeliz 2739547c12 internal/glimpl: [wasm] fix WebGL 1 support v2
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2020-12-06 21:57:14 +01:00
Elias Naur ffe5ab51a2 gpu/gl: remove OpenGL functions parameter from NewBackend
As a consequence, most API is gone from gpu/gl, and embedding Gio in
foreign frameworks don't need to provide an OpenGL implementation.

The next change simplifies the GLFW embedding example accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-04 20:50:22 +01:00
Inkeliz cd3b4561cf io/key: improve InputOp focus and blur
The existing implementation cannot remove the focus of some widget,
doesn't have an option to focus without display the on-screen keyboard
and it automatically focuses the first InputOp, aggressively.

That change aims to make possible: remove focus from any widget. Add
focus without displaying the on-screen-keyboard/soft keyboard. Don't
automatically focus any widget. Don't recover focus when the widget is
visible again.

Fixes gio#180.

Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2020-12-03 16:46:48 +01:00
Egon Elbre 21dc27b115 internal/ops: remove some bounds checks
Currently BCE is unable to understand that the accesses in the code are
safe. Added an explicit slice to make the length bounds obvious.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-24 14:14:26 +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
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
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
Elias Naur 4bab6fcf32 internal/f32color: add colorspace-correct function for alpha scaling
Package material's ad-hoc mulAlpha didn't take the sRGB color-space
into account, which meant that alpha-scaled colors were subtly wrong.
Introduce f32color.MulAlpha and convert all uses to it.

Thanks to René Post for finding and debugging the issue.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-09-28 09:06: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 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