Skip to content

Commit

Permalink
Merge pull request #13320 from carolhmj/fixMultiCanvasRenderOrder
Browse files Browse the repository at this point in the history
When rendering in a multi-canvas setup, always render the input view …
  • Loading branch information
sebavan authored Dec 7, 2022
2 parents d09fdab + 9ec1685 commit 7308fab
Showing 1 changed file with 77 additions and 49 deletions.
126 changes: 77 additions & 49 deletions packages/dev/core/src/Engines/Extensions/engine.views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ declare module "../../Engines/engine" {
* @returns the current engine
*/
unRegisterView(canvas: HTMLCanvasElement): Engine;

/**
* @internal
*/
_renderViewStep(view: EngineView): boolean;
}
}

Expand Down Expand Up @@ -156,6 +161,69 @@ Engine.prototype.unRegisterView = function (canvas: HTMLCanvasElement): Engine {
return this;
};

Engine.prototype._renderViewStep = function (view: EngineView): boolean {
const canvas = view.target;
const context = canvas.getContext("2d");
if (!context) {
return true;
}
const parent = this.getRenderingCanvas()!;

_onBeforeViewRenderObservable.notifyObservers(view);
const camera = view.camera;
let previewCamera: Nullable<Camera> = null;
let scene: Nullable<Scene> = null;
if (camera) {
scene = camera.getScene();

if (!scene || (scene.activeCameras && scene.activeCameras.length)) {
return true;
}

this.activeView = view;

previewCamera = scene.activeCamera;
scene.activeCamera = camera;
}

if (view.customResize) {
view.customResize(canvas);
} else {
// Set sizes
const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);
const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);

const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;
if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {
canvas.width = width;
canvas.height = height;
this.setSize(width, height);
}
}

if (!parent.width || !parent.height) {
return false;
}

// Render the frame
this._renderFrame();

this.flushFramebuffer();

// Copy to target
if (view.clearBeforeCopy) {
context.clearRect(0, 0, parent.width, parent.height);
}
context.drawImage(parent, 0, 0);

// Restore
if (previewCamera && scene) {
scene.activeCamera = previewCamera;
}
_onAfterViewRenderObservable.notifyObservers(view);
return true;
};

Engine.prototype._renderViews = function () {
if (!this.views || this.views.length === 0) {
return false;
Expand All @@ -167,67 +235,27 @@ Engine.prototype._renderViews = function () {
return false;
}

let inputElementView;
for (const view of this.views) {
if (!view.enabled) {
continue;
}
const canvas = view.target;
const context = canvas.getContext("2d");
if (!context) {
// Always render the view correspondent to the inputElement for last
if (canvas === this.inputElement) {
inputElementView = view;
continue;
}
_onBeforeViewRenderObservable.notifyObservers(view);
const camera = view.camera;
let previewCamera: Nullable<Camera> = null;
let scene: Nullable<Scene> = null;
if (camera) {
scene = camera.getScene();

if (scene.activeCameras && scene.activeCameras.length) {
continue;
}

this.activeView = view;

previewCamera = scene.activeCamera;
scene.activeCamera = camera;
}

if (view.customResize) {
view.customResize(canvas);
} else {
// Set sizes
const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);
const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);

const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;
if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {
canvas.width = width;
canvas.height = height;
this.setSize(width, height);
}
}

if (!parent.width || !parent.height) {
if (!this._renderViewStep(view)) {
return false;
}
}

// Render the frame
this._renderFrame();

this.flushFramebuffer();

// Copy to target
if (view.clearBeforeCopy) {
context.clearRect(0, 0, parent.width, parent.height);
}
context.drawImage(parent, 0, 0);

// Restore
if (previewCamera && scene) {
scene.activeCamera = previewCamera;
if (inputElementView) {
if (!this._renderViewStep(inputElementView)) {
return false;
}
_onAfterViewRenderObservable.notifyObservers(view);
}

this.activeView = null;
Expand Down

0 comments on commit 7308fab

Please sign in to comment.