graphics: Merge draw commands if possible

This commit is contained in:
Hajime Hoshi 2016-10-25 11:53:00 +09:00
parent a70f61b1d5
commit a65ededc3c

View File

@ -58,12 +58,42 @@ func (q *commandQueue) Enqueue(command command) {
q.commands = append(q.commands, command) q.commands = append(q.commands, command)
} }
func mergeCommands(commands []command) []command {
// TODO: This logic is relatively complicated. Add tests.
cs := make([]command, 0, len(commands))
var prev *drawImageCommand
for _, c := range commands {
switch c := c.(type) {
case *drawImageCommand:
if prev == nil {
prev = c
continue
}
if prev.isMergeable(c) {
prev = prev.merge(c)
continue
}
cs = append(cs, prev)
prev = c
continue
}
if prev != nil {
cs = append(cs, prev)
prev = nil
}
cs = append(cs, c)
}
if prev != nil {
cs = append(cs, prev)
}
return cs
}
// commandGroups separates q.commands into some groups. // commandGroups separates q.commands into some groups.
// The number of quads of drawImageCommand in one groups must be equal to or less than // The number of quads of drawImageCommand in one groups must be equal to or less than
// its limit (maxQuads). // its limit (maxQuads).
func (q *commandQueue) commandGroups() [][]command { func (q *commandQueue) commandGroups() [][]command {
cs := make([]command, len(q.commands)) cs := mergeCommands(q.commands)
copy(cs, q.commands)
gs := [][]command{} gs := [][]command{}
quads := 0 quads := 0
for 0 < len(cs) { for 0 < len(cs) {
@ -202,6 +232,34 @@ func (c *drawImageCommand) split(quadsNum int) [2]*drawImageCommand {
return [2]*drawImageCommand{&c1, &c2} return [2]*drawImageCommand{&c1, &c2}
} }
func (c *drawImageCommand) isMergeable(other *drawImageCommand) bool {
if c.dst != other.dst {
return false
}
if c.src != other.src {
return false
}
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if c.color.Element(i, j) != other.color.Element(i, j) {
return false
}
}
}
if c.mode != other.mode {
return false
}
return true
}
func (c *drawImageCommand) merge(other *drawImageCommand) *drawImageCommand {
newC := *c
newC.vertices = make([]uint8, 0, len(c.vertices)+len(other.vertices))
newC.vertices = append(newC.vertices, c.vertices...)
newC.vertices = append(newC.vertices, other.vertices...)
return &newC
}
func (c *drawImageCommand) quadsNum() int { func (c *drawImageCommand) quadsNum() int {
return len(c.vertices) / QuadVertexSizeInBytes() return len(c.vertices) / QuadVertexSizeInBytes()
} }