mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 10:42:42 +01:00
graphics: Refactoring: Avoid type switch
This commit is contained in:
parent
f1ba3e5894
commit
8d98f297f2
@ -32,6 +32,7 @@ import (
|
|||||||
// and executed only when necessary.
|
// and executed only when necessary.
|
||||||
type command interface {
|
type command interface {
|
||||||
Exec(indexOffsetInBytes int) error
|
Exec(indexOffsetInBytes int) error
|
||||||
|
NumVertices() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// commandQueue is a command queue for drawing commands.
|
// commandQueue is a command queue for drawing commands.
|
||||||
@ -42,10 +43,10 @@ type commandQueue struct {
|
|||||||
// vertices represents a vertices data in OpenGL's array buffer.
|
// vertices represents a vertices data in OpenGL's array buffer.
|
||||||
vertices []float32
|
vertices []float32
|
||||||
|
|
||||||
// verticesNum represents the current length of vertices.
|
// nvertices represents the current length of vertices.
|
||||||
// verticesNum must <= len(vertices).
|
// nvertices must <= len(vertices).
|
||||||
// vertices is never shrunk since re-extending a vertices buffer is heavy.
|
// vertices is never shrunk since re-extending a vertices buffer is heavy.
|
||||||
verticesNum int
|
nvertices int
|
||||||
|
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
@ -55,16 +56,16 @@ var theCommandQueue = &commandQueue{}
|
|||||||
|
|
||||||
// appendVertices appends vertices to the queue.
|
// appendVertices appends vertices to the queue.
|
||||||
func (q *commandQueue) appendVertices(vertices []float32) {
|
func (q *commandQueue) appendVertices(vertices []float32) {
|
||||||
if len(q.vertices) < q.verticesNum+len(vertices) {
|
if len(q.vertices) < q.nvertices+len(vertices) {
|
||||||
n := q.verticesNum + len(vertices) - len(q.vertices)
|
n := q.nvertices + len(vertices) - len(q.vertices)
|
||||||
q.vertices = append(q.vertices, make([]float32, n)...)
|
q.vertices = append(q.vertices, make([]float32, n)...)
|
||||||
}
|
}
|
||||||
// for-loop might be faster than copy:
|
// for-loop might be faster than copy:
|
||||||
// On GopherJS, copy might cause subarray calls.
|
// On GopherJS, copy might cause subarray calls.
|
||||||
for i := 0; i < len(vertices); i++ {
|
for i := 0; i < len(vertices); i++ {
|
||||||
q.vertices[q.verticesNum+i] = vertices[i]
|
q.vertices[q.nvertices+i] = vertices[i]
|
||||||
}
|
}
|
||||||
q.verticesNum += len(vertices)
|
q.nvertices += len(vertices)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnqueueDrawImageCommand enqueues a drawing-image command.
|
// EnqueueDrawImageCommand enqueues a drawing-image command.
|
||||||
@ -75,19 +76,19 @@ func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float
|
|||||||
if 0 < len(q.commands) {
|
if 0 < len(q.commands) {
|
||||||
if c, ok := q.commands[len(q.commands)-1].(*drawImageCommand); ok {
|
if c, ok := q.commands[len(q.commands)-1].(*drawImageCommand); ok {
|
||||||
if c.canMerge(dst, src, clr, mode, filter) {
|
if c.canMerge(dst, src, clr, mode, filter) {
|
||||||
c.verticesNum += len(vertices)
|
c.nvertices += len(vertices)
|
||||||
q.m.Unlock()
|
q.m.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c := &drawImageCommand{
|
c := &drawImageCommand{
|
||||||
dst: dst,
|
dst: dst,
|
||||||
src: src,
|
src: src,
|
||||||
verticesNum: len(vertices),
|
nvertices: len(vertices),
|
||||||
color: clr,
|
color: clr,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
q.commands = append(q.commands, c)
|
q.commands = append(q.commands, c)
|
||||||
q.m.Unlock()
|
q.m.Unlock()
|
||||||
@ -143,10 +144,7 @@ func (q *commandQueue) Flush() error {
|
|||||||
lastN := 0
|
lastN := 0
|
||||||
for _, g := range q.commandGroups() {
|
for _, g := range q.commandGroups() {
|
||||||
for _, c := range g {
|
for _, c := range g {
|
||||||
switch c := c.(type) {
|
n += c.NumVertices()
|
||||||
case *drawImageCommand:
|
|
||||||
n += c.verticesNum
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if 0 < n-lastN {
|
if 0 < n-lastN {
|
||||||
// Note that the vertices passed to BufferSubData is not under GC management
|
// Note that the vertices passed to BufferSubData is not under GC management
|
||||||
@ -165,10 +163,8 @@ func (q *commandQueue) Flush() error {
|
|||||||
if err := c.Exec(indexOffsetInBytes); err != nil {
|
if err := c.Exec(indexOffsetInBytes); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c, ok := c.(*drawImageCommand); ok {
|
n := c.NumVertices() * opengl.Float.SizeInBytes() / QuadVertexSizeInBytes()
|
||||||
n := c.verticesNum * opengl.Float.SizeInBytes() / QuadVertexSizeInBytes()
|
indexOffsetInBytes += 6 * n * 2
|
||||||
indexOffsetInBytes += 6 * n * 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if 0 < numc {
|
if 0 < numc {
|
||||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||||
@ -177,7 +173,7 @@ func (q *commandQueue) Flush() error {
|
|||||||
lastN = n
|
lastN = n
|
||||||
}
|
}
|
||||||
q.commands = nil
|
q.commands = nil
|
||||||
q.verticesNum = 0
|
q.nvertices = 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,12 +184,12 @@ func FlushCommands() error {
|
|||||||
|
|
||||||
// drawImageCommand represents a drawing command to draw an image on another image.
|
// drawImageCommand represents a drawing command to draw an image on another image.
|
||||||
type drawImageCommand struct {
|
type drawImageCommand struct {
|
||||||
dst *Image
|
dst *Image
|
||||||
src *Image
|
src *Image
|
||||||
verticesNum int
|
nvertices int
|
||||||
color *affine.ColorM
|
color *affine.ColorM
|
||||||
mode opengl.CompositeMode
|
mode opengl.CompositeMode
|
||||||
filter Filter
|
filter Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuadVertexSizeInBytes returns the size in bytes of vertices for a quadrangle.
|
// QuadVertexSizeInBytes returns the size in bytes of vertices for a quadrangle.
|
||||||
@ -228,6 +224,10 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *drawImageCommand) NumVertices() int {
|
||||||
|
return c.nvertices
|
||||||
|
}
|
||||||
|
|
||||||
// split splits the drawImageCommand c into two drawImageCommands.
|
// split splits the drawImageCommand c into two drawImageCommands.
|
||||||
//
|
//
|
||||||
// split is called when the number of vertices reaches of the maximum and
|
// split is called when the number of vertices reaches of the maximum and
|
||||||
@ -237,8 +237,8 @@ func (c *drawImageCommand) split(quadsNum int) [2]*drawImageCommand {
|
|||||||
c2 := *c
|
c2 := *c
|
||||||
s := opengl.Float.SizeInBytes()
|
s := opengl.Float.SizeInBytes()
|
||||||
n := quadsNum * QuadVertexSizeInBytes() / s
|
n := quadsNum * QuadVertexSizeInBytes() / s
|
||||||
c1.verticesNum = n
|
c1.nvertices = n
|
||||||
c2.verticesNum -= n
|
c2.nvertices -= n
|
||||||
return [2]*drawImageCommand{&c1, &c2}
|
return [2]*drawImageCommand{&c1, &c2}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ func (c *drawImageCommand) canMerge(dst, src *Image, clr *affine.ColorM, mode op
|
|||||||
|
|
||||||
// quadsNum returns the number of quadrangles.
|
// quadsNum returns the number of quadrangles.
|
||||||
func (c *drawImageCommand) quadsNum() int {
|
func (c *drawImageCommand) quadsNum() int {
|
||||||
return c.verticesNum * opengl.Float.SizeInBytes() / QuadVertexSizeInBytes()
|
return c.nvertices * opengl.Float.SizeInBytes() / QuadVertexSizeInBytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// replacePixelsCommand represents a command to replace pixels of an image.
|
// replacePixelsCommand represents a command to replace pixels of an image.
|
||||||
@ -294,6 +294,10 @@ func (c *replacePixelsCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *replacePixelsCommand) NumVertices() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// disposeCommand represents a command to dispose an image.
|
// disposeCommand represents a command to dispose an image.
|
||||||
type disposeCommand struct {
|
type disposeCommand struct {
|
||||||
target *Image
|
target *Image
|
||||||
@ -311,6 +315,10 @@ func (c *disposeCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *disposeCommand) NumVertices() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// newImageCommand represents a command to create an empty image with given width and height.
|
// newImageCommand represents a command to create an empty image with given width and height.
|
||||||
type newImageCommand struct {
|
type newImageCommand struct {
|
||||||
result *Image
|
result *Image
|
||||||
@ -338,6 +346,10 @@ func (c *newImageCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *newImageCommand) NumVertices() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// newScreenFramebufferImageCommand is a command to create a special image for the screen.
|
// newScreenFramebufferImageCommand is a command to create a special image for the screen.
|
||||||
type newScreenFramebufferImageCommand struct {
|
type newScreenFramebufferImageCommand struct {
|
||||||
result *Image
|
result *Image
|
||||||
@ -359,3 +371,7 @@ func (c *newScreenFramebufferImageCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
c.result.framebuffer = newScreenFramebuffer(c.width, c.height)
|
c.result.framebuffer = newScreenFramebuffer(c.width, c.height)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *newScreenFramebufferImageCommand) NumVertices() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user