Commit Graph

2178 Commits

Author SHA1 Message Date
Elias Naur 8999747ad2 app,gpu,internal/vk: add Vulkan port for Wayland, X11, Android
This change implements a Vulkan port for the two renderers, old and
compute. Run with GIORENDERER=forcecompute to test the compute renderer.

To shake out bugs faster, it is also made the default on systems that
support it. To disable Vulkan and force the use of OpenGL, use the
`novulkan` tag:

$ go run -tags novulkan gioui.org/example/kitchen

Don't forget to file an issue describing the issue that prompted the use
of the tag.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 18:40:05 +02:00
Elias Naur bdd0893dd0 app,gpu: move errDeviceLost from package app to package gpu
The Vulkan backend can return device lost error from more than just
Present.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:58 +02:00
Elias Naur b5e3756ee8 gpu/internal/driver: get rid of Device.MemoryBarrier
MemoryBarrier is meant to stand in for OpenGL ES 3.1's glMemoryBarrier.
However, it badly fits with the other backends: Metal and D3D11 have
automatic memory barriers, and Vulkan needs barriers for graphics as
well.

This change removes MemoryBarrier, and puts the burden on the backends.
The OpenGL backend simply adds a barrier between every compute dispatch.

This change only adds a single memory barrier compared to the manual
barriers before this change, which is unlikely to affect performance
much.. We can revisit the automatic barriers if they ever become a
performance problem.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:58 +02:00
Elias Naur 1f0f88dbd3 gpu: drop access flags and format from driver.Device.BindImageTexture
They can be deferred in the drivers that need them.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:58 +02:00
Elias Naur 0bdd24c51e gpu: fold driver.Framebuffer functionality into driver.Texture
driver.Device.NewFramebuffer doesn't provide additional information over
driver.Device.NewTexture, so Texture can hold its (optional) framebuffer
on behalf of the renderers. Metal don't even need a separate framebuffer
object.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:58 +02:00
Elias Naur b599a6d1c5 gpu: introduce driver.Device.PrepareTexture and use it in renderers
Vulkan textures (VkImage) are always in a particular layout, where each
layout is optimized for a particular use (transfer, sampling, compute
storage). Vulkan allows layout transitions everywhere except inside
render passes. This change adds driver.Device.PrepareTexture for
instructing the driver to switch a texture to a layout for sampling
in preparation for using it in a render pass.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:36 +02:00
Elias Naur 0ba984c19c gpu: [compute] don't change vertex buffers during render passes
Vulkan doesn't support it, so move vertex buffer updates outside render
passes. Splitting render passes is another approach, but not as
efficient.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:05 +02:00
Elias Naur 21ca9d13a8 gpu: switch from uniform buffers to combined push buffers
Vulkan doesn't support changing uniforms during a render pass. However,
push constants *can* be changed. The gio-shader repository was changed
to use push constants instead of uniforms, this change implements the
corresponding driver and renderer change.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:02 +02:00
Elias Naur 3a98f004f9 gpu/internal/opengl: reduce number of glsl shader variants
With the use of uniform buffers gone, we don't need the glsl 3.00 es
variant any longer.

We only support desktop OpenGL on macOS which is guaranteed to be
at least version 3.2, so we don't need the glsl 1.30 variant either.

Remove a test that depended on gl_VertexID which is not support in glsl
1.00 es.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:47:11 +02:00
Elias Naur 3d1e9b0856 gpu: rename DrawMode to Topology and move it to pipeline descriptors
Vulkan needs the topology stated in its pipeline descriptor, not at
draw time.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur 41e812d5e8 gpu: [compute] always bind valid materials texture
Currently, we run kernel4.comp with whatever texture was
bound (or none) when there are no materials in the set of layers.

However, Vulkan require every image binding to a compute shader to be
non-null and valid. This change works around that limitation by binding
a small dummy texture when no materials are needed.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur cc2edbaa51 gpu: introduce render passes
Modern GPU API such as Metal and Vulkan use explicit render passes
and command buffers for recording rendering commands. They don't have
global state; each render pass starts with a clean set of bound
textures, pipeline etc.

Change our GPU abstraction to better match newer API and modify our two
renderers to explicitly describe their render passes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur af6770de18 app: add error result to context.RenderTarget
Vulkan may report VK_ERROR_OUT_OF_DATE_KHR which is not a fatal error.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur 9e6ed3cb96 gpu/internal/rendertest: clean up headless context immediately
GPU contexts can hold on to a significant amount of resources. Clean
them up immediately instead of at test cleanup.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur f842178ac7 gpu/internal/metal: don't copy padding during images transfers
Don't copy the padding when stride is larger than the width. Applies to
Texture.Upload and Framebuffer.ReadPixels.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur da1c4a60e0 gpu/internal/rendertest: only dump images when -saveimages is set
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur 78b6268f9b gpu/headless: plug resource leaks in tests
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 13:26:43 +02:00
Elias Naur 18c2ba8e20 app: replace Window.Config with ConfigEvent
Unlike Raise, Close and other fire-and-forget methods on Window,
Config calls driverRun because it needs to wait for the result.
However, driverRun isn't guaranteed to block in all contexts.

This change avoids the synchronization dance altogether by removing the
Config method and introducing a ConfigEvent event. The event also makes
it clear when the configuration changes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 08:18:03 +02:00
Pierre Curto 64bcb1ccd5 layout: do not reset cross axis constraints in Direction for N, S, E and W
Fixes #268

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-19 11:04:02 +02:00
Pierre Curto 7463910191 gesture: fix typos in comments, remove unused type
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-19 11:04:02 +02:00
Elias Naur d1b35bf1d7 app: [macOS] trigger redraw on resize for context-less windows
Switching to using a CAMetalLayer as the layer backing our NSView
implementation broke programs such as the opengl example. Somehow, using
ANGLE on top of a CAMetalLayer (but not a CAEAGLLayer) stops resizes
from triggering redraws.

This change invalidates the view in setFrameSize, to force a redraw
and no longer rely on the implicit redraws.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-19 09:16:11 +02:00
Elias Naur 799ee3374d widget,widget/material: scroll using only drag position delta
This commit is based on a patch by Elias that improved drag scrolling
on the scrollbar by locking some parameters of the math at the start
of the scroll event.

I discovered while playing with that implementation that there was
an even simpler approach within his changeset. You can actually
use no information other than the delta between the current and
previous frame's scroll position to compute the scroll distance.
By simplifying the math to rely on no other inputs, the jitter that
we've been fighting simply disappears (it came from other inputs).

Turns out my attempts to make the logic smart were the problem.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2021-09-17 08:47:13 +02:00
Elias Naur c9d85c97e1 app: process driver funcs before queueing more
Window.driverFunc says it can be run from any context. However, running
it from the Window.run event loop may deadlock, at least until an
unrelated event arrives from the driver (e.g. a mouse move).

Example:
Window.Invalidate is called, which caused Window.run to queue a driver
func, and notify the Window.wakeups channel. However, another
Window.Invalidate arrives just in time for Window.run to process that
before Window.wakeups, leading to a deadlock because only one driver
func can be queued.

This change fixes the problem by processing wakeups before potentially
queueing more driver functions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-16 10:49:42 +02:00
Elias Naur f896a72ea1 app,gpu/internal/opengl: move glFlush to macOS context present
A previous change[0] moved all OpenGL function calls to the internal
opengl package, so that Gio can use desktop OpenGL and OpenGL ES (ANGLE)
in the same program without confusing the function pointers.

However the change also moved the glFlush that constitutes a buffer
swap, or present, on macOS. Other platforms don't need the flush, so
this change moves it back to macOS-specific code, in glContext.Present
where it belongs. It also uses dlopen and dlsym to avoid symbol
confusion between Apple's OpenGL framework and ANGLE's libGLESv2.dylib.

The motivation is that we're getting rid of the desktop OpenGL backend
on macOS in favor of Metal, and so should reduce the number of global
special-cases catering to that platform.

[0] https://gioui.org/commit/476d2269a

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-15 21:12:29 +02:00
Elias Naur dd6b379c74 internal/gl: explicitly state RTLD_LOCAL to dlopen
RTLD_LOCAL is the default on Linux, whereas RTLD_GLOBAL is default on
macOS. Be explicit.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-14 09:24:53 +02:00
Chris Waldon 77eed223ac widget/material: fix scrollbar indicator partially off-screen bug
This commit fixes a problem that could force the scroll indicator to
lay itself out outside of its configured bounds. This occurred when
the scroll indicator size was increased to meet the minimum size
configured on the style type while the scrollbar was near the end
of the list. The increased size did not take the start position
of the scroll indicator into account, which made the indicator begin
in the correct place, but extend beyond the end of its track.

This commit alters the logic to ensure that the scroll indicator can
never extend beyond the end of its track.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2021-09-14 06:42:22 +02:00
Chris Waldon da09aabbe8 widget/material: clamp fromListPosition end coordinate
Previously, it was possible for fromListPosition to return
an end coordinate greater than 1, which would make scroll
indicators using those coordinates render beyond the
boundaries of their scroll tracks. One could argue that
this is a bug in the scroll indicator, but I don't think
this method should return data outside of its documented
range.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2021-09-14 06:42:15 +02:00
Elias Naur fc5637804f gpu: plug another GPU resource leak
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-12 18:27:29 +02:00
Elias Naur dae3b0fa5a cmd/gogio: [Android] report unsupported JDK versions when d8 fails
d8 doesn't check and fails with an inscrutable error when using
unsupported JDK versions such as JDK 11.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-11 09:31:24 +02:00
Elias Naur c175aaeb7c cmd: bump gio version
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-10 08:25:53 +02:00
Elias Naur d5d0a75a9b app: fix build on FreeBSD
Somehow, the explicit include and library directories needed for OpenBSD
are required for FreeBSD as well.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-10 08:24:18 +02:00
Pierre Curto e92ca233f5 app: ignore app.Size when in fullscreen mode
Setting the window size while in fulscreen mode does not make sense.

Fixes gio#220

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-09 16:24:23 +02:00
Elias Naur 173f14be78 gpu: [compute] don't leak driver.Device instance
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-09 12:39:02 +02:00
Pierre Curto 2f66ed1dc8 app: add Window.Raise to bring a window to the front
Fixes gio#252

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-09 07:46:09 +02:00
Elias Naur c5d4e01e3d app: [X11] honour _NET_WM_STATE protocol
The _NET_WM_STATE protocol description[0] states that to change the
window mode for an X11,

"To change the state of a mapped window, a Client MUST send a
_NET_WM_STATE client message to the root window."

and that the window manager in turn

"The Window Manager MUST keep this property updated to reflect the
current state of the window."

However, our X11 implementation did both: send the message _and_ set or
deleted the property.

This change makes it so only the message is sent. It also replaces
toggling the property by setting or clearing, to ensure our mode and the
window manager's mode never gets out of sync.

Maybe fixes gio#265

[0] https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm46515148826720

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-08 13:25:17 +02:00
Pierre Curto b3751dd9ab app: fix invalid NewWindow config on X11
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-08 08:20:39 +02:00
Elias Naur f3f4bacb1c gpu: don't leak GPU buffer from sizedBuffer.Release
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-07 16:31:49 +02:00
Pierre Curto bdc2f3f4e8 app: add Window.Config, export app.Config
A Window configuration with its current option values can now be fetched during a FrameEvent.

The WindowMode and Orientation options have moved to methods on their corresponding types.

Fixes #260

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-07 08:06:56 +02:00
Pierre Curto 30663a71c5 build: check gofmt and sign-off first
Fixes #264

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-06 17:09:21 +02:00
Elias Naur bde046de54 gpu/internal/opengl: avoid PACK/UNPACK_ROW_LENGTH on WebGL 1
Fixes gio#259

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 13:58:19 +02:00
Walter Werner SCHNEIDER 0403b1ff8e text: add fmt.Stringer implementation for Weight
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
2021-09-05 13:58:19 +02:00
Elias Naur 74464f64dc app: use driver defer mechanism for changing animation flag
Now that Window.driverDefer can be run in any context, the special case
of setting the animation flag can use that mechanism instead of a
special purpose channel.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 13:58:19 +02:00
Elias Naur 9ffe43bc3a app: delete workarounds for driver callback deadlocks
Driver methods are invoked during event processing, but some of them may
generate events that would in turn deadlock because event processing is
not re-entrant. However, a previous change moved all such calls outside
event processing and so chained events can no longer deadlock.

This change deletes the workarounds.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 09:30:47 +02:00
Elias Naur 1796f24a38 app: introduce Window.driverDefer for blocking functions
Window.driverRun is designed to run functions on the driver event
goroutine, to avoid race conditions with internal driver state and,
more importantly, to run on the designated main or UI thread for
platforms that require that.

However, driverRun runs functions during the processing of a driver
event, so if a function in turn triggers another driver event,
deadlock occurs.

This change introduces Window.driverDefer for functions that don't need
to block event processing. Functions passed to driverDefer may
themselves trigger new events.

A few callers of driverRun remain; they need the result of their
functions but are guaranteed not to trigger new events.

Fixes gio#263

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 09:27:50 +02:00
Walter Werner SCHNEIDER 49a7b2e6f4 text/shaper: lookup closest font by weight
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
2021-09-04 11:21:55 +02:00
Felix Lange 23f6dcb868 app: [Android] simplify invalidate in onFrameCallback
Since onFrameCallback runs on the app UI thread, using plain
invalidate() can be used instead of postInvalidate(). The latter just
schedules a call to invalidate() on the UI thread.

Also, since onFrameCallback is directly called by JNI, there is no need
to set up a new JNI environment to call back into Java.

Signed-off-by: Felix Lange <fjl@twurst.com>
2021-09-04 07:26:47 +02:00
Felix Lange 0a4de4f88c cmd/gogio: handle darwin/arm64 in archNDK
This makes gogio builds work for android on darwin/arm64.

Signed-off-by: Felix Lange <fjl@twurst.com>
2021-09-03 14:46:33 +02:00
Elias Naur d03f618660 app: [Windows] avoid deadlock when changing window configuration
Some window configurations lead to WM_SIZE messages when changed, which
leads to deadlock because our window proc is not re-entrant. Avoid the
issues by ignoring redundant messages.

Fixes gio#262

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-03 12:11:55 +02:00
Walter Werner SCHNEIDER a5625031a4 text/shaper: add fmt.Stringer() implementation for Style
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
2021-09-03 07:16:03 +02:00
Walter Werner SCHNEIDER 86b685abe5 text/shaper: update fmt.Stringer() error message for Alignment
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
2021-09-03 07:15:44 +02:00