renderStereo method
Renders stereo: left eye then right eye, side by side. Renders offline, then applies FFR/FSR scaling, chromatic aberration, and ATW warping. Reuses cached image buffers if useATWFallback is true.
Implementation
void renderStereo(Canvas canvas, Size fullSize) {
final halfWidth = fullSize.width / 2;
final eyeSize = Size(halfWidth, fullSize.height);
final aspect = halfWidth / fullSize.height;
final Image leftImg;
final Image rightImg;
if (useATWFallback && _lastLeftImage != null && _lastRightImage != null) {
// Re-use last frame's successfully rendered images
leftImg = _lastLeftImage!;
rightImg = _lastRightImage!;
} else {
// Render new images and update cache
final newLeft = _renderEyeToImage(eyeSize, cameraRig.leftViewProjection(aspect));
final newRight = _renderEyeToImage(eyeSize, cameraRig.rightViewProjection(aspect));
_lastLeftImage?.dispose();
_lastRightImage?.dispose();
_lastLeftImage = newLeft;
_lastRightImage = newRight;
leftImg = newLeft;
rightImg = newRight;
}
// Left eye (offline warp)
canvas.save();
canvas.clipRect(Rect.fromLTWH(0, 0, halfWidth, fullSize.height));
_leftDistortionMesh.drawDistortedImage(
canvas,
leftImg,
eyeSize,
atwTransform: leftAtwMatrix,
enableChromaticAberration: enableChromaticAberration,
);
canvas.restore();
// Right eye (offline warp)
canvas.save();
canvas.clipRect(Rect.fromLTWH(halfWidth, 0, halfWidth, fullSize.height));
canvas.translate(halfWidth, 0);
_rightDistortionMesh.drawDistortedImage(
canvas,
rightImg,
eyeSize,
atwTransform: rightAtwMatrix,
enableChromaticAberration: enableChromaticAberration,
);
canvas.restore();
// Clear fallback flag after frame completion
useATWFallback = false;
// Divider
canvas.drawRect(
Rect.fromLTWH(halfWidth - 2, 0, 4, fullSize.height),
Paint()..color = const Color(0xFF000000),
);
}