mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
shader: Fix the case when the source image is nil for shaders
This commit is contained in:
parent
fc44589705
commit
2f843c49a6
@ -288,9 +288,21 @@ func (i *Image) drawImage(src *Image, bounds image.Rectangle, g mipmap.GeoM, col
|
|||||||
//
|
//
|
||||||
// Copying vertices and indices is the caller's responsibility.
|
// Copying vertices and indices is the caller's responsibility.
|
||||||
func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) {
|
func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) {
|
||||||
|
var srcs []*Image
|
||||||
|
if src != nil {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
for _, u := range uniforms {
|
||||||
|
if src, ok := u.(*Image); ok {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
if i == src {
|
if i == src {
|
||||||
panic("buffered: Image.DrawTriangles: src must be different from the receiver")
|
panic("buffered: Image.DrawTriangles: src must be different from the receiver")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delayedCommandsM.Lock()
|
delayedCommandsM.Lock()
|
||||||
defer delayedCommandsM.Unlock()
|
defer delayedCommandsM.Unlock()
|
||||||
@ -304,7 +316,9 @@ func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
src.resolvePendingPixels(true)
|
src.resolvePendingPixels(true)
|
||||||
|
}
|
||||||
i.resolvePendingPixels(false)
|
i.resolvePendingPixels(false)
|
||||||
|
|
||||||
var s *mipmap.Shader
|
var s *mipmap.Shader
|
||||||
@ -322,7 +336,11 @@ func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.img.DrawTriangles(src.img, vertices, indices, colorm, mode, filter, address, s, us)
|
var srcImg *mipmap.Mipmap
|
||||||
|
if src != nil {
|
||||||
|
srcImg = src.img
|
||||||
|
}
|
||||||
|
i.img.DrawTriangles(srcImg, vertices, indices, colorm, mode, filter, address, s, us)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Shader struct {
|
type Shader struct {
|
||||||
|
@ -152,9 +152,21 @@ func (i *Image) InternalSize() (int, int) {
|
|||||||
// If the source image is not specified, i.e., src is nil and there is no image in the uniform variables, the
|
// If the source image is not specified, i.e., src is nil and there is no image in the uniform variables, the
|
||||||
// elements for the source image are not used.
|
// elements for the source image are not used.
|
||||||
func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) {
|
func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) {
|
||||||
if src != nil && src.screen {
|
var srcs []*Image
|
||||||
|
if src != nil {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
for _, u := range uniforms {
|
||||||
|
if src, ok := u.(*Image); ok {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
|
if src.screen {
|
||||||
panic("graphicscommand: the screen image cannot be the rendering source")
|
panic("graphicscommand: the screen image cannot be the rendering source")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if i.lastCommand == lastCommandNone {
|
if i.lastCommand == lastCommandNone {
|
||||||
if !i.screen && mode != driver.CompositeModeClear {
|
if !i.screen && mode != driver.CompositeModeClear {
|
||||||
@ -162,14 +174,9 @@ func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if src != nil {
|
for _, src := range srcs {
|
||||||
src.resolveBufferedReplacePixels()
|
src.resolveBufferedReplacePixels()
|
||||||
}
|
}
|
||||||
for _, v := range uniforms {
|
|
||||||
if img, ok := v.(*Image); ok {
|
|
||||||
img.resolveBufferedReplacePixels()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i.resolveBufferedReplacePixels()
|
i.resolveBufferedReplacePixels()
|
||||||
|
|
||||||
theCommandQueue.EnqueueDrawTrianglesCommand(i, src, vertices, indices, clr, mode, filter, address, shader, uniforms)
|
theCommandQueue.EnqueueDrawTrianglesCommand(i, src, vertices, indices, clr, mode, filter, address, shader, uniforms)
|
||||||
|
@ -200,7 +200,12 @@ func (m *Mipmap) DrawTriangles(src *Mipmap, vertices []float32, indices []uint16
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.orig.DrawTriangles(src.orig, vertices, indices, colorm, mode, filter, address, s, us)
|
var srcOrig *shareable.Image
|
||||||
|
if src != nil {
|
||||||
|
srcOrig = src.orig
|
||||||
|
}
|
||||||
|
|
||||||
|
m.orig.DrawTriangles(srcOrig, vertices, indices, colorm, mode, filter, address, s, us)
|
||||||
m.disposeMipmaps()
|
m.disposeMipmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +384,26 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
}
|
}
|
||||||
theImages.makeStaleIfDependingOn(i)
|
theImages.makeStaleIfDependingOn(i)
|
||||||
|
|
||||||
if (img != nil && (img.stale || img.volatile)) || i.screen || !needsRestoring() || i.volatile {
|
var srcs []*Image
|
||||||
|
if img != nil {
|
||||||
|
srcs = append(srcs, img)
|
||||||
|
}
|
||||||
|
for _, u := range uniforms {
|
||||||
|
if src, ok := u.(*Image); ok {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add tests to confirm this logic.
|
||||||
|
var srcstale bool
|
||||||
|
for _, src := range srcs {
|
||||||
|
if src.stale || src.volatile {
|
||||||
|
srcstale = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcstale || i.screen || !needsRestoring() || i.volatile {
|
||||||
i.makeStale()
|
i.makeStale()
|
||||||
} else {
|
} else {
|
||||||
i.appendDrawTrianglesHistory(img, vertices, indices, colorm, mode, filter, address, shader, uniforms)
|
i.appendDrawTrianglesHistory(img, vertices, indices, colorm, mode, filter, address, shader, uniforms)
|
||||||
|
@ -286,26 +286,45 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
// Do not use defer for performance.
|
// Do not use defer for performance.
|
||||||
|
|
||||||
if img.disposed {
|
var srcs []*Image
|
||||||
|
if img != nil {
|
||||||
|
srcs = append(srcs, img)
|
||||||
|
}
|
||||||
|
for _, u := range uniforms {
|
||||||
|
if src, ok := u.(*Image); ok {
|
||||||
|
srcs = append(srcs, src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
|
if src.disposed {
|
||||||
panic("shareable: the drawing source image must not be disposed (DrawTriangles)")
|
panic("shareable: the drawing source image must not be disposed (DrawTriangles)")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if i.disposed {
|
if i.disposed {
|
||||||
panic("shareable: the drawing target image must not be disposed (DrawTriangles)")
|
panic("shareable: the drawing target image must not be disposed (DrawTriangles)")
|
||||||
}
|
}
|
||||||
if img.backend == nil {
|
|
||||||
img.allocate(true)
|
for _, src := range srcs {
|
||||||
|
if src.backend == nil {
|
||||||
|
src.allocate(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.ensureNotShared()
|
i.ensureNotShared()
|
||||||
|
|
||||||
// Compare i and img after ensuring i is not shared, or
|
// Compare i and source images after ensuring i is not shared, or
|
||||||
// i and img might share the same texture even though i != img.
|
// i and a source image might share the same texture even though i != src.
|
||||||
if i.backend.restorable == img.backend.restorable {
|
for _, src := range srcs {
|
||||||
panic("shareable: Image.DrawTriangles: img must be different from the receiver")
|
if i.backend.restorable == src.backend.restorable {
|
||||||
|
panic("shareable: Image.DrawTriangles: source must be different from the receiver")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ox, oy, _, _ := img.region()
|
var oxf, oyf float32
|
||||||
oxf, oyf := float32(ox), float32(oy)
|
if len(srcs) > 0 {
|
||||||
|
ox, oy, _, _ := srcs[0].region()
|
||||||
|
oxf, oyf = float32(ox), float32(oy)
|
||||||
n := len(vertices) / graphics.VertexFloatNum
|
n := len(vertices) / graphics.VertexFloatNum
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
vertices[i*graphics.VertexFloatNum+2] += oxf
|
vertices[i*graphics.VertexFloatNum+2] += oxf
|
||||||
@ -315,6 +334,7 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
vertices[i*graphics.VertexFloatNum+6] += oxf
|
vertices[i*graphics.VertexFloatNum+6] += oxf
|
||||||
vertices[i*graphics.VertexFloatNum+7] += oyf
|
vertices[i*graphics.VertexFloatNum+7] += oyf
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var s *restorable.Shader
|
var s *restorable.Shader
|
||||||
if shader != nil {
|
if shader != nil {
|
||||||
@ -343,13 +363,19 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address, s, us)
|
var r *restorable.Image
|
||||||
|
if img != nil {
|
||||||
|
r = img.backend.restorable
|
||||||
|
}
|
||||||
|
i.backend.restorable.DrawTriangles(r, vertices, indices, colorm, mode, filter, address, s, us)
|
||||||
|
|
||||||
i.nonUpdatedCount = 0
|
i.nonUpdatedCount = 0
|
||||||
delete(imagesToMakeShared, i)
|
delete(imagesToMakeShared, i)
|
||||||
|
|
||||||
if !img.isShared() && img.shareable() {
|
for _, src := range srcs {
|
||||||
imagesToMakeShared[img] = struct{}{}
|
if !src.isShared() && src.shareable() {
|
||||||
|
imagesToMakeShared[src] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backendsM.Unlock()
|
backendsM.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user