license import { backend_util , DataId , DataType , env , TensorInfo , util } from '@tensorflow/tfjs-core' ; export enum PackingScheme { /**
     * All values in a single texel are densely packed without any constraints.
     *
     * This is how the shader encodes a tensor with shape = [2, 3, 4]
     * (indices are [batch, row, col]).
     *
     * 000|001   010|011   020|021
     * -------   -------   -------
     * 002|003   012|013   022|023
     *
     * 100|101   110|111   120|121
     * -------   -------   -------
     * 102|103   112|113   122|123
     *
     */ DENSE , /**
     * Single texels contain only values from the same batch, and from adjacent
     * rows and columns.
     *
     * This is how the shader encodes a tensor with shape = [2, 3, 5]
     * (indices are [batch, row, col]).
     *
     * 000|001   002|003   004|xxx   020|021   022|023   024|xxx
     * -------   -------   -------   -------   -------   -------
     * 010|011   012|013   014|xxx   xxx|xxx   xxx|xxx   xxx|xxx
     *
     * 100|101   102|103   104|xxx   120|121   122|123   124|xxx
     * -------   -------   -------   -------   -------   -------
     * 110|111   112|113   114|xxx   xxx|xxx   xxx|xxx   xxx|xxx
     *
     */ SHARED_BATCH } export enum TextureUsage { RENDER , UPLOAD , PIXELS , DOWNLOAD } export enum PhysicalTextureType { UNPACKED_FLOAT16 , UNPACKED_FLOAT32 , PACKED_4X1_UNSIGNED_BYTE , PACKED_2X2_FLOAT32 , PACKED_2X2_FLOAT16 } export interface Texture { texture : WebGLTexture ; texShape : [ number , number ] ; } export interface TextureData { shape : number [ ] ; dtype : DataType ; values ? : backend_util . BackendValues ; texture ? : Texture ; complexTensorInfos ? : { real : TensorInfo ; imag : TensorInfo ; } ; /** [rows, columns] shape of the texture. */ texShape ? : [ number , number ] ; usage ? : TextureUsage ; isPacked ? : boolean ; refCount : number ; slice ? : { flatOffset : number ; origDataId : DataId ; } ; } export function getUnpackedMatrixTextureShapeWidthHeight ( rows , columns ) { return [ columns , rows ] ; } export function getUnpackedArraySizeFromMatrixSize ( matrixSize , channelsPerTexture ) { return matrixSize * channelsPerTexture ; } export function getColorMatrixTextureShapeWidthHeight ( rows , columns ) { return [ columns * 4 , rows ] ; } /**
 * Get shape for densely packed RGBA texture.
 */ export function getDenseTexShape ( shape ) { const size = util . sizeFromShape ( shape ) ; const texelsNeeded = Math . ceil ( size / 4 ) ; return util . sizeToSquarishShape ( texelsNeeded ) ; } export function getMatrixSizeFromUnpackedArraySize ( unpackedSize , channelsPerTexture ) { if ( unpackedSize % channelsPerTexture !== 0 ) { throw new Error ( `unpackedSize (${ unpackedSize }) must be a multiple of ` + `${ channelsPerTexture }` ) ; } return unpackedSize / channelsPerTexture ; } export function decodeMatrixFromUnpackedColorRGBAArray ( unpackedArray , matrix , channels ) { const requiredSize = unpackedArray . length * channels / 4 ; if ( matrix . length < requiredSize ) { throw new Error ( `matrix length (${ matrix . length }) must be >= ${ requiredSize }` ) ; } let dst = 0 ; for ( let src = 0 ; src < unpackedArray . length ; src += 4 ) { for ( let c = 0 ; c < channels ; c ++ ) { matrix [ dst ++ ] = unpackedArray [ src + c ] ; } } } export function getPackedMatrixTextureShapeWidthHeight ( rows , columns ) { return [ Math . max ( 1 , Math . ceil ( columns / 2 ) ) , Math . max ( 1 , Math . ceil ( rows / 2 ) ) ] ; } export function getPackedRGBAArraySizeFromMatrixShape ( rows , columns ) { const [ w , h ] = getPackedMatrixTextureShapeWidthHeight ( rows , columns ) ; return w * h * 4 ; } export interface TextureConfig { internalFormatFloat : number ; textureFormatFloat : number ; internalFormatPackedHalfFloat : number ; internalFormatHalfFloat : number ; internalFormatPackedFloat : number ; downloadTextureFormat : number ; downloadUnpackNumChannels : number ; defaultNumChannels : number ; textureTypeHalfFloat : number ; textureTypeFloat : number ; } export function getTextureConfig ( gl , textureHalfFloatExtension ? ) { const glany = gl as any ; let internalFormatFloat ; let internalFormatHalfFloat ; let internalFormatPackedHalfFloat ; let internalFormatPackedFloat ; let textureFormatFloat ; let downloadTextureFormat ; let downloadUnpackNumChannels ; let defaultNumChannels ; let textureTypeHalfFloat ; let textureTypeFloat ; if ( env ( ) . getNumber ( 'WEBGL_VERSION' ) === 2 ) { internalFormatFloat = glany . R32F ; internalFormatHalfFloat = glany . R16F ; internalFormatPackedHalfFloat = glany . RGBA16F ; internalFormatPackedFloat = glany . RGBA32F ; textureFormatFloat = glany . RED ; downloadUnpackNumChannels = 4 ; defaultNumChannels = 1 ; textureTypeHalfFloat = glany . HALF_FLOAT ; textureTypeFloat = glany . FLOAT ; downloadTextureFormat = glany . RGBA8 ; } else { internalFormatFloat = gl . RGBA ; internalFormatHalfFloat = gl . RGBA ; internalFormatPackedHalfFloat = gl . RGBA ; internalFormatPackedFloat = glany . RGBA ; textureFormatFloat = gl . RGBA ; downloadUnpackNumChannels = 4 ; defaultNumChannels = 4 ; textureTypeHalfFloat = textureHalfFloatExtension != null ? textureHalfFloatExtension . HALF_FLOAT_OES : null ; textureTypeFloat = gl . FLOAT ; downloadTextureFormat = gl . RGBA ; } return { internalFormatFloat , internalFormatHalfFloat , internalFormatPackedHalfFloat , internalFormatPackedFloat , textureFormatFloat , downloadTextureFormat , downloadUnpackNumChannels , defaultNumChannels , textureTypeHalfFloat , textureTypeFloat } ; }