mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-07 10:02:24 +02:00
Moving the paintGL to a true GraphicsEngine::render_performFrame()
This commit is contained in:
parent
8fd6c1fea2
commit
d2a66b9e7d
9 changed files with 360 additions and 205 deletions
|
@ -1886,7 +1886,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
auto displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
|
||||
properties["render_rate"] = _renderLoopCounter.rate();
|
||||
properties["render_rate"] = getRenderLoopRate();
|
||||
properties["target_render_rate"] = getTargetRenderFrameRate();
|
||||
properties["present_rate"] = displayPlugin->presentRate();
|
||||
properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate();
|
||||
|
@ -2900,7 +2900,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
|||
surfaceContext->setContextProperty("Recording", DependencyManager::get<RecordingScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data());
|
||||
surfaceContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||
surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface);
|
||||
surfaceContext->setContextProperty("FrameTimings", &_graphicsEngine._frameTimingsScriptingInterface);
|
||||
surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this));
|
||||
|
||||
surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE);
|
||||
|
@ -4437,7 +4437,7 @@ void Application::idle() {
|
|||
if (displayPlugin) {
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
|
||||
}
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, getRenderLoopRate());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||
|
@ -5382,7 +5382,7 @@ void Application::updateSecondaryCameraViewFrustum() {
|
|||
static bool domainLoadingInProgress = false;
|
||||
|
||||
void Application::update(float deltaTime) {
|
||||
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1);
|
||||
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_graphicsEngine._renderFrameCount + 1);
|
||||
|
||||
if (!_physicsEnabled) {
|
||||
if (!domainLoadingInProgress) {
|
||||
|
@ -5839,7 +5839,7 @@ void Application::update(float deltaTime) {
|
|||
// load the view frustum
|
||||
// FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering.
|
||||
// Then we can move this logic into the Avatar::simulate call.
|
||||
myAvatar->preDisplaySide(&_appRenderArgs._renderArgs);
|
||||
// myAvatar->preDisplaySide(&_appRenderArgs._renderArgs);
|
||||
|
||||
|
||||
{
|
||||
|
@ -5855,7 +5855,7 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::updateRenderArgs(float deltaTime) {
|
||||
editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) {
|
||||
_graphicsEngine.editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) {
|
||||
PerformanceTimer perfTimer("editRenderArgs");
|
||||
appRenderArgs._headPose = getHMDSensorPose();
|
||||
|
||||
|
@ -5969,6 +5969,13 @@ void Application::updateRenderArgs(float deltaTime) {
|
|||
QMutexLocker viewLocker(&_viewMutex);
|
||||
appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum);
|
||||
}
|
||||
|
||||
|
||||
// HACK
|
||||
// load the view frustum
|
||||
// FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering.
|
||||
// Then we can move this logic into the Avatar::simulate call.
|
||||
myAvatar->preDisplaySide(&appRenderArgs._renderArgs);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,6 @@
|
|||
#include <procedural/ProceduralSkybox.h>
|
||||
#include <graphics/Skybox.h>
|
||||
#include <ModelScriptingInterface.h>
|
||||
#include "FrameTimingsScriptingInterface.h"
|
||||
|
||||
#include "Sound.h"
|
||||
|
||||
|
@ -159,7 +158,7 @@ public:
|
|||
|
||||
void updateCamera(RenderArgs& renderArgs, float deltaTime);
|
||||
bool shouldPaint() const;
|
||||
void paintGL();
|
||||
// void paintGL();
|
||||
void resizeGL();
|
||||
|
||||
bool event(QEvent* event) override;
|
||||
|
@ -208,8 +207,8 @@ public:
|
|||
|
||||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
size_t getRenderFrameCount() const { return _renderFrameCount; }
|
||||
float getRenderLoopRate() const { return _renderLoopCounter.rate(); }
|
||||
size_t getRenderFrameCount() const { return _graphicsEngine.getRenderFrameCount(); }
|
||||
float getRenderLoopRate() const { return _graphicsEngine.getRenderLoopRate(); }
|
||||
float getTargetRenderFrameRate() const; // frames/second
|
||||
|
||||
float getFieldOfView() { return _fieldOfView.get(); }
|
||||
|
@ -569,14 +568,10 @@ private:
|
|||
QUndoStack _undoStack;
|
||||
UndoStackScriptingInterface _undoStackScriptingInterface;
|
||||
|
||||
uint32_t _renderFrameCount { 0 };
|
||||
|
||||
// Frame Rate Measurement
|
||||
RateCounter<500> _renderLoopCounter;
|
||||
RateCounter<500> _gameLoopCounter;
|
||||
|
||||
FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
|
||||
|
||||
QTimer _minimizedWindowTimer;
|
||||
QElapsedTimer _timerStart;
|
||||
QElapsedTimer _lastTimeUpdated;
|
||||
|
@ -671,24 +666,6 @@ private:
|
|||
GameWorkload _gameWorkload;
|
||||
|
||||
GraphicsEngine _graphicsEngine;
|
||||
|
||||
mutable QMutex _renderArgsMutex{ QMutex::Recursive };
|
||||
struct AppRenderArgs {
|
||||
render::Args _renderArgs;
|
||||
glm::mat4 _eyeToWorld;
|
||||
glm::mat4 _view;
|
||||
glm::mat4 _eyeOffsets[2];
|
||||
glm::mat4 _eyeProjections[2];
|
||||
glm::mat4 _headPose;
|
||||
glm::mat4 _sensorToWorld;
|
||||
float _sensorToWorldScale { 1.0f };
|
||||
bool _isStereo{ false };
|
||||
};
|
||||
AppRenderArgs _appRenderArgs;
|
||||
|
||||
|
||||
using RenderArgsEditor = std::function <void (AppRenderArgs&)>;
|
||||
void editRenderArgs(RenderArgsEditor editor);
|
||||
void updateRenderArgs(float deltaTime);
|
||||
|
||||
|
||||
|
|
|
@ -19,151 +19,144 @@
|
|||
#include "Util.h"
|
||||
|
||||
|
||||
// Statically provided display and input plugins
|
||||
extern DisplayPluginList getDisplayPlugins();
|
||||
|
||||
void Application::editRenderArgs(RenderArgsEditor editor) {
|
||||
QMutexLocker renderLocker(&_renderArgsMutex);
|
||||
editor(_appRenderArgs);
|
||||
|
||||
}
|
||||
|
||||
void Application::paintGL() {
|
||||
// Some plugins process message events, allowing paintGL to be called reentrantly.
|
||||
|
||||
_renderFrameCount++;
|
||||
// SG: Moved into the RenderEventHandler
|
||||
//_lastTimeRendered.start();
|
||||
|
||||
auto lastPaintBegin = usecTimestampNow();
|
||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount);
|
||||
PerformanceTimer perfTimer("paintGL");
|
||||
|
||||
if (nullptr == _displayPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayPluginPointer displayPlugin;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||
displayPlugin = getActiveDisplayPlugin();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginBeginFrameRender");
|
||||
// If a display plugin loses it's underlying support, it
|
||||
// needs to be able to signal us to not use it
|
||||
if (!displayPlugin->beginFrameRender(_renderFrameCount)) {
|
||||
QMetaObject::invokeMethod(this, "updateDisplayMode");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RenderArgs renderArgs;
|
||||
glm::mat4 HMDSensorPose;
|
||||
glm::mat4 eyeToWorld;
|
||||
glm::mat4 sensorToWorld;
|
||||
|
||||
bool isStereo;
|
||||
glm::mat4 stereoEyeOffsets[2];
|
||||
glm::mat4 stereoEyeProjections[2];
|
||||
|
||||
{
|
||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||
renderArgs = _appRenderArgs._renderArgs;
|
||||
|
||||
// don't render if there is no context.
|
||||
if (!_appRenderArgs._renderArgs._context) {
|
||||
return;
|
||||
}
|
||||
|
||||
HMDSensorPose = _appRenderArgs._headPose;
|
||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||
isStereo = _appRenderArgs._isStereo;
|
||||
for_each_eye([&](Eye eye) {
|
||||
stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye];
|
||||
stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye];
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/gpuContextReset");
|
||||
_graphicsEngine.getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose);
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::doInBatch("Application_render::gpuContextReset", _graphicsEngine.getGPUContext(), [&](gpu::Batch& batch) {
|
||||
batch.resetStages();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/renderOverlay");
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// NOTE: There is no batch associated with this renderArgs
|
||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize() * getRenderResolutionScale());
|
||||
_applicationOverlay.renderOverlay(&renderArgs);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/updateCompositor");
|
||||
getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld);
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer finalFramebuffer;
|
||||
QSize finalFramebufferSize;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getOutputFramebuffer");
|
||||
// Primary rendering pass
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
}
|
||||
|
||||
{
|
||||
if (isStereo) {
|
||||
renderArgs._context->enableStereo(true);
|
||||
renderArgs._context->setStereoProjections(stereoEyeProjections);
|
||||
renderArgs._context->setStereoViews(stereoEyeOffsets);
|
||||
}
|
||||
|
||||
renderArgs._hudOperator = displayPlugin->getHUDOperator();
|
||||
renderArgs._hudTexture = _applicationOverlay.getOverlayTexture();
|
||||
renderArgs._blitFramebuffer = finalFramebuffer;
|
||||
_graphicsEngine.render_runRenderFrame(&renderArgs);
|
||||
}
|
||||
|
||||
auto frame = _graphicsEngine.getGPUContext()->endFrame();
|
||||
frame->frameIndex = _renderFrameCount;
|
||||
frame->framebuffer = finalFramebuffer;
|
||||
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||
auto frameBufferCache = DependencyManager::get<FramebufferCache>();
|
||||
if (frameBufferCache) {
|
||||
frameBufferCache->releaseFramebuffer(framebuffer);
|
||||
}
|
||||
};
|
||||
// deliver final scene rendering commands to the display plugin
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginOutput");
|
||||
PerformanceTimer perfTimer("pluginOutput");
|
||||
_renderLoopCounter.increment();
|
||||
displayPlugin->submitFrame(frame);
|
||||
}
|
||||
|
||||
// Reset the framebuffer and stereo state
|
||||
renderArgs._blitFramebuffer.reset();
|
||||
renderArgs._context->enableStereo(false);
|
||||
|
||||
{
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
}
|
||||
|
||||
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||
_frameTimingsScriptingInterface.addValue(lastPaintDuration);
|
||||
}
|
||||
//void Application::paintGL() {
|
||||
// // Some plugins process message events, allowing paintGL to be called reentrantly.
|
||||
//
|
||||
// _renderFrameCount++;
|
||||
// // SG: Moved into the RenderEventHandler
|
||||
// //_lastTimeRendered.start();
|
||||
//
|
||||
// auto lastPaintBegin = usecTimestampNow();
|
||||
// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount);
|
||||
// PerformanceTimer perfTimer("paintGL");
|
||||
//
|
||||
// if (nullptr == _displayPlugin) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// DisplayPluginPointer displayPlugin;
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||
// displayPlugin = getActiveDisplayPlugin();
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/pluginBeginFrameRender");
|
||||
// // If a display plugin loses it's underlying support, it
|
||||
// // needs to be able to signal us to not use it
|
||||
// if (!displayPlugin->beginFrameRender(_renderFrameCount)) {
|
||||
// QMetaObject::invokeMethod(this, "updateDisplayMode");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// RenderArgs renderArgs;
|
||||
// glm::mat4 HMDSensorPose;
|
||||
// glm::mat4 eyeToWorld;
|
||||
// glm::mat4 sensorToWorld;
|
||||
//
|
||||
// bool isStereo;
|
||||
// glm::mat4 stereoEyeOffsets[2];
|
||||
// glm::mat4 stereoEyeProjections[2];
|
||||
//
|
||||
// {
|
||||
// QMutexLocker viewLocker(&_renderArgsMutex);
|
||||
// renderArgs = _appRenderArgs._renderArgs;
|
||||
//
|
||||
// // don't render if there is no context.
|
||||
// if (!_appRenderArgs._renderArgs._context) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// HMDSensorPose = _appRenderArgs._headPose;
|
||||
// eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||
// sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||
// isStereo = _appRenderArgs._isStereo;
|
||||
// for_each_eye([&](Eye eye) {
|
||||
// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye];
|
||||
// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye];
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/gpuContextReset");
|
||||
// _graphicsEngine.getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose);
|
||||
// // Reset the gpu::Context Stages
|
||||
// // Back to the default framebuffer;
|
||||
// gpu::doInBatch("Application_render::gpuContextReset", _graphicsEngine.getGPUContext(), [&](gpu::Batch& batch) {
|
||||
// batch.resetStages();
|
||||
// });
|
||||
// }
|
||||
//
|
||||
//
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/renderOverlay");
|
||||
// PerformanceTimer perfTimer("renderOverlay");
|
||||
// // NOTE: There is no batch associated with this renderArgs
|
||||
// // the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
// renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize() * getRenderResolutionScale());
|
||||
// _applicationOverlay.renderOverlay(&renderArgs);
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/updateCompositor");
|
||||
// getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld);
|
||||
// }
|
||||
//
|
||||
// gpu::FramebufferPointer finalFramebuffer;
|
||||
// QSize finalFramebufferSize;
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/getOutputFramebuffer");
|
||||
// // Primary rendering pass
|
||||
// auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
// finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||
// // Final framebuffer that will be handled to the display-plugin
|
||||
// finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// if (isStereo) {
|
||||
// renderArgs._context->enableStereo(true);
|
||||
// renderArgs._context->setStereoProjections(stereoEyeProjections);
|
||||
// renderArgs._context->setStereoViews(stereoEyeOffsets);
|
||||
// }
|
||||
//
|
||||
// renderArgs._hudOperator = displayPlugin->getHUDOperator();
|
||||
// renderArgs._hudTexture = _applicationOverlay.getOverlayTexture();
|
||||
// renderArgs._blitFramebuffer = finalFramebuffer;
|
||||
// _graphicsEngine.render_runRenderFrame(&renderArgs);
|
||||
// }
|
||||
//
|
||||
// auto frame = _graphicsEngine.getGPUContext()->endFrame();
|
||||
// frame->frameIndex = _renderFrameCount;
|
||||
// frame->framebuffer = finalFramebuffer;
|
||||
// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||
// auto frameBufferCache = DependencyManager::get<FramebufferCache>();
|
||||
// if (frameBufferCache) {
|
||||
// frameBufferCache->releaseFramebuffer(framebuffer);
|
||||
// }
|
||||
// };
|
||||
// // deliver final scene rendering commands to the display plugin
|
||||
// {
|
||||
// PROFILE_RANGE(render, "/pluginOutput");
|
||||
// PerformanceTimer perfTimer("pluginOutput");
|
||||
// _renderLoopCounter.increment();
|
||||
// displayPlugin->submitFrame(frame);
|
||||
// }
|
||||
//
|
||||
// // Reset the framebuffer and stereo state
|
||||
// renderArgs._blitFramebuffer.reset();
|
||||
// renderArgs._context->enableStereo(false);
|
||||
//
|
||||
// {
|
||||
// Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
// }
|
||||
//
|
||||
// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||
// _frameTimingsScriptingInterface.addValue(lastPaintDuration);
|
||||
//}
|
||||
|
||||
|
||||
// WorldBox Render Data & rendering functions
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <GeometryCache.h>
|
||||
#include <TextureCache.h>
|
||||
#include <FramebufferCache.h>
|
||||
#include <UpdateSceneTask.h>
|
||||
#include <RenderViewTask.h>
|
||||
#include <SecondaryCamera.h>
|
||||
|
@ -25,6 +26,12 @@
|
|||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/gl/GLBackend.h>
|
||||
#include <display-plugins/DisplayPlugin.h>
|
||||
|
||||
#include <display-plugins/CompositorHelper.h>
|
||||
#include <QMetaObject>
|
||||
#include "ui/Stats.h"
|
||||
#include "Application.h"
|
||||
|
||||
GraphicsEngine::GraphicsEngine() {
|
||||
}
|
||||
|
@ -44,7 +51,11 @@ void GraphicsEngine::initializeGPU(GLWidget* glwidget) {
|
|||
_offscreenContext->doneCurrent();
|
||||
_offscreenContext->setThreadContext();
|
||||
|
||||
_renderEventHandler = new RenderEventHandler(glwidget->qglContext());
|
||||
_renderEventHandler = new RenderEventHandler(
|
||||
glwidget->qglContext(),
|
||||
[this]() { this->render_performFrame(); }
|
||||
);
|
||||
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
|
@ -84,8 +95,6 @@ void GraphicsEngine::initializeRender(bool disableDeferred) {
|
|||
}
|
||||
|
||||
void GraphicsEngine::startup() {
|
||||
|
||||
|
||||
static_cast<RenderEventHandler*>(_renderEventHandler)->resumeThread();
|
||||
}
|
||||
|
||||
|
@ -110,27 +119,12 @@ void GraphicsEngine::shutdown() {
|
|||
void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("render");
|
||||
// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()");
|
||||
|
||||
// The pending changes collecting the changes here
|
||||
render::Transaction transaction;
|
||||
|
||||
// this is not in use at all anymore
|
||||
//if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
// render models...
|
||||
// PerformanceTimer perfTimer("entities");
|
||||
// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
// "Application::runRenderFrame() ... entities...");
|
||||
|
||||
//RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
|
||||
|
||||
//renderArgs->_debugFlags = renderDebugFlags;
|
||||
//}
|
||||
|
||||
// Make sure the WorldBox is in the scene
|
||||
// For the record, this one RenderItem is the first one we created and added to the scene.
|
||||
// We could move that code elsewhere but you know...
|
||||
if (!render::Item::isValidID(WorldBoxRenderData::_item)) {
|
||||
render::Transaction transaction;
|
||||
auto worldBoxRenderData = std::make_shared<WorldBoxRenderData>();
|
||||
auto worldBoxRenderPayload = std::make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData);
|
||||
|
||||
|
@ -141,7 +135,6 @@ void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) {
|
|||
}
|
||||
|
||||
{
|
||||
// PerformanceTimer perfTimer("EngineRun");
|
||||
_renderEngine->getRenderContext()->args = renderArgs;
|
||||
_renderEngine->run();
|
||||
}
|
||||
|
@ -154,7 +147,6 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI
|
|||
|
||||
|
||||
bool GraphicsEngine::shouldPaint() const {
|
||||
|
||||
// Throttle if requested
|
||||
if ((static_cast<RenderEventHandler*>(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
|
||||
return false;
|
||||
|
@ -167,3 +159,149 @@ bool GraphicsEngine::checkPendingRenderEvent() {
|
|||
bool expected = false;
|
||||
return (_renderEventHandler && static_cast<RenderEventHandler*>(_renderEventHandler)->_pendingRenderEvent.compare_exchange_strong(expected, true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GraphicsEngine::render_performFrame() {
|
||||
// Some plugins process message events, allowing paintGL to be called reentrantly.
|
||||
|
||||
_renderFrameCount++;
|
||||
// SG: Moved into the RenderEventHandler
|
||||
//_lastTimeRendered.start();
|
||||
|
||||
auto lastPaintBegin = usecTimestampNow();
|
||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount);
|
||||
PerformanceTimer perfTimer("paintGL");
|
||||
|
||||
/* if (nullptr == _displayPlugin) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
DisplayPluginPointer displayPlugin;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||
displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginBeginFrameRender");
|
||||
// If a display plugin loses it's underlying support, it
|
||||
// needs to be able to signal us to not use it
|
||||
if (!displayPlugin->beginFrameRender(_renderFrameCount)) {
|
||||
QMetaObject::invokeMethod(qApp, "updateDisplayMode");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RenderArgs renderArgs;
|
||||
glm::mat4 HMDSensorPose;
|
||||
glm::mat4 eyeToWorld;
|
||||
glm::mat4 sensorToWorld;
|
||||
|
||||
bool isStereo;
|
||||
glm::mat4 stereoEyeOffsets[2];
|
||||
glm::mat4 stereoEyeProjections[2];
|
||||
|
||||
{
|
||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||
renderArgs = _appRenderArgs._renderArgs;
|
||||
|
||||
// don't render if there is no context.
|
||||
if (!_appRenderArgs._renderArgs._context) {
|
||||
return;
|
||||
}
|
||||
|
||||
HMDSensorPose = _appRenderArgs._headPose;
|
||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||
isStereo = _appRenderArgs._isStereo;
|
||||
for_each_eye([&](Eye eye) {
|
||||
stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye];
|
||||
stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye];
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/gpuContextReset");
|
||||
getGPUContext()->beginFrame(_appRenderArgs._view, HMDSensorPose);
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::doInBatch("Application_render::gpuContextReset", getGPUContext(), [&](gpu::Batch& batch) {
|
||||
batch.resetStages();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/renderOverlay");
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// NOTE: There is no batch associated with this renderArgs
|
||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
renderArgs._viewport = glm::ivec4(0, 0, qApp->getDeviceSize() * qApp->getRenderResolutionScale());
|
||||
qApp->getApplicationOverlay().renderOverlay(&renderArgs);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/updateCompositor");
|
||||
qApp->getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld);
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer finalFramebuffer;
|
||||
QSize finalFramebufferSize;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getOutputFramebuffer");
|
||||
// Primary rendering pass
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
}
|
||||
|
||||
{
|
||||
if (isStereo) {
|
||||
renderArgs._context->enableStereo(true);
|
||||
renderArgs._context->setStereoProjections(stereoEyeProjections);
|
||||
renderArgs._context->setStereoViews(stereoEyeOffsets);
|
||||
}
|
||||
|
||||
renderArgs._hudOperator = displayPlugin->getHUDOperator();
|
||||
renderArgs._hudTexture = qApp->getApplicationOverlay().getOverlayTexture();
|
||||
renderArgs._blitFramebuffer = finalFramebuffer;
|
||||
render_runRenderFrame(&renderArgs);
|
||||
}
|
||||
|
||||
auto frame = getGPUContext()->endFrame();
|
||||
frame->frameIndex = _renderFrameCount;
|
||||
frame->framebuffer = finalFramebuffer;
|
||||
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||
auto frameBufferCache = DependencyManager::get<FramebufferCache>();
|
||||
if (frameBufferCache) {
|
||||
frameBufferCache->releaseFramebuffer(framebuffer);
|
||||
}
|
||||
};
|
||||
// deliver final scene rendering commands to the display plugin
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginOutput");
|
||||
PerformanceTimer perfTimer("pluginOutput");
|
||||
_renderLoopCounter.increment();
|
||||
displayPlugin->submitFrame(frame);
|
||||
}
|
||||
|
||||
// Reset the framebuffer and stereo state
|
||||
renderArgs._blitFramebuffer.reset();
|
||||
renderArgs._context->enableStereo(false);
|
||||
|
||||
{
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
}
|
||||
|
||||
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||
_frameTimingsScriptingInterface.addValue(lastPaintDuration);
|
||||
}
|
||||
|
||||
|
||||
void GraphicsEngine::editRenderArgs(RenderArgsEditor editor) {
|
||||
QMutexLocker renderLocker(&_renderArgsMutex);
|
||||
editor(_appRenderArgs);
|
||||
|
||||
}
|
|
@ -12,10 +12,30 @@
|
|||
|
||||
#include <gl/OffscreenGLCanvas.h>
|
||||
#include <gl/GLWidget.h>
|
||||
#include <qmutex.h>
|
||||
|
||||
#include <render/Engine.h>
|
||||
|
||||
#include <OctreeConstants.h>
|
||||
#include <shared/RateCounter.h>
|
||||
|
||||
#include "FrameTimingsScriptingInterface.h"
|
||||
|
||||
|
||||
struct AppRenderArgs {
|
||||
render::Args _renderArgs;
|
||||
glm::mat4 _eyeToWorld;
|
||||
glm::mat4 _view;
|
||||
glm::mat4 _eyeOffsets[2];
|
||||
glm::mat4 _eyeProjections[2];
|
||||
glm::mat4 _headPose;
|
||||
glm::mat4 _sensorToWorld;
|
||||
float _sensorToWorldScale{ 1.0f };
|
||||
bool _isStereo{ false };
|
||||
};
|
||||
|
||||
using RenderArgsEditor = std::function <void(AppRenderArgs&)>;
|
||||
|
||||
|
||||
class GraphicsEngine {
|
||||
public:
|
||||
|
@ -35,12 +55,25 @@ public:
|
|||
bool shouldPaint() const;
|
||||
bool checkPendingRenderEvent();
|
||||
|
||||
size_t getRenderFrameCount() const { return _renderFrameCount; }
|
||||
float getRenderLoopRate() const { return _renderLoopCounter.rate(); }
|
||||
|
||||
// Feed GRaphics Engine with new frame configuration
|
||||
void editRenderArgs(RenderArgsEditor editor);
|
||||
|
||||
private:
|
||||
// Thread specific calls
|
||||
void render_performFrame();
|
||||
void render_runRenderFrame(RenderArgs* renderArgs);
|
||||
|
||||
protected:
|
||||
|
||||
mutable QMutex _renderArgsMutex{ QMutex::Recursive };
|
||||
AppRenderArgs _appRenderArgs;
|
||||
|
||||
RateCounter<500> _renderLoopCounter;
|
||||
|
||||
uint32_t _renderFrameCount{ 0 };
|
||||
render::ScenePointer _renderScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) };
|
||||
render::EnginePointer _renderEngine{ new render::RenderEngine() };
|
||||
|
||||
|
@ -51,6 +84,8 @@ protected:
|
|||
|
||||
OffscreenGLCanvas* _offscreenContext{ nullptr };
|
||||
|
||||
FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
|
||||
|
||||
friend class Application;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "CrashHandler.h"
|
||||
|
||||
RenderEventHandler::RenderEventHandler(QOpenGLContext* context) {
|
||||
RenderEventHandler::RenderEventHandler(QOpenGLContext* context, RenderCall renderCall) :
|
||||
_renderCall(renderCall)
|
||||
{
|
||||
_renderContext = new OffscreenGLCanvas();
|
||||
_renderContext->setObjectName("RenderContext");
|
||||
_renderContext->create(context);
|
||||
|
@ -52,7 +54,7 @@ void RenderEventHandler::resumeThread() {
|
|||
void RenderEventHandler::render() {
|
||||
if (qApp->shouldPaint()) {
|
||||
_lastTimeRendered.start();
|
||||
qApp->paintGL();
|
||||
_renderCall();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,11 @@ class RenderEventHandler : public QObject {
|
|||
using Parent = QObject;
|
||||
Q_OBJECT
|
||||
public:
|
||||
RenderEventHandler(QOpenGLContext* context);
|
||||
|
||||
using RenderCall = std::function <void()>;
|
||||
RenderCall _renderCall;
|
||||
|
||||
RenderEventHandler(QOpenGLContext* context, RenderCall renderCall);
|
||||
|
||||
QElapsedTimer _lastTimeRendered;
|
||||
std::atomic<bool> _pendingRenderEvent{ true };
|
||||
|
|
|
@ -50,10 +50,10 @@ public:
|
|||
_default = toJsonValue(*this).toObject().toVariantMap();
|
||||
|
||||
_presets.unite(list.toVariantMap());
|
||||
if (C::alwaysEnabled || C::enabled) {
|
||||
if (C::enabled) {
|
||||
_presets.insert(DEFAULT, _default);
|
||||
}
|
||||
if (!C::alwaysEnabled) {
|
||||
if (false) { //!C::alwaysEnabled) {
|
||||
_presets.insert(NONE, QVariantMap{{ "enabled", false }});
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,11 @@ public:
|
|||
using Persistent = PersistentConfig<JobConfig>;
|
||||
|
||||
JobConfig() = default;
|
||||
JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {}
|
||||
JobConfig(bool enabled): enabled{ enabled } {}
|
||||
|
||||
bool isEnabled() { return /*alwaysEnabled ||*/ enabled; }
|
||||
void setEnabled(bool enable) { enabled = /*alwaysEnabled ||*/ enable; emit dirtyEnabled(); }
|
||||
|
||||
bool alwaysEnabled{ false };
|
||||
bool enabled{ true };
|
||||
|
||||
virtual void setPresetList(const QJsonObject& object);
|
||||
|
|
|
@ -164,7 +164,7 @@ public:
|
|||
|
||||
void run(const ContextPointer& jobContext) override {
|
||||
jobContext->jobConfig = std::static_pointer_cast<Config>(Concept::_config);
|
||||
if (jobContext->jobConfig->alwaysEnabled || jobContext->jobConfig->isEnabled()) {
|
||||
if (/*jobContext->jobConfig->alwaysEnabled || */jobContext->jobConfig->isEnabled()) {
|
||||
jobRun(_data, jobContext, _input.get<I>(), _output.edit<O>());
|
||||
}
|
||||
jobContext->jobConfig.reset();
|
||||
|
@ -339,7 +339,7 @@ public:
|
|||
|
||||
void run(const ContextPointer& jobContext) override {
|
||||
auto config = std::static_pointer_cast<C>(Concept::_config);
|
||||
if (config->alwaysEnabled || config->enabled) {
|
||||
if (config->enabled) {
|
||||
for (auto job : TaskConcept::_jobs) {
|
||||
job.run(jobContext);
|
||||
if (jobContext->taskFlow.doAbortTask()) {
|
||||
|
|
Loading…
Reference in a new issue