internal/graphicsdriver/opengl/gl: reladn: refactoring

This is a reland of a1ad87a262
This commit is contained in:
Hajime Hoshi 2022-11-09 16:07:30 +09:00
parent 96298bb59d
commit 097adcf8b6
3 changed files with 23 additions and 49 deletions

View File

@ -290,8 +290,8 @@ func (c *context) newShader(shaderType uint32, source string) (shader, error) {
if s == 0 { if s == 0 {
return 0, fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType) return 0, fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType)
} }
cSources, free := gl.Strs(source + "\x00") cSources, free := gl.CStr(source)
gl.ShaderSource(uint32(s), 1, cSources, nil) gl.ShaderSource(uint32(s), 1, &cSources, nil)
free() free()
gl.CompileShader(s) gl.CompileShader(s)
@ -325,8 +325,8 @@ func (c *context) newProgram(shaders []shader, attributes []string) (program, er
} }
for i, name := range attributes { for i, name := range attributes {
l, free := gl.Strs(name + "\x00") l, free := gl.CStr(name)
gl.BindAttribLocation(p, uint32(i), *l) gl.BindAttribLocation(p, uint32(i), l)
free() free()
} }
@ -360,8 +360,8 @@ func (c *context) deleteProgram(p program) {
} }
func (c *context) getUniformLocationImpl(p program, location string) uniformLocation { func (c *context) getUniformLocationImpl(p program, location string) uniformLocation {
l, free := gl.Strs(location + "\x00") l, free := gl.CStr(location)
uniform := uniformLocation(gl.GetUniformLocation(uint32(p), *l)) uniform := uniformLocation(gl.GetUniformLocation(uint32(p), l))
free() free()
return uniform return uniform
} }

View File

@ -17,27 +17,14 @@ func GoStr(cstr *byte) string {
return C.GoString((*C.char)(unsafe.Pointer(cstr))) return C.GoString((*C.char)(unsafe.Pointer(cstr)))
} }
// Strs takes a list of Go strings (with or without null-termination) and // CStr takes a Go string (with or without null-termination)
// returns their C counterpart. // and returns the C counterpart.
// //
// The returned free function must be called once you are done using the strings // The returned free function must be called once you are done using the string
// in order to free the memory. // in order to free the memory.
// func CStr(str string) (cstr *byte, free func()) {
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **byte, free func()) {
if len(strs) == 0 {
panic("gl: expected at least 1 string at Strs")
}
css := make([]*byte, 0, len(strs))
for _, str := range strs {
cs := C.CString(str) cs := C.CString(str)
css = append(css, (*byte)(unsafe.Pointer(cs))) return (*byte)(unsafe.Pointer(cs)), func() {
}
return (**byte)(&css[0]), func() {
for _, cs := range css {
C.free(unsafe.Pointer(cs)) C.free(unsafe.Pointer(cs))
} }
}
} }

View File

@ -26,31 +26,18 @@ func GoStr(cstr *byte) string {
return "" return ""
} }
// Strs takes a list of Go strings (with or without null-termination) and // CStr takes a Go string (with or without null-termination)
// returns their C counterpart. // and returns the C counterpart.
// //
// The returned free function must be called once you are done using the strings // The returned free function must be called once you are done using the string
// in order to free the memory. // in order to free the memory.
// func CStr(str string) (cstr *byte, free func()) {
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **byte, free func()) {
if len(strs) == 0 {
panic("gl: expected at least 1 string at Strs")
}
pinned := make([][]byte, 0, len(strs))
ptrs := make([]*byte, 0, len(strs))
for _, str := range strs {
bs := []byte(str) bs := []byte(str)
if len(bs) == 0 || bs[len(bs)-1] != 0 { if len(bs) == 0 || bs[len(bs)-1] != 0 {
bs = append(bs, 0) bs = append(bs, 0)
} }
pinned = append(pinned, bs) return &bs[0], func() {
ptrs = append(ptrs, &bs[0]) runtime.KeepAlive(bs)
} bs = nil
return &ptrs[0], func() {
runtime.KeepAlive(pinned)
pinned = nil
} }
} }