diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index ff6b04305..e620d7ccf 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -279,7 +279,9 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error { } } - graphicsDriver.Begin() + if err := graphicsDriver.Begin(); err != nil { + return err + } var present bool cs := q.commands for len(cs) > 0 { @@ -303,7 +305,9 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error { nc++ } if 0 < ne { - graphicsDriver.SetVertices(vs[:nv], es[:ne]) + if err := graphicsDriver.SetVertices(vs[:nv], es[:ne]); err != nil { + return err + } es = es[ne:] vs = vs[nv:] } @@ -322,7 +326,9 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error { } cs = cs[nc:] } - graphicsDriver.End(present) + if err := graphicsDriver.End(present); err != nil { + return err + } // Release the commands explicitly (#1803). // Apparently, the part of a slice between len and cap-1 still holds references. @@ -611,7 +617,9 @@ func (c *replacePixelsCommand) Exec(graphicsDriver graphicsdriver.Graphics, inde } if len(c.args[lastArgIdx:]) > 0 { - c.dst.image.ReplacePixels(c.args[lastArgIdx:]) + if err := c.dst.image.ReplacePixels(c.args[lastArgIdx:]); err != nil { + return err + } } return nil } diff --git a/internal/graphicsdriver/graphics.go b/internal/graphicsdriver/graphics.go index 3b2b8dfaa..719aa81ff 100644 --- a/internal/graphicsdriver/graphics.go +++ b/internal/graphicsdriver/graphics.go @@ -41,10 +41,10 @@ type ColorM interface { type Graphics interface { Initialize() error - Begin() - End(present bool) + Begin() error + End(present bool) error SetTransparent(transparent bool) - SetVertices(vertices []float32, indices []uint16) + SetVertices(vertices []float32, indices []uint16) error NewImage(width, height int) (Image, error) NewScreenFramebufferImage(width, height int) (Image, error) SetVsyncEnabled(enabled bool) @@ -76,7 +76,7 @@ type Image interface { Dispose() IsInvalidated() bool ReadPixels(buf []byte) error - ReplacePixels(args []*ReplacePixelsArgs) + ReplacePixels(args []*ReplacePixelsArgs) error } type ImageID int diff --git a/internal/graphicsdriver/metal/graphics_darwin.go b/internal/graphicsdriver/metal/graphics_darwin.go index 788308db5..eadb475ed 100644 --- a/internal/graphicsdriver/metal/graphics_darwin.go +++ b/internal/graphicsdriver/metal/graphics_darwin.go @@ -363,17 +363,19 @@ func Get() *Graphics { return &theGraphics } -func (g *Graphics) Begin() { +func (g *Graphics) Begin() error { // NSAutoreleasePool is required to release drawable correctly (#847). // https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/Drawables.html g.pool = C.allocAutoreleasePool() + return nil } -func (g *Graphics) End(present bool) { +func (g *Graphics) End(present bool) error { g.flushIfNeeded(present) g.screenDrawable = ca.MetalDrawable{} C.releaseAutoreleasePool(g.pool) g.pool = nil + return nil } func (g *Graphics) SetWindow(window uintptr) { @@ -457,7 +459,7 @@ func (g *Graphics) availableBuffer(length uintptr) mtl.Buffer { return newBuf } -func (g *Graphics) SetVertices(vertices []float32, indices []uint16) { +func (g *Graphics) SetVertices(vertices []float32, indices []uint16) error { vbSize := unsafe.Sizeof(vertices[0]) * uintptr(len(vertices)) ibSize := unsafe.Sizeof(indices[0]) * uintptr(len(indices)) @@ -466,6 +468,8 @@ func (g *Graphics) SetVertices(vertices []float32, indices []uint16) { g.ib = g.availableBuffer(ibSize) g.ib.CopyToContents(unsafe.Pointer(&indices[0]), ibSize) + + return nil } func (g *Graphics) flushIfNeeded(present bool) { @@ -1166,7 +1170,7 @@ func (i *Image) ReadPixels(buf []byte) error { return nil } -func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) { +func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) error { g := i.graphics g.flushRenderCommandEncoderIfNeeded() @@ -1226,6 +1230,8 @@ func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) { bce.CopyFromTexture(t, 0, 0, so, ss, i.texture, 0, 0, do) } bce.EndEncoding() + + return nil } func (i *Image) mtlTexture() mtl.Texture { diff --git a/internal/graphicsdriver/opengl/graphics.go b/internal/graphicsdriver/opengl/graphics.go index ad1868764..9512cb2ef 100644 --- a/internal/graphicsdriver/opengl/graphics.go +++ b/internal/graphicsdriver/opengl/graphics.go @@ -56,14 +56,16 @@ type Graphics struct { activatedTextures []activatedTexture } -func (g *Graphics) Begin() { +func (g *Graphics) Begin() error { // Do nothing. + return nil } -func (g *Graphics) End(present bool) { +func (g *Graphics) End(present bool) error { // Call glFlush to prevent black flicking (especially on Android (#226) and iOS). // TODO: examples/sprites worked without this. Is this really needed? g.context.flush() + return nil } func (g *Graphics) SetTransparent(transparent bool) { @@ -151,12 +153,13 @@ func (g *Graphics) Reset() error { return g.state.reset(&g.context) } -func (g *Graphics) SetVertices(vertices []float32, indices []uint16) { +func (g *Graphics) SetVertices(vertices []float32, indices []uint16) error { // Note that the vertices passed to BufferSubData is not under GC management // in opengl package due to unsafe-way. // See BufferSubData in context_mobile.go. g.context.arrayBufferSubData(vertices) g.context.elementArrayBufferSubData(indices) + return nil } func (g *Graphics) uniformVariableName(idx int) string { diff --git a/internal/graphicsdriver/opengl/image.go b/internal/graphicsdriver/opengl/image.go index d6d46ed97..37afc7bee 100644 --- a/internal/graphicsdriver/opengl/image.go +++ b/internal/graphicsdriver/opengl/image.go @@ -15,6 +15,8 @@ package opengl import ( + "errors" + "github.com/hajimehoshi/ebiten/v2/internal/graphics" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" ) @@ -118,12 +120,12 @@ func (i *Image) ensureStencilBuffer() error { return nil } -func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) { +func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) error { if i.screen { - panic("opengl: ReplacePixels cannot be called on the screen, that doesn't have a texture") + return errors.New("opengl: ReplacePixels cannot be called on the screen") } if len(args) == 0 { - return + return nil } // glFlush is necessary on Android. @@ -133,4 +135,5 @@ func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) { } i.graphics.drawCalled = false i.graphics.context.texSubImage2D(i.texture, args) + return nil }