Skip to content

Commit

Permalink
Merge pull request #1 from syntheticmagus/native-engine-perf-small-re…
Browse files Browse the repository at this point in the history
…factor

Native engine perf small refactor
  • Loading branch information
bghgary committed Oct 13, 2021
2 parents 52b7430 + 467791d commit 4fd95f6
Show file tree
Hide file tree
Showing 8 changed files with 644 additions and 570 deletions.
6 changes: 3 additions & 3 deletions src/DeviceInput/deviceInputSystem.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Engine } from '../Engines/engine';
import { INative } from '../Engines/Native/nativeInterfaces';
import { NativeDeviceInputWrapper } from './Implementations/nativeDeviceInputWrapper';
import { WebDeviceInputSystem } from './Implementations/webDeviceInputSystem';
import { IDeviceInputSystem } from './Interfaces/inputInterfaces';

/** @hidden */
declare const _native: any;
declare const _native: INative;

/**
* This class will take all inputs from Keyboard, Pointer, and
Expand All @@ -21,7 +21,7 @@ export class DeviceInputSystem {
public static Create(engine: Engine): IDeviceInputSystem {
// If running in Babylon Native, then defer to the native input system, which has the same public contract
if (!engine.deviceInputSystem) {
engine.deviceInputSystem = (typeof _native !== 'undefined' && _native.DeviceInputSystem) ? new NativeDeviceInputWrapper(new _native.DeviceInputSystem(engine)) : new WebDeviceInputSystem(engine);
engine.deviceInputSystem = (typeof _native !== 'undefined' && _native.DeviceInputSystem) ? new NativeDeviceInputWrapper(new _native.DeviceInputSystem()) : new WebDeviceInputSystem(engine);
}

return engine.deviceInputSystem;
Expand Down
2 changes: 2 additions & 0 deletions src/Engines/Native/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./nativeDataStream";
export * from "./validatedNativeDataStream";
90 changes: 90 additions & 0 deletions src/Engines/Native/nativeDataStream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { INative, INativeDataStream } from "./nativeInterfaces";

declare const _native: INative;

/** @hidden */
export type NativeData = Uint32Array;

/** @hidden */
export class NativeDataStream {
private readonly _uint32s: Uint32Array;
private readonly _int32s: Int32Array;
private readonly _float32s: Float32Array;
private readonly _length: number;
private _position: number;
private readonly _nativeDataStream: INativeDataStream;

// Must be multiple of 4!
private static readonly DEFAULT_BUFFER_SIZE = 65536;

constructor () {
const buffer = new ArrayBuffer(NativeDataStream.DEFAULT_BUFFER_SIZE);
this._uint32s = new Uint32Array(buffer);
this._int32s = new Int32Array(buffer);
this._float32s = new Float32Array(buffer);

this._length = NativeDataStream.DEFAULT_BUFFER_SIZE / 4;
this._position = 0;

this._nativeDataStream = new _native.NativeDataStream(() => {
this._flush();
});
}

public writeUint32(value: number): void {
this._flushIfNecessary(1);
this._uint32s[this._position++] = value;
}

public writeInt32(value: number): void {
this._flushIfNecessary(1);
this._int32s[this._position++] = value;
}

public writeFloat32(value: number): void {
this._flushIfNecessary(1);
this._float32s[this._position++] = value;
}

public writeUint32Array(values: Uint32Array): void {
this._flushIfNecessary(1 + values.length);
this._uint32s[this._position++] = values.length;
this._uint32s.set(values, this._position);
this._position += values.length;
}

public writeInt32Array(values: Int32Array): void {
this._flushIfNecessary(1 + values.length);
this._uint32s[this._position++] = values.length;
this._int32s.set(values, this._position);
this._position += values.length;
}

public writeFloat32Array(values: Float32Array): void {
this._flushIfNecessary(1 + values.length);
this._uint32s[this._position++] = values.length;
this._float32s.set(values, this._position);
this._position += values.length;
}

public writeNativeData(handle: NativeData) {
this._flushIfNecessary(handle.length);
this._uint32s.set(handle, this._position);
this._position += handle.length;
}

public writeBoolean(value: boolean) {
this.writeUint32(value ? 1 : 0);
}

private _flushIfNecessary(required: number): void {
if (this._position + required > this._length) {
this._flush();
}
}

private _flush(): void {
this._nativeDataStream.writeBuffer(this._uint32s.buffer, this._position);
this._position = 0;
}
}
251 changes: 251 additions & 0 deletions src/Engines/Native/nativeInterfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import { INativeInput } from "../../DeviceInput/Interfaces/inputInterfaces";
import { InternalTexture } from "../../Materials/Textures/internalTexture";
import { Nullable } from "../../types";
import { ICanvas, IImage } from "../ICanvas";
import { NativeData, NativeDataStream } from "./nativeDataStream";

/** @hidden */
export interface INativeEngine {
dispose(): void;

requestAnimationFrame(callback: () => void): void;

createVertexArray(): NativeData;

createIndexBuffer(bytes: ArrayBuffer, byteOffset: number, byteLength: number, is32Bits: boolean, dynamic: boolean): NativeData;
recordIndexBuffer(vertexArray: NativeData, indexBuffer: NativeData): void;
updateDynamicIndexBuffer(buffer: NativeData, bytes: ArrayBuffer, byteOffset: number, byteLength: number, startIndex: number): void;

createVertexBuffer(bytes: ArrayBuffer, byteOffset: number, byteLength: number, dynamic: boolean): NativeData;
recordVertexBuffer(vertexArray: NativeData, vertexBuffer: NativeData, location: number, byteOffset: number, byteStride: number, numElements: number, type: number, normalized: boolean): void;
updateDynamicVertexBuffer(vertexBuffer: NativeData, bytes: ArrayBuffer, byteOffset: number, byteLength: number): void;

createProgram(vertexShader: string, fragmentShader: string): any;
getUniforms(shaderProgram: any, uniformsNames: string[]): WebGLUniformLocation[];
getAttributes(shaderProgram: any, attributeNames: string[]): number[];

createTexture(): WebGLTexture;
loadTexture(texture: WebGLTexture, data: ArrayBufferView, generateMips: boolean, invertY: boolean, srgb: boolean, onSuccess: () => void, onError: () => void): void;
loadRawTexture(texture: WebGLTexture, data: ArrayBufferView, width: number, height: number, format: number, generateMips: boolean, invertY: boolean): void;
loadCubeTexture(texture: WebGLTexture, data: Array<ArrayBufferView>, generateMips: boolean, invertY: boolean, srgb: boolean, onSuccess: () => void, onError: () => void): void;
loadCubeTextureWithMips(texture: WebGLTexture, data: Array<Array<ArrayBufferView>>, invertY: boolean, srgb: boolean, onSuccess: () => void, onError: () => void): void;
getTextureWidth(texture: WebGLTexture): number;
getTextureHeight(texture: WebGLTexture): number;
copyTexture(desination: Nullable<WebGLTexture>, source: Nullable<WebGLTexture>): void;
deleteTexture(texture: Nullable<WebGLTexture>): void;

createImageBitmap(data: ArrayBufferView): ImageBitmap;
resizeImageBitmap(image: ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array;

createFrameBuffer(texture: WebGLTexture, width: number, height: number, format: number, generateStencilBuffer: boolean, generateDepthBuffer: boolean, generateMips: boolean): WebGLFramebuffer;

getRenderWidth(): number;
getRenderHeight(): number;
getHardwareScalingLevel(): number;
setHardwareScalingLevel(level: number): void;

setViewPort(x: number, y: number, width: number, height: number): void;

setCommandDataStream(dataStream: NativeDataStream): void;
submitCommands(): void;
}

/** @hidden */
interface INativeEngineConstructor {
prototype: INativeEngine;
new(): INativeEngine;

readonly PROTOCOL_VERSION: number;

readonly TEXTURE_NEAREST_NEAREST: number;
readonly TEXTURE_LINEAR_LINEAR: number;
readonly TEXTURE_LINEAR_LINEAR_MIPLINEAR: number;
readonly TEXTURE_NEAREST_NEAREST_MIPNEAREST: number;
readonly TEXTURE_NEAREST_LINEAR_MIPNEAREST: number;
readonly TEXTURE_NEAREST_LINEAR_MIPLINEAR: number;
readonly TEXTURE_NEAREST_LINEAR: number;
readonly TEXTURE_NEAREST_NEAREST_MIPLINEAR: number;
readonly TEXTURE_LINEAR_NEAREST_MIPNEAREST: number;
readonly TEXTURE_LINEAR_NEAREST_MIPLINEAR: number;
readonly TEXTURE_LINEAR_LINEAR_MIPNEAREST: number;
readonly TEXTURE_LINEAR_NEAREST: number;

readonly DEPTH_TEST_LESS: number;
readonly DEPTH_TEST_LEQUAL: number;
readonly DEPTH_TEST_EQUAL: number;
readonly DEPTH_TEST_GEQUAL: number;
readonly DEPTH_TEST_GREATER: number;
readonly DEPTH_TEST_NOTEQUAL: number;
readonly DEPTH_TEST_NEVER: number;
readonly DEPTH_TEST_ALWAYS: number;

readonly ADDRESS_MODE_WRAP: number;
readonly ADDRESS_MODE_MIRROR: number;
readonly ADDRESS_MODE_CLAMP: number;
readonly ADDRESS_MODE_BORDER: number;
readonly ADDRESS_MODE_MIRROR_ONCE: number;

readonly TEXTURE_FORMAT_RGB8: number;
readonly TEXTURE_FORMAT_RGBA8: number;
readonly TEXTURE_FORMAT_RGBA32F: number;

readonly ATTRIB_TYPE_INT8: number;
readonly ATTRIB_TYPE_UINT8: number;
readonly ATTRIB_TYPE_INT16: number;
readonly ATTRIB_TYPE_UINT16: number;
readonly ATTRIB_TYPE_FLOAT: number;

readonly ALPHA_DISABLE: number;
readonly ALPHA_ADD: number;
readonly ALPHA_COMBINE: number;
readonly ALPHA_SUBTRACT: number;
readonly ALPHA_MULTIPLY: number;
readonly ALPHA_MAXIMIZED: number;
readonly ALPHA_ONEONE: number;
readonly ALPHA_PREMULTIPLIED: number;
readonly ALPHA_PREMULTIPLIED_PORTERDUFF: number;
readonly ALPHA_INTERPOLATE: number;
readonly ALPHA_SCREENMODE: number;

readonly STENCIL_TEST_LESS: number;
readonly STENCIL_TEST_LEQUAL: number;
readonly STENCIL_TEST_EQUAL: number;
readonly STENCIL_TEST_GEQUAL: number;
readonly STENCIL_TEST_GREATER: number;
readonly STENCIL_TEST_NOTEQUAL: number;
readonly STENCIL_TEST_NEVER: number;
readonly STENCIL_TEST_ALWAYS: number;

readonly STENCIL_OP_FAIL_S_ZERO: number;
readonly STENCIL_OP_FAIL_S_KEEP: number;
readonly STENCIL_OP_FAIL_S_REPLACE: number;
readonly STENCIL_OP_FAIL_S_INCR: number;
readonly STENCIL_OP_FAIL_S_INCRSAT: number;
readonly STENCIL_OP_FAIL_S_DECR: number;
readonly STENCIL_OP_FAIL_S_DECRSAT: number;
readonly STENCIL_OP_FAIL_S_INVERT: number;

readonly STENCIL_OP_FAIL_Z_ZERO: number;
readonly STENCIL_OP_FAIL_Z_KEEP: number;
readonly STENCIL_OP_FAIL_Z_REPLACE: number;
readonly STENCIL_OP_FAIL_Z_INCR: number;
readonly STENCIL_OP_FAIL_Z_INCRSAT: number;
readonly STENCIL_OP_FAIL_Z_DECR: number;
readonly STENCIL_OP_FAIL_Z_DECRSAT: number;
readonly STENCIL_OP_FAIL_Z_INVERT: number;

readonly STENCIL_OP_PASS_Z_ZERO: number;
readonly STENCIL_OP_PASS_Z_KEEP: number;
readonly STENCIL_OP_PASS_Z_REPLACE: number;
readonly STENCIL_OP_PASS_Z_INCR: number;
readonly STENCIL_OP_PASS_Z_INCRSAT: number;
readonly STENCIL_OP_PASS_Z_DECR: number;
readonly STENCIL_OP_PASS_Z_DECRSAT: number;
readonly STENCIL_OP_PASS_Z_INVERT: number;

readonly COMMAND_DELETEVERTEXARRAY: NativeData;
readonly COMMAND_DELETEINDEXBUFFER: NativeData;
readonly COMMAND_DELETEVERTEXBUFFER: NativeData;
readonly COMMAND_SETPROGRAM: NativeData;
readonly COMMAND_SETMATRIX: NativeData;
readonly COMMAND_SETMATRIX3X3: NativeData;
readonly COMMAND_SETMATRIX2X2: NativeData;
readonly COMMAND_SETMATRICES: NativeData;
readonly COMMAND_SETINT: NativeData;
readonly COMMAND_SETINTARRAY: NativeData;
readonly COMMAND_SETINTARRAY2: NativeData;
readonly COMMAND_SETINTARRAY3: NativeData;
readonly COMMAND_SETINTARRAY4: NativeData;
readonly COMMAND_SETFLOATARRAY: NativeData;
readonly COMMAND_SETFLOATARRAY2: NativeData;
readonly COMMAND_SETFLOATARRAY3: NativeData;
readonly COMMAND_SETFLOATARRAY4: NativeData;
readonly COMMAND_SETTEXTURESAMPLING: NativeData;
readonly COMMAND_SETTEXTUREWRAPMODE: NativeData;
readonly COMMAND_SETTEXTUREANISOTROPICLEVEL: NativeData;
readonly COMMAND_SETTEXTURE: NativeData;
readonly COMMAND_BINDVERTEXARRAY: NativeData;
readonly COMMAND_SETSTATE: NativeData;
readonly COMMAND_DELETEPROGRAM: NativeData;
readonly COMMAND_SETZOFFSET: NativeData;
readonly COMMAND_SETZOFFSETUNITS: NativeData;
readonly COMMAND_SETDEPTHTEST: NativeData;
readonly COMMAND_SETDEPTHWRITE: NativeData;
readonly COMMAND_SETCOLORWRITE: NativeData;
readonly COMMAND_SETBLENDMODE: NativeData;
readonly COMMAND_SETFLOAT: NativeData;
readonly COMMAND_SETFLOAT2: NativeData;
readonly COMMAND_SETFLOAT3: NativeData;
readonly COMMAND_SETFLOAT4: NativeData;
readonly COMMAND_BINDFRAMEBUFFER: NativeData;
readonly COMMAND_UNBINDFRAMEBUFFER: NativeData;
readonly COMMAND_DELETEFRAMEBUFFER: NativeData;
readonly COMMAND_DRAWINDEXED: NativeData;
readonly COMMAND_DRAW: NativeData;
readonly COMMAND_CLEAR: NativeData;
readonly COMMAND_SETSTENCIL: NativeData;
}

/** @hidden */
export interface INativeCamera {
createVideo(constraints: MediaTrackConstraints): any;
updateVideoTexture(texture: Nullable<InternalTexture>, video: HTMLVideoElement, invertY: boolean): void;
}

/** @hidden */
interface INativeCameraConstructor {
prototype: INativeCamera;
new(): INativeCamera;
}

/** @hidden */
interface INativeCanvasConstructor {
prototype: ICanvas;
new(): ICanvas;

loadTTFAsync(fontName: string, buffer: ArrayBuffer): void;
}

/** @hidden */
interface INativeImageConstructor {
prototype: IImage;
new(): IImage;
}

/** @hidden */
interface IDeviceInputSystemConstructor {
prototype: INativeInput;
new(): INativeInput;
}

/** @hidden */
export interface INativeDataStream {
writeBuffer(buffer: ArrayBuffer, length: number): void;
}

/** @hidden */
interface INativeDataStreamConstructor {
prototype: INativeDataStream;
new(requestFlushCallback: () => void): INativeDataStream;

readonly VALIDATION_ENABLED: boolean;
readonly VALIDATION_UINT_32: number;
readonly VALIDATION_INT_32: number;
readonly VALIDATION_FLOAT_32: number;
readonly VALIDATION_UINT_32_ARRAY: number;
readonly VALIDATION_INT_32_ARRAY: number;
readonly VALIDATION_FLOAT_32_ARRAY: number;
readonly VALIDATION_NATIVE_DATA: number;
readonly VALIDATION_BOOLEAN: number;
}

/** @hidden */
export interface INative {
Engine: INativeEngineConstructor;
Camera: INativeCameraConstructor;
Canvas: INativeCanvasConstructor;
Image: INativeImageConstructor;
XMLHttpRequest: any; // TODO: how to do this?
DeviceInputSystem: IDeviceInputSystemConstructor;
NativeDataStream: INativeDataStreamConstructor;
}
Loading

0 comments on commit 4fd95f6

Please sign in to comment.