From 915fff96f84c79f480f128d572ee54ffa6a00ad4 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 9 Nov 2022 12:51:02 +0900 Subject: [PATCH] all: reduce reflect usages --- .../graphicsdriver/directx/api_windows.go | 9 ++--- .../graphicsdriver/opengl/gl/conversions.go | 15 +------ .../opengl/gl/conversions_cgo.go | 12 +++--- .../opengl/gl/conversions_nocgo.go | 39 ++++++++++--------- 4 files changed, 31 insertions(+), 44 deletions(-) diff --git a/internal/graphicsdriver/directx/api_windows.go b/internal/graphicsdriver/directx/api_windows.go index 577ace3bb..fcf7c8721 100644 --- a/internal/graphicsdriver/directx/api_windows.go +++ b/internal/graphicsdriver/directx/api_windows.go @@ -17,7 +17,6 @@ package directx import ( "fmt" "math" - "reflect" "runtime" "syscall" "unsafe" @@ -2294,11 +2293,9 @@ func (i *_ID3DBlob) Release() uint32 { } func (i *_ID3DBlob) String() string { - var str string - h := (*reflect.StringHeader)(unsafe.Pointer(&str)) - h.Data = i.GetBufferPointer() - h.Len = int(i.GetBufferSize()) - return str + bs := make([]byte, int(i.GetBufferSize())) + copy(bs, unsafe.Slice((*byte)(unsafe.Pointer(i.GetBufferPointer())), i.GetBufferSize())) + return string(bs) } type _IDXGIAdapter struct { diff --git a/internal/graphicsdriver/opengl/gl/conversions.go b/internal/graphicsdriver/opengl/gl/conversions.go index e9c1a5f74..0401a99d2 100644 --- a/internal/graphicsdriver/opengl/gl/conversions.go +++ b/internal/graphicsdriver/opengl/gl/conversions.go @@ -4,8 +4,6 @@ package gl import ( "fmt" - "reflect" - "strings" "unsafe" ) @@ -14,7 +12,7 @@ import ( // // For example: // -// var data []uint8 +// var data []byte // ... // gl.TexImage2D(glconst.TEXTURE_2D, ..., glconst.UNSIGNED_BYTE, gl.Ptr(&data[0])) func Ptr(data any) unsafe.Pointer { @@ -40,14 +38,3 @@ func Ptr(data any) unsafe.Pointer { } return addr } - -// Str takes a null-terminated Go string and returns its GL-compatible address. -// This function reaches into Go string storage in an unsafe way so the caller -// must ensure the string is not garbage collected. -func Str(str string) *uint8 { - if !strings.HasSuffix(str, "\x00") { - panic("str argument missing null terminator: " + str) - } - header := (*reflect.StringHeader)(unsafe.Pointer(&str)) - return (*uint8)(unsafe.Pointer(header.Data)) -} diff --git a/internal/graphicsdriver/opengl/gl/conversions_cgo.go b/internal/graphicsdriver/opengl/gl/conversions_cgo.go index a2fc88c06..87aa0375e 100644 --- a/internal/graphicsdriver/opengl/gl/conversions_cgo.go +++ b/internal/graphicsdriver/opengl/gl/conversions_cgo.go @@ -13,7 +13,7 @@ import "C" // GoStr takes a null-terminated string returned by OpenGL and constructs a // corresponding Go string. -func GoStr(cstr *uint8) string { +func GoStr(cstr *byte) string { return C.GoString((*C.char)(unsafe.Pointer(cstr))) } @@ -24,18 +24,18 @@ func GoStr(cstr *uint8) string { // in order to free the memory. // // If no strings are provided as a parameter this function will panic. -func Strs(strs ...string) (cstrs **uint8, free func()) { +func Strs(strs ...string) (cstrs **byte, free func()) { if len(strs) == 0 { - panic("Strs: expected at least 1 string") + panic("gl: expected at least 1 string at Strs") } - css := make([]*uint8, 0, len(strs)) + css := make([]*byte, 0, len(strs)) for _, str := range strs { cs := C.CString(str) - css = append(css, (*uint8)(unsafe.Pointer(cs))) + css = append(css, (*byte)(unsafe.Pointer(cs))) } - return (**uint8)(&css[0]), func() { + return (**byte)(&css[0]), func() { for _, cs := range css { C.free(unsafe.Pointer(cs)) } diff --git a/internal/graphicsdriver/opengl/gl/conversions_nocgo.go b/internal/graphicsdriver/opengl/gl/conversions_nocgo.go index cf8bf3ddd..c878c8d90 100644 --- a/internal/graphicsdriver/opengl/gl/conversions_nocgo.go +++ b/internal/graphicsdriver/opengl/gl/conversions_nocgo.go @@ -6,22 +6,24 @@ package gl import ( "runtime" - "strings" "unsafe" ) // GoStr takes a null-terminated string returned by OpenGL and constructs a // corresponding Go string. -func GoStr(cstr *uint8) string { - str := "" - for { - if *cstr == 0 { - break - } - str += string(*cstr) - cstr = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(cstr)) + 1)) +func GoStr(cstr *byte) string { + if cstr == nil { + return "" } - return str + x := unsafe.Slice(cstr, 1e9) + for i, c := range x { + if c == 0 { + str := make([]byte, i) + copy(str, x[:i]) + return string(str) + } + } + return "" } // Strs takes a list of Go strings (with or without null-termination) and @@ -31,19 +33,20 @@ func GoStr(cstr *uint8) string { // in order to free the memory. // // If no strings are provided as a parameter this function will panic. -func Strs(strs ...string) (cstrs **uint8, free func()) { +func Strs(strs ...string) (cstrs **byte, free func()) { if len(strs) == 0 { - panic("Strs: expected at least 1 string") + panic("gl: expected at least 1 string at Strs") } - var pinned []string - var ptrs []*uint8 + pinned := make([][]byte, 0, len(strs)) + ptrs := make([]*byte, 0, len(strs)) for _, str := range strs { - if !strings.HasSuffix(str, "\x00") { - str += "\x00" + bs := []byte(str) + if len(bs) == 0 || bs[len(bs)-1] != 0 { + bs = append(bs, 0) } - pinned = append(pinned, str) - ptrs = append(ptrs, Str(str)) + pinned = append(pinned, bs) + ptrs = append(ptrs, &bs[0]) } return &ptrs[0], func() {