Commit Graph

2083 Commits

Author SHA1 Message Date
Elias Naur 07fdc1a2de gpu,gpu/internal: drop implied transformation from BlitFramebuffer
The Metal (and presumably the D3D11) backend doesn't support transformed
framebuffer blits. The only caller doesn't need it either, so drop that
capability from the driver abstraction.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 58cc817e5f gpu,gpu/internal: move vertex buffer stride to pipeline state
Metal needs the vertex stride at pipeline creation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 1af910959b gpu: fold buffer clearing into framebuffer bind
In Metal, clearing a framebuffer is most efficiently done during bind.
Modify our driver accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur d38c78d7ac gpu,gpu/internal: move InputDesc back from gioui.org/shader module
It was moved to gioui.org/shader by mistake.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur afaa31eca8 gpu: introduce pipeline abstraction
Modern API such as Metal and Vulkan want clients to compile expensive
state changes into pipeline objects. Change our GPU driver abstraction
to match, thereby paving the way for future drivers.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 13b93b27d8 gpu: update gioui.org/shader for portable materials.vert shader
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:31:46 +02:00
Elias Naur 04cc616e1f cmd/gogio: bump minimum iOS version to 10.0
The Go 1.17 runtime crashes on iOS 9 because clock_gettime is missing.
iOS 10 introduced clock_gettime.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-21 08:30:48 +02:00
Chris Waldon ae3103e180 app/internal/wm: implement ViewEvent for X11
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2021-08-20 06:59:17 +02:00
Elias Naur f475087296 gpu/internal/opengl: handle switch from non-sRGB output to sRGB output
The opengl example has a screenshot functionality that renders to a
non-sRGB texture, whereas window rendering is to a sRGB capable EGL
surface. The opengl driver detects the switch from an sRGB capable
output to a non-sRGB capable output, but not the switch back. This
change releases the emulation framebuffer on the switch back.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-19 10:25:05 +02:00
Elias Naur 3773daf155 go.*: update gioui.org/cpu dependency
Avoids panics when freeing cpu resources on unsupported platforms.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-17 10:02:56 +02:00
Elias Naur 8140e39c20 go.*,gpu: use gioui.org/cpu.Supported to determine CPU fallback support
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-17 09:44:17 +02:00
Elias Naur c7ea90c4e2 gpu,go.*: update gioui.org/shader dependency
Fixes the opengl example on macOS.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 18:22:32 +02:00
Elias Naur 6b537f0d4e gpu/headless: remove useless framebuffer bind
GPU.Frame now takes an explicit RenderTarget and it is no longer
necessary to bind the target.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:47:23 +02:00
Elias Naur 6c3711d95a gpu/headless: remove useless headless_gl.go abstraction
There is no longer any shared code between OpenGL backends (unlike
EGL backends).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:47:23 +02:00
Elias Naur 8d8bc19c23 gpu/internal/opengl: remove "gpu" prefix from type names
Refactor only.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:47:23 +02:00
Elias Naur 0d1ee09a64 cmd/gogio: set minimum iOS simulator version to 13
Metal is available from iOS 8 on devices, yet from version 13 on the
simulator.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:47:23 +02:00
Elias Naur 71f834d26f app/internal/wm: remove superfluous main thread switching
The affected code paths are guaranteed to be run on the main thread by
the app.Window callers.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-16 15:45:46 +02:00
Elias Naur 71c5a134d7 gpu: correct GPU.Profile reference to profile.Op
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-13 08:25:22 +02:00
Elias Naur 23640ec38f app,app/internal/wm: create contexts on the main thread
Instead of handing the internal/wm driver a method to run code on the
(blocked) main thread, just run the necessary driver methods on the main
thread.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-12 15:21:37 +02:00
Elias Naur 811e2b53e0 app: ensure context is nil after release
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-11 16:49:37 +02:00
Elias Naur c49fe63d56 internal/gl: use libGLESv2.so.2 for Unix platforms
The unprefixed library names are for development, and Android.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 15:54:00 +02:00
Elias Naur 06556986c5 app/internal/wm: remove gio_ prefixes from static (local) C functions
Static C functions don't pollute the global namespace.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 15:36:49 +02:00
Elias Naur 6aee543234 all: switch to external shaders in the gioui.org/shaders module
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:47:41 +01:00
Elias Naur 18b4442393 all: remove Z buffer support
It is no longer needed by any rendering backend.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:47:37 +01:00
Elias Naur cea8e21f97 gpu: remove opaque rectangle optimization
The default renderer tracks opaque rectangle draw operations and render
them front-to-back with a z-buffer to omit overdraw. However,

- Overlapping opaque rectangles are rare in a GUI, and the most common
instance, a solid window background, is already optimized to a glClear.
- A z-buffer is memory heavy.
- We conservatively assume a 16-bit depth buffer, which limits the
  number of drawing operations to 64k (#127).
- Depth buffer support makes GPU ports more complex, especially for
  upcoming ports (Metal, Vulkan).
- The compute renderer doesn't use z-buffers.

This change removes the optimization; a follow-up removes GPU backend
support.

Fixes gio#127

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:46:16 +01:00
Elias Naur 2059862416 all: merge .m files with their .go counterparts
The only reason for separate files is Objective-C callbacks into Go,
or when the Go side is common, yet the Objective-C side differs from
macOS to iOS.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:46:16 +01:00
Elias Naur 7d84e419c9 gpu,gpu/headless,app/internal/wm: add explicit RenderTarget API
Both the OpenGL and the Direct3D API are stateful and gpu.GPU renders to
the render target current when Frame is called.

Modern GPU API such as Metal don't have a concept of a current render
target, and the target even changes each frame.

Add RenderTarget and add an explicit target argument to GPU.Frame as
well as the underlying driver.Device.BeginFrame.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:45:23 +01:00
Elias Naur 0bdc2e0432 app,app/internal/wm: fold context MakeCurrent/ReleaseCurrent into Lock/Unlock
While here, make context Refresh useful and remove the redundant
MakeCurrent from the window loop.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:53:19 +02:00
Elias Naur 4dd6a50670 .builds: upgrade Apple builder to Go 1.16
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:53:19 +02:00
Petr Karmashev 1efe68c154 op/paint: remove duplicate word
Signed-off-by: Petr Karmashev <smonkl@bk.ru>
2021-08-04 12:58:05 +02:00
Elias Naur 8cec7e04eb gpu,gpu/shaders: [compute] decode sRGB texels in shader when EXT_sRGB is missing
This change avoids the hard dependency on GPU support for sRGB encoded
textures in the compute renderer.

With this change and the previously added CPU fallback, Gio no longer
rely on any GPU functionality outside the OpenGL ES 2.0 level.

Fixes gio#49
Fixes gio#154
Fixes gio#97
Fixes gio#36
Fixes gio#172

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 09:05:55 +02:00
Elias Naur d8f8740574 gpu/internal/opengl: use the linear colorspace when EXT_sRGB is missing
The SRGBFBO emulates a framebuffer in the sRGB colorspace. However, some
low-end devices may not have EXT_sRGB support to store framebuffer content in
sRGB.

This change handles missing EXT_sRGB support by falling back to the linear RGB colorspace.
Falling back loses color precision but is better than failing.

Updates gio#49
Updates gio#154
Updates gio#97
Updates gio#36
Updates gio#172

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur 68fa64dfd5 gpu/internal/opengl: detect sRGB triple in terms of srgbaTripleFor
Refactor in preparation for relaxing sRGB format requirements.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur 970fadf852 gpu/internal/driver: introduce and use FeatureSRGB
No functional changes; a follow-up will implement graceful fallback in
the compute renderer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:59 +02:00
Elias Naur b3a8c24334 gpu/internal/driver: rename TextureFormatSRGB to TextureFormatSRGBA
The format implies an alpha channel; name it accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:37:18 +02:00
Elias Naur 43c5082dab .builds: upgrade to FreeBSD 13
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-29 08:23:21 +02:00
Elias Naur 6e9bb7b91c widget,widget/material: remove Color field from Icon
Icons are meant to be shared among multiple widgets, but their Color
state may end up with unexpected values after use. Replace the state
with and explicit argument to Layout.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-28 14:19:39 +02:00
Elias Naur ea38195e2e gpu: [compute] add CPU fallback
This change adds a CPU fallback for devices that don't support the old
renderer nor have GPU support for compute programs.

Most of the hard work is implemented in the gioui.org/cpu module. It
uses the SwiftShader project with light modification to output
statically compiled CPU .o files for each compute program.

The CPU fallback only covers Linux and Android on arm, arm64, amd64
architectures. There is no fundamental reason support can't be extended
to other platforms:

- macOS and iOS are probably easy, but it's likely that virtually every
  device has GPU support for compute shaders.
- Windows needs a Cgo-less port, or a build constraint to require a C
  compiler (Gio core doesn't).
- FreeBSD and OpenBSD are probably also easy to do because they're so
  similar to Linux.
- The 386 binaries didn't work properly in my tests, so fixes to
  SwiftShader is probably needed. However, I expect virtually every
  Intel device can run amd64 binaries.

Updates gio#49
Fixes gio#228

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:56:50 +02:00
Elias Naur f14c151883 gpu,gpu/internal: generate hashes of compute programs
The CPU fallback for the compute renderer is contained in a separate
module for space reasons, but the CPU binaries must exactly match the
compute programs. However, there is no way to express that constraint
in go.mod.

This change generates hashes of every compute program so that a
following change can verify the CPU binaries match the programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 5197f637a7 gpu: [compute] compute and store clipping path hashes during construction
The hash of the clipping paths that affect drawing operations are computed
and used to quickly determine that two operations are not equal, the
most likely outcome of a comparison.

However, for paths that are constructed once and cached computing the
hash at every frame is wasteful. This is especially true for text, which
is both cached and also among the largest paths in a frame.

This change moves the hashing to op/clip.Path construction time, and
stores the hash in the ops list so it won't be re-computed at every use.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 88fb798cca gpu: [compute] speed up path comparisons with op keys
To re-use previously cached layers, the compute renderer must know
whether two drawing operations are equal. In the case two operations are
not equal, a fast hash comparison will most likely fail. In the case two
equal operations with complicated clipping paths, the comparison of the
path data is expensive.

This change adds support for fast ops.Key comparisons, where two paths
are equal if their ops.Key are. This is an optimization that kicks in
for text rendering, where glyph clipping shapes are re-used across
frames.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 4ab872e36a gpu: [compute] re-use layers that differ only in integer offsets
To re-use drawing operations common to two layers, every operation must
exactly match, including their transformations. However, layers that
differ only by an integer offset can be re-used because rendering does
not depend on the absolute integer offset. This is important in the very
common case of scrolling otherwise static UI content.

This change separate the integer offset from drawing operations and
relaxes the layer cache to match layers that differ only in integer
offsets.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 318ddd0644 gpu: [compute] add function for separating integer offsets from transforms
Refactor only; separateTransform is needed in the following change.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur e6c31a02fd gpu: [compute] cache and re-use drawing operations from the previous frame
The compute renderer is more expensive to run than the old renderer on
low-end GPUs, and even more so on CPUs. To ensure good performance
regardless of the end-user device, this change implements automatic
re-use of content rendered in the frame before the current.

The basic idea is that every drawing operation (PaintOp), along with its
transform and clipping, can be hashed and efficiently looked up. A naïve
caching approach is then to rasterize every operation to separate
sections of several large texture atlases, turning a cache hit into a
very cheap texture copy.

However, for scenes with lots of overlapping operations, the resulting
texture memory from separating the operations would be much larger than
the memory for just the window framebuffer.

So instead of caching individual operations, this change caches layers,
which are sequences of drawing operations. It starts by putting all
operations into a single layer. Then, if the subsequent frame re-uses a
sub-sequence of that larger layer, it is split.

For example, consider a UI similar to the kitchen sample:

Hello, Gio

<Editor>

<Line Editor>

<Button> <Button> <Button>

<ProgressBar>

<Checkbox> <Toggle>

In the first frame, all of the drawing operations comprising the UI will
be stored and cached in a single layer. In the second frame the
progress bar will have moved and the renderer splits the UI into three
layers: layer A for everything up to (but not including) the progress
bar, layer B with just the progress bar, and layer C for the rest. Note
that nothing has been re-used yet. In the third frame, the progress bar
moves again, and this time layer A and C can be copied from the cache
only the progress bar needs redrawing through the compute programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 938e51f111 gpu: [compute] clear viewport through glClear, not through compute
The performance difference is negligible, but is useful when the compute
pipeline can skip rendering to empty tiles.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 89ab5ebf4f gpu: [compute] unify resource cleanup
Rename all resource release methods to "Release", and release all
resources with a slice and loop.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur b87cbc04f3 gpu: [compute] add compute renderer specific decoding of ops
Until now, the two renderers have shared structures and code for
decoding drawing ops and convert them to GPU-friendly structures.

However, the decoder is tailored to the old renderer and use
structures that poorly fits the new compute renderer.

This change copies the decoder and specializes the copy for the compute
renderer, avoiding a round-trip through the old renderer decoder.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur 60a47e7de5 gpu/internal,internal/gl: add support for strided texture uploads
The CPU fallback of the compute renderer needs to upload subtextures
from a larger image.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur abfbeb87cc gpu/internal/d3d11: stub BlitFramebuffer for D3D11
The compute renderer doesn't run on Windows yet, but the d3d11 backend needs
the method to satisfy the driver interface.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:34:18 +02:00
Elias Naur b7a983d7ff go.*: update dependencies, bump go.mod Go version to 1.16
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-27 14:33:52 +02:00