mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 15:45:38 +00:00
3ae5a37c24
A recent change made the OpenGL functions an interface of the functions required for the implementation of GPU, a renderer for Gio operations. That allowed for running Gio on external systems where OpenGL is available. However, to allow for non-OpenGL flavored backends such as Vulkan, Metal and Direct3D, this change introduces Backend for the high-level operations required by GPU. This change also adds a concrete backend to package gl. Type Backend is a first cut heavily based on OpenGL. Future changes will add more backends, where the Backend interface quite possibly will need refinement. Signed-off-by: Elias Naur <mail@eliasnaur.com>
110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
package gpu
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"gioui.org/internal/ops"
|
|
)
|
|
|
|
type resourceCache struct {
|
|
res map[interface{}]resource
|
|
newRes map[interface{}]resource
|
|
}
|
|
|
|
// opCache is like a resourceCache using the concrete Key
|
|
// key type to avoid allocations.
|
|
type opCache struct {
|
|
res map[ops.Key]resource
|
|
newRes map[ops.Key]resource
|
|
}
|
|
|
|
func newResourceCache() *resourceCache {
|
|
return &resourceCache{
|
|
res: make(map[interface{}]resource),
|
|
newRes: make(map[interface{}]resource),
|
|
}
|
|
}
|
|
|
|
func (r *resourceCache) get(key interface{}) (resource, bool) {
|
|
v, exists := r.res[key]
|
|
if exists {
|
|
r.newRes[key] = v
|
|
}
|
|
return v, exists
|
|
}
|
|
|
|
func (r *resourceCache) put(key interface{}, val resource) {
|
|
if _, exists := r.newRes[key]; exists {
|
|
panic(fmt.Errorf("key exists, %p", key))
|
|
}
|
|
r.res[key] = val
|
|
r.newRes[key] = val
|
|
}
|
|
|
|
func (r *resourceCache) frame() {
|
|
for k, v := range r.res {
|
|
if _, exists := r.newRes[k]; !exists {
|
|
delete(r.res, k)
|
|
v.release()
|
|
}
|
|
}
|
|
for k, v := range r.newRes {
|
|
delete(r.newRes, k)
|
|
r.res[k] = v
|
|
}
|
|
}
|
|
|
|
func (r *resourceCache) release() {
|
|
for _, v := range r.newRes {
|
|
v.release()
|
|
}
|
|
r.newRes = nil
|
|
r.res = nil
|
|
}
|
|
|
|
func newOpCache() *opCache {
|
|
return &opCache{
|
|
res: make(map[ops.Key]resource),
|
|
newRes: make(map[ops.Key]resource),
|
|
}
|
|
}
|
|
|
|
func (r *opCache) get(key ops.Key) (resource, bool) {
|
|
v, exists := r.res[key]
|
|
if exists {
|
|
r.newRes[key] = v
|
|
}
|
|
return v, exists
|
|
}
|
|
|
|
func (r *opCache) put(key ops.Key, val resource) {
|
|
if _, exists := r.newRes[key]; exists {
|
|
panic(fmt.Errorf("key exists, %#v", key))
|
|
}
|
|
r.res[key] = val
|
|
r.newRes[key] = val
|
|
}
|
|
|
|
func (r *opCache) frame() {
|
|
for k, v := range r.res {
|
|
if _, exists := r.newRes[k]; !exists {
|
|
delete(r.res, k)
|
|
v.release()
|
|
}
|
|
}
|
|
for k, v := range r.newRes {
|
|
delete(r.newRes, k)
|
|
r.res[k] = v
|
|
}
|
|
}
|
|
|
|
func (r *opCache) release() {
|
|
for _, v := range r.newRes {
|
|
v.release()
|
|
}
|
|
r.newRes = nil
|
|
r.res = nil
|
|
}
|