From f11a656426932017e3d3ef0c4029488de23a0774 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sat, 20 Jun 2020 23:29:56 +0200 Subject: [PATCH] gpu: exploit pathCache in collectOps Previously the cache was only filled during gpu-buffer creation, resulting in extra work on the CPU to transform vertices if the same shape was used multiple times in the same frame. Cases such as font rendering was cached already before this change as it is drawn in it's own op.Ops that is never reset - and thus re-used from one frame to the next. Since we are now calling put() twice per frame an update should no longer panic. Signed-off-by: Viktor --- gpu/caches.go | 3 --- gpu/gpu.go | 7 +++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gpu/caches.go b/gpu/caches.go index 4217b040..b9622639 100644 --- a/gpu/caches.go +++ b/gpu/caches.go @@ -85,9 +85,6 @@ func (r *opCache) get(key ops.Key) (opCacheValue, bool) { } func (r *opCache) put(key ops.Key, val opCacheValue) { - if _, exists := r.newRes[key]; exists { - panic(fmt.Errorf("key exists, %#v", key)) - } r.res[key] = val r.newRes[key] = val } diff --git a/gpu/gpu.go b/gpu/gpu.go index fccb0fcc..6a6abe43 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -319,7 +319,7 @@ func (g *GPU) Collect(viewport image.Point, frameOps *op.Ops) { g.cleanupTimer = g.timers.newTimer() } for _, p := range g.drawOps.pathOps { - if _, exists := g.drawOps.pathCache.get(p.pathKey); !exists { + if v, exists := g.drawOps.pathCache.get(p.pathKey); !exists || v.data == nil { data := buildPath(g.ctx, p.pathVerts) g.drawOps.pathCache.put(p.pathKey, opCacheValue{ data: data, @@ -746,10 +746,13 @@ loop: auxKey = auxKey.SetTransform(trans) if v, ok := d.pathCache.get(auxKey); ok { // Since the GPU data exists in the cache aux will not be used. + // Why is this not used for the offset shapes? op.bounds = v.bounds } else { aux, op.bounds = d.buildVerts(aux, trans) - // this will be added to the cache when building the paths later + // add it to the cache, without GPU data, so the transform can be + // reused. + d.pathCache.put(auxKey, opCacheValue{bounds: op.bounds}) } } else { aux, op.bounds, _ = d.boundsForTransformedRect(bounds, trans)