diff --git a/internal/atlas/image.go b/internal/atlas/image.go index d1eea954d..46e6fbf34 100644 --- a/internal/atlas/image.go +++ b/internal/atlas/image.go @@ -408,7 +408,7 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderSrcImageCount]*Image, vertice vertices[i+2] += oxf vertices[i+3] += oyf } - if shader.ir.Unit == shaderir.Texels { + if shader.ensureShader().Unit() == shaderir.Texels { sw, sh := srcs[0].backend.restorable.InternalSize() swf, shf := float32(sw), float32(sh) for i := 0; i < n; i += graphics.VertexFloatCount { diff --git a/internal/atlas/shader.go b/internal/atlas/shader.go index 40dfbf615..f2ff046ed 100644 --- a/internal/atlas/shader.go +++ b/internal/atlas/shader.go @@ -75,12 +75,6 @@ func (s *Shader) deallocate() { } var ( - NearestFilterShader = &Shader{ - shader: restorable.NearestFilterShader, - ir: restorable.LinearFilterShaderIR, - } - LinearFilterShader = &Shader{ - shader: restorable.LinearFilterShader, - ir: restorable.LinearFilterShaderIR, - } + NearestFilterShader = &Shader{shader: restorable.NearestFilterShader} + LinearFilterShader = &Shader{shader: restorable.LinearFilterShader} ) diff --git a/internal/restorable/images.go b/internal/restorable/images.go index 0adb14746..a1d84d0e2 100644 --- a/internal/restorable/images.go +++ b/internal/restorable/images.go @@ -22,12 +22,14 @@ import ( // images is a set of Image objects. type images struct { - images map[*Image]struct{} + images map[*Image]struct{} + shaders map[*Shader]struct{} } // theImages represents the images for the current process. var theImages = &images{ - images: map[*Image]struct{}{}, + images: map[*Image]struct{}{}, + shaders: map[*Shader]struct{}{}, } func SwapBuffers(graphicsDriver graphicsdriver.Graphics) error { @@ -62,11 +64,19 @@ func (i *images) add(img *Image) { i.images[img] = struct{}{} } +func (i *images) addShader(shader *Shader) { + i.shaders[shader] = struct{}{} +} + // remove removes img from the images. func (i *images) remove(img *Image) { delete(i.images, img) } +func (i *images) removeShader(shader *Shader) { + delete(i.shaders, shader) +} + var graphicsDriverInitialized bool // InitializeGraphicsDriverState initializes the graphics driver state. diff --git a/internal/restorable/shader.go b/internal/restorable/shader.go index 9715f5d72..acf94504e 100644 --- a/internal/restorable/shader.go +++ b/internal/restorable/shader.go @@ -27,26 +27,37 @@ import ( type Shader struct { shader *graphicscommand.Shader + ir *shaderir.Program } func NewShader(ir *shaderir.Program) *Shader { s := &Shader{ shader: graphicscommand.NewShader(ir), + ir: ir, } + theImages.addShader(s) return s } func (s *Shader) Dispose() { + theImages.removeShader(s) s.shader.Dispose() s.shader = nil + s.ir = nil +} + +func (s *Shader) restore() { + s.shader = graphicscommand.NewShader(s.ir) +} + +func (s *Shader) Unit() shaderir.Unit { + return s.ir.Unit } var ( - NearestFilterShader *Shader - NearestFilterShaderIR *shaderir.Program - LinearFilterShader *Shader - LinearFilterShaderIR *shaderir.Program - clearShader *Shader + NearestFilterShader *Shader + LinearFilterShader *Shader + clearShader *Shader ) func init() { @@ -79,9 +90,7 @@ func init() { if err := wg.Wait(); err != nil { panic(err) } - NearestFilterShaderIR = nearestIR NearestFilterShader = NewShader(nearestIR) - LinearFilterShaderIR = linearIR LinearFilterShader = NewShader(linearIR) clearShader = NewShader(clearIR) }