shareable, restorable, graphicscommand: Remove making arrays at DrawTriangles

Updates #1220
This commit is contained in:
Hajime Hoshi 2020-06-29 13:24:49 +09:00
parent aee5d6d708
commit dea3785750
3 changed files with 60 additions and 64 deletions

View File

@ -126,6 +126,13 @@ func (i *Image) InternalSize() (int, int) {
return i.internalWidth, i.internalHeight return i.internalWidth, i.internalHeight
} }
func processSrc(src *Image) {
if src.screen {
panic("graphicscommand: the screen image cannot be the rendering source")
}
src.resolveBufferedReplacePixels()
}
// DrawTriangles draws triangles with the given image. // DrawTriangles draws triangles with the given image.
// //
// The vertex floats are: // The vertex floats are:
@ -152,30 +159,19 @@ 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{}) {
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")
}
}
if i.lastCommand == lastCommandNone { if i.lastCommand == lastCommandNone {
if !i.screen && mode != driver.CompositeModeClear { if !i.screen && mode != driver.CompositeModeClear {
panic("graphicscommand: the image must be cleared first") panic("graphicscommand: the image must be cleared first")
} }
} }
for _, src := range srcs { if src != nil {
src.resolveBufferedReplacePixels() processSrc(src)
}
for _, u := range uniforms {
if src, ok := u.(*Image); ok {
processSrc(src)
}
} }
i.resolveBufferedReplacePixels() i.resolveBufferedReplacePixels()

View File

@ -385,22 +385,19 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
} }
theImages.makeStaleIfDependingOn(i) theImages.makeStaleIfDependingOn(i)
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. // TODO: Add tests to confirm this logic.
var srcstale bool var srcstale bool
for _, src := range srcs { if img != nil && (img.stale || img.volatile) {
if src.stale || src.volatile { srcstale = true
srcstale = true }
break if !srcstale {
for _, u := range uniforms {
if src, ok := u.(*Image); ok {
if src.stale || src.volatile {
srcstale = true
break
}
}
} }
} }

View File

@ -272,6 +272,27 @@ func (i *Image) regionWithPadding() (x, y, width, height int) {
return i.node.Region() return i.node.Region()
} }
func (i *Image) processSrc(src *Image) {
if src.disposed {
panic("shareable: the drawing source image must not be disposed (DrawTriangles)")
}
if src.backend == nil {
src.allocate(true)
}
// Compare i and source images after ensuring i is not shared, or
// i and a source image might share the same texture even though i != src.
if i.backend.restorable == src.backend.restorable {
panic("shareable: Image.DrawTriangles: source must be different from the receiver")
}
}
func makeSharedIfNeeded(src *Image) {
if !src.isShared() && src.shareable() {
imagesToMakeShared[src] = struct{}{}
}
}
// DrawTriangles draws triangles with the given image. // DrawTriangles draws triangles with the given image.
// //
// The vertex floats are: // The vertex floats are:
@ -292,38 +313,17 @@ 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.
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)")
}
}
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)")
} }
for _, src := range srcs {
if src.backend == nil {
src.allocate(true)
}
}
i.ensureNotShared() i.ensureNotShared()
// Compare i and source images after ensuring i is not shared, or if img != nil {
// i and a source image might share the same texture even though i != src. i.processSrc(img)
for _, src := range srcs { }
if i.backend.restorable == src.backend.restorable { for _, u := range uniforms {
panic("shareable: Image.DrawTriangles: source must be different from the receiver") if src, ok := u.(*Image); ok {
i.processSrc(src)
} }
} }
@ -334,8 +334,8 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
dy = paddingSize dy = paddingSize
} }
var oxf, oyf float32 var oxf, oyf float32
if len(srcs) > 0 { if img != nil {
ox, oy, _, _ := srcs[0].regionWithPadding() ox, oy, _, _ := img.regionWithPadding()
ox += paddingSize ox += paddingSize
oy += paddingSize oy += paddingSize
oxf, oyf = float32(ox), float32(oy) oxf, oyf = float32(ox), float32(oy)
@ -388,9 +388,12 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
i.nonUpdatedCount = 0 i.nonUpdatedCount = 0
delete(imagesToMakeShared, i) delete(imagesToMakeShared, i)
for _, src := range srcs { if img != nil {
if !src.isShared() && src.shareable() { makeSharedIfNeeded(img)
imagesToMakeShared[src] = struct{}{} }
for _, u := range uniforms {
if src, ok := u.(*Image); ok {
makeSharedIfNeeded(src)
} }
} }