History

INtroducing th eGraphics Engine to group al the graphics related (render and gpu) elements

Sam Gateau committed 8 years ago

Commit 0f3cb0f1 parent acab1c715 files · +686 −320Browse files

Showing the changes to interface/src/graphics/GraphicsEngine.cpp (1 of 15 files). Show all

Unified · Split

interface/src/graphics/GraphicsEngine.cpp+167−0
@@ -0,0 +1,167 @@
1//
2// GraphicsEngine.cpp
3//
4// Created by Sam Gateau on 29/6/2018.
5// Copyright 2018 High Fidelity, Inc.
6//
7// Distributed under the Apache License, Version 2.0.
8// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
9//
10#include "GraphicsEngine.h"
11
12#include <shared/GlobalAppProperties.h>
13
14#include "WorldBox.h"
15#include "LODManager.h"
16
17#include <GeometryCache.h>
18#include <TextureCache.h>
19#include <UpdateSceneTask.h>
20#include <RenderViewTask.h>
21#include <SecondaryCamera.h>
22
23#include "RenderEventHandler.h"
24
25#include <gpu/Batch.h>
26#include <gpu/Context.h>
27#include <gpu/gl/GLBackend.h>
28
29GraphicsEngine::GraphicsEngine() {
30}
31
32GraphicsEngine::~GraphicsEngine() {
33}
34
35void GraphicsEngine::initializeGPU(GLWidget* glwidget) {
36
37 // Build an offscreen GL context for the main thread.
38 _offscreenContext = new OffscreenGLCanvas();
39 _offscreenContext->setObjectName("MainThreadContext");
40 _offscreenContext->create(glwidget->qglContext());
41 if (!_offscreenContext->makeCurrent()) {
42 qFatal("Unable to make offscreen context current");
43 }
44 _offscreenContext->doneCurrent();
45 _offscreenContext->setThreadContext();
46
47 _renderEventHandler = new RenderEventHandler(glwidget->qglContext());
48 if (!_offscreenContext->makeCurrent()) {
49 qFatal("Unable to make offscreen context current");
50 }
51
52 // Requires the window context, because that's what's used in the actual rendering
53 // and the GPU backend will make things like the VAO which cannot be shared across
54 // contexts
55 glwidget->makeCurrent();
56 gpu::Context::init<gpu::gl::GLBackend>();
57 qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,
58 QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram)));
59 glwidget->makeCurrent();
60 _gpuContext = std::make_shared<gpu::Context>();
61
62 DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext);
63
64 // Restore the default main thread context
65 _offscreenContext->makeCurrent();
66}
67
68void GraphicsEngine::initializeRender(bool disableDeferred) {
69
70 // Set up the render engine
71 render::CullFunctor cullFunctor = LODManager::shouldRender;
72 _renderEngine->addJob<UpdateSceneTask>("UpdateScene");
73#ifndef Q_OS_ANDROID
74 _renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor, !disableDeferred);
75#endif
76 _renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, !disableDeferred, render::ItemKey::TAG_BITS_0, render::ItemKey::TAG_BITS_0);
77 _renderEngine->load();
78 _renderEngine->registerScene(_renderScene);
79
80 // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
81 DependencyManager::get<GeometryCache>()->initializeShapePipelines();
82
83
84}
85
86void GraphicsEngine::startup() {
87
88
89 static_cast<RenderEventHandler*>(_renderEventHandler)->resumeThread();
90}
91
92void GraphicsEngine::shutdown() {
93 // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual
94 // removal of the items.
95 // See https://highfidelity.fogbugz.com/f/cases/5328
96 _renderScene->enqueueFrame(); // flush all the transactions
97 _renderScene->processTransactionQueue(); // process and apply deletions
98
99 _gpuContext->shutdown();
100
101
102 // shutdown render engine
103 _renderScene = nullptr;
104 _renderEngine = nullptr;
105}
106
107
108void GraphicsEngine::render_runRenderFrame(RenderArgs* renderArgs) {
109 PROFILE_RANGE(render, __FUNCTION__);
110 PerformanceTimer perfTimer("render");
111// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()");
112
113 // The pending changes collecting the changes here
114 render::Transaction transaction;
115
116 // this is not in use at all anymore
117 //if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
118 // render models...
119 // PerformanceTimer perfTimer("entities");
120 // PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
121 // "Application::runRenderFrame() ... entities...");
122
123 //RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
124
125 //renderArgs->_debugFlags = renderDebugFlags;
126 //}
127
128 // Make sure the WorldBox is in the scene
129 // For the record, this one RenderItem is the first one we created and added to the scene.
130 // We could move that code elsewhere but you know...
131 if (!render::Item::isValidID(WorldBoxRenderData::_item)) {
132 auto worldBoxRenderData = std::make_shared<WorldBoxRenderData>();
133 auto worldBoxRenderPayload = std::make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData);
134
135 WorldBoxRenderData::_item = _renderScene->allocateID();
136
137 transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
138 _renderScene->enqueueTransaction(transaction);
139 }
140
141 {
142 // PerformanceTimer perfTimer("EngineRun");
143 _renderEngine->getRenderContext()->args = renderArgs;
144 _renderEngine->run();
145 }
146}
147
148static const unsigned int THROTTLED_SIM_FRAMERATE = 15;
149static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE;
150
151
152
153
154bool GraphicsEngine::shouldPaint() const {
155
156 // Throttle if requested
157 if ((static_cast<RenderEventHandler*>(_renderEventHandler)->_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
158 return false;
159 }
160
161 return true;
162}
163
164bool GraphicsEngine::checkPendingRenderEvent() {
165 bool expected = false;
166 return (_renderEventHandler && static_cast<RenderEventHandler*>(_renderEventHandler)->_pendingRenderEvent.compare_exchange_strong(expected, true));
167}