internal/graphicsdriver/opengl: drop WebGL 1 support

Closes #2191
This commit is contained in:
Hajime Hoshi 2023-03-18 22:49:26 +09:00
parent 280b4ff18a
commit cbff3555db
5 changed files with 24 additions and 129 deletions

View File

@ -145,7 +145,6 @@ jobs:
- name: go test (Wasm) - name: go test (Wasm)
run: | run: |
env GOOS=js GOARCH=wasm cleanenv -remove-prefix GITHUB_ -remove-prefix JAVA_ -- go test -shuffle=on -v ./... env GOOS=js GOARCH=wasm cleanenv -remove-prefix GITHUB_ -remove-prefix JAVA_ -- go test -shuffle=on -v ./...
env GOOS=js GOARCH=wasm EBITENGINE_OPENGL=webgl1 cleanenv -remove-prefix GITHUB_ -remove-prefix JAVA_ -- go test -shuffle=on -v ./...
- name: Install ebitenmobile - name: Install ebitenmobile
run: | run: |

View File

@ -20,25 +20,17 @@ import (
) )
func (g *Game) loseAndRestoreContext() { func (g *Game) loseAndRestoreContext() {
doc := js.Global().Get("document")
canvas := doc.Call("getElementsByTagName", "canvas").Index(0)
context := canvas.Call("getContext", "webgl2")
if !context.Truthy() {
context = canvas.Call("getContext", "webgl")
if !context.Truthy() {
context = canvas.Call("getContext", "experimental-webgl")
}
}
if g.lost { if g.lost {
return return
} }
// Edge might not support the extension. See doc := js.Global().Get("document")
// https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context canvas := doc.Call("getElementsByTagName", "canvas").Index(0)
context := canvas.Call("getContext", "webgl2")
ext := context.Call("getExtension", "WEBGL_lose_context") ext := context.Call("getExtension", "WEBGL_lose_context")
if !ext.Truthy() { if !ext.Truthy() {
fmt.Println("Fail to force context lost. Edge might not support the extension yet.") fmt.Println("Fail to force context lost.")
return return
} }

View File

@ -22,12 +22,8 @@ import (
type contextPlatform struct { type contextPlatform struct {
canvas js.Value canvas js.Value
webGL2 bool
} }
func (c *context) glslVersion() glsl.GLSLVersion { func (c *context) glslVersion() glsl.GLSLVersion {
if c.webGL2 {
return glsl.GLSLVersionES300 return glsl.GLSLVersionES300
} }
return glsl.GLSLVersionES100
}

View File

@ -96,8 +96,6 @@ type defaultContext struct {
fnVertexAttribPointer js.Value fnVertexAttribPointer js.Value
fnViewport js.Value fnViewport js.Value
webGL2 bool
buffers values buffers values
framebuffers values framebuffers values
programs values programs values
@ -226,10 +224,6 @@ func NewDefaultContext(v js.Value) (Context, error) {
fnViewport: v.Get("viewport").Call("bind", v), fnViewport: v.Get("viewport").Call("bind", v),
} }
if webGL2 := js.Global().Get("WebGL2RenderingContext"); webGL2.Truthy() {
g.webGL2 = v.InstanceOf(webGL2)
}
return g, nil return g, nil
} }
@ -290,11 +284,7 @@ func (c *defaultContext) BufferInit(target uint32, size int, usage uint32) {
func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) { func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) {
l := len(data) l := len(data)
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(l, data) arr := jsutil.TemporaryUint8ArrayFromUint8Slice(l, data)
if c.webGL2 {
c.fnBufferSubData.Invoke(target, offset, arr, 0, l) c.fnBufferSubData.Invoke(target, offset, arr, 0, l)
} else {
c.fnBufferSubData.Invoke(target, offset, arr.Call("subarray", 0, l))
}
} }
func (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 { func (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 {
@ -540,27 +530,16 @@ func (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32)
func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) { func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) {
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(len(pixels), pixels) arr := jsutil.TemporaryUint8ArrayFromUint8Slice(len(pixels), pixels)
if c.webGL2 {
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
// GLsizei width, GLsizei height, // GLsizei width, GLsizei height,
// GLenum format, GLenum type, ArrayBufferView pixels, srcOffset); // GLenum format, GLenum type, ArrayBufferView pixels, srcOffset);
c.fnTexSubImage2D.Invoke(target, level, xoffset, yoffset, width, height, format, xtype, arr, 0) c.fnTexSubImage2D.Invoke(target, level, xoffset, yoffset, width, height, format, xtype, arr, 0)
} else {
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
// GLsizei width, GLsizei height,
// GLenum format, GLenum type, ArrayBufferView? pixels);
c.fnTexSubImage2D.Invoke(target, level, xoffset, yoffset, width, height, format, xtype, arr)
}
} }
func (c *defaultContext) Uniform1fv(location int32, value []float32) { func (c *defaultContext) Uniform1fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniform1fv.Invoke(l, arr, 0, len(value)) c.fnUniform1fv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform1fv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform1i(location int32, v0 int32) { func (c *defaultContext) Uniform1i(location int32, v0 int32) {
@ -571,101 +550,61 @@ func (c *defaultContext) Uniform1i(location int32, v0 int32) {
func (c *defaultContext) Uniform1iv(location int32, value []int32) { func (c *defaultContext) Uniform1iv(location int32, value []int32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryInt32Array(len(value), value) arr := jsutil.TemporaryInt32Array(len(value), value)
if c.webGL2 {
c.fnUniform1iv.Invoke(l, arr, 0, len(value)) c.fnUniform1iv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform1iv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform2fv(location int32, value []float32) { func (c *defaultContext) Uniform2fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniform2fv.Invoke(l, arr, 0, len(value)) c.fnUniform2fv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform2fv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform2iv(location int32, value []int32) { func (c *defaultContext) Uniform2iv(location int32, value []int32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryInt32Array(len(value), value) arr := jsutil.TemporaryInt32Array(len(value), value)
if c.webGL2 {
c.fnUniform2iv.Invoke(l, arr, 0, len(value)) c.fnUniform2iv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform2iv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform3fv(location int32, value []float32) { func (c *defaultContext) Uniform3fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniform3fv.Invoke(l, arr, 0, len(value)) c.fnUniform3fv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform3fv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform3iv(location int32, value []int32) { func (c *defaultContext) Uniform3iv(location int32, value []int32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryInt32Array(len(value), value) arr := jsutil.TemporaryInt32Array(len(value), value)
if c.webGL2 {
c.fnUniform3iv.Invoke(l, arr, 0, len(value)) c.fnUniform3iv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform3iv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform4fv(location int32, value []float32) { func (c *defaultContext) Uniform4fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniform4fv.Invoke(l, arr, 0, len(value)) c.fnUniform4fv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform4fv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) Uniform4iv(location int32, value []int32) { func (c *defaultContext) Uniform4iv(location int32, value []int32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryInt32Array(len(value), value) arr := jsutil.TemporaryInt32Array(len(value), value)
if c.webGL2 {
c.fnUniform4iv.Invoke(l, arr, 0, len(value)) c.fnUniform4iv.Invoke(l, arr, 0, len(value))
} else {
c.fnUniform4iv.Invoke(l, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) { func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniformMatrix2fv.Invoke(l, false, arr, 0, len(value)) c.fnUniformMatrix2fv.Invoke(l, false, arr, 0, len(value))
} else {
c.fnUniformMatrix2fv.Invoke(l, false, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) UniformMatrix3fv(location int32, value []float32) { func (c *defaultContext) UniformMatrix3fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniformMatrix3fv.Invoke(l, false, arr, 0, len(value)) c.fnUniformMatrix3fv.Invoke(l, false, arr, 0, len(value))
} else {
c.fnUniformMatrix3fv.Invoke(l, false, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) UniformMatrix4fv(location int32, value []float32) { func (c *defaultContext) UniformMatrix4fv(location int32, value []float32) {
l := c.getUniformLocation(location) l := c.getUniformLocation(location)
arr := jsutil.TemporaryFloat32Array(len(value), value) arr := jsutil.TemporaryFloat32Array(len(value), value)
if c.webGL2 {
c.fnUniformMatrix4fv.Invoke(l, false, arr, 0, len(value)) c.fnUniformMatrix4fv.Invoke(l, false, arr, 0, len(value))
} else {
c.fnUniformMatrix4fv.Invoke(l, false, arr.Call("subarray", 0, len(value)))
}
} }
func (c *defaultContext) UseProgram(program uint32) { func (c *defaultContext) UseProgram(program uint32) {

View File

@ -16,8 +16,6 @@ package opengl
import ( import (
"fmt" "fmt"
"os"
"strings"
"syscall/js" "syscall/js"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
@ -34,23 +32,10 @@ func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
attr.Set("premultipliedAlpha", true) attr.Set("premultipliedAlpha", true)
attr.Set("stencil", true) attr.Set("stencil", true)
var webGL2 bool
if webGL2MightBeAvailable() {
glContext = canvas.Call("getContext", "webgl2", attr) glContext = canvas.Call("getContext", "webgl2", attr)
}
if glContext.Truthy() {
webGL2 = true
} else {
// Even though WebGL2RenderingContext exists, getting a webgl2 context might fail (#1738).
glContext = canvas.Call("getContext", "webgl", attr)
if !glContext.Truthy() {
glContext = canvas.Call("getContext", "experimental-webgl", attr)
}
}
if !glContext.Truthy() { if !glContext.Truthy() {
return nil, fmt.Errorf("opengl: getContext failed") return nil, fmt.Errorf("opengl: getContext for webgl2 failed")
} }
ctx, err := gl.NewDefaultContext(glContext) ctx, err := gl.NewDefaultContext(glContext)
@ -61,22 +46,6 @@ func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
g := &Graphics{} g := &Graphics{}
g.context.canvas = canvas g.context.canvas = canvas
g.context.ctx = ctx g.context.ctx = ctx
g.context.webGL2 = webGL2
if !webGL2 {
glContext.Call("getExtension", "OES_standard_derivatives")
}
return g, nil return g, nil
} }
func webGL2MightBeAvailable() bool {
env := os.Getenv("EBITENGINE_OPENGL")
for _, t := range strings.Split(env, ",") {
switch strings.TrimSpace(t) {
case "webgl1":
return false
}
}
return js.Global().Get("WebGL2RenderingContext").Truthy()
}