Merge branch 'master' of https://github.com/highfidelity/hifi into reset-hud-on-driving

This commit is contained in:
howard-stearns 2016-05-20 13:41:41 -07:00
commit dcc8764fa7
6 changed files with 66 additions and 54 deletions

View file

@ -1822,28 +1822,37 @@ bool Application::event(QEvent* event) {
return false;
}
static bool justPresented = false;
// Presentation/painting logic
// TODO: Decouple presentation and painting loops
static bool isPainting = false;
if ((int)event->type() == (int)Present) {
if (justPresented) {
justPresented = false;
// If presentation is hogging the main thread, repost as low priority to avoid hanging the GUI.
if (isPainting) {
// If painting (triggered by presentation) is hogging the main thread,
// repost as low priority to avoid hanging the GUI.
// This has the effect of allowing presentation to exceed the paint budget by X times and
// only dropping every (1/X) frames, instead of every ceil(X) frames.
// only dropping every (1/X) frames, instead of every ceil(X) frames
// (e.g. at a 60FPS target, painting for 17us would fall to 58.82FPS instead of 30FPS).
removePostedEvents(this, Present);
postEvent(this, new QEvent(static_cast<QEvent::Type>(Present)), Qt::LowEventPriority);
isPainting = false;
return true;
}
idle();
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
isPainting = true;
return true;
} else if ((int)event->type() == (int)Paint) {
// NOTE: This must be updated as close to painting as possible,
// or AvatarInputs will mysteriously move to the bottom-right
AvatarInputs::getInstance()->update();
justPresented = true;
paintGL();
isPainting = false;
return true;
}
@ -2658,9 +2667,6 @@ void Application::idle() {
// Sync up the _renderedFrameIndex
_renderedFrameIndex = displayPlugin->presentCount();
// Request a paint ASAP
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority + 1);
// Update the deadlock watchdog
updateHeartbeat();
@ -2687,8 +2693,6 @@ void Application::idle() {
_keyboardDeviceHasFocus = true;
}
// We're going to execute idle processing, so restart the last idle timer
_lastTimeUpdated.start();

View file

@ -149,17 +149,12 @@ void DeferredLightingEffect::prepare(RenderArgs* args) {
batch.setFramebuffer(deferredFbo);
// Clear Color, Depth and Stencil
// Clear Color, Depth and Stencil for deferred buffer
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_COLOR1 | gpu::Framebuffer::BUFFER_COLOR2 |
gpu::Framebuffer::BUFFER_DEPTH |
gpu::Framebuffer::BUFFER_STENCIL,
vec4(vec3(0), 1), 1.0, 0.0, true);
// clear the normal and specular buffers
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
const float MAX_SPECULAR_EXPONENT = 128.0f;
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
vec4(vec3(0), 0), 1.0, 0.0, true);
});
}
@ -469,9 +464,10 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
batch.setInputBuffer(0, mesh->getVertexBuffer());
batch.setInputFormat(mesh->getVertexFormat());
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
{
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>(0);
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
}
}
}
}
@ -548,14 +544,12 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
// Stencil test all the light passes for objects pixels only, not the background
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
if (lightVolume) {
state->setCullMode(gpu::State::CULL_BACK);
// No need for z test since the depth buffer is not bound state->setDepthTest(true, false, gpu::LESS_EQUAL);
// TODO: We should bind the true depth buffer both as RT and texture for the depth test
state->setDepthTest(true, false, gpu::LESS_EQUAL);
// TODO: We should use DepthClamp and avoid changing geometry for inside /outside cases
state->setDepthClampEnable(true);
// additive blending
state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
@ -662,10 +656,13 @@ model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
_spotLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(unsigned short) * indices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));
delete[] indexData;
model::Mesh::Part part(0, indices, 0, model::Mesh::TRIANGLES);
//DEBUG: model::Mesh::Part part(0, indices, 0, model::Mesh::LINE_STRIP);
_spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(sizeof(part), (gpu::Byte*) &part), gpu::Element::PART_DRAWCALL));
std::vector<model::Mesh::Part> parts;
parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::TRIANGLES));
parts.push_back(model::Mesh::Part(0, indices, 0, model::Mesh::LINE_STRIP)); // outline version
_spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
}
return _spotLightMesh;
}

View file

@ -52,17 +52,19 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
batch.setFramebuffer(fbo);
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(1.0, 1.0, 1.0), 1.0), 1.0, 0, true);
vec4(vec3(1.0, 1.0, 1.0), 0.0), 1.0, 0, true);
batch.setProjectionTransform(shadow.getProjection());
batch.setViewTransform(shadow.getView());
auto shadowPipeline = _shapePlumber->pickPipeline(args, ShapeKey());
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, ShapeKey::Builder().withSkinned());
args->_pipeline = shadowPipeline;
batch.setPipeline(shadowPipeline->pipeline);
std::vector<ShapeKey> skinnedShapeKeys{};
// Iterate through all inShapes and render the unskinned
args->_pipeline = shadowPipeline;
batch.setPipeline(shadowPipeline->pipeline);
for (auto items : inShapes) {
if (items.first.isSkinned()) {
skinnedShapeKeys.push_back(items.first);
@ -71,6 +73,7 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
}
}
// Reiterate to render the skinned
args->_pipeline = shadowSkinnedPipeline;
batch.setPipeline(shadowSkinnedPipeline->pipeline);
for (const auto& key : skinnedShapeKeys) {

View file

@ -87,7 +87,8 @@ float evalShadowAttenuationPCF(vec4 position, vec4 shadowTexcoord) {
float evalShadowAttenuation(vec4 position) {
vec4 shadowTexcoord = evalShadowTexcoord(position);
if (shadowTexcoord.x < 0.0 || shadowTexcoord.x > 1.0 ||
shadowTexcoord.y < 0.0 || shadowTexcoord.y > 1.0) {
shadowTexcoord.y < 0.0 || shadowTexcoord.y > 1.0 ||
shadowTexcoord.z < 0.0 || shadowTexcoord.z > 1.0) {
// If a point is not in the map, do not attenuate
return 1.0;
}

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ScriptCache.h"
#include <QCoreApplication>
#include <QEventLoop>
#include <QNetworkAccessManager>
@ -20,7 +22,7 @@
#include <assert.h>
#include <SharedUtil.h>
#include "ScriptCache.h"
#include "ScriptEngines.h"
#include "ScriptEngineLogging.h"
ScriptCache::ScriptCache(QObject* parent) {
@ -78,22 +80,25 @@ void ScriptCache::scriptDownloaded() {
QList<ScriptUser*> scriptUsers = _scriptUsers.values(url);
_scriptUsers.remove(url);
if (req->getResult() == ResourceRequest::Success) {
auto scriptContents = req->getData();
_scriptCache[url] = scriptContents;
lock.unlock();
qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
if (!DependencyManager::get<ScriptEngines>()->isStopped()) {
if (req->getResult() == ResourceRequest::Success) {
auto scriptContents = req->getData();
_scriptCache[url] = scriptContents;
lock.unlock();
qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
foreach(ScriptUser* user, scriptUsers) {
user->scriptContentsAvailable(url, scriptContents);
}
} else {
lock.unlock();
qCWarning(scriptengine) << "Error loading script from URL " << url;
foreach(ScriptUser* user, scriptUsers) {
user->errorInLoadingScript(url);
foreach(ScriptUser* user, scriptUsers) {
user->scriptContentsAvailable(url, scriptContents);
}
} else {
lock.unlock();
qCWarning(scriptengine) << "Error loading script from URL " << url;
foreach(ScriptUser* user, scriptUsers) {
user->errorInLoadingScript(url);
}
}
}
req->deleteLater();
}
@ -162,9 +167,11 @@ void ScriptCache::scriptContentAvailable() {
}
}
foreach(contentAvailableCallback thisCallback, allCallbacks) {
thisCallback(url.toString(), scriptContent, true, success);
}
req->deleteLater();
}
if (!DependencyManager::get<ScriptEngines>()->isStopped()) {
foreach(contentAvailableCallback thisCallback, allCallbacks) {
thisCallback(url.toString(), scriptContent, true, success);
}
}
}

View file

@ -68,6 +68,7 @@ public:
// Called at shutdown time
void shutdownScripting();
bool isStopped() const { return _isStopped; }
signals:
void scriptCountChanged();
@ -86,7 +87,6 @@ protected:
void onScriptEngineLoaded(const QString& scriptFilename);
void onScriptEngineError(const QString& scriptFilename);
void launchScriptEngine(ScriptEngine* engine);
bool isStopped() const { return _isStopped; }
QReadWriteLock _scriptEnginesHashLock;
QHash<QUrl, ScriptEngine*> _scriptEnginesHash;