The double-negative DisabledOp is harder to understand than a
straightforward EnabledOp. Note that the absence of an EnabledOp
implies still means that the widget is enabled.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When storing a string in an interface value that escapes, Go has to heap
allocate space for the string header, as interface values can only store
pointers. In text-heavy applications, this can lead to hundreds of
allocations per frame due to semantic.LabelOp, the primary user of
string-typed references in ops.
Instead of allocating each string header individually, provide a slice
of strings to store string-typed references in, and store pointers into
this slice as the actual references. This only allocates when resizing
the slice's backing array, and averages out to no allocations, as the
backing array gets reused between calls to Ops.Reset.
We introduce two new functions, Write1String and Write2String, which
make use of this new slice for their last argument. We could've
automated this in the existing Write1 and Write2 methods, but that would
require type assertions on each call, and the vast majority of ops do
not make use of strings.
Signed-off-by: Dominik Honnef <dominik@honnef.co>
Without eglTerminate, using EGL will crash or report spurious errors after
creating and destroying enough contexts. The test program in #528
takes 5-10 window cycles before errors show up for me.
Fixes: https://todo.sr.ht/~eliasnaur/gio/528
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit defines an environment-variable-based debug mechanism allowing
users to toggle various debug features of their applications at runtime. The
only currently supported features are debug logging in the text stack and
suppressing the usage message that would otherwise be printed if you supplied
a malformed GIODEBUG value. The syntax is a comma-delimited list of features
right now. To see the usage, set the variable to the empty string (or any other
unsupported value):
$ GIODEBUG="" go run .
To suppress the usage message, use GIODEBUG=silent. This may be helpful for scripts
trying to activate debug features and inspect their output across versions of Gio
with different debug options available.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
When building GPU vertices from paths, we call stroke.SplitCubic once
per OpCubic. Before this change, each call to stroke.SplitCubic would
allocate a slice, which we would only use to iterate over.
This allocation can be easily avoided by reusing the slice. We can
conveniently store it in gpu.quadSplitter.
In a real application that renders hundreds of paths with tens of
rounded rectangles per path, this saved roughly 4500 allocations (or 1
MB worth) per frame.
Signed-off-by: Dominik Honnef <dominik@honnef.co>
When the line overlaps itself backtracking exactly, e.g.
path.MoveTo(0, 100)
path.LineTo(100, 0)
path.LineTo(0, 100)
then acos calculation is relatively unstable. By using atan2 it avoids
some of such problems in the calculation. Additionally, it simpliflies
the round join calculation.
Fixes: https://todo.sr.ht/~eliasnaur/gio/474
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
All GPU APIs except OpenGL ES 2 can generate mipmaps for textures.
This trades 33% more GPU memory use for improved rendering quality
and speed for downscaled images.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before that change, Gio could crash when the WebGL context was lost
unexpectedly. Now, Gio will properly handle such situation and
recreate the buffers/resources when context is restored and will
wait until context is recovered.
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
The Nix version of the macOS toolchain has difficulties compiling
Objective-C modules; disable modules instead of figuring out why.
It also doesn't include any frameworks automatically; add them explicitly.
While here, move suppression of OpenGL deprecation to a GL-specific
file.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Using clean struct creation creates a lot of temporary variables in
assembly. Inline the assignments, which generates less code.
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
Size and NumRefs are always used together, so consolidate info to
a single table to avoid two separate lookups.
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
As suggested by Egon Elbre, passing a large struct of function pointers
forces Cgo checks on all of the pointer on every Cgo call. This
change instead passes only the relevant function pointer.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The app.Window.Perform(ActionMove) is the wrong abstraction for
initiating a move gesture: Windows needs to know the move gesture
area at pointer move, and macOS needs to know the pointer button
down event that triggers the move gesture. This change replaces
Perform(ActionMove) with a new system.ActionInputOp that marks an
area movable.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
There are no public API that uses f32.Rectangle anymore. Move Rectangle
to an internal package for internal use.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The unit.Value is a struct and thus more inconvenient to use than its
underlying float32 type. In addition, most uses don't need a general
value, but rather a specific unit given by the context. This change
replaces unit.Value with two float32 units, Dp and Sp. It also changes
variables and parameters of unit.Value to a specific unit type matching
the context. That is, unit.Dp everywhere except for text sizes which are
in Sp.
Switching to typed float32s has multiple advantages
- They can be constants:
const touchSlop = unit.Dp(16)
- Casting untyped constants is no longer necessary:
insets := layout.UniformInset(16)
- Calculation with values is natural:
func (s ScrollbarStyle) Width() unit.Dp {
return s.Indicator.MinorWidth + s.Track.MinorPadding + s.Track.MinorPadding
}
The main API change is that calls to gtx.Px must be replaced with either
gtx.Dp or gtx.Sp depending on the unit.
Idea by Christophe Meessen.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before this change, every Event would be passed to the focused InputOp
tag, making it impossible to implement, say, program-wide shortcuts.
This change implements key.Event routing similar to how pointer.Events
are routed: every InputOp describes the set of keys it can handle, and
the router use that information to deliver an Event to the matching
handler.
This is an API change, because every InputOp must now include a filter
matching the keys it wants to handle.
Fixes: https://todo.sr.ht/~eliasnaur/gio/395
Signed-off-by: Elias Naur <mail@eliasnaur.com>
vkDeviceWaitIdle and vkQueueWaitIdle are expensive; a vkFence is cheaper
and the usual way to ensure a previous frame has completed before starting
another.
References: https://todo.sr.ht/~eliasnaur/gio/375
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Add most of the common cursors defined by different systems.
Normalize cursor names to match CSS.
This is API change: some cursor names have changed, and the
underlying type is no longer a string.
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
Before that patch, the Call function was used to call each
JS function related to WebGL. The Call function contains
strings, which is slow on most browsers. Now, it uses
Bind on the initialization and re-use the same function,
avoiding the usage of strings.
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
This change implements reporting of the caret position from Editor, as well
as Windows, macOS, Android support. As a result, the IME composition window
on Windows and macOS is now positioned correctly.
References: https://todo.sr.ht/~eliasnaur/gio/246
Signed-off-by: Elias Naur <mail@eliasnaur.com>
A recorded macro is prefixed with an internal macro op that stores
the end of the macro. The end is used to efficiently skip the macro
when not calling it. The call a macro, the CallOp stores the start
position of the macro.
To support seamless wrapping of Ops lists, this change removes the
dependency on the macro op prefix from CallOp. Internal code can
now call an Ops like this:
var ops op.Ops
var wrapper op.Ops
ops.AddCall(&wrapper.Internal, &ops.Internal, ops.PC{}, ops.PCFor(&ops.Internal))
References: https://todo.sr.ht/~eliasnaur/gio/318
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Remove unnecessary fill when starting a recording in op.Record.
Have the exact number of possible stack kinds in ops.Ops.
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
Multiple operations Op, such as clip.Path, cannot
be interleaved with other ops. This patch adds a
mechanism to ensure that is the case by starting
multi ops with ops.BeginMulti and ending them with
ops.EndMulti while operations are written to op.Ops
with ops.WriteMulti.
This mechanism is applied to clip.Path.
Fixes: https://todo.sr.ht/~eliasnaur/gio/336
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
According to the Vulkan specification the pApplicationInfo member of
the VkInstanceCreateInfo structure may be NULL. However, the Android
emulator crashes on vkEnumeratePhysicalDevices if set to NULL.
This change adds a minimal info to please the emulator.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
OpenGL stores the current context in thread-local memory, but commit
4f5baa9a51 removed a runtime.LockOSThread from app.Window that ensured
the goroutine that drives the context stays on the operating thread that
has the context current. This change restores the thread lock.
As a bonus, this change makes the OpenGL contexts responsible for locking
the thread at MakeCurrent, thereby removing LockOSThread calls from GPU
backend-agnostic code.
Fixes: https://todo.sr.ht/~eliasnaur/gio/334
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The calculated value for maxDist (the maximum allowable error when
converting cubic Beziers to quadratics) was way too small when the
first control point was very close to the starting point of the segment.
(f32.Rectangle.Add does not expand the rectangle to include the new point;
it moves the rectangle by the point's X and Y coordinates.)
Splitting the curve into such small pieces was resulting in very ugly
output.
Fixes: https://todo.sr.ht/~eliasnaur/gio/331
Signed-off-by: Andy Balholm <andy@balholm.com>