Commit Graph

122 Commits

Author SHA1 Message Date
Elias Naur bc2c3db43e op/clip,gpu: move approximation of complex strokes to op/clip.Op.Add
Before this change, the two renderers both had special case code for
approximating strokes they don't support natively. This change moves
that conversion to clip.Op.Add, for several reasons:

- The compute renderer no longer need fallback logic and caches for
  strokes it doesn't support.
- The approximation logic is slow. Moving it to clip.Op.Add will not
  speed it up, but will make the cost easier to spot in profiles. Until all
  strokes are supported natively, users can use macros to cache
  expensive strokes.
- Reduced garbage: Op.Add takes an op.Ops anyway, and can use that for
  storing the approximated stroke outline.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 19:37:45 +01:00
Elias Naur 06c53c3777 internal/ops: expose PC and ResetAt
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 16:21:11 +01:00
Elias Naur 0a4b6549da internal/stroke,gpu: move stroking of path data to package internal/strokg
Pure refactor, preparing for use in op/clip.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 15:42:43 +01:00
Elias Naur 7825bda8f8 internal/stroke,op/clip: don't import op/clip from internal/stroke
To avoid an import cycle in a future change, internal/stroke can no
longer import op/clip. Move required op/clip functionality to
internal/stroke and duplicate the remaining types.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 15:28:52 +01:00
Elias Naur 8c8d1dc16f internal/stroke,gpu: create internal package for stroke to path conversion
Complex strokes are not yet supported in either of the current renderers,
so they are converted to filled outlines in package gpu.

We're about to move that complexity up to the op/clip package, so we're
going to need the converter available from outside package gpu. This
change extracts the conversion code and related types to the separate,
internal package stroke.

No functional changes; a follow-up moves the stroke conversion.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 12:35:41 +01:00
Elias Naur 13da40f601 gpu,op/clip: [compute] get rid of stroke vs fill flags
The fill mode is now controlled by a SetFillMode command, not by flags
on each path segment and fill command.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-19 21:46:31 +01:00
Elias Naur eeb045c59f internal/gl: use dlsym(3) to load ES 3 symbols
There was a special case for optional symbols for macOS/iOS. It turns out
dlsym(3) works as expected, so this change deletes the special case.

The change is required to make Gio work with ANGLE, which emulates
OpenGL ES on top of Metal.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-16 18:15:37 +01:00
Elias Naur 2b21b48a7c gpu,gpu/shaders: revert attempt to fix path gaps
This is effectively a revert of [0], reintroducing the path gaps
described in [1]. A follow-up change will implement another attempt.

[0] https://gioui.org/commit/2feec23561cd84d6b8ddbab84a202df66b123208
[1] https://github.com/linebender/piet-gpu/issues/62

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-13 15:23:25 +01:00
Elias Naur c4850e876d internal/gl: remove redundant parentheses
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 19:04:34 +01:00
Elias Naur 9e79cee447 op/clip,gpu,internal/scene: encode cubic bézier curves natively
The compute renderer supports cubic curves, so encode them as such.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur a369c408f9 gpu: [compute] skip encoding roundtrip for path data
Since clip.Path now encodes paths in the format expected by
elements.comp, use that data directly instead of a roundtrip through
drawOps.buildVerts.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur eb9bf60b09 gpu,internal/ops: decode scene commands directly, not through quads
We're about to let clip.Path use more of the compute renderer features
(lines, cubic béziers). This change prepares the gpu package for reading
one of several commands types, not just the quadratic béziers of before.

The old Quad type is still the basis for the stroking algorithms, but
this change moves it into package gpu which is the only user.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur 07572387e3 internal/ops: switch quad encoding to compute format
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur 9366fce0f3 internal/scene: extract compute shader encoding to a separate package
We're about to encode clip.Paths with the format compatible with the
compute renderer. This change extracts the encoding to a re-usable
package.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur fdfa481082 internal/byteslice: add specialized Uint32 for []uint32 view
Uint32 is the garbage-free and more efficient version of Slice.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur b8bdb96d35 op/clip,gpu,internal/opconst: remove quad count from Path op
The check for path segments in gpu is redundant; clip.Op.Add doesn't add
the Path op if there were no segments.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:19:31 +01:00
Elias Naur 2328ddfeca internal/byteslice: rename package unsafe
All functions left in the old package unsafe were provided byte slice
views of other types. Rename the package accordingly and avoid a name
clash with the standard library package unsafe.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 11:27:02 +01:00
Elias Naur 86f10e33d7 internal/unsafe: get rid of SliceOf
Move SliceOf to the package of the only user and unexport it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 11:20:07 +01:00
Elias Naur 5894127204 internal/unsafe: get rid of GoString
The only users were GOOS=windows code, which can use
golang.org/x/sys/windows.BytePtrToString instead.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 11:19:53 +01:00
Elias Naur cb1defbc63 gpu/internal/rendertest: move rendertest package below gpu
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:32:43 +01:00
Elias Naur 7bc0603d7e internal/gl: rename internal/glimpl
Now that the OpenGL driver package is named "opengl", we can finally get
rid of the ugly "glimpl" name.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:27:44 +01:00
Elias Naur 2c7aba9e7c gpu/internal/convertshaders: move internal/cmd/convertshaders
The convert program is only used by the shaders from package gpu, and
we're about to make the backend package imported by the program internal
to package gpu. Move the converter below package gpu.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:47 +01:00
Elias Naur 2a66bfb2b4 gpu/headless: move package app/headless
Package headless is more about rendering that windows. Move it
accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:47 +01:00
Elias Naur 5a9edc9af8 internal/cocoainit: move app/internal/cocoainit
We're about to move app/headless to gpu/headless, and it imports
cocoainit.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:47 +01:00
Elias Naur 3af4e6accf internal/egl: move app/internal/egl
We're about to move package app/headless to gpu/headless, and it needs
the egl package.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:47 +01:00
Elias Naur 86d17efc2c internal/srgb: move app/internal/srgb
We're about to move app/headless to gpu/headless, and it imports
package srgb indirectly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:47 +01:00
Elias Naur e17dd5bd30 internal/d3d11: extract Direct3D API to separate package
We're about the merge the Direct3D backend into package gpu. Extract the
raw Direct3D API to its own package, just like package glimpl.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-06 14:26:25 +01:00
Egon Elbre 8571433707 internal/cmd/convertshaders: parallelize compilation
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-01 09:59:32 +01:00
Egon Elbre f6fba73885 internal/cmd/convertshaders: add Windows comp shader compilation
Use dxc (DirectXShaderCompiler) for compiling, which is newer than fxc
and doesn't not fail compilation with dynamically uniform flows with
barriers.

Currently requires -directcompute to enable generating the shaders.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-02-25 13:01:18 +01:00
pierre 14595dde9f internal/opconst: removed unused TypeLayer
Signed-off-by: pierre <pierre.curto@gmail.com>
2021-02-24 10:11:50 +01:00
Elias Naur 7286b075e2 internal/cmd/convertshaders: use wine for running the HLSL compiler
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-02-10 21:57:57 +01:00
Elias Naur 57872856e8 internal/unsafe: fix SliceOf to return len equals to cap
Broken by gioui.org/commit/2dce8a0155ae192f54f74747d660b9f311e9e364,
found while debugging the dormant OpenGL backend for Windows.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-26 14:48:27 +01:00
Elias Naur 84b586ae6c gpu: don't automatically clear screen before rendering
Gio UI may be overlaid on top of custom graphics such as in the glfw example.
That will only work if Gio doesn't clear the screen (to white).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-22 18:33:34 +01:00
Elias Naur e70a16c345 io/router/key: add explicit tag to FocusOp; make last SoftKeyboardOp apply
The target of FocusOp is too subtle; be explicit instead and remove
any doubt.

Multiple SoftKeyboardOp in a single frame is rare, but if they do occur,
they should behave as if they were from separate frames: the last one
applies.

As a side-effect the key event router can be much simplified.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-22 16:34:51 +01:00
Elias Naur d0d6c6c38e internal/glimpl: hook up glTexStorage2D on iOS
The glTexStorage2D is part of OpenGL ES 3, but wasn't its function
pointer wasn't initialized on iOS.

Fixes a crash on startup on iOS devices and simulators.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-21 11:40:31 +01:00
Elias Naur d6886737a5 op: change Defer to only restore transformation state
It turns out restoring all operation state from the moment Defer
is executed is too much; for example, a right-click pop-up needs
the transformation, but not the current clip.

Change Defer to only restore the transformation, and reset all
other state.

Other combinations may be needed in future; we'll deal with them then,
possibly by exposing the load state mask.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-19 20:04:30 +01:00
Egon Elbre 468bd6f53a widget/material: add hover to Button
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-01-18 10:56:57 +01:00
Elias Naur 99bfa6a33c internal/f32color: revert incorrect NRGBA to linear color change
Egon Elbre convinced me commit 01d5e72291 was incorrect, because
in the NRGBA colorspace the alpha value is linear, not gamma adjusted.

Updates gio#192

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-16 09:58:04 +01:00
Elias Naur 01d5e72291 internal/f32color: correct pre-multipled color conversion
Tweak a test color to avoid an off-by-1 rounding error after changing
the conversion formula.

Fixes gio#192

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-15 16:02:39 +01:00
Elias Naur f86703e4b0 op: introduce Defer for deferring CallOps
Updates gio#164

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-14 15:53:49 +01:00
Elias Naur d331dd2de8 op: rename StackOp/Push/Pop to StateOp/Save/Load
The semantics were relaxed in a previous commit; this change renames
to operations accordingly.

API change. Use gofmt to adjust your code accordingly:

gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 21:28:59 +01:00
Elias Naur f7902f299b op: implement StackOp in terms of general save/load of state
Push/Pop only allows saving and restoring operation state in a
stack-like manner. We're going to need restoring arbitrary state
for implementing deferred operations.

Generalize state save/restore and implement Push and Pop on top of
that.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 20:53:25 +01:00
Egon Elbre f114acdb02 widget: use correct color in Icon
iconvg seems to expect a linear premultiplied color.

Fixes gio#132

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-01-11 14:32:28 +01:00
Sebastien Binet 8676a73a91 internal/rendertest: use a YIQ-based algorithm to compare images
This PR implements an image comparison algorithm in the NTSC YIQ color
space, as described in:

  Measuring perceived color difference using YIQ NTSC
  transmission color space in mobile applications.
  Yuriy Kotsarenko, Fernando Ramos.

An electronic version is available at:

- http://www.progmat.uaem.mx:8080/artVol2Num2/Articulo3Vol2Num2.pdf

This should allow the image comparison to be a tad more robust than
comparing plain uint8 pixel values.

Signed-off-by: Sebastien Binet <s@sbinet.org>
2021-01-02 12:54:29 +01:00
Elias Naur d23514fd58 gpu: add compute implementation
The old renderer is still the default, so the new compute renderer will only be
used in the rare case the old renderer is not supported but the new is. That
happens on the Samsung J2 Prime and Moto C Android phones. Or set the
GIORENDERER environment variable to "forcecompute" to disable the old renderer:

$ GIORENDERER=forcecompute go run ...

Missing features:
- Gradients are not supported yet, and render as a solid color.
- Draw timers are not added, and profile.Events are not emitted.
- Stroked paths may in some cases appear corrupted because their clip
  outlines are not continuous when generated by Gio. Sebastien is
  working on a fix.
- The new renderer shares most CPU-side logic with the old renderer,
  resulting in several inefficient conversion steps between the old
  operations representation and the new. This is slower, but minimizes
  divergence in features and bugs between the two renderers.

Roadmap:
- The compute renderer supports features that Gio does not yet
exploit: stroked paths with round caps, transformations, lines,
cubic beziér curves.
- More stroke styles and maybe dashed strokes natively in shaders.
- Metal and Direct3D ports.

The most important feature is porting the renderer to run on the CPU. A
CPU renderer will both support Gio on devices with insufficient GPU
support, and allow us to remove the old renderer. Two renderers is twice
the maintenance but the feature set of the weakest implementation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur b1ff179aa0 gpu,app,internal/glimpl: update GL backend for the compute renderer
Modern graphics APIs have immutable objects, with mutable data. For example,
a texture's dimensions are immutable, while the texture contents is not.
Change the GPU API abstraction to match.

Clearing a Texture is convenient to do with a plain []byte. Generalize
Texture.Upload to take a plain byte slice and introduce a helper function for
uploading *image.RGBA data.

Add TextureFormatRGBA8, a format for the linear RGB colorspace.

Add OpenGL ES 3.1 functions for compute programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur e9403d8b18 internal/unsafe: add StructView
Needed by the compute renderer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur 269e7e0d7b internal/cmd/convertshaders: add support for compute shaders
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur bfe2d04c60 gpu,app,internal/glimpl: update GL backend for the compute renderer
Modern graphics APIs have immutable objects, with mutable data. For example,
a texture's dimensions are immutable, while the texture contents is not.
Change the GPU API abstraction to match.

Clearing a Texture is convenient to do with a plain []byte. Generalize
Texture.Upload to take a plain byte slice and introduce a helper function for
uploading *image.RGBA data.

Add TextureFormatRGBA8 a format for the linear RGB colorspace.

Add OpenGL ES 3.1 functions for compute programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 17:21:35 +01:00
Elias Naur e012c3f393 internal/glimpl: [wasm] pass correctly sized buffers to WebGL functions
Before this change, the entire byte buffer would be passed to WebGL, even
though its size may be (much) larger than the source data.
Remakably, this hasn't resulted in any problems until the use of
glBufferSubData, which require the passed data fits the buffer size.

As a bonus, this fix should speed up the wasm port by virtue of passing
much less data across the wasm<->js barrier.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-31 12:31:57 +01:00