zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

buf_js.go (4135B)


      1 // Copyright 2019 The Ebiten Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package jsutil
     16 
     17 import (
     18 	"syscall/js"
     19 )
     20 
     21 var go2cpp = js.Global().Get("go2cpp").Truthy()
     22 
     23 var (
     24 	object       = js.Global().Get("Object")
     25 	arrayBuffer  = js.Global().Get("ArrayBuffer")
     26 	uint8Array   = js.Global().Get("Uint8Array")
     27 	float32Array = js.Global().Get("Float32Array")
     28 )
     29 
     30 var (
     31 	// temporaryArrayBuffer is a temporary buffer used at gl.readPixels or gl.texSubImage2D.
     32 	// The read data is converted to Go's byte slice as soon as possible.
     33 	// To avoid often allocating ArrayBuffer, reuse the buffer whenever possible.
     34 	temporaryArrayBuffer = arrayBuffer.New(16)
     35 
     36 	// temporaryUint8Array is a Uint8ArrayBuffer whose underlying buffer is always temporaryArrayBuffer.
     37 	temporaryUint8Array = uint8Array.New(temporaryArrayBuffer)
     38 
     39 	// temporaryFloat32Array is a Float32ArrayBuffer whose underlying buffer is always temporaryArrayBuffer.
     40 	temporaryFloat32Array = float32Array.New(temporaryArrayBuffer)
     41 )
     42 
     43 var (
     44 	temporaryArrayBufferByteLengthFunc  js.Value
     45 	temporaryUint8ArrayByteLengthFunc   js.Value
     46 	temporaryFloat32ArrayByteLengthFunc js.Value
     47 )
     48 
     49 func init() {
     50 	if go2cpp {
     51 		return
     52 	}
     53 	temporaryArrayBufferByteLengthFunc = object.Call("getOwnPropertyDescriptor", arrayBuffer.Get("prototype"), "byteLength").Get("get").Call("bind", temporaryArrayBuffer)
     54 	temporaryUint8ArrayByteLengthFunc = object.Call("getOwnPropertyDescriptor", object.Call("getPrototypeOf", uint8Array).Get("prototype"), "byteLength").Get("get").Call("bind", temporaryUint8Array)
     55 	temporaryFloat32ArrayByteLengthFunc = object.Call("getOwnPropertyDescriptor", object.Call("getPrototypeOf", float32Array).Get("prototype"), "byteLength").Get("get").Call("bind", temporaryFloat32Array)
     56 }
     57 
     58 func temporaryArrayBufferByteLength() int {
     59 	if go2cpp {
     60 		return temporaryArrayBuffer.Get("byteLength").Int()
     61 	}
     62 	return temporaryArrayBufferByteLengthFunc.Invoke().Int()
     63 }
     64 
     65 func temporaryUint8ArrayByteLength() int {
     66 	if go2cpp {
     67 		return temporaryUint8Array.Get("byteLength").Int()
     68 	}
     69 	return temporaryUint8ArrayByteLengthFunc.Invoke().Int()
     70 }
     71 
     72 func temporaryFloat32ArrayByteLength() int {
     73 	if go2cpp {
     74 		return temporaryFloat32Array.Get("byteLength").Int()
     75 	}
     76 	return temporaryFloat32ArrayByteLengthFunc.Invoke().Int()
     77 }
     78 
     79 func ensureTemporaryArrayBufferSize(byteLength int) {
     80 	bufl := temporaryArrayBufferByteLength()
     81 	if bufl < byteLength {
     82 		for bufl < byteLength {
     83 			bufl *= 2
     84 		}
     85 		temporaryArrayBuffer = arrayBuffer.New(bufl)
     86 	}
     87 	if temporaryUint8ArrayByteLength() < bufl {
     88 		temporaryUint8Array = uint8Array.New(temporaryArrayBuffer)
     89 	}
     90 	if temporaryFloat32ArrayByteLength() < bufl {
     91 		temporaryFloat32Array = float32Array.New(temporaryArrayBuffer)
     92 	}
     93 }
     94 
     95 // TemporaryUint8Array returns a Uint8Array whose length is at least minLength.
     96 // Be careful that the length can exceed the given minLength.
     97 // data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
     98 func TemporaryUint8Array(minLength int, data interface{}) js.Value {
     99 	ensureTemporaryArrayBufferSize(minLength)
    100 	if data != nil {
    101 		copySliceToTemporaryArrayBuffer(data)
    102 	}
    103 	return temporaryUint8Array
    104 }
    105 
    106 // TemporaryFloat32Array returns a Float32Array whose length is at least minLength.
    107 // Be careful that the length can exceed the given minLength.
    108 // data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
    109 func TemporaryFloat32Array(minLength int, data interface{}) js.Value {
    110 	ensureTemporaryArrayBufferSize(minLength * 4)
    111 	if data != nil {
    112 		copySliceToTemporaryArrayBuffer(data)
    113 	}
    114 	return temporaryFloat32Array
    115 }