mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/jsutil: Optimization: Avoid using empty interface{} conversions
This commit is contained in:
parent
a826ecb29b
commit
a082db04fd
@ -242,7 +242,7 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
||||
c.bindFramebuffer(f.native)
|
||||
|
||||
l := 4 * width * height
|
||||
p := jsutil.TemporaryUint8Array(l, nil)
|
||||
p := jsutil.TemporaryUint8ArrayFromUint8Slice(l, nil)
|
||||
gl.readPixels.Invoke(0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, p)
|
||||
|
||||
return uint8ArrayToSlice(p, l)
|
||||
@ -567,7 +567,7 @@ func (c *context) bindElementArrayBuffer(b buffer) {
|
||||
func (c *context) arrayBufferSubData(data []float32) {
|
||||
gl := c.gl
|
||||
l := len(data) * 4
|
||||
arr := jsutil.TemporaryUint8Array(l, data)
|
||||
arr := jsutil.TemporaryUint8ArrayFromFloat32Slice(l, data)
|
||||
if c.usesWebGL2() {
|
||||
gl.bufferSubData.Invoke(gles.ARRAY_BUFFER, 0, arr, 0, l)
|
||||
} else {
|
||||
@ -578,7 +578,7 @@ func (c *context) arrayBufferSubData(data []float32) {
|
||||
func (c *context) elementArrayBufferSubData(data []uint16) {
|
||||
gl := c.gl
|
||||
l := len(data) * 2
|
||||
arr := jsutil.TemporaryUint8Array(l, data)
|
||||
arr := jsutil.TemporaryUint8ArrayFromUint16Slice(l, data)
|
||||
if c.usesWebGL2() {
|
||||
gl.bufferSubData.Invoke(gles.ELEMENT_ARRAY_BUFFER, 0, arr, 0, l)
|
||||
} else {
|
||||
@ -624,7 +624,7 @@ func (c *context) texSubImage2D(t textureNative, args []*driver.ReplacePixelsArg
|
||||
c.bindTexture(t)
|
||||
gl := c.gl
|
||||
for _, a := range args {
|
||||
arr := jsutil.TemporaryUint8Array(len(a.Pixels), a.Pixels)
|
||||
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(len(a.Pixels), a.Pixels)
|
||||
if c.usesWebGL2() {
|
||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
// GLsizei width, GLsizei height,
|
||||
|
@ -92,24 +92,38 @@ func ensureTemporaryArrayBufferSize(byteLength int) {
|
||||
}
|
||||
}
|
||||
|
||||
// TemporaryUint8Array returns a Uint8Array whose length is at least minLength.
|
||||
// TemporaryUint8ArrayFromUint8Slice returns a Uint8Array whose length is at least minLength from a uint8 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func TemporaryUint8Array(minLength int, data interface{}) js.Value {
|
||||
func TemporaryUint8ArrayFromUint8Slice(minLength int, data []uint8) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength)
|
||||
if data != nil {
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
}
|
||||
copyUint8SliceToTemporaryArrayBuffer(data)
|
||||
return temporaryUint8Array
|
||||
}
|
||||
|
||||
// TemporaryUint8ArrayFromUint16Slice returns a Uint8Array whose length is at least minLength from a uint16 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func TemporaryUint8ArrayFromUint16Slice(minLength int, data []uint16) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 2)
|
||||
copyUint16SliceToTemporaryArrayBuffer(data)
|
||||
return temporaryUint8Array
|
||||
}
|
||||
|
||||
// TemporaryUint8ArrayFromFloat32Slice returns a Uint8Array whose length is at least minLength from a float32 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func TemporaryUint8ArrayFromFloat32Slice(minLength int, data []float32) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 4)
|
||||
copyFloat32SliceToTemporaryArrayBuffer(data)
|
||||
return temporaryUint8Array
|
||||
}
|
||||
|
||||
// TemporaryFloat32Array returns a Float32Array whose length is at least minLength.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func TemporaryFloat32Array(minLength int, data interface{}) js.Value {
|
||||
func TemporaryFloat32Array(minLength int, data []float32) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 4)
|
||||
if data != nil {
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
}
|
||||
copyFloat32SliceToTemporaryArrayBuffer(data)
|
||||
return temporaryFloat32Array
|
||||
}
|
||||
|
@ -15,82 +15,39 @@
|
||||
package jsutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"syscall/js"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func sliceToByteSlice(s interface{}) (bs []byte) {
|
||||
switch s := s.(type) {
|
||||
case []int8:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []int16:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 2
|
||||
h.Cap *= 2
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []int32:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 4
|
||||
h.Cap *= 4
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []int64:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 8
|
||||
h.Cap *= 8
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []uint8:
|
||||
return s
|
||||
case []uint16:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 2
|
||||
h.Cap *= 2
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []uint32:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 4
|
||||
h.Cap *= 4
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []uint64:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 8
|
||||
h.Cap *= 8
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []float32:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 4
|
||||
h.Cap *= 4
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
case []float64:
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
|
||||
h.Len *= 8
|
||||
h.Cap *= 8
|
||||
bs = *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(s)
|
||||
default:
|
||||
panic(fmt.Sprintf("jsutil: unexpected value at sliceToBytesSlice: %T", s))
|
||||
func copyUint8SliceToTemporaryArrayBuffer(src []uint8) {
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
return
|
||||
js.CopyBytesToJS(temporaryUint8Array, src)
|
||||
}
|
||||
|
||||
func copySliceToTemporaryArrayBuffer(src interface{}) {
|
||||
switch s := src.(type) {
|
||||
case []uint8:
|
||||
js.CopyBytesToJS(temporaryUint8Array, s)
|
||||
case []int8, []int16, []int32, []uint16, []uint32, []float32, []float64:
|
||||
js.CopyBytesToJS(temporaryUint8Array, sliceToByteSlice(s))
|
||||
default:
|
||||
panic(fmt.Sprintf("jsutil: unexpected value at CopySliceToJS: %T", s))
|
||||
func copyUint16SliceToTemporaryArrayBuffer(src []uint16) {
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&src))
|
||||
h.Len *= 2
|
||||
h.Cap *= 2
|
||||
bs := *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(src)
|
||||
js.CopyBytesToJS(temporaryUint8Array, bs)
|
||||
}
|
||||
|
||||
func copyFloat32SliceToTemporaryArrayBuffer(src []float32) {
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&src))
|
||||
h.Len *= 4
|
||||
h.Cap *= 4
|
||||
bs := *(*[]byte)(unsafe.Pointer(h))
|
||||
runtime.KeepAlive(src)
|
||||
js.CopyBytesToJS(temporaryUint8Array, bs)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user