Git Product home page Git Product logo

games's People

Contributors

danprince avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

ashsimmonds

games's Issues

use lru/weak caches

Noticed strange behaviour where text shadows would disappear after ~90s for no obvious reason. A bit of debugging showed that my benchmarking example was creating a new gradient fill every frame. The cache responsible for text was filling up (one new cached canvas per frame) and eventually it must have affected the rendering behaviour.

Can think of a couple of solutions here. The first would be to use a standard LRU cache with a fixed capacity. Frequently rendered text would stay in the cache with a guarantee that memory won't ever spiral out of control (even if I do something stupid, like recreating a gradient once per frame).

The other option would be to solve the leaking memory with a weak map. A cache built this way would automatically evict entries when there are no more references, whilst allowing the cache to hold as many active entries as necessary.

The tricky thing with weak maps here is that the cache keys are composite (a font, a text color/gradient/pattern, a shadow color/gradient/pattern, and the text itself). That means the cache would need be made of layered weak maps.

cache.get([font, color, shadow, text]);
// behind the scenes, every layer is a weak map
map.get(font)?.get(color)?.get(shadow)?.get(text)

// vs

cache.get(`${font.url}/${key(color)/${key(shadow)}/${text}`)
// behind the scenes it's a single lookup
object[`${font.url}/${key(color)/${key(shadow)}/${text}`]
Something like this?
export class WeakCompositeCache<Keys extends [], Value> {
  private map = new WeakMap();

  set(keys: Keys, value: Value) {
    let cache = this.map;

    for (let i = 0; i < keys.length - 1; i++) {
      let key = keys[i];
      let child = cache.get(key);
      if (!child) {
        child = new WeakMap();
        cache.set(key, child);
      }
      cache = child;
    }

    let key = keys[keys.length - 1];
    cache.set(key, value);
  }

  get(keys: Keys): Value | undefined {
    let cache = this.map;

    for (let i = 0; i < keys.length - 1; i++) {
      let key = keys[i];
      let child = cache.get(key);
      if (!child) return undefined;
    }

    let key = keys[keys.length - 1];
    return cache.get(key);
  }
}

I suspect the LRU approach has better performance and stricter guarantees for memory leaks.

texture batching

Noticing in benchmarks that even with caching in place, rendering text is still much slower than rendering sprites. Seems happy rendering ~6k sprites at 60FPS, but only around ~1k words (both pretty arbitrary measures depending on size etc).

This is almost certainly because it's more expensive to keep sending different textures to the GPU (each unique piece of text is rendered to a separate canvas then cached).

Could try maintaining a main cache texture and have the others drawn into it instead.

Packing sprites into the texture cache efficiently seems like a non-starter (immediately sacrificing the performance gains to calculate layout) and you'd have to recalculate the layout each time the cache changed.

Maybe simpler to work with a horizontal strip instead. Each time we add an item to the cache we'd expand the strip's width/height to accommodate for the new canvas, then add it to the end.

create a font from a sprite

Sometimes useful to be able to manage the font inside a spritesheet rather than a separate file (consistent palette, colocated sprite editing etc).

Should make it possible to create a font from a sprite rectangle inside a sheet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.