gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/internal/gpu/caches.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package gpu 4 5 import ( 6 "fmt" 7 8 "gioui.org/ui/internal/ops" 9 ) 10 11 type resourceCache struct { 12 res map[interface{}]resource 13 newRes map[interface{}]resource 14 } 15 16 // opCache is like a resourceCache using the concrete Key 17 // key type to avoid allocations. 18 type opCache struct { 19 res map[ops.Key]resource 20 newRes map[ops.Key]resource 21 } 22 23 func newResourceCache() *resourceCache { 24 return &resourceCache{ 25 res: make(map[interface{}]resource), 26 newRes: make(map[interface{}]resource), 27 } 28 } 29 30 func (r *resourceCache) get(key interface{}) (resource, bool) { 31 v, exists := r.res[key] 32 if exists { 33 r.newRes[key] = v 34 } 35 return v, exists 36 } 37 38 func (r *resourceCache) put(key interface{}, val resource) { 39 if _, exists := r.newRes[key]; exists { 40 panic(fmt.Errorf("key exists, %p", key)) 41 } 42 r.res[key] = val 43 r.newRes[key] = val 44 } 45 46 func (r *resourceCache) frame(ctx *context) { 47 for k, v := range r.res { 48 if _, exists := r.newRes[k]; !exists { 49 delete(r.res, k) 50 v.release(ctx) 51 } 52 } 53 for k, v := range r.newRes { 54 delete(r.newRes, k) 55 r.res[k] = v 56 } 57 } 58 59 func (r *resourceCache) release(ctx *context) { 60 for _, v := range r.newRes { 61 v.release(ctx) 62 } 63 r.newRes = nil 64 r.res = nil 65 } 66 67 func newOpCache() *opCache { 68 return &opCache{ 69 res: make(map[ops.Key]resource), 70 newRes: make(map[ops.Key]resource), 71 } 72 } 73 74 func (r *opCache) get(key ops.Key) (resource, bool) { 75 v, exists := r.res[key] 76 if exists { 77 r.newRes[key] = v 78 } 79 return v, exists 80 } 81 82 func (r *opCache) put(key ops.Key, val resource) { 83 if _, exists := r.newRes[key]; exists { 84 panic(fmt.Errorf("key exists, %#v", key)) 85 } 86 r.res[key] = val 87 r.newRes[key] = val 88 } 89 90 func (r *opCache) frame(ctx *context) { 91 for k, v := range r.res { 92 if _, exists := r.newRes[k]; !exists { 93 delete(r.res, k) 94 v.release(ctx) 95 } 96 } 97 for k, v := range r.newRes { 98 delete(r.newRes, k) 99 r.res[k] = v 100 } 101 } 102 103 func (r *opCache) release(ctx *context) { 104 for _, v := range r.newRes { 105 v.release(ctx) 106 } 107 r.newRes = nil 108 r.res = nil 109 }