Skip to content

Commit 5f0c5e1

Browse files
author
Avaer Kazmer
authored
Merge pull request #983 from exokitxr/retina
Real devicePixelRatio
2 parents 0a070e6 + 49c8d02 commit 5f0c5e1

File tree

7 files changed

+99
-42
lines changed

7 files changed

+99
-42
lines changed

deps/exokit-bindings/egl/src/egl.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ NAN_METHOD(GetFramebufferSize) {
151151
info.GetReturnValue().Set(result);
152152
}
153153

154+
NAN_METHOD(GetDevicePixelRatio) {
155+
info.GetReturnValue().Set(JS_NUM(1));
156+
}
157+
154158
EGLContext GetGLContext(NATIVEwindow *window) {
155159
return window->context;
156160
}
@@ -369,6 +373,7 @@ Local<Object> makeWindow() {
369373
Nan::SetMethod(target, "setWindowPos", egl::SetWindowPos);
370374
Nan::SetMethod(target, "getWindowPos", egl::GetWindowPos);
371375
Nan::SetMethod(target, "getFramebufferSize", egl::GetFramebufferSize);
376+
Nan::SetMethod(target, "getDevicePixelRatio", egl::GetDevicePixelRatio);
372377
Nan::SetMethod(target, "iconifyWindow", egl::IconifyWindow);
373378
Nan::SetMethod(target, "restoreWindow", egl::RestoreWindow);
374379
Nan::SetMethod(target, "setEventHandler", egl::SetEventHandler);

deps/exokit-bindings/glfw/src/glfw.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,19 @@ NAN_METHOD(GetFramebufferSize) {
968968
info.GetReturnValue().Set(result);
969969
}
970970

971+
double GetDevicePixelRatio() {
972+
NATIVEwindow *window = CreateNativeWindow(100, 100, false, nullptr);
973+
int width, height;
974+
glfwGetFramebufferSize(window, &width, &height);
975+
glfwDestroyWindow(window);
976+
return (double)width/100.0;
977+
}
978+
979+
NAN_METHOD(GetDevicePixelRatio) {
980+
double devicePixelRatio = GetDevicePixelRatio();
981+
info.GetReturnValue().Set(JS_NUM(devicePixelRatio));
982+
}
983+
971984
NATIVEwindow *GetGLContext(NATIVEwindow *window) {
972985
return window;
973986
}
@@ -1748,6 +1761,7 @@ Local<Object> makeWindow() {
17481761
Nan::SetMethod(target, "setWindowPos", glfw::SetWindowPos);
17491762
Nan::SetMethod(target, "getWindowPos", glfw::GetWindowPos);
17501763
Nan::SetMethod(target, "getFramebufferSize", glfw::GetFramebufferSize);
1764+
Nan::SetMethod(target, "getDevicePixelRatio", glfw::GetDevicePixelRatio);
17511765
Nan::SetMethod(target, "iconifyWindow", glfw::IconifyWindow);
17521766
Nan::SetMethod(target, "restoreWindow", glfw::RestoreWindow);
17531767
Nan::SetMethod(target, "setEventHandler", glfw::SetEventHandler);

examples/fakeDisplay.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,31 @@ window._makeFakeDisplay = () => {
1010
exclusive: true,
1111
});
1212

13-
fakeDisplay.layers = layers;
13+
await new Promise((accept, reject) => {
14+
session.requestAnimationFrame((timestamp, frame) => {
15+
fakeDisplay.layers = layers;
1416

15-
renderer.vr.enabled = true;
16-
renderer.vr.setDevice(fakeDisplay);
17-
renderer.vr.setSession(session, {
18-
frameOfReferenceType: 'stage',
17+
renderer.vr.enabled = true;
18+
renderer.vr.setDevice(fakeDisplay);
19+
renderer.vr.setSession(session, {
20+
frameOfReferenceType: 'stage',
21+
});
22+
renderer.vr.setAnimationLoop(animate);
23+
24+
const viewport = session.baseLayer.getViewport(frame.views[0]);
25+
const height = viewport.height;
26+
const fullWidth = (() => {
27+
let result = 0;
28+
for (let i = 0; i < frame.views.length; i++) {
29+
result += session.baseLayer.getViewport(frame.views[i]).width;
30+
}
31+
return result;
32+
})();
33+
renderer.setSize(fullWidth, height);
34+
35+
accept();
36+
});
1937
});
20-
renderer.vr.setAnimationLoop(animate);
2138
} else {
2239
await fakeDisplay.requestPresent([
2340
{
@@ -30,6 +47,9 @@ window._makeFakeDisplay = () => {
3047
renderer.vr.enabled = true;
3148
renderer.vr.setDevice(fakeDisplay);
3249
renderer.vr.setAnimationLoop(animate);
50+
51+
const {renderWidth: width, renderHeight: height} = display.getEyeParameters('left');
52+
renderer.setSize(width * 2, height);
3353
}
3454

3555
const context = renderer.getContext();

examples/realitytabs.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@
556556
// camera.position.z = 1;
557557

558558
const renderer = new THREE.WebGLRenderer( { antialias: true } );
559-
renderer.setPixelRatio( window.devicePixelRatio );
559+
// renderer.setPixelRatio( window.devicePixelRatio );
560560
renderer.setSize( window.innerWidth, window.innerHeight );
561561
document.body.appendChild(renderer.domElement);
562562

src/VR.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ class FakeVRDisplay extends VRDisplay {
381381

382382
requestPresent(layers) {
383383
return Promise.resolve().then(() => {
384-
GlobalContext.xrState.renderWidth[0] = this.window.innerWidth * this.window.devicePixelRatio / 2;
385-
GlobalContext.xrState.renderHeight[0] = this.window.innerHeight * this.window.devicePixelRatio;
384+
GlobalContext.xrState.renderWidth[0] = this.window.innerWidth / 2;
385+
GlobalContext.xrState.renderHeight[0] = this.window.innerHeight;
386386

387387
if (this.onrequestpresent) {
388388
this.onrequestpresent(layers);
@@ -411,8 +411,8 @@ class FakeVRDisplay extends VRDisplay {
411411
requestSession({exclusive = true} = {}) {
412412
const self = this;
413413

414-
GlobalContext.xrState.renderWidth[0] = this.window.innerWidth * this.window.devicePixelRatio / 2;
415-
GlobalContext.xrState.renderHeight[0] = this.window.innerHeight * this.window.devicePixelRatio;
414+
GlobalContext.xrState.renderWidth[0] = this.window.innerWidth / 2;
415+
GlobalContext.xrState.renderHeight[0] = this.window.innerHeight;
416416

417417
const session = {
418418
addEventListener(e, fn) {

src/Window.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,15 @@ const _makeWindow = (options = {}, parent = null, top = null) => {
426426

427427
window.innerWidth = defaultCanvasSize[0];
428428
window.innerHeight = defaultCanvasSize[1];
429-
window.devicePixelRatio = 1;
429+
Object.defineProperty(window, 'devicePixelRatio', {
430+
get() {
431+
if (!GlobalContext.xrState.devicePixelRatio[0]) {
432+
GlobalContext.xrState.devicePixelRatio[0] = nativeWindow.getDevicePixelRatio();
433+
}
434+
return GlobalContext.xrState.devicePixelRatio[0];
435+
},
436+
set(devicePixelRatio) {},
437+
});
430438
window.document = null;
431439
const location = new Location(options.url);
432440
Object.defineProperty(window, 'location', {

src/index.js

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -175,31 +175,34 @@ nativeBindings.nativeGl.onconstruct = (gl, canvas) => {
175175
gl.setWindowHandle(windowHandle);
176176
gl.setDefaultVao(vao);
177177

178-
const nativeWindowSize = nativeWindow.getFramebufferSize(windowHandle);
178+
/* const nativeWindowSize = nativeWindow.getFramebufferSize(windowHandle);
179179
const nativeWindowHeight = nativeWindowSize.height;
180180
const nativeWindowWidth = nativeWindowSize.width;
181181
182-
// Calculate devicePixelRatio.
183-
window.devicePixelRatio = nativeWindowWidth / canvasWidth;
184-
185182
// Tell DOM how large the window is.
186-
window.innerHeight = nativeWindowHeight / window.devicePixelRatio;
187-
window.innerWidth = nativeWindowWidth / window.devicePixelRatio;
183+
window.innerHeight = nativeWindowSize.height;
184+
window.innerWidth = nativeWindowSize.width; */
188185

189186
const title = `Exokit ${version}`;
190187
nativeWindow.setWindowTitle(windowHandle, title);
191188

189+
const [fbo, tex, depthTex, msFbo, msTex, msDepthTex] = nativeWindow.createRenderTarget(gl, canvasWidth, canvasHeight, sharedColorTexture, sharedDepthStencilTexture, sharedMsColorTexture, sharedMsDepthStencilTexture);
190+
gl.setDefaultFramebuffer(msFbo);
191+
gl.framebuffer = {
192+
msFbo,
193+
msTex,
194+
msDepthTex,
195+
fbo,
196+
tex,
197+
depthTex,
198+
};
199+
gl.resize = (width, height) => {
200+
nativeWindow.setCurrentWindowContext(windowHandle);
201+
nativeWindow.resizeRenderTarget(gl, width, height, fbo, tex, depthTex, msFbo, msTex, msDepthTex);
202+
};
203+
192204
const {hidden} = document;
193205
if (hidden) {
194-
const [fbo, tex, depthTex, msFbo, msTex, msDepthTex] = nativeWindow.createRenderTarget(gl, canvasWidth, canvasHeight, sharedColorTexture, sharedDepthStencilTexture, sharedMsColorTexture, sharedMsDepthStencilTexture);
195-
196-
gl.setDefaultFramebuffer(msFbo);
197-
198-
gl.resize = (width, height) => {
199-
nativeWindow.setCurrentWindowContext(windowHandle);
200-
nativeWindow.resizeRenderTarget(gl, width, height, fbo, tex, depthTex, msFbo, msTex, msDepthTex);
201-
};
202-
203206
// TODO: handle multiple child canvases
204207
document.framebuffer = {
205208
canvas,
@@ -210,11 +213,6 @@ nativeBindings.nativeGl.onconstruct = (gl, canvas) => {
210213
tex,
211214
depthTex,
212215
};
213-
} else {
214-
gl.resize = (width, height) => {
215-
nativeWindow.setCurrentWindowContext(windowHandle);
216-
nativeWindow.resizeRenderTarget(gl, width, height, sharedFramebuffer, sharedColorTexture, sharedDepthStencilTexture, sharedMsFramebuffer, sharedMsColorTexture, sharedMsDepthStencilTexture);
217-
};
218216
}
219217

220218
const ondomchange = () => {
@@ -477,6 +475,7 @@ class XRState {
477475
}
478476
return result;
479477
})();
478+
this.devicePixelRatio = _makeTypedArray(Uint32Array, 1);
480479
}
481480
}
482481
const xrState = GlobalContext.xrState = new XRState();
@@ -1170,13 +1169,13 @@ nativeBindings.nativeWindow.setEventHandler((type, data) => {
11701169
break;
11711170
}
11721171
case 'framebufferResize': {
1173-
const {width, height} = data;
1172+
/* const {width, height} = data;
11741173
innerWidth = width;
11751174
innerHeight = height;
11761175
11771176
window.innerWidth = innerWidth / window.devicePixelRatio;
11781177
window.innerHeight = innerHeight / window.devicePixelRatio;
1179-
window.dispatchEvent(new window.Event('resize'));
1178+
window.dispatchEvent(new window.Event('resize')); */
11801179
break;
11811180
}
11821181
case 'keydown': {
@@ -1385,7 +1384,8 @@ const _startRenderLoop = () => {
13851384

13861385
const width = vrPresentState.glContext.canvas.width * (args.blit ? 0.5 : 1);
13871386
const height = vrPresentState.glContext.canvas.height;
1388-
nativeWindow.blitFrameBuffer(context, vrPresentState.msFbo, 0, width, height, width, height, true, false, false);
1387+
const {width: dWidth, height: dHeight} = nativeWindow.getFramebufferSize(windowHandle);
1388+
nativeWindow.blitFrameBuffer(context, vrPresentState.msFbo, 0, width, height, dWidth, dHeight, true, false, false);
13891389
} else if (vrPresentState.glContext === context && vrPresentState.system && vrPresentState.hasPose) {
13901390
if (vrPresentState.layers.length > 0) {
13911391
const {openVRDisplay} = window[symbols.mrDisplaysSymbol];
@@ -1400,7 +1400,8 @@ const _startRenderLoop = () => {
14001400

14011401
const width = vrPresentState.glContext.canvas.width * (args.blit ? 0.5 : 1);
14021402
const height = vrPresentState.glContext.canvas.height;
1403-
nativeWindow.blitFrameBuffer(context, vrPresentState.msFbo, 0, width, height, width, height, true, false, false);
1403+
const {width: dWidth, height: dHeight} = nativeWindow.getFramebufferSize(windowHandle);
1404+
nativeWindow.blitFrameBuffer(context, vrPresentState.fbo, 0, width, height, dWidth, dHeight, true, false, false);
14041405
} else if (oculusMobileVrPresentState.glContext === context && oculusMobileVrPresentState.hasPose) {
14051406
if (oculusMobileVrPresentState.layers.length > 0) {
14061407
const {oculusMobileVrDisplay} = window[symbols.mrDisplaysSymbol];
@@ -1423,10 +1424,19 @@ const _startRenderLoop = () => {
14231424

14241425
mlPresentState.mlContext.SubmitFrame(mlPresentState.mlTex, mlPresentState.mlGlContext.canvas.width, mlPresentState.mlGlContext.canvas.height);
14251426
mlPresentState.mlHasPose = false;
1426-
} else if (fakePresentState.layers.length > 0) {
1427-
const {fakeVrDisplay} = window[symbols.mrDisplaysSymbol];
1428-
_decorateModelViewProjections(fakePresentState.layers, fakeVrDisplay, 1);
1429-
nativeWindow.composeLayers(context, 0, fakePresentState.layers);
1427+
} else {
1428+
if (fakePresentState.layers.length > 0) {
1429+
const {fakeVrDisplay} = window[symbols.mrDisplaysSymbol];
1430+
_decorateModelViewProjections(fakePresentState.layers, fakeVrDisplay, 1);
1431+
nativeWindow.composeLayers(context, context.framebuffer.fbo, fakePresentState.layers);
1432+
} else {
1433+
nativeWindow.blitFrameBuffer(context, context.framebuffer.msFbo, context.framebuffer.fbo, context.canvas.width, context.canvas.height, context.canvas.width, context.canvas.height, true, false, false);
1434+
}
1435+
1436+
const width = context.canvas.width * (args.blit ? 0.5 : 1);
1437+
const height = context.canvas.height;
1438+
const {width: dWidth, height: dHeight} = nativeWindow.getFramebufferSize(windowHandle);
1439+
nativeWindow.blitFrameBuffer(context, context.framebuffer.fbo, 0, width, height, dWidth, dHeight, true, false, false);
14301440
}
14311441
}
14321442

@@ -2106,8 +2116,8 @@ const _startRenderLoop = () => {
21062116
let currentRenderLoop = _startRenderLoop();
21072117

21082118
const _bindWindow = (window, newWindowCb) => {
2109-
window.innerWidth = innerWidth;
2110-
window.innerHeight = innerHeight;
2119+
// window.innerWidth = innerWidth;
2120+
// window.innerHeight = innerHeight;
21112121

21122122
window.on('navigate', newWindowCb);
21132123
window.document.on('paste', e => {

0 commit comments

Comments
 (0)