Move to IPC data version 2, includes the IMU data time in milliseconds, removes fields that the extension settings may own
This commit is contained in:
parent
6a4de14eb4
commit
a3efb03dd9
|
|
@ -5,12 +5,12 @@ uniform bool show_banner;
|
|||
uniform sampler2D uDesktopTexture;
|
||||
uniform mat4 imu_quat_data;
|
||||
uniform vec4 look_ahead_cfg;
|
||||
uniform float look_ahead_ms;
|
||||
uniform float display_zoom;
|
||||
uniform float display_north_offset;
|
||||
uniform float lens_distance_ratio;
|
||||
uniform bool sbs_enabled;
|
||||
uniform bool sbs_content;
|
||||
uniform bool sbs_mode_stretched;
|
||||
uniform bool custom_banner_enabled;
|
||||
uniform float stage_aspect_ratio;
|
||||
uniform float display_aspect_ratio;
|
||||
|
|
@ -19,7 +19,6 @@ uniform float trim_height_percent;
|
|||
uniform float half_fov_z_rads;
|
||||
uniform float half_fov_y_rads;
|
||||
uniform float screen_distance;
|
||||
uniform float frametime;
|
||||
|
||||
float look_ahead_ms_cap = 45.0;
|
||||
|
||||
|
|
@ -67,29 +66,29 @@ void PS_IMU_Transform(vec4 pos, vec2 texcoord, out vec4 color) {
|
|||
float lens_z_offset = 0.0;
|
||||
float aspect_ratio = stage_aspect_ratio;
|
||||
|
||||
if(enabled && sbs_enabled) {
|
||||
bool right_display = texcoord.x > 0.5;
|
||||
aspect_ratio /= 2;
|
||||
// if(enabled && sbs_enabled) {
|
||||
// bool right_display = texcoord.x > 0.5;
|
||||
// aspect_ratio /= 2;
|
||||
|
||||
lens_y_offset = lens_distance_ratio / 3;
|
||||
if(right_display)
|
||||
lens_y_offset = -lens_y_offset;
|
||||
if(sbs_content) {
|
||||
// source video is SBS, left-half of the screen goes to the left lens, right-half to the right lens
|
||||
if(right_display)
|
||||
texcoord_x_min = 0.5;
|
||||
else
|
||||
texcoord_x_max = 0.5;
|
||||
}
|
||||
if(!sbs_mode_stretched) {
|
||||
// if the content isn't stretched, assume it's centered in the middle 50% of the screen
|
||||
texcoord_x_min = max(0.25, texcoord_x_min);
|
||||
texcoord_x_max = min(0.75, texcoord_x_max);
|
||||
}
|
||||
// lens_y_offset = lens_distance_ratio / 3;
|
||||
// if(right_display)
|
||||
// lens_y_offset = -lens_y_offset;
|
||||
// if(sbs_content) {
|
||||
// // source video is SBS, left-half of the screen goes to the left lens, right-half to the right lens
|
||||
// if(right_display)
|
||||
// texcoord_x_min = 0.5;
|
||||
// else
|
||||
// texcoord_x_max = 0.5;
|
||||
// }
|
||||
// if(!sbs_mode_stretched) {
|
||||
// // if the content isn't stretched, assume it's centered in the middle 50% of the screen
|
||||
// texcoord_x_min = max(0.25, texcoord_x_min);
|
||||
// texcoord_x_max = min(0.75, texcoord_x_max);
|
||||
// }
|
||||
|
||||
// translate the texcoord respresenting the current lens's half of the screen to a full-screen texcoord
|
||||
texcoord.x = (texcoord.x - (right_display ? 0.5 : 0.0)) * 2;
|
||||
}
|
||||
// // translate the texcoord respresenting the current lens's half of the screen to a full-screen texcoord
|
||||
// texcoord.x = (texcoord.x - (right_display ? 0.5 : 0.0)) * 2;
|
||||
// }
|
||||
|
||||
if(!enabled || show_banner) {
|
||||
// vec2 banner_size = vec2(800.0 / ReShade::ScreenSize.x, 200.0 / ReShade::ScreenSize.y); // Assuming ScreenWidth and ScreenHeight are defined
|
||||
|
|
@ -142,8 +141,8 @@ void PS_IMU_Transform(vec4 pos, vec2 texcoord, out vec4 color) {
|
|||
float look_ahead_scanline_adjust = texcoord.y * look_ahead_cfg.z;
|
||||
|
||||
// use the 4th value of the look-ahead config to cap the look-ahead value
|
||||
float look_ahead_ms = min(min(look_ahead_cfg.x + frametime * look_ahead_cfg.y, look_ahead_cfg.w), look_ahead_ms_cap) + look_ahead_scanline_adjust;
|
||||
float look_ahead_ms_squared = pow(look_ahead_ms, 2);
|
||||
float look_ahead_ms_capped = min(min(look_ahead_ms, look_ahead_cfg.w), look_ahead_ms_cap) + look_ahead_scanline_adjust;
|
||||
float look_ahead_ms_squared = pow(look_ahead_ms_capped, 2);
|
||||
|
||||
// apply most recent velocity and acceleration to most recent position to get a predicted position
|
||||
vec3 res = applyLookAhead(rotated_vector_t0, velocity_t0, accel_t0, look_ahead_ms, look_ahead_ms_squared) -
|
||||
|
|
|
|||
|
|
@ -60,10 +60,13 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
}
|
||||
|
||||
_find_supported_monitor() {
|
||||
const target_monitor_id = this._monitor_manager.getMonitorPropertiesList()?.find(
|
||||
monitor => SUPPORTED_MONITOR_PRODUCTS.includes(monitor.product))?.index;
|
||||
if (target_monitor_id !== undefined) {
|
||||
return this._monitor_manager.getMonitors()[target_monitor_id];
|
||||
const target_monitor = this._monitor_manager.getMonitorPropertiesList()?.find(
|
||||
monitor => SUPPORTED_MONITOR_PRODUCTS.includes(monitor.product));
|
||||
if (target_monitor !== undefined) {
|
||||
return {
|
||||
monitor: this._monitor_manager.getMonitors()[target_monitor.index],
|
||||
refreshRate: target_monitor.refreshRate,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -74,10 +77,13 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
console.log('Monitors changed, disabling XR effect');
|
||||
this._effect_disable();
|
||||
}
|
||||
this._target_monitor = this._find_supported_monitor();
|
||||
const target_monitor = this._find_supported_monitor();
|
||||
|
||||
// if target_monitor isn't set, do nothing and wait for MonitorManager to call this again
|
||||
if (this._target_monitor && this._running_poller_id === undefined) {
|
||||
if (target_monitor && this._running_poller_id === undefined) {
|
||||
this._target_monitor = target_monitor.monitor;
|
||||
this._refresh_rate = target_monitor.refreshRate;
|
||||
|
||||
if (this._check_driver_running()) {
|
||||
this._effect_enable();
|
||||
} else {
|
||||
|
|
@ -118,7 +124,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
|
||||
this._xr_effect = new XREffect({
|
||||
target_monitor: this._target_monitor,
|
||||
target_framerate: 60
|
||||
target_framerate: this._refresh_rate ?? 60
|
||||
});
|
||||
|
||||
this._overlay.add_effect_with_name('xr-desktop', this._xr_effect);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ export function dataViewUint(dataView, dataViewInfo) {
|
|||
return dataView.getUint32(dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX], true);
|
||||
}
|
||||
|
||||
export function dataViewBigUint(dataView, dataViewInfo) {
|
||||
return Number(dataView.getBigUint64(dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX], true));
|
||||
}
|
||||
|
||||
export function dataViewUintArray(dataView, dataViewInfo) {
|
||||
const uintArray = []
|
||||
let offset = dataViewInfo[DATA_VIEW_INFO_OFFSET_INDEX];
|
||||
|
|
|
|||
|
|
@ -71,7 +71,11 @@ export function getMonitorConfig(displayConfigProxy, callback) {
|
|||
const vendor = props['vendor'].get_string()[0];
|
||||
const product = props['product'].get_string()[0];
|
||||
const serial = props['serial'].get_string()[0];
|
||||
monitors.push([displayName, connectorName, vendor, product, serial]);
|
||||
|
||||
// grab refresh rate from the modes array
|
||||
const refreshRate = result[3][i][4];
|
||||
|
||||
monitors.push([displayName, connectorName, vendor, product, serial, refreshRate]);
|
||||
}
|
||||
callback(monitors, null);
|
||||
}
|
||||
|
|
@ -139,7 +143,7 @@ export default class MonitorManager {
|
|||
}
|
||||
const monitorProperties = [];
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
const [monitorName, connectorName, vendor, product, serial] = result[i];
|
||||
const [monitorName, connectorName, vendor, product, serial, refreshRate] = result[i];
|
||||
const monitorIndex = this._backendManager.get_monitor_for_connector(connectorName);
|
||||
console.log(`\n\nFound monitor ${monitorName}, vendor ${vendor}, product ${product}, serial ${serial}, connector ${connectorName}, index ${monitorIndex}\n\n`);
|
||||
if (monitorIndex >= 0) {
|
||||
|
|
@ -149,7 +153,8 @@ export default class MonitorManager {
|
|||
vendor: vendor,
|
||||
product: product,
|
||||
serial: serial,
|
||||
connector: connectorName
|
||||
connector: connectorName,
|
||||
refreshRate: refreshRate
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
export function getEpochSec() {
|
||||
return Math.floor(Date.now() / 1000);
|
||||
return toSec(Date.now());
|
||||
}
|
||||
|
||||
export function toSec(milliseconds) {
|
||||
return Math.floor(milliseconds / 1000);
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import Globals from './globals.js';
|
|||
import {
|
||||
dataViewEnd,
|
||||
dataViewUint8,
|
||||
dataViewUint,
|
||||
dataViewBigUint,
|
||||
dataViewUintArray,
|
||||
dataViewFloat,
|
||||
dataViewFloatArray,
|
||||
|
|
@ -20,28 +20,24 @@ import {
|
|||
} from "./ipc.js";
|
||||
import { degreeToRadian } from "./math.js";
|
||||
import { getShaderSource } from "./shader.js";
|
||||
import { getEpochSec } from "./time.js";
|
||||
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 = 1;
|
||||
const DATA_LAYOUT_VERSION = 2;
|
||||
|
||||
// DataView info: [offset, size, count]
|
||||
const VERSION = [0, UINT8_SIZE, 1];
|
||||
const ENABLED = [dataViewEnd(VERSION), BOOL_SIZE, 1];
|
||||
const EPOCH_SEC = [dataViewEnd(ENABLED), UINT_SIZE, 1];
|
||||
const LOOK_AHEAD_CFG = [dataViewEnd(EPOCH_SEC), FLOAT_SIZE, 4];
|
||||
const LOOK_AHEAD_CFG = [dataViewEnd(ENABLED), FLOAT_SIZE, 4];
|
||||
const DISPLAY_RES = [dataViewEnd(LOOK_AHEAD_CFG), UINT_SIZE, 2];
|
||||
const DISPLAY_FOV = [dataViewEnd(DISPLAY_RES), FLOAT_SIZE, 1];
|
||||
const DISPLAY_ZOOM = [dataViewEnd(DISPLAY_FOV), FLOAT_SIZE, 1];
|
||||
const DISPLAY_NORTH_OFFSET = [dataViewEnd(DISPLAY_ZOOM), FLOAT_SIZE, 1];
|
||||
const LENS_DISTANCE_RATIO = [dataViewEnd(DISPLAY_NORTH_OFFSET), FLOAT_SIZE, 1];
|
||||
const LENS_DISTANCE_RATIO = [dataViewEnd(DISPLAY_FOV), FLOAT_SIZE, 1];
|
||||
const SBS_ENABLED = [dataViewEnd(LENS_DISTANCE_RATIO), BOOL_SIZE, 1];
|
||||
const SBS_CONTENT = [dataViewEnd(SBS_ENABLED), BOOL_SIZE, 1];
|
||||
const SBS_MODE_STRETCHED = [dataViewEnd(SBS_CONTENT), BOOL_SIZE, 1];
|
||||
const CUSTOM_BANNER_ENABLED = [dataViewEnd(SBS_MODE_STRETCHED), BOOL_SIZE, 1];
|
||||
const IMU_QUAT_DATA = [dataViewEnd(CUSTOM_BANNER_ENABLED), FLOAT_SIZE, 16];
|
||||
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);
|
||||
|
||||
// cached after first retrieval
|
||||
|
|
@ -50,6 +46,7 @@ const shaderUniformLocations = {
|
|||
'show_banner': null,
|
||||
'imu_quat_data': null,
|
||||
'look_ahead_cfg': null,
|
||||
'look_ahead_ms': null,
|
||||
'stage_aspect_ratio': null,
|
||||
'display_aspect_ratio': null,
|
||||
'trim_width_percent': null,
|
||||
|
|
@ -59,12 +56,10 @@ const shaderUniformLocations = {
|
|||
'lens_distance_ratio': null,
|
||||
'sbs_enabled': null,
|
||||
'sbs_content': null,
|
||||
'sbs_mode_stretched': null,
|
||||
'custom_banner_enabled': null,
|
||||
'half_fov_z_rads': null,
|
||||
'half_fov_y_rads': null,
|
||||
'screen_distance': null,
|
||||
'frametime': null
|
||||
'screen_distance': null
|
||||
};
|
||||
|
||||
function transferUniformBoolean(effect, location, dataView, dataViewInfo) {
|
||||
|
|
@ -103,14 +98,25 @@ function setUniformMatrix(effect, locationName, components, dataView, dataViewIn
|
|||
effect.set_uniform_matrix(shaderUniformLocations[locationName], true, components, floatArray);
|
||||
}
|
||||
|
||||
function lookAheadMS(dataView) {
|
||||
const lookAheadCfg = dataViewFloatArray(dataView, LOOK_AHEAD_CFG);
|
||||
const imuDateMS = dataViewBigUint(dataView, EPOCH_MS);
|
||||
|
||||
// how stale the imu data is
|
||||
const dataAge = Date.now() - imuDateMS;
|
||||
|
||||
return lookAheadCfg[0] + dataAge;
|
||||
}
|
||||
|
||||
// most uniforms don't change frequently, this function should be called periodically
|
||||
function setIntermittentUniformVariables() {
|
||||
const dataView = this._dataView;
|
||||
|
||||
if (dataView.byteLength === DATA_VIEW_LENGTH) {
|
||||
const version = dataViewUint8(dataView, VERSION);
|
||||
const date = dataViewUint(dataView, EPOCH_SEC);
|
||||
const validKeepalive = Math.abs(getEpochSec() - date) < 5;
|
||||
const imuDateMS = dataViewBigUint(dataView, EPOCH_MS);
|
||||
const currentDateMS = Date.now();
|
||||
const validKeepalive = Math.abs(toSec(currentDateMS) - toSec(imuDateMS)) < 5;
|
||||
const imuData = dataViewFloatArray(dataView, IMU_QUAT_DATA);
|
||||
const imuResetState = 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 && !imuResetState;
|
||||
|
|
@ -135,12 +141,8 @@ function setIntermittentUniformVariables() {
|
|||
|
||||
// all these values are transferred directly, unmodified from the driver
|
||||
transferUniformFloat(this, 'look_ahead_cfg', dataView, LOOK_AHEAD_CFG);
|
||||
transferUniformFloat(this, 'display_zoom', dataView, DISPLAY_ZOOM);
|
||||
transferUniformFloat(this, 'display_north_offset', dataView, DISPLAY_NORTH_OFFSET);
|
||||
transferUniformFloat(this, 'lens_distance_ratio', dataView, LENS_DISTANCE_RATIO);
|
||||
transferUniformBoolean(this, 'sbs_enabled', dataView, SBS_ENABLED);
|
||||
transferUniformBoolean(this, 'sbs_content', dataView, SBS_CONTENT);
|
||||
transferUniformBoolean(this, 'sbs_mode_stretched', dataView, SBS_MODE_STRETCHED);
|
||||
transferUniformBoolean(this, 'custom_banner_enabled', dataView, CUSTOM_BANNER_ENABLED);
|
||||
|
||||
// computed values with no dataViewInfo, so we set these manually
|
||||
|
|
@ -152,7 +154,11 @@ function setIntermittentUniformVariables() {
|
|||
setSingleFloat(this, 'half_fov_z_rads', halfFovZRads);
|
||||
setSingleFloat(this, 'half_fov_y_rads', halfFovYRads);
|
||||
setSingleFloat(this, 'screen_distance', screenDistance);
|
||||
setSingleFloat(this, 'frametime', this._frametime);
|
||||
|
||||
// TOOD - drive from settings
|
||||
setSingleFloat(this, 'display_zoom', 1.0);
|
||||
setSingleFloat(this, 'display_north_offset', 1.0);
|
||||
setSingleFloat(this, 'sbs_content', 0.0);
|
||||
}
|
||||
setSingleFloat(this, 'enabled', enabled ? 1.0 : 0.0);
|
||||
} else if (dataView.byteLength !== 0) {
|
||||
|
|
@ -217,6 +223,7 @@ export const XREffect = GObject.registerClass({
|
|||
}
|
||||
|
||||
if (this._dataView.byteLength === DATA_VIEW_LENGTH) {
|
||||
setSingleFloat(this, 'look_ahead_ms', lookAheadMS(this._dataView));
|
||||
setUniformMatrix(this, 'imu_quat_data', 4, this._dataView, IMU_QUAT_DATA);
|
||||
} else if (this._dataView.byteLength !== 0) {
|
||||
console.error(`Invalid dataView.byteLength: ${this._dataView.byteLength} !== ${DATA_VIEW_LENGTH}`)
|
||||
|
|
|
|||
Loading…
Reference in New Issue