internal/ui: refactoring: move updateVsyncOnRenderThread to the OpenGL driver

Updates #2714
This commit is contained in:
Hajime Hoshi 2023-12-20 02:38:09 +09:00
parent 12ae411d15
commit f6f0cf05e6
6 changed files with 33 additions and 37 deletions

View File

@ -35,6 +35,7 @@ type activatedTexture struct {
type Graphics struct {
state openGLState
context context
vsync bool
nextImageID graphicsdriver.ImageID
images map[graphicsdriver.ImageID]*Image
@ -56,7 +57,9 @@ type Graphics struct {
}
func newGraphics(ctx gl.Context) *Graphics {
g := &Graphics{}
g := &Graphics{
vsync: true,
}
if isDebug {
g.context.ctx = &gl.DebugContext{Context: ctx}
} else {
@ -78,7 +81,9 @@ func (g *Graphics) End(present bool) error {
// The last uniforms must be reset before swapping the buffer (#2517).
if present {
g.state.resetLastUniforms()
g.swapBuffers()
if err := g.swapBuffers(); err != nil {
return err
}
}
return nil
@ -298,7 +303,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
func (g *Graphics) SetVsyncEnabled(enabled bool) {
// Do nothing
g.vsync = enabled
}
func (g *Graphics) NeedsRestoring() bool {

View File

@ -45,8 +45,25 @@ func (g *Graphics) makeContextCurrent() {
// TODO: Implement this (#2714).
}
func (g *Graphics) swapBuffers() {
func (g *Graphics) swapBuffers() error {
// Call SwapIntervals even though vsync is not changed.
// When toggling to fullscreen, vsync state might be reset unexpectedly (#1787).
// SwapInterval is affected by the current monitor of the window.
// This needs to be called at least after SetMonitor.
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
if g.vsync {
if err := glfw.SwapInterval(1); err != nil {
return err
}
} else {
if err := glfw.SwapInterval(0); err != nil {
return err
}
}
// TODO: Implement this (#2714).
return nil
}
func (g *Graphics) SetGLFWClientAPI() error {

View File

@ -49,5 +49,6 @@ func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
func (g *Graphics) makeContextCurrent() {
}
func (g *Graphics) swapBuffers() {
func (g *Graphics) swapBuffers() error {
return nil
}

View File

@ -43,5 +43,6 @@ func NewGraphics(context mgl.Context) (graphicsdriver.Graphics, error) {
func (g *Graphics) makeContextCurrent() {
}
func (g *Graphics) swapBuffers() {
func (g *Graphics) swapBuffers() error {
return nil
}

View File

@ -39,6 +39,7 @@ func (g *Graphics) makeContextCurrent() {
theEGL.makeContextCurrent()
}
func (g *Graphics) swapBuffers() {
func (g *Graphics) swapBuffers() error {
theEGL.swapBuffers()
return nil
}

View File

@ -1336,7 +1336,7 @@ func (u *UserInterface) update() (float64, float64, error) {
}
}
// Initialize vsync after SetMonitor is called. See the comment in updateVsync.
// Initialize vsync after SetMonitor is called.
// Calling this inside setWindowSize didn't work (#1363).
// Also, setFPSMode has to be called after graphicscommand.SetRenderThread is called (#2714).
if !u.fpsModeInited {
@ -1466,13 +1466,6 @@ func (u *UserInterface) updateGame() error {
}
if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u, func() {
// Call updateVsync even though fpsMode is not updated.
// When toggling to fullscreen, vsync state might be reset unexpectedly (#1787).
if err := u.updateVsyncOnRenderThread(); err != nil {
u.setError(err)
return
}
// This works only for OpenGL.
if err := u.swapBuffersOnRenderThread(); err != nil {
u.setError(err)
@ -1861,28 +1854,6 @@ func (u *UserInterface) minimumWindowWidth() (int, error) {
return 1, nil
}
func (u *UserInterface) updateVsyncOnRenderThread() error {
if u.GraphicsLibrary() == GraphicsLibraryOpenGL {
// SwapInterval is affected by the current monitor of the window.
// This needs to be called at least after SetMonitor.
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
//
// TODO: (#405) If triple buffering is needed, SwapInterval(0) should be called,
// but is this correct? If glfw.SwapInterval(0) and the driver doesn't support triple
// buffering, what will happen?
if u.fpsMode == FPSModeVsyncOn {
if err := glfw.SwapInterval(1); err != nil {
return err
}
} else {
if err := glfw.SwapInterval(0); err != nil {
return err
}
}
}
return nil
}
// currentMonitor returns the current active monitor.
//
// currentMonitor must be called on the main thread.