mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
shareable: Add Shader
This commit is contained in:
parent
1c980a16f5
commit
9c637c65be
@ -150,7 +150,7 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color
|
||||
if level == 0 {
|
||||
vs := quadVertices(bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y, a, b, c, d, tx, ty, cr, cg, cb, ca, screen)
|
||||
is := graphics.QuadIndices()
|
||||
m.orig.DrawTriangles(src.orig, vs, is, colorm, mode, filter, driver.AddressClampToZero)
|
||||
m.orig.DrawTriangles(src.orig, vs, is, colorm, mode, filter, driver.AddressClampToZero, nil, nil)
|
||||
} else if buf := src.level(bounds, level); buf != nil {
|
||||
w, h := sizeForLevel(bounds.Dx(), bounds.Dy(), level)
|
||||
s := pow2(level)
|
||||
@ -160,7 +160,7 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color
|
||||
d *= s
|
||||
vs := quadVertices(0, 0, w, h, a, b, c, d, tx, ty, cr, cg, cb, ca, false)
|
||||
is := graphics.QuadIndices()
|
||||
m.orig.DrawTriangles(buf, vs, is, colorm, mode, filter, driver.AddressClampToZero)
|
||||
m.orig.DrawTriangles(buf, vs, is, colorm, mode, filter, driver.AddressClampToZero, nil, nil)
|
||||
}
|
||||
m.disposeMipmaps()
|
||||
}
|
||||
@ -183,7 +183,7 @@ func (m *Mipmap) DrawTriangles(src *Mipmap, vertices []float32, indices []uint16
|
||||
vertices[i*n+11] *= ca
|
||||
}
|
||||
}
|
||||
m.orig.DrawTriangles(src.orig, vertices, indices, colorm, mode, filter, address)
|
||||
m.orig.DrawTriangles(src.orig, vertices, indices, colorm, mode, filter, address, nil, nil)
|
||||
m.disposeMipmaps()
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ func (m *Mipmap) level(r image.Rectangle, level int) *shareable.Image {
|
||||
return nil
|
||||
}
|
||||
s := shareable.NewImage(w2, h2, m.volatile)
|
||||
s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressClampToZero)
|
||||
s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressClampToZero, nil, nil)
|
||||
imgs[level] = s
|
||||
|
||||
return imgs[level]
|
||||
|
@ -282,7 +282,7 @@ func (i *Image) region() (x, y, width, height int) {
|
||||
// 9: Color G
|
||||
// 10: Color B
|
||||
// 11: Color Y
|
||||
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address) {
|
||||
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) {
|
||||
backendsM.Lock()
|
||||
// Do not use defer for performance.
|
||||
|
||||
@ -316,7 +316,36 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
||||
vertices[i*graphics.VertexFloatNum+7] += oyf
|
||||
}
|
||||
|
||||
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address, nil, nil)
|
||||
var s *restorable.Shader
|
||||
if shader != nil {
|
||||
s = shader.shader
|
||||
}
|
||||
|
||||
firstImage := true
|
||||
us := make([]interface{}, len(uniforms))
|
||||
for i := 0; i < len(uniforms); i++ {
|
||||
switch v := us[i].(type) {
|
||||
case *Image:
|
||||
us[i] = v.backend.restorable
|
||||
if !firstImage {
|
||||
i++
|
||||
pos := us[i].([]float32)
|
||||
pos[0] += oxf
|
||||
pos[1] += oyf
|
||||
i++
|
||||
region := us[i].([]float32)
|
||||
region[0] += oxf
|
||||
region[1] += oyf
|
||||
region[2] += oxf
|
||||
region[3] += oyf
|
||||
}
|
||||
firstImage = false
|
||||
default:
|
||||
us[i] = v
|
||||
}
|
||||
}
|
||||
|
||||
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address, s, us)
|
||||
|
||||
i.nonUpdatedCount = 0
|
||||
delete(imagesToMakeShared, i)
|
||||
|
@ -89,7 +89,7 @@ func TestEnsureNotShared(t *testing.T) {
|
||||
// img4.ensureNotShared() should be called.
|
||||
vs := quadVertices(size/2, size/2, size/4, size/4, 1)
|
||||
is := graphics.QuadIndices()
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
want := false
|
||||
if got := img4.IsSharedForTesting(); got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
@ -119,7 +119,7 @@ func TestEnsureNotShared(t *testing.T) {
|
||||
|
||||
// Check further drawing doesn't cause panic.
|
||||
// This bug was fixed by 03dcd948.
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
}
|
||||
|
||||
func TestReshared(t *testing.T) {
|
||||
@ -159,7 +159,7 @@ func TestReshared(t *testing.T) {
|
||||
// Use img1 as a render target.
|
||||
vs := quadVertices(size, size, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img2, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img1.DrawTriangles(img2, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -169,7 +169,7 @@ func TestReshared(t *testing.T) {
|
||||
if err := MakeImagesSharedForTesting(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -196,7 +196,7 @@ func TestReshared(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), true; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -224,7 +224,7 @@ func TestReshared(t *testing.T) {
|
||||
if err := MakeImagesSharedForTesting(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
img0.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
img0.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
if got, want := img3.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -319,7 +319,7 @@ func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.ReplacePixels(pix)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, w, h)
|
||||
@ -361,7 +361,7 @@ func TestSmallImages(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, w, h)
|
||||
if err != nil {
|
||||
@ -403,7 +403,7 @@ func TestLongImages(t *testing.T) {
|
||||
const scale = 120
|
||||
vs := quadVertices(w, h, 0, 0, scale)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, dstW, dstH)
|
||||
if err != nil {
|
||||
|
52
internal/shareable/shader.go
Normal file
52
internal/shareable/shader.go
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2020 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shareable
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||
"github.com/hajimehoshi/ebiten/internal/shaderir"
|
||||
)
|
||||
|
||||
type Shader struct {
|
||||
shader *restorable.Shader
|
||||
}
|
||||
|
||||
func NewShader(program *shaderir.Program) *Shader {
|
||||
s := &Shader{
|
||||
shader: restorable.NewShader(program),
|
||||
}
|
||||
runtime.SetFinalizer(s, (*Shader).MarkDisposed)
|
||||
return s
|
||||
}
|
||||
|
||||
// MarkDisposed marks the shader as disposed. The actual operation is deferred.
|
||||
// MarkDisposed can be called from finalizers.
|
||||
//
|
||||
// A function from finalizer must not be blocked, but disposing operation can be blocked.
|
||||
// Defer this operation until it becomes safe. (#913)
|
||||
func (s *Shader) MarkDisposed() {
|
||||
deferredM.Lock()
|
||||
deferred = append(deferred, func() {
|
||||
s.dispose()
|
||||
})
|
||||
deferredM.Unlock()
|
||||
}
|
||||
|
||||
func (s *Shader) dispose() {
|
||||
s.shader.Dispose()
|
||||
s.shader = nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user