Like a previous change for pointer ops, process key ops during the
router decode of ops. This is a performance optimization and preparation
for processing future accessibility ops without without another decode
loop.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The router package decodes the entire ops list thrice: once for pointer
ops, once for key ops, once for other ops. This change removes one
decode round by merging other ops and pointer ops decoding.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The default renderer caches pre-processed paths for efficient re-use,
but failed to distinguish outline paths from stroke paths.
Fixes gio#294
Signed-off-by: Elias Naur <mail@eliasnaur.com>
dropHandlers is mainly used for single tag removal except in one instance.
In that case, simply use a loop.
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
Ops is in the internal package ops, but external clients can reach its
method through op.Ops.Internal. Hide them by converting them to internal
package functions.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
A previous change merged PassOp with AreaOp under the assumption that
the pass mode would be set on a particular area. That assumption turns
out not to hold, so this change brings back PassOp as an independent
stack operation.
This is an API change: replace AreaOp{Pass: true} with a separate
pointer.PassOp operation.
Fixes gio#288
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The mapErr helper may map the error to nil, in which case the caller
should continue, not exit.
This change split up error mapping into mapErr which never maps to nil,
and mapSurfaceErr which handles the VK_KHR_swapchain errors and may map
to nil.
Maybe fixes gio#287
Signed-off-by: Elias Naur <mail@eliasnaur.com>
In a discussion with Raph Levien, the author of our compute renderer
implementation, it became clear to me that it's not at all certain that
complex strokes will ever be efficiently supported by a GPU renderer.
At the same time, the machinery for converting a complex stroke to a
GPU-friendly outline has a significant maintenance cost. Further, it is
surprising to users that complex strokes are significantly slower and
allocate memory.
This change removes support for complex strokes, leaving only
round-capped, round-joined strokes supported by the compute renderer.
The default renderer still converts all strokes to outline, but it also
caches the result.
This is an API change. The complex stroke conversion code has been moved
to the external gioui.org/x/stroke package, with a similar API.
Updats gio#282 (Inkeliz brought up the allocation issue)
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The op.Save and Load methods exist to support the need for
transformation, clip, pointer area state to behave as stacks. For
example, layout needs to apply an offset to its children but not
subsequent operations.
Before this change, op.Save and Load were used to save and restore the
state:
ops := new(op.Ops)
// Save state.
state := op.Save(ops)
// Apply offset.
op.Offset(...).Add(ops)
// Draw with offset applied.
draw(ops)
// Restore state.
state.Load()
A drawback with the op.Save mechanism is that there is no direct
connection between the state change and the saving and loading of state.
This causes confusion as to when a Save/Load is needed and who is
responsible for performing them, which leads to subtle bugs and over-use
of Save/Loads.
This change gets rid of the general state stack and replaces it with
per-state stacks. There is now a stack for transformation, clip, pointer
areas, and they can only be restored by the code pushing state to them.
The example above now becomes:
ops := new(op.Ops)
// Push offset to the transformation stack.
stack := op.Offset(...).Push(ops)
// Draw with offset applied.
draw(ops)
// Restore state.
stack.Pop()
For convenience, transformation also be Add'ed if the stack operation is
not required.
Simple state such as the current material no longer has a way to be
restored; it is assumed the client of a PaintOp adds their desired
material operation before it.
API change: replace op.Save/Load with explicit Push/Pop scopes for
op.TransformOps, pointer.AreaOps, clip.Ops.
To ease porting, this change retains a version of op.Save/Load that
saves and restores the transformation and clip stacks. It also retains
an Add method for clip.Op.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
We're about to make operation scopes explicit, which would result in
both AreaOp and PassOp be scoped. However, PassOp seems to light to have
its separate stack, so this change instead makes pass-through a property
of an area. We're assuming that clients that want pass-through are also
aware of the affected hit area.
API change: replace PassOps with the AreaOp.PassThrough field.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This change avoids a macro wrapping every text shape, and prepares text
shaping for scoped clip operations.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Most importantly, return dimensions and transformation instead of adding
operations. Makes the function easier to test, and supports scoped
transform and clip stacks.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
We're about to split state into a clip stack and a transform stack. The
intersect fields belongs to clip state.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The clip field tracks the intersection of the clip stack, and belongs in
the clip stack entries. This is a refactor that makes it easier to
implement scoped clip operations.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The rect field tracks whether the clip stack can be represented by a
pixel-aligned rectangle. It is easier to track as part of pathOp instead
of the global drawState.
Remove an obsolete comment while here.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Since the Process* methods on clipboardQueue are called while decoding
the ops, no need to recheck for the op type.
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
Most Gio programs have exlusive access to their OpenGL contexts, where
saving and restoring of the GL state is not required.
This change applies to all OpenGL platforms, but matters most for WASM
where syscalls are slow.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before this change, the sRGB emulation target would always be the
current framebuffer. Now it's the render target passed to BeginFrame.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
glGetUniformLocation can return -1 (not found) for uniforms that have
been optimized out during linking of a GPU program. This happens because
the default renderer compile multiple program from the same generic
template.
Updates gio#280
Signed-off-by: Elias Naur <mail@eliasnaur.com>
CFTypeRefs may not always contain valid pointers, so they must not be
stored in pointer types lest the Go runtime treats them as such.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before this change, it was unclear who owned the platform specific
VkSurfaceKHR object, leading to a double-free in the error path for
devices with no Vulkan support. This change moves the ownership to the
platform specific code.
Add vk.EnumeratePhysicalDevices while here (refactor was part of
debugging of the double-free).
Signed-off-by: Elias Naur <mail@eliasnaur.com>