Add parity byte checking

This commit is contained in:
wheaney 2024-06-14 13:51:28 -07:00
parent cddb2e051e
commit bfcf0b497f
4 changed files with 57 additions and 15 deletions

1
.gitmodules vendored
View File

@ -5,6 +5,7 @@
[submodule "modules/XRLinuxDriver"]
path = modules/XRLinuxDriver
url = https://github.com/wheaney/XRLinuxDriver.git
branch = breezy_sbs
[submodule "modules/sombrero"]
path = modules/sombrero
url = https://github.com/wheaney/sombrero.git

View File

@ -24,7 +24,7 @@ export function dataViewBigUint(dataView, dataViewInfo) {
return Number(dataView.getBigUint64(dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX], true));
}
export function dataViewUintArray(dataView, dataViewInfo) {
export function dataViewUint32Array(dataView, dataViewInfo) {
const uintArray = []
let offset = dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX];
for (let i = 0; i < dataViewInfo[DATA_VIEW_INFO_COUNT_INDEX]; i++) {
@ -34,6 +34,16 @@ export function dataViewUintArray(dataView, dataViewInfo) {
return uintArray;
}
export function dataViewUint8Array(dataView, dataViewInfo) {
const uintArray = []
let offset = dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX];
for (let i = 0; i < dataViewInfo[DATA_VIEW_INFO_SIZE_INDEX] * dataViewInfo[DATA_VIEW_INFO_COUNT_INDEX]; i++) {
uintArray.push(dataView.getUint8(offset));
offset += UINT8_SIZE;
}
return uintArray;
}
export function dataViewFloat(dataView, dataViewInfo) {
return dataView.getFloat32(dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX], true);
}

View File

@ -11,7 +11,8 @@ import {
dataViewEnd,
dataViewUint8,
dataViewBigUint,
dataViewUintArray,
dataViewUint32Array,
dataViewUint8Array,
dataViewFloat,
dataViewFloatArray,
BOOL_SIZE,
@ -28,7 +29,7 @@ import { toSec } from "./time.js";
export const IPC_FILE_PATH = "/dev/shm/breezy_desktop_imu";
// the driver should be using the same data layout version
const DATA_LAYOUT_VERSION = 2;
const DATA_LAYOUT_VERSION = 3;
// DataView info: [offset, size, count]
const VERSION = [0, UINT8_SIZE, 1];
@ -41,7 +42,8 @@ const SBS_ENABLED = [dataViewEnd(LENS_DISTANCE_RATIO), BOOL_SIZE, 1];
const CUSTOM_BANNER_ENABLED = [dataViewEnd(SBS_ENABLED), BOOL_SIZE, 1];
const EPOCH_MS = [dataViewEnd(CUSTOM_BANNER_ENABLED), UINT_SIZE, 2];
const IMU_QUAT_DATA = [dataViewEnd(EPOCH_MS), FLOAT_SIZE, 16];
const DATA_VIEW_LENGTH = dataViewEnd(IMU_QUAT_DATA);
const IMU_PARITY_BYTE = [dataViewEnd(IMU_QUAT_DATA), UINT8_SIZE, 1];
const DATA_VIEW_LENGTH = dataViewEnd(IMU_PARITY_BYTE);
// cached after first retrieval
const shaderUniformLocations = {
@ -119,7 +121,7 @@ function setIntermittentUniformVariables() {
const imuData = dataViewFloatArray(dataView, IMU_QUAT_DATA);
const imuResetState = validKeepalive && imuData[0] === 0.0 && imuData[1] === 0.0 && imuData[2] === 0.0 && imuData[3] === 1.0;
const enabled = dataViewUint8(dataView, ENABLED) !== 0 && version === DATA_LAYOUT_VERSION && validKeepalive;
const displayRes = dataViewUintArray(dataView, DISPLAY_RES);
const displayRes = dataViewUint32Array(dataView, DISPLAY_RES);
if (enabled) {
const displayFov = dataViewFloat(dataView, DISPLAY_FOV);
@ -166,6 +168,20 @@ function setIntermittentUniformVariables() {
}
}
function checkParityByte(dataView) {
const parityByte = dataViewUint8(dataView, IMU_PARITY_BYTE);
let parity = 0;
const epochUint8 = dataViewUint8Array(dataView, EPOCH_MS);
const imuDataUint8 = dataViewUint8Array(dataView, IMU_QUAT_DATA);
for (let i = 0; i < epochUint8.length; i++) {
parity ^= epochUint8[i];
}
for (let i = 0; i < imuDataUint8.length; i++) {
parity ^= imuDataUint8[i];
}
return parityByte === parity;
}
export const XREffect = GObject.registerClass({
Properties: {
'target-monitor': GObject.ParamSpec.jsobject(
@ -283,9 +299,9 @@ export const XREffect = GObject.registerClass({
var frametime = this._frametime;
var calibratingImage = this.calibratingImage;
var customBannerImage = this.customBannerImage;
const data = Globals.ipc_file.load_contents(null);
let data = Globals.ipc_file.load_contents(null);
if (data[0]) {
const buffer = new Uint8Array(data[1]).buffer;
let buffer = new Uint8Array(data[1]).buffer;
this._dataView = new DataView(buffer);
if (!this._initialized) {
this.set_uniform_float(this.get_uniform_location('uDesktopTexture'), 1, [0]);
@ -314,13 +330,28 @@ export const XREffect = GObject.registerClass({
this._initialized = true;
}
if (this._dataView.byteLength === DATA_VIEW_LENGTH) {
setSingleFloat(this, 'display_north_offset', this.display_distance);
setSingleFloat(this, 'look_ahead_ms', lookAheadMS(this._dataView));
setUniformMatrix(this, 'imu_quat_data', 4, this._dataView, IMU_QUAT_DATA);
setSingleFloat(this, 'display_size', this.widescreen_display_size);
} else if (this._dataView.byteLength !== 0) {
Globals.logger.log(`ERROR: Invalid dataView.byteLength: ${this._dataView.byteLength} !== ${DATA_VIEW_LENGTH}`)
let success = false;
let attempts = 0;
while (!success && attempts < 2) {
if (this._dataView.byteLength === DATA_VIEW_LENGTH) {
if (checkParityByte(this._dataView)) {
setSingleFloat(this, 'display_north_offset', this.display_distance);
setSingleFloat(this, 'look_ahead_ms', lookAheadMS(this._dataView));
setUniformMatrix(this, 'imu_quat_data', 4, this._dataView, IMU_QUAT_DATA);
setSingleFloat(this, 'display_size', this.widescreen_display_size);
success = true;
}
} else if (this._dataView.byteLength !== 0) {
Globals.logger.log(`ERROR: Invalid dataView.byteLength: ${this._dataView.byteLength} !== ${DATA_VIEW_LENGTH}`)
}
if (!success && ++attempts < 3) {
data = Globals.ipc_file.load_contents(null);
if (data[0]) {
buffer = new Uint8Array(data[1]).buffer;
this._dataView = new DataView(buffer);
}
}
}
// improves sampling quality for smooth text and edges

@ -1 +1 @@
Subproject commit f45b8fbaa7ef0b3f824a3452a91dc74bffb6ea38
Subproject commit 29d73864d1dc531143ffb7211592b1f803980758