mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/graphicsdriver/opengl: refactoring: move some functions from internal/ui
Updates #2714
This commit is contained in:
parent
ee2ca6d20c
commit
4895ae7f93
@ -752,7 +752,7 @@ func EndFrame() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SwapBuffers(graphicsDriver graphicsdriver.Graphics, swapBuffersForGL func()) error {
|
||||
func SwapBuffers(graphicsDriver graphicsdriver.Graphics) error {
|
||||
func() {
|
||||
backendsM.Lock()
|
||||
defer backendsM.Unlock()
|
||||
@ -762,7 +762,7 @@ func SwapBuffers(graphicsDriver graphicsdriver.Graphics, swapBuffersForGL func()
|
||||
}
|
||||
}()
|
||||
|
||||
if err := restorable.SwapBuffers(graphicsDriver, swapBuffersForGL); err != nil {
|
||||
if err := restorable.SwapBuffers(graphicsDriver); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -59,8 +59,8 @@ func SetVsyncEnabled(enabled bool, graphicsDriver graphicsdriver.Graphics) {
|
||||
|
||||
// FlushCommands flushes the command queue and present the screen if needed.
|
||||
// If endFrame is true, the current screen might be used to present.
|
||||
func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, endFrame, swapBuffersForGL); err != nil {
|
||||
func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, endFrame); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -178,7 +178,7 @@ func (q *commandQueue) Enqueue(command command) {
|
||||
}
|
||||
|
||||
// Flush flushes the command queue.
|
||||
func (q *commandQueue) Flush(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {
|
||||
func (q *commandQueue) Flush(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
|
||||
if err := q.err.Load(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
@ -212,10 +212,6 @@ func (q *commandQueue) Flush(graphicsDriver graphicsdriver.Graphics, endFrame bo
|
||||
return
|
||||
}
|
||||
|
||||
if endFrame && swapBuffersForGL != nil {
|
||||
swapBuffersForGL()
|
||||
}
|
||||
|
||||
theCommandQueueManager.putCommandQueue(q)
|
||||
}, sync)
|
||||
|
||||
@ -504,7 +500,7 @@ func (c *commandQueueManager) enqueueDrawTrianglesCommand(dst *Image, srcs [grap
|
||||
c.current.EnqueueDrawTrianglesCommand(dst, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
|
||||
}
|
||||
|
||||
func (c *commandQueueManager) flush(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {
|
||||
func (c *commandQueueManager) flush(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
|
||||
// Switch the command queue.
|
||||
prev := c.current
|
||||
q, err := c.pool.get()
|
||||
@ -516,7 +512,7 @@ func (c *commandQueueManager) flush(graphicsDriver graphicsdriver.Graphics, endF
|
||||
if prev == nil {
|
||||
return nil
|
||||
}
|
||||
if err := prev.Flush(graphicsDriver, endFrame, swapBuffersForGL); err != nil {
|
||||
if err := prev.Flush(graphicsDriver, endFrame); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -154,7 +154,7 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, args []graphi
|
||||
args: args,
|
||||
}
|
||||
theCommandQueueManager.enqueueCommand(c)
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, false, nil); err != nil {
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -183,7 +183,7 @@ func (i *Image) IsInvalidated(graphicsDriver graphicsdriver.Graphics) (bool, err
|
||||
image: i,
|
||||
}
|
||||
theCommandQueueManager.enqueueCommand(c)
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, false, nil); err != nil {
|
||||
if err := theCommandQueueManager.flush(graphicsDriver, false); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return c.result, nil
|
||||
|
@ -33,15 +33,16 @@ type egl struct {
|
||||
context C.EGLContext
|
||||
}
|
||||
|
||||
func (e *egl) init(nativeWindowHandle uintptr) error {
|
||||
// Initialize EGL
|
||||
func newEGL(nativeWindowHandle uintptr) (*egl, error) {
|
||||
e := &egl{}
|
||||
|
||||
e.display = C.eglGetDisplay(C.NativeDisplayType(C.EGL_DEFAULT_DISPLAY))
|
||||
if e.display == 0 {
|
||||
return fmt.Errorf("opengl: eglGetDisplay failed")
|
||||
return nil, fmt.Errorf("opengl: eglGetDisplay failed")
|
||||
}
|
||||
|
||||
if r := C.eglInitialize(e.display, nil, nil); r == 0 {
|
||||
return fmt.Errorf("opengl: eglInitialize failed")
|
||||
return nil, fmt.Errorf("opengl: eglInitialize failed")
|
||||
}
|
||||
|
||||
configAttribs := []C.EGLint{
|
||||
@ -55,20 +56,20 @@ func (e *egl) init(nativeWindowHandle uintptr) error {
|
||||
var numConfigs C.EGLint
|
||||
var config C.EGLConfig
|
||||
if r := C.eglChooseConfig(e.display, &configAttribs[0], &config, 1, &numConfigs); r == 0 {
|
||||
return fmt.Errorf("opengl: eglChooseConfig failed")
|
||||
return nil, fmt.Errorf("opengl: eglChooseConfig failed")
|
||||
}
|
||||
if numConfigs != 1 {
|
||||
return fmt.Errorf("opengl: eglChooseConfig failed: numConfigs must be 1 but %d", numConfigs)
|
||||
return nil, fmt.Errorf("opengl: eglChooseConfig failed: numConfigs must be 1 but %d", numConfigs)
|
||||
}
|
||||
|
||||
e.surface = C.eglCreateWindowSurface(e.display, config, C.NativeWindowType(nativeWindowHandle), nil)
|
||||
if e.surface == C.EGLSurface(C.EGL_NO_SURFACE) {
|
||||
return fmt.Errorf("opengl: eglCreateWindowSurface failed")
|
||||
return nil, fmt.Errorf("opengl: eglCreateWindowSurface failed")
|
||||
}
|
||||
|
||||
// Set the current rendering API.
|
||||
if r := C.eglBindAPI(C.EGL_OPENGL_API); r == 0 {
|
||||
return fmt.Errorf("opengl: eglBindAPI failed")
|
||||
return nil, fmt.Errorf("opengl: eglBindAPI failed")
|
||||
}
|
||||
|
||||
// Create new context and set it as current.
|
||||
@ -81,10 +82,10 @@ func (e *egl) init(nativeWindowHandle uintptr) error {
|
||||
C.EGL_NONE}
|
||||
e.context = C.eglCreateContext(e.display, config, C.EGLContext(C.EGL_NO_CONTEXT), &contextAttribs[0])
|
||||
if e.context == C.EGLContext(C.EGL_NO_CONTEXT) {
|
||||
return fmt.Errorf("opengl: eglCreateContext failed: error: %d", C.eglGetError())
|
||||
return nil, fmt.Errorf("opengl: eglCreateContext failed: error: %d", C.eglGetError())
|
||||
}
|
||||
|
||||
return nil
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (e *egl) makeContextCurrent() error {
|
||||
|
@ -54,6 +54,8 @@ type Graphics struct {
|
||||
// activatedTextures is a set of activated textures.
|
||||
// textureNative cannot be a map key unfortunately.
|
||||
activatedTextures []activatedTexture
|
||||
|
||||
graphicsPlatform
|
||||
}
|
||||
|
||||
func newGraphics(ctx gl.Context) *Graphics {
|
||||
|
@ -26,6 +26,10 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
window *glfw.Window
|
||||
}
|
||||
|
||||
// NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL.
|
||||
// The returned graphics value is nil iff the error is not nil.
|
||||
func NewGraphics() (graphicsdriver.Graphics, error) {
|
||||
@ -83,9 +87,12 @@ func setGLFWClientAPI(isES bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) SetGLFWWindow(window *glfw.Window) {
|
||||
g.window = window
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
// TODO: Implement this (#2714).
|
||||
return nil
|
||||
return g.window.MakeContextCurrent()
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
@ -105,6 +112,8 @@ func (g *Graphics) swapBuffers() error {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement this (#2714).
|
||||
if err := g.window.SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
}
|
||||
|
||||
// NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL.
|
||||
// The returned graphics value is nil iff the error is not nil.
|
||||
func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
|
||||
|
@ -23,6 +23,9 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
}
|
||||
|
||||
// NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL.
|
||||
// The returned graphics value is nil iff the error is not nil.
|
||||
func NewGraphics(context mgl.Context) (graphicsdriver.Graphics, error) {
|
||||
|
@ -21,25 +21,29 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
var (
|
||||
theEGL egl
|
||||
)
|
||||
type graphicsPlatform struct {
|
||||
egl *egl
|
||||
}
|
||||
|
||||
func NewGraphics(nativeWindowType uintptr) (graphicsdriver.Graphics, error) {
|
||||
theEGL.init(nativeWindowType)
|
||||
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newGraphics(ctx), nil
|
||||
g := newGraphics(ctx)
|
||||
e, err := newEGL(nativeWindowType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.egl = e
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
return theEGL.makeContextCurrent()
|
||||
return g.egl.makeContextCurrent()
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
theEGL.swapBuffers()
|
||||
g.egl.swapBuffers()
|
||||
return nil
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
func ResolveStaleImages(graphicsDriver graphicsdriver.Graphics) error {
|
||||
return resolveStaleImages(graphicsDriver, false, nil)
|
||||
return resolveStaleImages(graphicsDriver, false)
|
||||
}
|
||||
|
||||
func AppendRegionRemovingDuplicates(regions *[]image.Rectangle, region image.Rectangle) {
|
||||
|
@ -56,7 +56,7 @@ var theImages = &images{
|
||||
shaders: map[*Shader]struct{}{},
|
||||
}
|
||||
|
||||
func SwapBuffers(graphicsDriver graphicsdriver.Graphics, swapBuffersForGL func()) error {
|
||||
func SwapBuffers(graphicsDriver graphicsdriver.Graphics) error {
|
||||
if debug.IsDebug {
|
||||
debug.Logf("Internal image sizes:\n")
|
||||
imgs := make([]*graphicscommand.Image, 0, len(theImages.images))
|
||||
@ -65,13 +65,13 @@ func SwapBuffers(graphicsDriver graphicsdriver.Graphics, swapBuffersForGL func()
|
||||
}
|
||||
graphicscommand.LogImagesInfo(imgs)
|
||||
}
|
||||
return resolveStaleImages(graphicsDriver, true, swapBuffersForGL)
|
||||
return resolveStaleImages(graphicsDriver, true)
|
||||
}
|
||||
|
||||
// resolveStaleImages flushes the queued draw commands and resolves all stale images.
|
||||
// If endFrame is true, the current screen might be used to present when flushing the commands.
|
||||
func resolveStaleImages(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {
|
||||
if err := graphicscommand.FlushCommands(graphicsDriver, endFrame, swapBuffersForGL); err != nil {
|
||||
func resolveStaleImages(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
|
||||
if err := graphicscommand.FlushCommands(graphicsDriver, endFrame); err != nil {
|
||||
return err
|
||||
}
|
||||
if !needsRestoring() {
|
||||
|
@ -63,12 +63,12 @@ func newContext(game Game) *context {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) updateFrame(graphicsDriver graphicsdriver.Graphics, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface, swapBuffersForGL func()) error {
|
||||
func (c *context) updateFrame(graphicsDriver graphicsdriver.Graphics, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface) error {
|
||||
// TODO: If updateCount is 0 and vsync is disabled, swapping buffers can be skipped.
|
||||
return c.updateFrameImpl(graphicsDriver, clock.UpdateFrame(), outsideWidth, outsideHeight, deviceScaleFactor, ui, false, swapBuffersForGL)
|
||||
return c.updateFrameImpl(graphicsDriver, clock.UpdateFrame(), outsideWidth, outsideHeight, deviceScaleFactor, ui, false)
|
||||
}
|
||||
|
||||
func (c *context) forceUpdateFrame(graphicsDriver graphicsdriver.Graphics, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface, swapBuffersForGL func()) error {
|
||||
func (c *context) forceUpdateFrame(graphicsDriver graphicsdriver.Graphics, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface) error {
|
||||
n := 1
|
||||
if ui.GraphicsLibrary() == GraphicsLibraryDirectX {
|
||||
// On DirectX, both framebuffers in the swap chain should be updated.
|
||||
@ -76,14 +76,14 @@ func (c *context) forceUpdateFrame(graphicsDriver graphicsdriver.Graphics, outsi
|
||||
n = 2
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
if err := c.updateFrameImpl(graphicsDriver, 1, outsideWidth, outsideHeight, deviceScaleFactor, ui, true, swapBuffersForGL); err != nil {
|
||||
if err := c.updateFrameImpl(graphicsDriver, 1, outsideWidth, outsideHeight, deviceScaleFactor, ui, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, updateCount int, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface, forceDraw bool, swapBuffersForGL func()) (err error) {
|
||||
func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, updateCount int, outsideWidth, outsideHeight float64, deviceScaleFactor float64, ui *UserInterface, forceDraw bool) (err error) {
|
||||
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
|
||||
// Just ignore such cases. Otherwise, creating a zero-sized framebuffer causes a panic.
|
||||
if outsideWidth == 0 || outsideHeight == 0 {
|
||||
@ -102,7 +102,7 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
|
||||
return
|
||||
}
|
||||
|
||||
if err1 := atlas.SwapBuffers(graphicsDriver, swapBuffersForGL); err1 != nil && err == nil {
|
||||
if err1 := atlas.SwapBuffers(graphicsDriver); err1 != nil && err == nil {
|
||||
err = err1
|
||||
return
|
||||
}
|
||||
|
@ -1177,7 +1177,10 @@ func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
if g, ok := u.graphicsDriver.(interface{ SetWindow(uintptr) }); ok {
|
||||
switch g := u.graphicsDriver.(type) {
|
||||
case interface{ SetGLFWWindow(window *glfw.Window) }:
|
||||
g.SetGLFWWindow(u.window)
|
||||
case interface{ SetWindow(uintptr) }:
|
||||
w, err := u.nativeWindow()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1405,15 +1408,6 @@ func (u *UserInterface) loopGame() (ferr error) {
|
||||
})
|
||||
}()
|
||||
|
||||
u.renderThread.Call(func() {
|
||||
if u.GraphicsLibrary() == GraphicsLibraryOpenGL {
|
||||
if err := u.window.MakeContextCurrent(); err != nil {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for {
|
||||
if err := u.updateGame(); err != nil {
|
||||
return err
|
||||
@ -1458,13 +1452,7 @@ func (u *UserInterface) updateGame() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u, func() {
|
||||
// This works only for OpenGL.
|
||||
if err := u.swapBuffersOnRenderThread(); err != nil {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
}); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1543,15 +1531,6 @@ func (u *UserInterface) updateIconIfNeeded() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) swapBuffersOnRenderThread() error {
|
||||
if u.GraphicsLibrary() == GraphicsLibraryOpenGL {
|
||||
if err := u.window.SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateWindowSizeLimits must be called from the main thread.
|
||||
func (u *UserInterface) updateWindowSizeLimits() error {
|
||||
m, err := u.currentMonitor()
|
||||
|
@ -365,11 +365,11 @@ func (u *UserInterface) updateImpl(force bool) error {
|
||||
|
||||
w, h := u.outsideSize()
|
||||
if force {
|
||||
if err := u.context.forceUpdateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u, nil); err != nil {
|
||||
if err := u.context.forceUpdateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u, nil); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ func (u *UserInterface) update() error {
|
||||
}()
|
||||
|
||||
w, h := u.outsideSize()
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u, nil); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -95,7 +95,7 @@ func (u *UserInterface) loopGame() error {
|
||||
for {
|
||||
recordProfilerHeartbeat()
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u, nil); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
|
||||
func (u *UserInterface) loopGame() error {
|
||||
for {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, screenWidth, screenHeight, deviceScaleFactor, u, nil); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, screenWidth, screenHeight, deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user