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  }