resolve conflicts on merge with upstream/master

This commit is contained in:
Stephen Birarda 2015-07-08 22:54:36 -07:00
commit 19c5f0b67c
13 changed files with 293 additions and 67 deletions

View file

@ -1176,7 +1176,6 @@ bool Application::event(QEvent* event) {
}
bool Application::eventFilter(QObject* object, QEvent* event) {
if (event->type() == QEvent::ShortcutOverride) {
if (DependencyManager::get<OffscreenUi>()->shouldSwallowShortcut(event)) {
event->accept();
@ -1792,6 +1791,7 @@ void Application::checkFPS() {
}
void Application::idle() {
PROFILE_RANGE(__FUNCTION__);
static SimpleAverage<float> interIdleDurations;
static uint64_t lastIdleEnd{ 0 };

View file

@ -58,6 +58,7 @@ void GLCanvas::initializeGL() {
}
void GLCanvas::paintGL() {
PROFILE_RANGE(__FUNCTION__);
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) {
Application::getInstance()->paintGL();
}

View file

@ -161,6 +161,7 @@ namespace render {
template <> void payloadRender(const RenderableModelEntityItemMeta::Pointer& payload, RenderArgs* args) {
if (args) {
if (payload && payload->entity) {
PROFILE_RANGE("MetaModelRender");
payload->entity->render(args);
}
}

View file

@ -12,9 +12,11 @@
#include "EntityItem.h"
#include <QtCore/QObject>
#include <QtEndian>
#include <glm/gtx/transform.hpp>
#include <BufferParser.h>
#include <ByteCountCoding.h>
#include <GLMHelpers.h>
#include <Octree.h>
@ -354,50 +356,78 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// ~27-35 bytes...
const int MINIMUM_HEADER_BYTES = 27;
int bytesRead = 0;
if (bytesLeftToRead < MINIMUM_HEADER_BYTES) {
return 0;
}
int clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
BufferParser parser(data, bytesLeftToRead);
#ifdef DEBUG
#define VALIDATE_ENTITY_ITEM_PARSER 1
#endif
#ifdef VALIDATE_ENTITY_ITEM_PARSER
int bytesRead = 0;
int originalLength = bytesLeftToRead;
// TODO: figure out a way to avoid the big deep copy below.
QByteArray originalDataBuffer((const char*)data, originalLength); // big deep copy!
int clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
const unsigned char* dataAt = data;
#endif
// id
QByteArray encodedID = originalDataBuffer.mid(bytesRead, NUM_BYTES_RFC4122_UUID); // maximum possible size
_id = QUuid::fromRfc4122(encodedID);
dataAt += encodedID.size();
bytesRead += encodedID.size();
parser.readUuid(_id);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
QByteArray encodedID = originalDataBuffer.mid(bytesRead, NUM_BYTES_RFC4122_UUID); // maximum possible size
QUuid id = QUuid::fromRfc4122(encodedID);
dataAt += encodedID.size();
bytesRead += encodedID.size();
Q_ASSERT(id == _id);
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
// type
parser.readCompressedCount<quint32>((quint32&)_type);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
QByteArray encodedType = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint32> typeCoder = encodedType;
encodedType = typeCoder; // determine true length
dataAt += encodedType.size();
bytesRead += encodedType.size();
quint32 type = typeCoder;
_type = (EntityTypes::EntityType)type;
EntityTypes::EntityType oldType = (EntityTypes::EntityType)type;
Q_ASSERT(oldType == _type);
Q_ASSERT(parser.offset() == bytesRead);
#endif
bool overwriteLocalData = true; // assume the new content overwrites our local data
quint64 now = usecTimestampNow();
// _created
quint64 createdFromBuffer = 0;
memcpy(&createdFromBuffer, dataAt, sizeof(createdFromBuffer));
dataAt += sizeof(createdFromBuffer);
bytesRead += sizeof(createdFromBuffer);
quint64 now = usecTimestampNow();
if (_created == UNKNOWN_CREATED_TIME) {
// we don't yet have a _created timestamp, so we accept this one
createdFromBuffer -= clockSkew;
if (createdFromBuffer > now || createdFromBuffer == UNKNOWN_CREATED_TIME) {
createdFromBuffer = now;
{
quint64 createdFromBuffer = 0;
parser.readValue(createdFromBuffer);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
quint64 createdFromBuffer2 = 0;
memcpy(&createdFromBuffer2, dataAt, sizeof(createdFromBuffer2));
dataAt += sizeof(createdFromBuffer2);
bytesRead += sizeof(createdFromBuffer2);
Q_ASSERT(createdFromBuffer2 == createdFromBuffer);
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
if (_created == UNKNOWN_CREATED_TIME) {
// we don't yet have a _created timestamp, so we accept this one
createdFromBuffer -= clockSkew;
if (createdFromBuffer > now || createdFromBuffer == UNKNOWN_CREATED_TIME) {
createdFromBuffer = now;
}
_created = createdFromBuffer;
}
_created = createdFromBuffer;
}
#ifdef WANT_DEBUG
@ -417,15 +447,21 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
#endif
quint64 lastEditedFromBuffer = 0;
quint64 lastEditedFromBufferAdjusted = 0;
// TODO: we could make this encoded as a delta from _created
// _lastEdited
memcpy(&lastEditedFromBuffer, dataAt, sizeof(lastEditedFromBuffer));
dataAt += sizeof(lastEditedFromBuffer);
bytesRead += sizeof(lastEditedFromBuffer);
lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew;
parser.readValue(lastEditedFromBuffer);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
quint64 lastEditedFromBuffer2 = 0;
memcpy(&lastEditedFromBuffer2, dataAt, sizeof(lastEditedFromBuffer2));
dataAt += sizeof(lastEditedFromBuffer2);
bytesRead += sizeof(lastEditedFromBuffer2);
Q_ASSERT(lastEditedFromBuffer2 == lastEditedFromBuffer);
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
quint64 lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew;
if (lastEditedFromBufferAdjusted > now) {
lastEditedFromBufferAdjusted = now;
}
@ -487,9 +523,21 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
}
// last updated is stored as ByteCountCoded delta from lastEdited
QByteArray encodedUpdateDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
quint64 updateDelta = updateDeltaCoder;
quint64 updateDelta;
parser.readCompressedCount(updateDelta);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
QByteArray encodedUpdateDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
quint64 updateDelta2 = updateDeltaCoder;
Q_ASSERT(updateDelta == updateDelta2);
encodedUpdateDelta = updateDeltaCoder; // determine true length
dataAt += encodedUpdateDelta.size();
bytesRead += encodedUpdateDelta.size();
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
if (overwriteLocalData) {
_lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that
#ifdef WANT_DEBUG
@ -499,17 +547,25 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
#endif
}
encodedUpdateDelta = updateDeltaCoder; // determine true length
dataAt += encodedUpdateDelta.size();
bytesRead += encodedUpdateDelta.size();
// Newer bitstreams will have a last simulated and a last updated value
quint64 lastSimulatedFromBufferAdjusted = now;
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) {
// last simulated is stored as ByteCountCoded delta from lastEdited
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
quint64 simulatedDelta = simulatedDeltaCoder;
quint64 simulatedDelta;
parser.readCompressedCount(simulatedDelta);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
quint64 simulatedDelta2 = simulatedDeltaCoder;
Q_ASSERT(simulatedDelta2 == simulatedDelta);
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
dataAt += encodedSimulatedDelta.size();
bytesRead += encodedSimulatedDelta.size();
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
if (overwriteLocalData) {
lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
if (lastSimulatedFromBufferAdjusted > now) {
@ -521,9 +577,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now);
#endif
}
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
dataAt += encodedSimulatedDelta.size();
bytesRead += encodedSimulatedDelta.size();
}
#ifdef WANT_DEBUG
@ -537,10 +590,26 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// Property Flags
QByteArray encodedPropertyFlags = originalDataBuffer.mid(bytesRead); // maximum possible size
EntityPropertyFlags propertyFlags = encodedPropertyFlags;
dataAt += propertyFlags.getEncodedLength();
bytesRead += propertyFlags.getEncodedLength();
EntityPropertyFlags propertyFlags;
parser.readFlags(propertyFlags);
#ifdef VALIDATE_ENTITY_ITEM_PARSER
{
QByteArray encodedPropertyFlags = originalDataBuffer.mid(bytesRead); // maximum possible size
EntityPropertyFlags propertyFlags2 = encodedPropertyFlags;
dataAt += propertyFlags.getEncodedLength();
bytesRead += propertyFlags.getEncodedLength();
Q_ASSERT(propertyFlags2 == propertyFlags);
Q_ASSERT(parser.offset() == bytesRead);
}
#endif
#ifdef VALIDATE_ENTITY_ITEM_PARSER
Q_ASSERT(parser.data() + parser.offset() == dataAt);
#else
const unsigned char* dataAt = parser.data() + parser.offset();
int bytesRead = parser.offset();
#endif
if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) {
// pack SimulationOwner and terse update properties near each other
@ -549,6 +618,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// even when we would otherwise ignore the rest of the packet.
if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) {
QByteArray simOwnerData;
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData);
SimulationOwner newSimOwner;

View file

@ -11,7 +11,7 @@
#include <QtCore/QObject>
#include <QDebug>
#include <BufferParser.h>
#include <PacketHeaders.h>
#include "RegisteredMetaTypes.h"
@ -33,11 +33,8 @@ EntityItemID::EntityItemID(const QUuid& id) : QUuid(id)
EntityItemID EntityItemID::readEntityItemIDFromBuffer(const unsigned char* data, int bytesLeftToRead) {
EntityItemID result;
if (bytesLeftToRead >= NUM_BYTES_RFC4122_UUID) {
// id
QByteArray encodedID((const char*)data, NUM_BYTES_RFC4122_UUID);
result = QUuid::fromRfc4122(encodedID);
BufferParser(data, bytesLeftToRead).readUuid(result);
}
return result;
}

View file

@ -12,6 +12,17 @@
#include <QDebug>
#if defined(NSIGHT_FOUND)
#include "nvToolsExt.h"
ProfileRange::ProfileRange(const char *name) {
nvtxRangePush(name);
}
ProfileRange::~ProfileRange() {
nvtxRangePop();
}
#endif
#define ADD_COMMAND(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
using namespace gpu;

View file

@ -26,17 +26,11 @@
#include "Framebuffer.h"
#if defined(NSIGHT_FOUND)
#include "nvToolsExt.h"
class ProfileRange {
public:
ProfileRange(const char *name) {
nvtxRangePush(name);
}
~ProfileRange() {
nvtxRangePop();
}
ProfileRange(const char *name);
~ProfileRange();
};
#define PROFILE_RANGE(name) ProfileRange profileRangeThis(name);
#else
#define PROFILE_RANGE(name)

View file

@ -33,9 +33,11 @@ bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
}
void Context::render(Batch& batch) {
PROFILE_RANGE(__FUNCTION__);
_backend->render(batch);
}
void Context::syncCache() {
PROFILE_RANGE(__FUNCTION__);
_backend->syncCache();
}

View file

@ -417,6 +417,7 @@ void Model::reset() {
}
bool Model::updateGeometry() {
PROFILE_RANGE(__FUNCTION__);
bool needFullUpdate = false;
bool needToRebuild = false;
@ -690,6 +691,7 @@ void Model::recalculateMeshPartOffsets() {
// entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible)
// and then the calls use the most recent such result.
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
PROFILE_RANGE(__FUNCTION__);
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
if (!_calculatedMeshBoxesValid || calculatedMeshTrianglesNeeded || (!_calculatedMeshPartBoxesValid && pickAgainstTriangles) ) {
@ -1281,6 +1283,7 @@ Blender::Blender(Model* model, int blendNumber, const QWeakPointer<NetworkGeomet
}
void Blender::run() {
PROFILE_RANGE(__FUNCTION__);
QVector<glm::vec3> vertices, normals;
if (!_model.isNull()) {
int offset = 0;
@ -1392,6 +1395,7 @@ void Model::snapToRegistrationPoint() {
}
void Model::simulate(float deltaTime, bool fullUpdate) {
PROFILE_RANGE(__FUNCTION__);
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
@ -1829,6 +1833,7 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
}
AABox Model::getPartBounds(int meshIndex, int partIndex) {
if (meshIndex < _meshStates.size()) {
const MeshState& state = _meshStates.at(meshIndex);
bool isSkinned = state.clusterMatrices.size() > 1;
@ -1859,6 +1864,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) {
}
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent) {
// PROFILE_RANGE(__FUNCTION__);
PerformanceTimer perfTimer("Model::renderPart");
if (!_readyWhenAdded) {
return; // bail asap
@ -1933,7 +1939,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
args, locations);
updateVisibleJointStates();
{
updateVisibleJointStates();
}
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
// to false to rebuild out mesh groups.
@ -2076,9 +2084,13 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
}
_mutex.lock();
qint64 offset = _calculatedMeshPartOffset[QPair<int,int>(meshIndex, partIndex)];
_mutex.unlock();
qint64 offset;
{
// FIXME_STUTTER: We should n't have any lock here
_mutex.lock();
offset = _calculatedMeshPartOffset[QPair<int,int>(meshIndex, partIndex)];
_mutex.unlock();
}
if (part.quadIndices.size() > 0) {
batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset);

View file

@ -9,4 +9,16 @@ add_dependency_external_projects(glm)
find_package(GLM REQUIRED)
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
link_hifi_libraries(shared gpu model)
link_hifi_libraries(shared gpu model)
if (WIN32)
if (USE_NSIGHT)
# try to find the Nsight package and add it to the build if we find it
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
endif (WIN32)

View file

@ -11,6 +11,7 @@
#include "Scene.h"
#include <numeric>
#include "gpu/Batch.h"
using namespace render;
@ -167,6 +168,7 @@ void consolidateChangeQueue(PendingChangesQueue& queue, PendingChanges& singleBa
}
void Scene::processPendingChangesQueue() {
PROFILE_RANGE(__FUNCTION__);
_changeQueueMutex.lock();
PendingChanges consolidatedPendingChanges;
consolidateChangeQueue(_changeQueue, consolidatedPendingChanges);

View file

@ -22,10 +22,10 @@ uniform vec3 inBoundPos;
uniform vec3 inBoundDim;
uniform ivec4 inStatus;
vec3 paintRainbow(float nv) {
float v = nv * 5.f;
vec3 paintRainbow(float normalizedHue) {
float v = normalizedHue * 6.f;
if (v < 0.f) {
return vec3(0.f, 0.f, 0.f);
return vec3(1.f, 0.f, 0.f);
} else if (v < 1.f) {
return vec3(1.f, v, 0.f);
} else if (v < 2.f) {
@ -36,8 +36,10 @@ vec3 paintRainbow(float nv) {
return vec3(0.f, 1.f - (v-3.f), 1.f );
} else if (v < 5.f) {
return vec3((v-4.f), 0.f, 1.f );
} else if (v < 6.f) {
return vec3(1.f, 0.f, 1.f - (v-5.f));
} else {
return vec3(1.f, 1.f, 1.f);
return vec3(1.f, 0.f, 0.f);
}
}

View file

@ -0,0 +1,122 @@
//
// Created by Bradley Austin Davis on 2015/07/08
// Copyright 2013-2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_BufferParser_h
#define hifi_BufferParser_h
#include <cstdint>
#include <QUuid>
#include <QtEndian>
#include "GLMHelpers.h"
#include "ByteCountCoding.h"
#include "PropertyFlags.h"
class BufferParser {
public:
BufferParser(const uint8_t* data, size_t size, size_t offset = 0) :
_offset(offset), _data(data), _size(size) {
}
template<typename T>
inline void readValue(T& result) {
Q_ASSERT(remaining() >= sizeof(T));
memcpy(&result, _data + _offset, sizeof(T));
_offset += sizeof(T);
}
inline void readUuid(QUuid& result) {
readValue(result.data1);
readValue(result.data2);
readValue(result.data3);
readValue(result.data4);
result.data1 = qFromBigEndian<quint32>(result.data1);
result.data2 = qFromBigEndian<quint16>(result.data2);
result.data3 = qFromBigEndian<quint16>(result.data3);
}
template <typename T>
inline void readFlags(PropertyFlags<T>& result) {
// FIXME doing heap allocation
QByteArray encoded((const char*)(_data + _offset), remaining());
result.decode(encoded);
_offset += result.getEncodedLength();
}
template<typename T>
inline void readCompressedCount(T& result) {
// FIXME switch to a heapless implementation as soon as Brad provides it.
ByteCountCoded<T> codec;
_offset += codec.decode(reinterpret_cast<const char*>(_data + _offset), remaining());
result = codec.data;
}
inline size_t remaining() const {
return _size - _offset;
}
inline size_t offset() const {
return _offset;
}
inline const uint8_t* data() const {
return _data;
}
private:
size_t _offset{ 0 };
const uint8_t* const _data;
const size_t _size;
};
template<>
inline void BufferParser::readValue<quat>(quat& result) {
size_t advance = unpackOrientationQuatFromBytes(_data + _offset, result);
_offset += advance;
}
template<>
inline void BufferParser::readValue(QString& result) {
uint16_t length; readValue(length);
result = QString((const char*)_data + _offset);
}
template<>
inline void BufferParser::readValue(QUuid& result) {
uint16_t length; readValue(length);
Q_ASSERT(16 == length);
readUuid(result);
}
template<>
inline void BufferParser::readValue(xColor& result) {
readValue(result.red);
readValue(result.blue);
readValue(result.green);
}
template<>
inline void BufferParser::readValue(QVector<glm::vec3>& result) {
uint16_t length; readValue(length);
result.resize(length);
memcpy(result.data(), _data + _offset, sizeof(glm::vec3) * length);
_offset += sizeof(glm::vec3) * length;
}
template<>
inline void BufferParser::readValue(QByteArray& result) {
uint16_t length; readValue(length);
result = QByteArray((char*)_data + _offset, (int)length);
_offset += length;
}
#endif