docs: public void update (Image image) {
      // if we're a repeating texture (or we want mipmaps) and this image is non-POT on the relevant
      // axes, we need to scale it before we upload it; we'll just do this on the CPU since it feels
      // like creating a second texture, a frame buffer to render into it, sending a GPU batch and
      // doing all the blah blah blah is going to be more expensive overall
      if (config.repeatX || config.repeatY || config.mipmaps) {
        int pixWidth = image.pixelWidth(), pixHeight = image.pixelHeight();
        int potWidth = config.toTexWidth(pixWidth), potHeight = config.toTexWidth(pixHeight);
        if (potWidth != pixWidth || potHeight != pixHeight) {
          Canvas scaled = gfx.createCanvasImpl(Scale.ONE, potWidth, potHeight);
          scaled.draw(image, 0, 0, potWidth, potHeight);
          scaled.image.upload(gfx, this);
          scaled.close();
        } else image.upload(gfx, this); // fast path, woo!
      }
      else image.upload(gfx, this); // fast path, woo!
      if (config.mipmaps) gfx.gl.glGenerateMipmap(GL_TEXTURE_2D);
    }