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