Commit Graph

1505 Commits

Author SHA1 Message Date
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
Elias Naur 223f8fd40a example/kitchen: bump gio version
Add explicit inset to ButtonLayout.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-30 20:46:02 +02:00
Elias Naur 6ef1ff7cfb widget/material: remove Inset from ButtonLayoutStyle
ButtonLayout is for custom button content; insets belong to the
custom content, not the button.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-30 20:44:35 +02:00
Elias Naur 958b19ae22 app/internal/window: [macOS] ignore result from CVDisplayLinkStart
Larry Clapp reported a panic from failing to start the display link.
Ignore the error and hope the error is transient.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-30 11:36:26 +02:00
Elias Naur 851255f7a6 widget: tolerate nil shader in Editor movement methods
Fixes gio#142

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-28 22:34:58 +02:00
Elias Naur 2f8833d985 app/internal/window: [X11] avoid -d=checkptr check failures
Casting a *XClientMessageEvent or *XSelectionEvent to *XEvent is
technically incorrect because the union XEvent is the larger structure.

Use an XEvent variable as the backing storage for the specialized
event types instead.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-27 15:29:42 +02:00
Elias Naur f5985b5e7d cmd,example: bump gio version
Add os.Exit to examples now that app.Main never returns.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 16:30:34 +02:00
Sebastien Binet 6a9a870462 app{,/internal/window}: make app.Main blocking on desktop platforms
This CL implements the app.Main function as a blocking-forever function
for JS, Wayland, Windows and X11.
This works better for applications that can now programmatically close
windows.
2020-06-26 16:20:42 +02:00
Elias Naur facf5cbb9d cmd,example: bump gio version
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 16:16:15 +02:00
Elias Naur 31e8339e1b app/internal/window: [Windows] fix min/max size
Fixes gio#141

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 16:14:41 +01:00
Elias Naur acc0424dd7 example,cmd: bump gio version
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 15:57:54 +02:00
Elias Naur d97f7f9093 app/internal/window,cmd/gogio: [iOS] export GioViewController
The Gio GioAppDelegate created the GioViewController programmatically.
When using gogio's -buildmode=archive users may want to use a different
method (for example storyboards) but there can only be one app delegate.

Move the GioAppDelegate to gogio's exe buildmode, and export the
GioViewController for embedding use.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 15:47:00 +02:00
Elias Naur 79014a81d5 app/internal/window: [iOS] move logic out of GioAppDelegate
We'd like to remove GioAppDelegate when Gio is embedded with
gogio's -buildmode=archive. Minimize the code in GioAppDelegate.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 15:25:40 +02:00
Elias Naur 913a780d64 text: remove Metrics from Face interface
It's not used in text shaping, so let's not require it.

Note that the concrete opentype package still retains the Metrics
implementation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-26 10:44:19 +02:00
Elias Naur db03b0898d app/internal/window: run main on main thread on Android and iOS
Before this change, Android and iOS were special for two reasons:
app.Main would return immediately, and the program main was invoked from
a goroutine. We can reduce that to one special case by either

- run the program main from the main thread,
- or make app.Main block.

Choose to run main on the main thread.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-25 16:21:28 +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 5bd0ecea5e cmd/gogio: add -tags flag for supplying extra tags to the build
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-22 20:57:35 +02:00
Elias Naur 342c0da320 cmd/gogio: add ldflags flag for extra flags
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-22 20:50:28 +02:00
Elias Naur 2f984673a2 cmd/gogio: [Android] use correct android.hardware.type.pc feature
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-22 20:49:49 +02:00
Greg Pomerantz 3a542cc80c cmd/gogio: [Android] check $ANDROID_NDK_ROOT
If the Android NDK is not found in a standard location (e.g. you are
on an F-Droid build server), check the $ANDROID_NDK_ROOT environment
variable.

Signed-off-by: Greg Pomerantz <gmp.gio@wow.st>
2020-06-22 18:26:32 +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
Sebastien Binet 59f07023d4 app/internal: [X11] implement Window.Close
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-06-22 17:21:39 +02:00
Jason 9cfbdafe14 app/window,app/internal/window: allow min/max window size
The app.MinSize and app.MaxSize options restricts the window size:

w := app.NewWindow(
	app.Size(unit.Dp(600), unit.Dp(596)),
	app.MinSize(unit.Dp(600), unit.Dp(596)),
	app.MaxSize(unit.Dp(600), unit.Dp(596)),
	app.Title(APPNAME),
)

Signed-off-by: Jason <sourcehut@sweatyballs.es>
2020-06-22 13:00:27 +02:00
Gordon Klaus 20cf570709 example/kitchen: add Float/Slider
Signed-off-by: Gordon Klaus <gordon.klaus@gmail.com>
2020-06-22 12:19:07 +02:00
Gordon Klaus 5368743478 widget,widget/material: add Float and Slider
Signed-off-by: Gordon Klaus <gordon.klaus@gmail.com>
2020-06-22 12:17:35 +02:00
Elias Naur 817e0fa9c3 example,cmd: bump gio version
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-21 22:43:46 +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
Elias Naur 9e3d3b6f58 text,font/gofont: replace text.Collection with slice of FontFaces
A slice of FontFace pairs are simpler, and thread safe in case a client
wants to append or modify the font collection.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-21 21:44:28 +02:00
Elias Naur 424a728988 text: fix typo
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-21 21:14:05 +02:00
Viktor 1a9ae1af69 example/kitchen: include example of affine transforms
Include an example of transforming the entire UI in the example.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:38:27 +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 901478d102 gpu: avoid pointers of pathData
Save allocations by using pathData instead of *pathData.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor 42f07ca538 internal/f32color: use explicit type to avoid allocation
f32color.RGBAFromSRGB is used extensively in package gpu, avoid an
interface type to save allocations.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor 818d0c4af1 gpu: cache transformed bounds
To avoid duplicate work when using macros and non-offset transforms,
cache also the new bounding boxes set up for them. The ops.Reader
already generates Keys for all operations, so use them in the cache.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor 062cb210ea gpu: optimize opCache to avoid expensive map lookups
Benchmarking showed that the double map access calls
were a bottleneck. Rework the cache to avoid half of them.

The simplest, naive approach would have been to store a
pointer to a struct with a keep field in the map, allowing cheap
update and frame() operation. Benchmarking showed that the
increased GC pressure of that approach decreased performance
however.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor f11a656426 gpu: exploit pathCache in collectOps
Previously the cache was only filled during gpu-buffer creation,
resulting in extra work on the CPU to transform vertices if the same
shape was used multiple times in the same frame. Cases such as font
rendering was cached already before this change as it is drawn in it's
own op.Ops that is never reset - and thus re-used from one frame
to the next.

Since we are now calling put() twice per frame an update should no
longer panic.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor cfb9565895 gpu: reintroduce reuse of offset-only stenciling
Reintroduce support for offset in stencil vertex so we can reuse
cached values if the only difference in transform is offset. Split
current transform into a pure-offset part and the rest and use
only the complex part as cache key.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:20:36 +02:00
Viktor 380938c602 gpu: cache quad splitting and transform
Cache also CPU operations by moving pathCache into
drawOps and use it in collectOps to avoid splitting and
transformation of quads if in cache. In order to support
this use a concrete type in opCache instead of interface.

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 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 e7bc1a4553 f32: implement 2D affine transformations
Implements 2D affine transformations. This commit is a step
towards full affine transformations for drawing operations.

Heavily based on the work by Péter Szilágyi in patch 9212

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
2020-06-21 11:17:37 +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
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
tainted-bit 5c0f190849 widget: add optional password masking to Editor
This change adds optional password masking to the Editor. To enable
this feature, set the new Mask field to a non-zero rune. Every rune
in the Editor's contents will be replaced by the mask rune in the
visual display, except for newlines. The actual contents of the
editor can still be accessed with Len, Text, and SetText.

Fixes gio#80

Signed-off-by: tainted-bit <sourcehut@taintedbit.com>
2020-06-21 10:54:41 +02:00
Elias Naur a21aefa8b7 widget: remove Editor references to text.Line.Len and text.Glyph.Rune
In preparation for adding editor masking, Editor can't rely on the
Rune and Len fields of the laid out text.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-20 18:33:31 +02:00
Elias Naur ffec83a001 widget: add Editor tests
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-20 16:50:45 +02:00
Elias Naur dcbbcbb543 widget: introduce Editor.moveLines
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-20 16:50:45 +02:00
Elias Naur ef21a7ace1 widget: maintain Editor caret position
Only call layoutCaret when the text layout changes, adjust position
for caret movement.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-20 16:50:30 +02:00
Elias Naur 8f31f8da2c widget: move Editor caret information to sub-struct
In preparation for maintaining the caret position.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-20 12:26:24 +02:00