mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
graphics: Rename DrawImage -> DrawTriangles for consistency
This commit is contained in:
parent
020cba22c5
commit
cce41e8152
8
image.go
8
image.go
@ -80,7 +80,7 @@ func (m *mipmap) level(r image.Rectangle, level int) *shareable.Image {
|
|||||||
vs = src.QuadVertices(0, 0, w, h, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
|
vs = src.QuadVertices(0, 0, w, h, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
|
||||||
}
|
}
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
s.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterLinear, graphics.AddressClampToZero)
|
s.DrawTriangles(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterLinear, graphics.AddressClampToZero)
|
||||||
imgs = append(imgs, s)
|
imgs = append(imgs, s)
|
||||||
w = w2
|
w = w2
|
||||||
h = h2
|
h = h2
|
||||||
@ -357,7 +357,7 @@ func (i *Image) drawImage(img *Image, options *DrawImageOptions) {
|
|||||||
src := img.mipmap.original()
|
src := img.mipmap.original()
|
||||||
vs := src.QuadVertices(bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
vs := src.QuadVertices(bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
i.mipmap.original().DrawImage(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
|
i.mipmap.original().DrawTriangles(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
|
||||||
} else if src := img.mipmap.level(bounds, level); src != nil {
|
} else if src := img.mipmap.level(bounds, level); src != nil {
|
||||||
w, h := src.Size()
|
w, h := src.Size()
|
||||||
s := 1 << uint(level)
|
s := 1 << uint(level)
|
||||||
@ -367,7 +367,7 @@ func (i *Image) drawImage(img *Image, options *DrawImageOptions) {
|
|||||||
d *= float32(s)
|
d *= float32(s)
|
||||||
vs := src.QuadVertices(0, 0, w, h, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
vs := src.QuadVertices(0, 0, w, h, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
i.mipmap.original().DrawImage(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
|
i.mipmap.original().DrawTriangles(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
|
||||||
}
|
}
|
||||||
i.disposeMipmaps()
|
i.disposeMipmaps()
|
||||||
}
|
}
|
||||||
@ -487,7 +487,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
|||||||
float32(r.Min.X), float32(r.Min.Y), float32(r.Max.X), float32(r.Max.Y),
|
float32(r.Min.X), float32(r.Min.Y), float32(r.Max.X), float32(r.Max.Y),
|
||||||
v.ColorR, v.ColorG, v.ColorB, v.ColorA)
|
v.ColorR, v.ColorG, v.ColorB, v.ColorA)
|
||||||
}
|
}
|
||||||
i.mipmap.original().DrawImage(img.mipmap.original(), vs, indices, options.ColorM.impl, mode, filter, graphics.Address(options.Address))
|
i.mipmap.original().DrawTriangles(img.mipmap.original(), vs, indices, options.ColorM.impl, mode, filter, graphics.Address(options.Address))
|
||||||
i.disposeMipmaps()
|
i.disposeMipmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func SetGraphicsDriver(driver driver.Graphics) {
|
|||||||
|
|
||||||
// command represents a drawing command.
|
// command represents a drawing command.
|
||||||
//
|
//
|
||||||
// A command for drawing that is created when Image functions are called like DrawImage,
|
// A command for drawing that is created when Image functions are called like DrawTriangles,
|
||||||
// or Fill.
|
// or Fill.
|
||||||
// A command is not immediately executed after created. Instaed, it is queued after created,
|
// A command is not immediately executed after created. Instaed, it is queued after created,
|
||||||
// and executed only when necessary.
|
// and executed only when necessary.
|
||||||
@ -94,9 +94,9 @@ func (q *commandQueue) appendIndices(indices []uint16, offset uint16) {
|
|||||||
q.nindices += len(indices)
|
q.nindices += len(indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nindices int, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address, forceNewCommand bool) {
|
func (q *commandQueue) doEnqueueDrawTrianglesCommand(dst, src *Image, nvertices, nindices int, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address, forceNewCommand bool) {
|
||||||
if nindices > graphics.IndicesNum {
|
if nindices > graphics.IndicesNum {
|
||||||
panic(fmt.Sprintf("graphicscommand: nindices must be <= graphics.IndicesNum but not at doEnqueueDrawImageCommand: nindices: %d, graphics.IndicesNum: %d", nindices, graphics.IndicesNum))
|
panic(fmt.Sprintf("graphicscommand: nindices must be <= graphics.IndicesNum but not at doEnqueueDrawTrianglesCommand: nindices: %d, graphics.IndicesNum: %d", nindices, graphics.IndicesNum))
|
||||||
}
|
}
|
||||||
if !forceNewCommand && 0 < len(q.commands) {
|
if !forceNewCommand && 0 < len(q.commands) {
|
||||||
if last := q.commands[len(q.commands)-1]; last.CanMerge(dst, src, color, mode, filter, address) {
|
if last := q.commands[len(q.commands)-1]; last.CanMerge(dst, src, color, mode, filter, address) {
|
||||||
@ -105,7 +105,7 @@ func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nin
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c := &drawImageCommand{
|
c := &drawTrianglesCommand{
|
||||||
dst: dst,
|
dst: dst,
|
||||||
src: src,
|
src: src,
|
||||||
nvertices: nvertices,
|
nvertices: nvertices,
|
||||||
@ -118,10 +118,10 @@ func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nin
|
|||||||
q.commands = append(q.commands, c)
|
q.commands = append(q.commands, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnqueueDrawImageCommand enqueues a drawing-image command.
|
// EnqueueDrawTrianglesCommand enqueues a drawing-image command.
|
||||||
func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float32, indices []uint16, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst, src *Image, vertices []float32, indices []uint16, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
if len(indices) > graphics.IndicesNum {
|
if len(indices) > graphics.IndicesNum {
|
||||||
panic(fmt.Sprintf("graphicscommand: len(indices) must be <= graphics.IndicesNum but not at EnqueueDrawImageCommand: len(indices): %d, graphics.IndicesNum: %d", len(indices), graphics.IndicesNum))
|
panic(fmt.Sprintf("graphicscommand: len(indices) must be <= graphics.IndicesNum but not at EnqueueDrawTrianglesCommand: len(indices): %d, graphics.IndicesNum: %d", len(indices), graphics.IndicesNum))
|
||||||
}
|
}
|
||||||
|
|
||||||
split := false
|
split := false
|
||||||
@ -137,12 +137,12 @@ func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float
|
|||||||
q.tmpNumIndices += len(indices)
|
q.tmpNumIndices += len(indices)
|
||||||
|
|
||||||
// TODO: If dst is the screen, reorder the command to be the last.
|
// TODO: If dst is the screen, reorder the command to be the last.
|
||||||
q.doEnqueueDrawImageCommand(dst, src, len(vertices), len(indices), color, mode, filter, address, split)
|
q.doEnqueueDrawTrianglesCommand(dst, src, len(vertices), len(indices), color, mode, filter, address, split)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue enqueues a drawing command other than a draw-image command.
|
// Enqueue enqueues a drawing command other than a draw-image command.
|
||||||
//
|
//
|
||||||
// For a draw-image command, use EnqueueDrawImageCommand.
|
// For a draw-image command, use EnqueueDrawTrianglesCommand.
|
||||||
func (q *commandQueue) Enqueue(command command) {
|
func (q *commandQueue) Enqueue(command command) {
|
||||||
// TODO: If dst is the screen, reorder the command to be the last.
|
// TODO: If dst is the screen, reorder the command to be the last.
|
||||||
q.commands = append(q.commands, command)
|
q.commands = append(q.commands, command)
|
||||||
@ -192,7 +192,7 @@ func (q *commandQueue) Flush() {
|
|||||||
}
|
}
|
||||||
// TODO: indexOffset should be reset if the command type is different
|
// TODO: indexOffset should be reset if the command type is different
|
||||||
// from the previous one. This fix is needed when another drawing command is
|
// from the previous one. This fix is needed when another drawing command is
|
||||||
// introduced than drawImageCommand.
|
// introduced than drawTrianglesCommand.
|
||||||
indexOffset += c.NumIndices()
|
indexOffset += c.NumIndices()
|
||||||
}
|
}
|
||||||
if 0 < nc {
|
if 0 < nc {
|
||||||
@ -219,8 +219,8 @@ func FlushCommands() {
|
|||||||
theCommandQueue.Flush()
|
theCommandQueue.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// drawImageCommand represents a drawing command to draw an image on another image.
|
// drawTrianglesCommand represents a drawing command to draw an image on another image.
|
||||||
type drawImageCommand struct {
|
type drawTrianglesCommand struct {
|
||||||
dst *Image
|
dst *Image
|
||||||
src *Image
|
src *Image
|
||||||
nvertices int
|
nvertices int
|
||||||
@ -231,12 +231,12 @@ type drawImageCommand struct {
|
|||||||
address graphics.Address
|
address graphics.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawImageCommand) String() string {
|
func (c *drawTrianglesCommand) String() string {
|
||||||
return fmt.Sprintf("draw-image: dst: %p <- src: %p, colorm: %v, mode %d, filter: %d, address: %d", c.dst, c.src, c.color, c.mode, c.filter, c.address)
|
return fmt.Sprintf("draw-image: dst: %p <- src: %p, colorm: %v, mode %d, filter: %d, address: %d", c.dst, c.src, c.color, c.mode, c.filter, c.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec executes the drawImageCommand.
|
// Exec executes the drawTrianglesCommand.
|
||||||
func (c *drawImageCommand) Exec(indexOffset int) error {
|
func (c *drawTrianglesCommand) Exec(indexOffset int) error {
|
||||||
// TODO: Is it ok not to bind any framebuffer here?
|
// TODO: Is it ok not to bind any framebuffer here?
|
||||||
if c.nindices == 0 {
|
if c.nindices == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -250,25 +250,25 @@ func (c *drawImageCommand) Exec(indexOffset int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawImageCommand) NumVertices() int {
|
func (c *drawTrianglesCommand) NumVertices() int {
|
||||||
return c.nvertices
|
return c.nvertices
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawImageCommand) NumIndices() int {
|
func (c *drawTrianglesCommand) NumIndices() int {
|
||||||
return c.nindices
|
return c.nindices
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawImageCommand) AddNumVertices(n int) {
|
func (c *drawTrianglesCommand) AddNumVertices(n int) {
|
||||||
c.nvertices += n
|
c.nvertices += n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawImageCommand) AddNumIndices(n int) {
|
func (c *drawTrianglesCommand) AddNumIndices(n int) {
|
||||||
c.nindices += n
|
c.nindices += n
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanMerge returns a boolean value indicating whether the other drawImageCommand can be merged
|
// CanMerge returns a boolean value indicating whether the other drawTrianglesCommand can be merged
|
||||||
// with the drawImageCommand c.
|
// with the drawTrianglesCommand c.
|
||||||
func (c *drawImageCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) bool {
|
func (c *drawTrianglesCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) bool {
|
||||||
if c.dst != dst {
|
if c.dst != dst {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ type lastCommand int
|
|||||||
const (
|
const (
|
||||||
lastCommandNone lastCommand = iota
|
lastCommandNone lastCommand = iota
|
||||||
lastCommandClear
|
lastCommandClear
|
||||||
lastCommandDrawImage
|
lastCommandDrawTriangles
|
||||||
lastCommandReplacePixels
|
lastCommandReplacePixels
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ func (i *Image) Size() (int, int) {
|
|||||||
return i.width, i.height
|
return i.width, i.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DrawImage(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
if src.screen {
|
if src.screen {
|
||||||
panic("graphicscommand: the screen image cannot be the rendering source")
|
panic("graphicscommand: the screen image cannot be the rendering source")
|
||||||
}
|
}
|
||||||
@ -93,12 +93,12 @@ func (i *Image) DrawImage(src *Image, vertices []float32, indices []uint16, clr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
theCommandQueue.EnqueueDrawImageCommand(i, src, vertices, indices, clr, mode, filter, address)
|
theCommandQueue.EnqueueDrawTrianglesCommand(i, src, vertices, indices, clr, mode, filter, address)
|
||||||
|
|
||||||
if i.lastCommand == lastCommandNone && !i.screen {
|
if i.lastCommand == lastCommandNone && !i.screen {
|
||||||
i.lastCommand = lastCommandClear
|
i.lastCommand = lastCommandClear
|
||||||
} else {
|
} else {
|
||||||
i.lastCommand = lastCommandDrawImage
|
i.lastCommand = lastCommandDrawTriangles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,10 +115,10 @@ func (i *Image) Pixels() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(p []byte, x, y, width, height int) {
|
func (i *Image) ReplacePixels(p []byte, x, y, width, height int) {
|
||||||
// ReplacePixels for a part might invalidate the current image that are drawn by DrawImage (#593, #738).
|
// ReplacePixels for a part might invalidate the current image that are drawn by DrawTriangles (#593, #738).
|
||||||
if i.lastCommand == lastCommandDrawImage {
|
if i.lastCommand == lastCommandDrawTriangles {
|
||||||
if x != 0 || y != 0 || i.width != width || i.height != height {
|
if x != 0 || y != 0 || i.width != width || i.height != height {
|
||||||
panic("graphicscommand: ReplacePixels for a part after DrawImage is forbidden")
|
panic("graphicscommand: ReplacePixels for a part after DrawTriangles is forbidden")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pixels := make([]byte, len(p))
|
pixels := make([]byte, len(p))
|
||||||
@ -137,9 +137,9 @@ func (i *Image) ReplacePixels(p []byte, x, y, width, height int) {
|
|||||||
|
|
||||||
// CopyPixels is basically same as Pixels and ReplacePixels, but reading pixels from GPU is done lazily.
|
// CopyPixels is basically same as Pixels and ReplacePixels, but reading pixels from GPU is done lazily.
|
||||||
func (i *Image) CopyPixels(src *Image) {
|
func (i *Image) CopyPixels(src *Image) {
|
||||||
if i.lastCommand == lastCommandDrawImage {
|
if i.lastCommand == lastCommandDrawTriangles {
|
||||||
if i.width != src.width || i.height != src.height {
|
if i.width != src.width || i.height != src.height {
|
||||||
panic("graphicscommand: Copy for a part after DrawImage is forbidden")
|
panic("graphicscommand: Copy for a part after DrawTriangles is forbidden")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func TestClear(t *testing.T) {
|
|||||||
|
|
||||||
vs := graphics.QuadVertices(w/2, h/2, 0, 0, w/2, h/2, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := graphics.QuadVertices(w/2, h/2, 0, 0, w/2, h/2, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawImage(src, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
|
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
|
|
||||||
pix := dst.Pixels()
|
pix := dst.Pixels()
|
||||||
for j := 0; j < h/2; j++ {
|
for j := 0; j < h/2; j++ {
|
||||||
@ -58,13 +58,13 @@ func TestClear(t *testing.T) {
|
|||||||
got := color.RGBA{pix[idx], pix[idx+1], pix[idx+2], pix[idx+3]}
|
got := color.RGBA{pix[idx], pix[idx+1], pix[idx+2], pix[idx+3]}
|
||||||
want := color.RGBA{}
|
want := color.RGBA{}
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("dst.At(%d, %d) after DrawImage: got %v, want: %v", i, j, got, want)
|
t.Errorf("dst.At(%d, %d) after DrawTriangles: got %v, want: %v", i, j, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplacePixelsPartAfterDrawImage(t *testing.T) {
|
func TestReplacePixelsPartAfterDrawTriangles(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r == nil {
|
if r := recover(); r == nil {
|
||||||
t.Errorf("ReplacePixels must panic but not")
|
t.Errorf("ReplacePixels must panic but not")
|
||||||
@ -76,7 +76,7 @@ func TestReplacePixelsPartAfterDrawImage(t *testing.T) {
|
|||||||
dst := NewImage(w, h)
|
dst := NewImage(w, h)
|
||||||
vs := graphics.QuadVertices(16, 16, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := graphics.QuadVertices(16, 16, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawImage(clr, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
|
dst.DrawTriangles(clr, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
dst.DrawImage(src, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ func (p *Pixels) Slice() []byte {
|
|||||||
return p.pixels
|
return p.pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
// drawImageHistoryItem is an item for history of draw-image commands.
|
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
||||||
type drawImageHistoryItem struct {
|
type drawTrianglesHistoryItem struct {
|
||||||
image *Image
|
image *Image
|
||||||
vertices []float32
|
vertices []float32
|
||||||
indices []uint16
|
indices []uint16
|
||||||
@ -95,9 +95,9 @@ type Image struct {
|
|||||||
|
|
||||||
basePixels *Pixels
|
basePixels *Pixels
|
||||||
|
|
||||||
// drawImageHistory is a set of draw-image commands.
|
// drawTrianglesHistory is a set of draw-image commands.
|
||||||
// TODO: This should be merged with the similar command queue in package graphics (#433).
|
// TODO: This should be merged with the similar command queue in package graphics (#433).
|
||||||
drawImageHistory []*drawImageHistoryItem
|
drawTrianglesHistory []*drawTrianglesHistoryItem
|
||||||
|
|
||||||
// stale indicates whether the image needs to be synced with GPU as soon as possible.
|
// stale indicates whether the image needs to be synced with GPU as soon as possible.
|
||||||
stale bool
|
stale bool
|
||||||
@ -189,7 +189,7 @@ func (i *Image) fill(r, g, b, a uint8) {
|
|||||||
af = float32(a) / 0xff
|
af = float32(a) / 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are not 'drawImageHistoryItem's for this image and emptyImage.
|
// There are not 'drawTrianglesHistoryItem's for this image and emptyImage.
|
||||||
// As emptyImage is a priority image, this is restored before other regular images are restored.
|
// As emptyImage is a priority image, this is restored before other regular images are restored.
|
||||||
dw, dh := i.internalSize()
|
dw, dh := i.internalSize()
|
||||||
sw, sh := emptyImage.Size()
|
sw, sh := emptyImage.Size()
|
||||||
@ -201,14 +201,14 @@ func (i *Image) fill(r, g, b, a uint8) {
|
|||||||
if a == 0 {
|
if a == 0 {
|
||||||
c = graphics.CompositeModeClear
|
c = graphics.CompositeModeClear
|
||||||
}
|
}
|
||||||
i.image.DrawImage(emptyImage.image, vs, is, nil, c, graphics.FilterNearest, graphics.AddressClampToZero)
|
i.image.DrawTriangles(emptyImage.image, vs, is, nil, c, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
|
|
||||||
w, h := i.Size()
|
w, h := i.Size()
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
color: color.RGBA{r, g, b, a},
|
color: color.RGBA{r, g, b, a},
|
||||||
length: 4 * w * h,
|
length: 4 * w * h,
|
||||||
}
|
}
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ func (i *Image) PutVertex(vs []float32, dx, dy, sx, sy float32, bx0, by0, bx1, b
|
|||||||
// makeStale makes the image stale.
|
// makeStale makes the image stale.
|
||||||
func (i *Image) makeStale() {
|
func (i *Image) makeStale() {
|
||||||
i.basePixels = nil
|
i.basePixels = nil
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = true
|
i.stale = true
|
||||||
|
|
||||||
// Don't have to call makeStale recursively here.
|
// Don't have to call makeStale recursively here.
|
||||||
@ -271,7 +271,7 @@ func (i *Image) makeStale() {
|
|||||||
|
|
||||||
func (i *Image) CopyPixels(src *Image) {
|
func (i *Image) CopyPixels(src *Image) {
|
||||||
// TODO: Avoid making other images stale if possible. (#514)
|
// TODO: Avoid making other images stale if possible. (#514)
|
||||||
// For this purpuse, images should remember which part of that is used for DrawImage.
|
// For this purpuse, images should remember which part of that is used for DrawTriangles.
|
||||||
theImages.makeStaleIfDependingOn(i)
|
theImages.makeStaleIfDependingOn(i)
|
||||||
|
|
||||||
i.image.CopyPixels(src.image)
|
i.image.CopyPixels(src.image)
|
||||||
@ -293,7 +293,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Avoid making other images stale if possible. (#514)
|
// TODO: Avoid making other images stale if possible. (#514)
|
||||||
// For this purpuse, images should remember which part of that is used for DrawImage.
|
// For this purpuse, images should remember which part of that is used for DrawTriangles.
|
||||||
theImages.makeStaleIfDependingOn(i)
|
theImages.makeStaleIfDependingOn(i)
|
||||||
|
|
||||||
if pixels == nil {
|
if pixels == nil {
|
||||||
@ -319,13 +319,13 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
// See restore() implementation.
|
// See restore() implementation.
|
||||||
i.basePixels = nil
|
i.basePixels = nil
|
||||||
}
|
}
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(i.drawImageHistory) > 0 {
|
if len(i.drawTrianglesHistory) > 0 {
|
||||||
panic("restorable: ReplacePixels for a part after DrawImage is forbidden")
|
panic("restorable: ReplacePixels for a part after DrawTriangles is forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
if i.stale {
|
if i.stale {
|
||||||
@ -352,10 +352,10 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawImage draws a given image img to the image.
|
// DrawTriangles draws a given image img to the image.
|
||||||
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
if i.priority {
|
if i.priority {
|
||||||
panic("restorable: DrawImage cannot be called on a priority image")
|
panic("restorable: DrawTriangles cannot be called on a priority image")
|
||||||
}
|
}
|
||||||
if len(vertices) == 0 {
|
if len(vertices) == 0 {
|
||||||
return
|
return
|
||||||
@ -365,25 +365,25 @@ func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colo
|
|||||||
if img.stale || img.volatile || i.screen || !IsRestoringEnabled() || i.volatile {
|
if img.stale || img.volatile || i.screen || !IsRestoringEnabled() || i.volatile {
|
||||||
i.makeStale()
|
i.makeStale()
|
||||||
} else {
|
} else {
|
||||||
i.appendDrawImageHistory(img, vertices, indices, colorm, mode, filter, address)
|
i.appendDrawTrianglesHistory(img, vertices, indices, colorm, mode, filter, address)
|
||||||
}
|
}
|
||||||
i.image.DrawImage(img.image, vertices, indices, colorm, mode, filter, address)
|
i.image.DrawTriangles(img.image, vertices, indices, colorm, mode, filter, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendDrawImageHistory appends a draw-image history item to the image.
|
// appendDrawTrianglesHistory appends a draw-image history item to the image.
|
||||||
func (i *Image) appendDrawImageHistory(image *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (i *Image) appendDrawTrianglesHistory(image *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
if i.stale || i.volatile || i.screen {
|
if i.stale || i.volatile || i.screen {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: Would it be possible to merge draw image history items?
|
// TODO: Would it be possible to merge draw image history items?
|
||||||
const maxDrawImageHistoryNum = 1024
|
const maxDrawTrianglesHistoryNum = 1024
|
||||||
if len(i.drawImageHistory)+1 > maxDrawImageHistoryNum {
|
if len(i.drawTrianglesHistory)+1 > maxDrawTrianglesHistoryNum {
|
||||||
i.makeStale()
|
i.makeStale()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// All images must be resolved and not stale each after frame.
|
// All images must be resolved and not stale each after frame.
|
||||||
// So we don't have to care if image is stale or not here.
|
// So we don't have to care if image is stale or not here.
|
||||||
item := &drawImageHistoryItem{
|
item := &drawTrianglesHistoryItem{
|
||||||
image: image,
|
image: image,
|
||||||
vertices: vertices,
|
vertices: vertices,
|
||||||
indices: indices,
|
indices: indices,
|
||||||
@ -392,14 +392,14 @@ func (i *Image) appendDrawImageHistory(image *Image, vertices []float32, indices
|
|||||||
filter: filter,
|
filter: filter,
|
||||||
address: address,
|
address: address,
|
||||||
}
|
}
|
||||||
i.drawImageHistory = append(i.drawImageHistory, item)
|
i.drawTrianglesHistory = append(i.drawTrianglesHistory, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) readPixelsFromGPUIfNeeded() {
|
func (i *Image) readPixelsFromGPUIfNeeded() {
|
||||||
if i.basePixels == nil || len(i.drawImageHistory) > 0 || i.stale {
|
if i.basePixels == nil || len(i.drawTrianglesHistory) > 0 || i.stale {
|
||||||
graphicscommand.FlushCommands()
|
graphicscommand.FlushCommands()
|
||||||
i.readPixelsFromGPU()
|
i.readPixelsFromGPU()
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,7 +441,7 @@ func (i *Image) readPixelsFromGPU() {
|
|||||||
pixels: pix,
|
pixels: pix,
|
||||||
length: len(pix),
|
length: len(pix),
|
||||||
}
|
}
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +465,7 @@ func (i *Image) resolveStale() {
|
|||||||
|
|
||||||
// dependsOn returns a boolean value indicating whether the image depends on target.
|
// dependsOn returns a boolean value indicating whether the image depends on target.
|
||||||
func (i *Image) dependsOn(target *Image) bool {
|
func (i *Image) dependsOn(target *Image) bool {
|
||||||
for _, c := range i.drawImageHistory {
|
for _, c := range i.drawTrianglesHistory {
|
||||||
if c.image == target {
|
if c.image == target {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -476,7 +476,7 @@ func (i *Image) dependsOn(target *Image) bool {
|
|||||||
// dependingImages returns all images that is depended by the image.
|
// dependingImages returns all images that is depended by the image.
|
||||||
func (i *Image) dependingImages() map[*Image]struct{} {
|
func (i *Image) dependingImages() map[*Image]struct{} {
|
||||||
r := map[*Image]struct{}{}
|
r := map[*Image]struct{}{}
|
||||||
for _, c := range i.drawImageHistory {
|
for _, c := range i.drawTrianglesHistory {
|
||||||
r[c.image] = struct{}{}
|
r[c.image] = struct{}{}
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
@ -487,7 +487,7 @@ func (i *Image) hasDependency() bool {
|
|||||||
if i.stale {
|
if i.stale {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return len(i.drawImageHistory) > 0
|
return len(i.drawTrianglesHistory) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore restores *graphicscommand.Image from the pixels using its state.
|
// Restore restores *graphicscommand.Image from the pixels using its state.
|
||||||
@ -498,7 +498,7 @@ func (i *Image) restore() error {
|
|||||||
// be changed.
|
// be changed.
|
||||||
i.image = graphicscommand.NewScreenFramebufferImage(w, h)
|
i.image = graphicscommand.NewScreenFramebufferImage(w, h)
|
||||||
i.basePixels = nil
|
i.basePixels = nil
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -520,11 +520,11 @@ func (i *Image) restore() error {
|
|||||||
pix := make([]uint8, w*h*4)
|
pix := make([]uint8, w*h*4)
|
||||||
gimg.ReplacePixels(pix, 0, 0, w, h)
|
gimg.ReplacePixels(pix, 0, 0, w, h)
|
||||||
}
|
}
|
||||||
for _, c := range i.drawImageHistory {
|
for _, c := range i.drawTrianglesHistory {
|
||||||
if c.image.hasDependency() {
|
if c.image.hasDependency() {
|
||||||
panic("restorable: all dependencies must be already resolved but not")
|
panic("restorable: all dependencies must be already resolved but not")
|
||||||
}
|
}
|
||||||
gimg.DrawImage(c.image.image, c.vertices, c.indices, c.colorm, c.mode, c.filter, c.address)
|
gimg.DrawTriangles(c.image.image, c.vertices, c.indices, c.colorm, c.mode, c.filter, c.address)
|
||||||
}
|
}
|
||||||
i.image = gimg
|
i.image = gimg
|
||||||
|
|
||||||
@ -533,7 +533,7 @@ func (i *Image) restore() error {
|
|||||||
pixels: pix,
|
pixels: pix,
|
||||||
length: len(pix),
|
length: len(pix),
|
||||||
}
|
}
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -547,7 +547,7 @@ func (i *Image) Dispose() {
|
|||||||
i.image.Dispose()
|
i.image.Dispose()
|
||||||
i.image = nil
|
i.image = nil
|
||||||
i.basePixels = nil
|
i.basePixels = nil
|
||||||
i.drawImageHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ func TestRestoreChain(t *testing.T) {
|
|||||||
for i := 0; i < num-1; i++ {
|
for i := 0; i < num-1; i++ {
|
||||||
vs := quadVertices(imgs[i], 1, 1, 0, 0)
|
vs := quadVertices(imgs[i], 1, 1, 0, 0)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
imgs[i+1].DrawImage(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
imgs[i+1].DrawTriangles(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
}
|
}
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
@ -168,10 +168,10 @@ func TestRestoreChain2(t *testing.T) {
|
|||||||
imgs[8].Fill(clr8.R, clr8.G, clr8.B, clr8.A)
|
imgs[8].Fill(clr8.R, clr8.G, clr8.B, clr8.A)
|
||||||
|
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
imgs[8].DrawImage(imgs[7], quadVertices(imgs[7], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
imgs[8].DrawTriangles(imgs[7], quadVertices(imgs[7], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
imgs[9].DrawImage(imgs[8], quadVertices(imgs[8], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
imgs[9].DrawTriangles(imgs[8], quadVertices(imgs[8], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
imgs[i+1].DrawImage(imgs[i], quadVertices(imgs[i], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
imgs[i+1].DrawTriangles(imgs[i], quadVertices(imgs[i], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -209,10 +209,10 @@ func TestRestoreOverrideSource(t *testing.T) {
|
|||||||
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
||||||
img1.Fill(clr0.R, clr0.G, clr0.B, clr0.A)
|
img1.Fill(clr0.R, clr0.G, clr0.B, clr0.A)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img2.DrawImage(img1, quadVertices(img1, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img2.DrawTriangles(img1, quadVertices(img1, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img3.DrawImage(img2, quadVertices(img2, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img3.DrawTriangles(img2, quadVertices(img2, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img0.Fill(clr1.R, clr1.G, clr1.B, clr1.A)
|
img0.Fill(clr1.R, clr1.G, clr1.B, clr1.A)
|
||||||
img1.DrawImage(img0, quadVertices(img0, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img0, quadVertices(img0, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -289,23 +289,23 @@ func TestRestoreComplexGraph(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
vs := quadVertices(img0, w, h, 0, 0)
|
vs := quadVertices(img0, w, h, 0, 0)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img3.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img3.DrawTriangles(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img1, w, h, 1, 0)
|
vs = quadVertices(img1, w, h, 1, 0)
|
||||||
img3.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img3.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img1, w, h, 1, 0)
|
vs = quadVertices(img1, w, h, 1, 0)
|
||||||
img4.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img4.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img2, w, h, 2, 0)
|
vs = quadVertices(img2, w, h, 2, 0)
|
||||||
img4.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img4.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img3, w, h, 0, 0)
|
vs = quadVertices(img3, w, h, 0, 0)
|
||||||
img5.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img5.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img3, w, h, 0, 0)
|
vs = quadVertices(img3, w, h, 0, 0)
|
||||||
img6.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img6.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img4, w, h, 1, 0)
|
vs = quadVertices(img4, w, h, 1, 0)
|
||||||
img6.DrawImage(img4, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img6.DrawTriangles(img4, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img2, w, h, 0, 0)
|
vs = quadVertices(img2, w, h, 0, 0)
|
||||||
img7.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img7.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
vs = quadVertices(img3, w, h, 2, 0)
|
vs = quadVertices(img3, w, h, 2, 0)
|
||||||
img7.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img7.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -395,8 +395,8 @@ func TestRestoreRecursive(t *testing.T) {
|
|||||||
img0.Dispose()
|
img0.Dispose()
|
||||||
}()
|
}()
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawImage(img0, quadVertices(img0, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img0, quadVertices(img0, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img0.DrawImage(img1, quadVertices(img1, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, quadVertices(img1, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -472,7 +472,7 @@ func TestReplacePixels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDrawImageAndReplacePixels(t *testing.T) {
|
func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
||||||
base := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
base := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||||
base.Pix[0] = 0xff
|
base.Pix[0] = 0xff
|
||||||
base.Pix[1] = 0
|
base.Pix[1] = 0
|
||||||
@ -485,7 +485,7 @@ func TestDrawImageAndReplacePixels(t *testing.T) {
|
|||||||
|
|
||||||
vs := quadVertices(img0, 1, 1, 0, 0)
|
vs := quadVertices(img0, 1, 1, 0, 0)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -517,8 +517,8 @@ func TestDispose(t *testing.T) {
|
|||||||
defer img2.Dispose()
|
defer img2.Dispose()
|
||||||
|
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawImage(img2, quadVertices(img2, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img2, quadVertices(img2, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img0.DrawImage(img1, quadVertices(img1, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, quadVertices(img1, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -611,7 +611,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
|||||||
|
|
||||||
vs := quadVertices(img0, 1, 1, 0, 0)
|
vs := quadVertices(img0, 1, 1, 0, 0)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
||||||
|
|
||||||
// BasePixelsForTesting is available without GPU accessing.
|
// BasePixelsForTesting is available without GPU accessing.
|
||||||
@ -656,7 +656,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
|||||||
src.Fill(0xff, 0xff, 0xff, 0xff)
|
src.Fill(0xff, 0xff, 0xff, 0xff)
|
||||||
vs := quadVertices(src, 1, 1, 0, 0)
|
vs := quadVertices(src, 1, 1, 0, 0)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
|
|
||||||
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
||||||
// stale.
|
// stale.
|
||||||
|
@ -65,8 +65,8 @@ func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
|
|||||||
s := b.page.Size()
|
s := b.page.Size()
|
||||||
newImg := restorable.NewImage(s, s)
|
newImg := restorable.NewImage(s, s)
|
||||||
oldImg := b.restorable
|
oldImg := b.restorable
|
||||||
// Do not use DrawImage here. ReplacePixels will be called on a part of newImg later, and it looked like
|
// Do not use DrawTriangles here. ReplacePixels will be called on a part of newImg later, and it looked like
|
||||||
// ReplacePixels on a part of image deletes other region that are rendered by DrawImage (#593, #758).
|
// ReplacePixels on a part of image deletes other region that are rendered by DrawTriangles (#593, #758).
|
||||||
newImg.CopyPixels(oldImg)
|
newImg.CopyPixels(oldImg)
|
||||||
oldImg.Dispose()
|
oldImg.Dispose()
|
||||||
b.restorable = newImg
|
b.restorable = newImg
|
||||||
@ -132,7 +132,7 @@ func (i *Image) ensureNotShared() {
|
|||||||
newImg := restorable.NewImage(w, h)
|
newImg := restorable.NewImage(w, h)
|
||||||
vs := i.backend.restorable.QuadVertices(x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := i.backend.restorable.QuadVertices(x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
newImg.DrawImage(i.backend.restorable, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
newImg.DrawTriangles(i.backend.restorable, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
|
|
||||||
i.dispose(false)
|
i.dispose(false)
|
||||||
i.backend = &backend{
|
i.backend = &backend{
|
||||||
@ -197,7 +197,7 @@ func (i *Image) QuadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32,
|
|||||||
return i.backend.restorable.QuadVertices(sx0+ox, sy0+oy, sx1+ox, sy1+oy, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
return i.backend.restorable.QuadVertices(sx0+ox, sy0+oy, sx1+ox, sy1+oy, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutVertices puts the given dest with vertices that can be passed to DrawImage.
|
// PutVertices puts the given dest with vertices that can be passed to DrawTriangles.
|
||||||
func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
|
func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
i.allocate(true)
|
i.allocate(true)
|
||||||
@ -209,15 +209,15 @@ func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1,
|
|||||||
|
|
||||||
const MaxCountForShare = 10
|
const MaxCountForShare = 10
|
||||||
|
|
||||||
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
if img.disposed {
|
if img.disposed {
|
||||||
panic("shareable: the drawing source image must not be disposed (DrawImage)")
|
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 (DrawImage)")
|
panic("shareable: the drawing target image must not be disposed (DrawTriangles)")
|
||||||
}
|
}
|
||||||
if img.backend == nil {
|
if img.backend == nil {
|
||||||
img.allocate(true)
|
img.allocate(true)
|
||||||
@ -228,10 +228,10 @@ func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colo
|
|||||||
// Compare i and img after ensuring i is not shared, or
|
// Compare i and img after ensuring i is not shared, or
|
||||||
// i and img might share the same texture even though i != img.
|
// i and img might share the same texture even though i != img.
|
||||||
if i.backend.restorable == img.backend.restorable {
|
if i.backend.restorable == img.backend.restorable {
|
||||||
panic("shareable: Image.DrawImage: img must be different from the receiver")
|
panic("shareable: Image.DrawTriangles: img must be different from the receiver")
|
||||||
}
|
}
|
||||||
|
|
||||||
i.backend.restorable.DrawImage(img.backend.restorable, vertices, indices, colorm, mode, filter, address)
|
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address)
|
||||||
|
|
||||||
i.countForShare = 0
|
i.countForShare = 0
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
// img4.ensureNotShared() should be called.
|
// img4.ensureNotShared() should be called.
|
||||||
vs := img3.QuadVertices(0, 0, size/2, size/2, 1, 0, 0, 1, size/4, size/4, 1, 1, 1, 1)
|
vs := img3.QuadVertices(0, 0, size/2, size/2, 1, 0, 0, 1, size/4, size/4, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img4.DrawImage(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img4.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want := false
|
want := false
|
||||||
if got := img4.IsSharedForTesting(); got != want {
|
if got := img4.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -109,7 +109,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
|
|
||||||
// Check further drawing doesn't cause panic.
|
// Check further drawing doesn't cause panic.
|
||||||
// This bug was fixed by 03dcd948.
|
// This bug was fixed by 03dcd948.
|
||||||
img4.DrawImage(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img4.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Disabled_TestReshared(t *testing.T) {
|
func Disabled_TestReshared(t *testing.T) {
|
||||||
@ -152,7 +152,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
// Use img1 as a render target.
|
// Use img1 as a render target.
|
||||||
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawImage(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want = false
|
want = false
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -160,7 +160,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
|
|
||||||
// Use img1 as a render source.
|
// Use img1 as a render source.
|
||||||
for i := 0; i < MaxCountForShare-1; i++ {
|
for i := 0; i < MaxCountForShare-1; i++ {
|
||||||
img0.DrawImage(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want := false
|
want := false
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -178,7 +178,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img0.DrawImage(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want = true
|
want = true
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -197,7 +197,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
|
|
||||||
// Use img3 as a render source. img3 never uses a shared texture.
|
// Use img3 as a render source. img3 never uses a shared texture.
|
||||||
for i := 0; i < MaxCountForShare*2; i++ {
|
for i := 0; i < MaxCountForShare*2; i++ {
|
||||||
img0.DrawImage(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want := false
|
want := false
|
||||||
if got := img3.IsSharedForTesting(); got != want {
|
if got := img3.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -261,7 +261,7 @@ func TestExtend(t *testing.T) {
|
|||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplacePixelsAfterDrawImage(t *testing.T) {
|
func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
|
||||||
const w, h = 256, 256
|
const w, h = 256, 256
|
||||||
src := NewImage(w, h)
|
src := NewImage(w, h)
|
||||||
defer src.Dispose()
|
defer src.Dispose()
|
||||||
@ -279,7 +279,7 @@ func TestReplacePixelsAfterDrawImage(t *testing.T) {
|
|||||||
|
|
||||||
vs := src.QuadVertices(0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := src.QuadVertices(0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
dst.ReplacePixels(pix)
|
dst.ReplacePixels(pix)
|
||||||
|
|
||||||
for j := 0; j < h; j++ {
|
for j := 0; j < h; j++ {
|
||||||
|
Loading…
Reference in New Issue
Block a user