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>
OpenGL ES 2.0 doesn't support GL_PACK_ROW_LENGTH, so this change implements
a fallback using a temporary buffer.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Backend.queryState sets GL_ACTIVE_TEXTURE to access texture bindings; this change
makes sure GL_ACTIVE_TEXTURE is restored.
Also, make sure GL state changes made in Backend.restoreState is reflected
in Backend.glstate. Backend.glstate is not used after restoreState, so this
is just for clarity.
This is an alternative to https://github.com/gioui/gio/pull/77.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
For some reason, the Android emulator OpenGL implementation needs the output
framebuffer current when eglSwapBuffers is called; otherwise sRGB emulation
breaks. We used to restore the default FBO explicitly, 9b5e9ae607
restored it implicitly through automatic state restoring, but 30ecf75a0f
broke that by only saving and restoring shared context state. This change
restores the explicit behaviour for non-shared contexts.
Signed-off-by: Elias Naur <mail@eliasnaur.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>
There are too many driver issues with ES 3.1 compute shaders. Most
devices support Vulkan but some, such as the Samsung J2, will fall back
to the CPU renderer.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
To use glCopyTexSubImage2D on the Samsung J2 it's not enough to
set GL_READ_FRAMEBUFFER. This change binds GL_FRAMEBUFFER, setting both
READ_FRAMEBUFFER and DRAW_FRAMEBUFFER, fixing the issue.
Setting only GL_READ_FRAMEBUFFER was also a genuine bug, because OpenGL
ES 2.0 doesn't support it.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
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>
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>
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>
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>
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>
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>
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>
On my Fedora Intel GPU, issuing a glBufferSubData immediately after a
glBufferData with no data may leave the buffer cleared.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
OpenGL ES 2.0 doesn't support glBlitFramebuffer, but does support
glCopyTexSubImage2D. Fortunately, we don't need the extra features of
glBlitFramebuffer anyway.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
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>
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>
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>
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>
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>
To ease the integration with foreign OpenGL contexts, carefully save the
context state before rendering a frame and restore it afterwards. Gio
rendering can then be mixed with OpenGL code that expects exclusive
control over context state.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This changes moves the macOS specific setup for desktop OpenGL to the
portable opengl package. The opengl package already takes care of the
desktop OpenGL setup for sRGB framebuffers, and by moving the code we
avoid calling the wrong OpenGL functions in case both OpenGL.framework
and ANGLE libGLESv2.dylib is linked into the program.
Remove the interface casting expressions for gl.Functions; it wasn't
worth the trouble to keep updated.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Desktop OpenGL implements a GL_FRAMEBUFFER_SRGB setting; query that instead
of the frambuffer color encoding.
With this change it is no longer necessary to enable FRAMEBUFFER_SRGB
in the macOS setup; remove it.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
macOS is the only platform where desktop OpenGL is used. To support
foreign ANGLE contexts add a setting to override Gio's selection of
OpenGL implementation.
The bulk of this change is making all function pointers per-context
instead of global, and loading the OpenGL library dynamically. As a side
effect we're closer to Gio tolerating a platform without any OpenGL
implementation. For example, Apple has deprecated OpenGL and OpenGL ES
on its platforms and may remove them in the future.
Note that as a side-effect of this change, Gio needs Go 1.16 or newer to
run on iOS.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Programs such as gio-example/glfw rely on Gio drawing blending with
the framebuffer background. This change makes it so when sRGB emulation
is active.
Signed-off-by: Elias Naur <mail@eliasnaur.com>