Merge branch 'master' of https://github.com/highfidelity/hifi into workload

This commit is contained in:
samcake 2018-03-15 17:00:20 -07:00
commit 50bdd1ad2f
23 changed files with 1308 additions and 854 deletions

View file

@ -42,7 +42,7 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
ThreadedAssignment(message) ThreadedAssignment(message)
{ {
// make sure we hear about node kills so we can tell the other nodes // make sure we hear about node kills so we can tell the other nodes
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled); connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &AvatarMixer::handleAvatarKilled);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket"); packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket");
@ -423,14 +423,15 @@ void AvatarMixer::throttle(std::chrono::microseconds duration, int frame) {
} }
} }
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
if (killedNode->getType() == NodeType::Agent void AvatarMixer::handleAvatarKilled(SharedNodePointer avatarNode) {
&& killedNode->getLinkedData()) { if (avatarNode->getType() == NodeType::Agent
&& avatarNode->getLinkedData()) {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
{ // decrement sessionDisplayNames table and possibly remove { // decrement sessionDisplayNames table and possibly remove
QMutexLocker nodeDataLocker(&killedNode->getLinkedData()->getMutex()); QMutexLocker nodeDataLocker(&avatarNode->getLinkedData()->getMutex());
AvatarMixerClientData* nodeData = dynamic_cast<AvatarMixerClientData*>(killedNode->getLinkedData()); AvatarMixerClientData* nodeData = dynamic_cast<AvatarMixerClientData*>(avatarNode->getLinkedData());
const QString& baseDisplayName = nodeData->getBaseDisplayName(); const QString& baseDisplayName = nodeData->getBaseDisplayName();
// No sense guarding against very rare case of a node with no entry, as this will work without the guard and do one less lookup in the common case. // No sense guarding against very rare case of a node with no entry, as this will work without the guard and do one less lookup in the common case.
if (--_sessionDisplayNames[baseDisplayName].second <= 0) { if (--_sessionDisplayNames[baseDisplayName].second <= 0) {
@ -447,12 +448,12 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
// we relay avatar kill packets to agents that are not upstream // we relay avatar kill packets to agents that are not upstream
// and downstream avatar mixers, if the node that was just killed was being replicated // and downstream avatar mixers, if the node that was just killed was being replicated
return (node->getType() == NodeType::Agent && !node->isUpstream()) || return (node->getType() == NodeType::Agent && !node->isUpstream()) ||
(killedNode->isReplicated() && shouldReplicateTo(*killedNode, *node)); (avatarNode->isReplicated() && shouldReplicateTo(*avatarNode, *node));
}, [&](const SharedNodePointer& node) { }, [&](const SharedNodePointer& node) {
if (node->getType() == NodeType::Agent) { if (node->getType() == NodeType::Agent) {
if (!killPacket) { if (!killPacket) {
killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason)); killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason));
killPacket->write(killedNode->getUUID().toRfc4122()); killPacket->write(avatarNode->getUUID().toRfc4122());
killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected);
} }
@ -462,7 +463,7 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
if (!replicatedKillPacket) { if (!replicatedKillPacket) {
replicatedKillPacket = NLPacket::create(PacketType::ReplicatedKillAvatar, replicatedKillPacket = NLPacket::create(PacketType::ReplicatedKillAvatar,
NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason)); NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason));
replicatedKillPacket->write(killedNode->getUUID().toRfc4122()); replicatedKillPacket->write(avatarNode->getUUID().toRfc4122());
replicatedKillPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); replicatedKillPacket->writePrimitive(KillAvatarReason::AvatarDisconnected);
} }
@ -479,7 +480,7 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
return false; return false;
} }
if (node->getUUID() == killedNode->getUUID()) { if (node->getUUID() == avatarNode->getUUID()) {
return false; return false;
} }
@ -489,7 +490,7 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
QMetaObject::invokeMethod(node->getLinkedData(), QMetaObject::invokeMethod(node->getLinkedData(),
"cleanupKilledNode", "cleanupKilledNode",
Qt::AutoConnection, Qt::AutoConnection,
Q_ARG(const QUuid&, QUuid(killedNode->getUUID()))); Q_ARG(const QUuid&, QUuid(avatarNode->getUUID())));
} }
); );
} }
@ -605,7 +606,9 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer<ReceivedMessage> mes
void AvatarMixer::handleKillAvatarPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) { void AvatarMixer::handleKillAvatarPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) {
auto start = usecTimestampNow(); auto start = usecTimestampNow();
DependencyManager::get<NodeList>()->processKillNode(*message); handleAvatarKilled(node);
node->setLinkedData(nullptr);
auto end = usecTimestampNow(); auto end = usecTimestampNow();
_handleKillAvatarPacketElapsedTime += (end - start); _handleKillAvatarPacketElapsedTime += (end - start);

View file

@ -39,7 +39,7 @@ public slots:
/// runs the avatar mixer /// runs the avatar mixer
void run() override; void run() override;
void nodeKilled(SharedNodePointer killedNode); void handleAvatarKilled(SharedNodePointer killedNode);
void sendStatsPacket() override; void sendStatsPacket() override;

View file

@ -442,12 +442,16 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream
PrioritizedEntity queuedItem = _sendQueue.top(); PrioritizedEntity queuedItem = _sendQueue.top();
EntityItemPointer entity = queuedItem.getEntity(); EntityItemPointer entity = queuedItem.getEntity();
if (entity) { if (entity) {
// Only send entities that match the jsonFilters, but keep track of everything we've tried to send so we don't try to send it again const QUuid& entityID = entity->getID();
// Only send entities that match the jsonFilters, but keep track of everything we've tried to send so we don't try to send it again;
// also send if we previously matched since this represents change to a matched item.
bool entityMatchesFilters = entity->matchesJSONFilters(jsonFilters); bool entityMatchesFilters = entity->matchesJSONFilters(jsonFilters);
if (entityMatchesFilters || entityNodeData->isEntityFlaggedAsExtra(entity->getID())) { bool entityPreviouslyMatchedFilter = entityNodeData->sentFilteredEntity(entityID);
if (entityMatchesFilters || entityNodeData->isEntityFlaggedAsExtra(entityID) || entityPreviouslyMatchedFilter) {
if (!jsonFilters.isEmpty() && entityMatchesFilters) { if (!jsonFilters.isEmpty() && entityMatchesFilters) {
// Record explicitly filtered-in entity so that extra entities can be flagged. // Record explicitly filtered-in entity so that extra entities can be flagged.
entityNodeData->insertSentFilteredEntity(entity->getID()); entityNodeData->insertSentFilteredEntity(entityID);
} }
OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData); OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData);
@ -458,6 +462,10 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream
params.stopReason = EncodeBitstreamParams::DIDNT_FIT; params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
break; break;
} }
if (entityPreviouslyMatchedFilter && !entityMatchesFilters) {
entityNodeData->removeSentFilteredEntity(entityID);
}
++_numEntities; ++_numEntities;
} }
if (queuedItem.shouldForceRemove()) { if (queuedItem.shouldForceRemove()) {

File diff suppressed because it is too large Load diff

View file

@ -46,6 +46,19 @@ static int YOUTUBE_MAX_FPS = 30;
static QTouchDevice _touchDevice; static QTouchDevice _touchDevice;
WebEntityRenderer::ContentType WebEntityRenderer::getContentType(const QString& urlString) {
if (urlString.isEmpty()) {
return ContentType::NoContent;
}
const QUrl url(urlString);
if (url.scheme() == "http" || url.scheme() == "https" ||
urlString.toLower().endsWith(".htm") || urlString.toLower().endsWith(".html")) {
return ContentType::HtmlContent;
}
return ContentType::QmlContent;
}
WebEntityRenderer::WebEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { WebEntityRenderer::WebEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
static std::once_flag once; static std::once_flag once;
std::call_once(once, [&]{ std::call_once(once, [&]{
@ -123,13 +136,45 @@ void WebEntityRenderer::onTimeout() {
} }
void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
withWriteLock([&] { // If the content type has changed, or the old content type was QML, we need to
// This work must be done on the main thread // destroy the existing surface (because surfaces don't support changing the root
if (!hasWebSurface()) { // object, so subsequent loads of content just overlap the existing content
// If we couldn't create a new web surface, exit bool urlChanged = false;
if (!buildWebSurface(entity)) { {
return; auto newSourceUrl = entity->getSourceUrl();
auto newContentType = getContentType(newSourceUrl);
auto currentContentType = ContentType::NoContent;
withReadLock([&] {
urlChanged = _lastSourceUrl != newSourceUrl;
currentContentType = _contentType;
});
if (urlChanged) {
if (newContentType != ContentType::HtmlContent || currentContentType != ContentType::HtmlContent) {
destroyWebSurface();
} }
withWriteLock([&] {
_lastSourceUrl = newSourceUrl;
_contentType = newContentType;
});
}
}
withWriteLock([&] {
if (_contentType == ContentType::NoContent) {
return;
}
// This work must be done on the main thread
// If we couldn't create a new web surface, exit
if (!hasWebSurface() && !buildWebSurface(entity)) {
return;
}
if (urlChanged) {
_webSurface->getRootItem()->setProperty("url", _lastSourceUrl);
} }
if (_contextPosition != entity->getWorldPosition()) { if (_contextPosition != entity->getWorldPosition()) {
@ -138,11 +183,6 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
_webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(_contextPosition)); _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(_contextPosition));
} }
if (_lastSourceUrl != entity->getSourceUrl()) {
_lastSourceUrl = entity->getSourceUrl();
loadSourceURL();
}
_lastDPI = entity->getDPI(); _lastDPI = entity->getDPI();
_lastLocked = entity->getLocked(); _lastLocked = entity->getLocked();
@ -232,9 +272,6 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
// Let us interact with the keyboard // Let us interact with the keyboard
surfaceContext->setContextProperty("tabletInterface", DependencyManager::get<TabletScriptingInterface>().data()); surfaceContext->setContextProperty("tabletInterface", DependencyManager::get<TabletScriptingInterface>().data());
}); });
_fadeStartTime = usecTimestampNow();
loadSourceURL();
_webSurface->resume();
// forward web events to EntityScriptingInterface // forward web events to EntityScriptingInterface
auto entities = DependencyManager::get<EntityScriptingInterface>(); auto entities = DependencyManager::get<EntityScriptingInterface>();
@ -243,6 +280,29 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
emit entities->webEventReceived(entityItemID, message); emit entities->webEventReceived(entityItemID, message);
}); });
if (_contentType == ContentType::HtmlContent) {
// We special case YouTube URLs since we know they are videos that we should play with at least 30 FPS.
// FIXME this doesn't handle redirects or shortened URLs, consider using a signaling method from the
// web entity
if (QUrl(_lastSourceUrl).host().endsWith("youtube.com", Qt::CaseInsensitive)) {
_webSurface->setMaxFps(YOUTUBE_MAX_FPS);
} else {
_webSurface->setMaxFps(DEFAULT_MAX_FPS);
}
_webSurface->load("controls/WebEntityView.qml", [this](QQmlContext* context, QObject* item) {
item->setProperty("url", _lastSourceUrl);
});
} else if (_contentType == ContentType::QmlContent) {
_webSurface->load(_lastSourceUrl, [this](QQmlContext* context, QObject* item) {
if (item && item->objectName() == "tabletRoot") {
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data());
}
});
}
_fadeStartTime = usecTimestampNow();
_webSurface->resume();
return true; return true;
} }
@ -289,32 +349,6 @@ glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) con
return dims; return dims;
} }
void WebEntityRenderer::loadSourceURL() {
const QUrl sourceUrl(_lastSourceUrl);
if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" ||
_lastSourceUrl.toLower().endsWith(".htm") || _lastSourceUrl.toLower().endsWith(".html")) {
_contentType = htmlContent;
// We special case YouTube URLs since we know they are videos that we should play with at least 30 FPS.
if (sourceUrl.host().endsWith("youtube.com", Qt::CaseInsensitive)) {
_webSurface->setMaxFps(YOUTUBE_MAX_FPS);
} else {
_webSurface->setMaxFps(DEFAULT_MAX_FPS);
}
_webSurface->load("controls/WebEntityView.qml", [this](QQmlContext* context, QObject* item) {
item->setProperty("url", _lastSourceUrl);
});
} else {
_contentType = qmlContent;
_webSurface->load(_lastSourceUrl);
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data());
}
}
}
void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) { void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) {
if (!_lastLocked && _webSurface) { if (!_lastLocked && _webSurface) {
PointerEvent webEvent = event; PointerEvent webEvent = event;

View file

@ -47,15 +47,19 @@ private:
bool buildWebSurface(const TypedEntityPointer& entity); bool buildWebSurface(const TypedEntityPointer& entity);
void destroyWebSurface(); void destroyWebSurface();
bool hasWebSurface(); bool hasWebSurface();
void loadSourceURL();
glm::vec2 getWindowSize(const TypedEntityPointer& entity) const; glm::vec2 getWindowSize(const TypedEntityPointer& entity) const;
int _geometryId{ 0 }; int _geometryId{ 0 };
enum contentType { enum class ContentType {
htmlContent, NoContent,
qmlContent HtmlContent,
QmlContent
}; };
contentType _contentType;
static ContentType getContentType(const QString& urlString);
ContentType _contentType{ ContentType::NoContent };
QSharedPointer<OffscreenQmlSurface> _webSurface; QSharedPointer<OffscreenQmlSurface> _webSurface;
glm::vec3 _contextPosition; glm::vec3 _contextPosition;
gpu::TexturePointer _texture; gpu::TexturePointer _texture;

View file

@ -33,7 +33,7 @@ public:
// these can only be called from the OctreeSendThread for the given Node // these can only be called from the OctreeSendThread for the given Node
void insertSentFilteredEntity(const QUuid& entityID) { _sentFilteredEntities.insert(entityID); } void insertSentFilteredEntity(const QUuid& entityID) { _sentFilteredEntities.insert(entityID); }
void removeSentFilteredEntity(const QUuid& entityID) { _sentFilteredEntities.remove(entityID); } void removeSentFilteredEntity(const QUuid& entityID) { _sentFilteredEntities.remove(entityID); }
bool sentFilteredEntity(const QUuid& entityID) { return _sentFilteredEntities.contains(entityID); } bool sentFilteredEntity(const QUuid& entityID) const { return _sentFilteredEntities.contains(entityID); }
QSet<QUuid> getSentFilteredEntities() { return _sentFilteredEntities; } QSet<QUuid> getSentFilteredEntities() { return _sentFilteredEntities; }
// the following flagged extra entity methods can only be called from the OctreeSendThread for the given Node // the following flagged extra entity methods can only be called from the OctreeSendThread for the given Node

View file

@ -93,12 +93,16 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_setUniformBuffer), (&::gpu::gl::GLBackend::do_setUniformBuffer),
(&::gpu::gl::GLBackend::do_setResourceBuffer), (&::gpu::gl::GLBackend::do_setResourceBuffer),
(&::gpu::gl::GLBackend::do_setResourceTexture), (&::gpu::gl::GLBackend::do_setResourceTexture),
(&::gpu::gl::GLBackend::do_setResourceFramebufferSwapChainTexture),
(&::gpu::gl::GLBackend::do_setFramebuffer), (&::gpu::gl::GLBackend::do_setFramebuffer),
(&::gpu::gl::GLBackend::do_setFramebufferSwapChain),
(&::gpu::gl::GLBackend::do_clearFramebuffer), (&::gpu::gl::GLBackend::do_clearFramebuffer),
(&::gpu::gl::GLBackend::do_blit), (&::gpu::gl::GLBackend::do_blit),
(&::gpu::gl::GLBackend::do_generateTextureMips), (&::gpu::gl::GLBackend::do_generateTextureMips),
(&::gpu::gl::GLBackend::do_advance),
(&::gpu::gl::GLBackend::do_beginQuery), (&::gpu::gl::GLBackend::do_beginQuery),
(&::gpu::gl::GLBackend::do_endQuery), (&::gpu::gl::GLBackend::do_endQuery),
(&::gpu::gl::GLBackend::do_getQuery), (&::gpu::gl::GLBackend::do_getQuery),

View file

@ -123,15 +123,19 @@ public:
// Resource Stage // Resource Stage
virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final; virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final; virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final;
virtual void do_setResourceFramebufferSwapChainTexture(const Batch& batch, size_t paramOffset) final;
// Pipeline Stage // Pipeline Stage
virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final; virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final;
// Output stage // Output stage
virtual void do_setFramebuffer(const Batch& batch, size_t paramOffset) final; virtual void do_setFramebuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_setFramebufferSwapChain(const Batch& batch, size_t paramOffset) final;
virtual void do_clearFramebuffer(const Batch& batch, size_t paramOffset) final; virtual void do_clearFramebuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_blit(const Batch& batch, size_t paramOffset) = 0; virtual void do_blit(const Batch& batch, size_t paramOffset) = 0;
virtual void do_advance(const Batch& batch, size_t paramOffset) final;
// Query section // Query section
virtual void do_beginQuery(const Batch& batch, size_t paramOffset) final; virtual void do_beginQuery(const Batch& batch, size_t paramOffset) final;
virtual void do_endQuery(const Batch& batch, size_t paramOffset) final; virtual void do_endQuery(const Batch& batch, size_t paramOffset) final;
@ -242,6 +246,8 @@ protected:
void setupStereoSide(int side); void setupStereoSide(int side);
#endif #endif
virtual void setResourceTexture(unsigned int slot, const TexturePointer& resourceTexture);
virtual void setFramebuffer(const FramebufferPointer& framebuffer);
virtual void initInput() final; virtual void initInput() final;
virtual void killInput() final; virtual void killInput() final;
virtual void syncInputStateCache() final; virtual void syncInputStateCache() final;

View file

@ -37,6 +37,19 @@ void GLBackend::resetOutputStage() {
void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) { void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) {
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint); auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
setFramebuffer(framebuffer);
}
void GLBackend::do_setFramebufferSwapChain(const Batch& batch, size_t paramOffset) {
auto swapChain = batch._swapChains.get(batch._params[paramOffset]._uint);
if (swapChain) {
auto index = batch._params[paramOffset + 1]._uint;
FramebufferPointer framebuffer = static_cast<const FramebufferSwapChain*>(swapChain.get())->get(index);
setFramebuffer(framebuffer);
}
}
void GLBackend::setFramebuffer(const FramebufferPointer& framebuffer) {
if (_output._framebuffer != framebuffer) { if (_output._framebuffer != framebuffer) {
auto newFBO = getFramebufferID(framebuffer); auto newFBO = getFramebufferID(framebuffer);
if (_output._drawFBO != newFBO) { if (_output._drawFBO != newFBO) {
@ -47,6 +60,13 @@ void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) {
} }
} }
void GLBackend::do_advance(const Batch& batch, size_t paramOffset) {
auto ringbuffer = batch._swapChains.get(batch._params[paramOffset]._uint);
if (ringbuffer) {
ringbuffer->advance();
}
}
void GLBackend::do_clearFramebuffer(const Batch& batch, size_t paramOffset) { void GLBackend::do_clearFramebuffer(const Batch& batch, size_t paramOffset) {
if (_stereo.isStereo() && !_pipeline._stateCache.scissorEnable) { if (_stereo.isStereo() && !_pipeline._stateCache.scissorEnable) {
qWarning("Clear without scissor in stereo mode"); qWarning("Clear without scissor in stereo mode");

View file

@ -251,6 +251,31 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
releaseResourceTexture(slot); releaseResourceTexture(slot);
return; return;
} }
setResourceTexture(slot, resourceTexture);
}
void GLBackend::do_setResourceFramebufferSwapChainTexture(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
if (slot >= (GLuint)MAX_NUM_RESOURCE_TEXTURES) {
qCDebug(gpugllogging) << "GLBackend::do_setResourceFramebufferSwapChainTexture: Trying to set a resource Texture at slot #" << slot << " which doesn't exist. MaxNumResourceTextures = " << getMaxNumResourceTextures();
return;
}
SwapChainPointer swapChain = batch._swapChains.get(batch._params[paramOffset + 0]._uint);
if (!swapChain) {
releaseResourceTexture(slot);
return;
}
auto index = batch._params[paramOffset + 2]._uint;
auto renderBufferSlot = batch._params[paramOffset + 3]._uint;
FramebufferPointer resourceFramebuffer = static_cast<const FramebufferSwapChain*>(swapChain.get())->get(index);
TexturePointer resourceTexture = resourceFramebuffer->getRenderBuffer(renderBufferSlot);
setResourceTexture(slot, resourceTexture);
}
void GLBackend::setResourceTexture(unsigned int slot, const TexturePointer& resourceTexture) {
// check cache before thinking // check cache before thinking
if (_resource._textures[slot] == resourceTexture) { if (_resource._textures[slot] == resourceTexture) {
return; return;
@ -267,11 +292,11 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
glActiveTexture(GL_TEXTURE0 + slot); glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(target, to); glBindTexture(target, to);
(void) CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
_resource._textures[slot] = resourceTexture; _resource._textures[slot] = resourceTexture;
_stats._RSAmountTextureMemoryBounded += (int) object->size(); _stats._RSAmountTextureMemoryBounded += (int)object->size();
} else { } else {
releaseResourceTexture(slot); releaseResourceTexture(slot);

View file

@ -105,7 +105,7 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
if (_viewIsCamera && (_viewCorrectionEnabled && _correction.correction != glm::mat4())) { if (_viewIsCamera && (_viewCorrectionEnabled && _correction.correction != glm::mat4())) {
// FIXME should I switch to using the camera correction buffer in Transform.slf and leave this out? // FIXME should I switch to using the camera correction buffer in Transform.slf and leave this out?
Transform result; Transform result;
_view.mult(result, _view, _correction.correction); _view.mult(result, _view, _correction.correctionInverse);
if (_skybox) { if (_skybox) {
result.setTranslation(vec3()); result.setTranslation(vec3());
} }

View file

@ -173,7 +173,47 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) {
case gpu::RGB: case gpu::RGB:
case gpu::RGBA: case gpu::RGBA:
case gpu::XY: case gpu::XY:
result = GL_RG8; switch (dstFormat.getType()) {
case gpu::UINT32:
result = GL_RG32UI;
break;
case gpu::INT32:
result = GL_RG32I;
break;
case gpu::FLOAT:
result = GL_RG32F;
break;
case gpu::UINT16:
result = GL_RG16UI;
break;
case gpu::INT16:
result = GL_RG16I;
break;
case gpu::HALF:
result = GL_RG16F;
break;
case gpu::UINT8:
result = GL_RG8UI;
break;
case gpu::INT8:
result = GL_RG8I;
break;
case gpu::NUINT8:
result = GL_RG8;
break;
case gpu::NINT8:
result = GL_RG8_SNORM;
break;
case gpu::NUINT32:
case gpu::NINT32:
case gpu::NUINT2:
case gpu::NINT2_10_10_10:
case gpu::COMPRESSED:
case gpu::NUINT16:
case gpu::NINT16:
case gpu::NUM_TYPES: // quiet compiler
Q_UNREACHABLE();
}
break; break;
default: default:
qCWarning(gpugllogging) << "Unknown combination of texel format"; qCWarning(gpugllogging) << "Unknown combination of texel format";
@ -312,7 +352,48 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
case gpu::RGB: case gpu::RGB:
case gpu::RGBA: case gpu::RGBA:
case gpu::XY: case gpu::XY:
texel.internalFormat = GL_RG8; switch (dstFormat.getType()) {
case gpu::UINT32:
texel.internalFormat = GL_RG32UI;
break;
case gpu::INT32:
texel.internalFormat = GL_RG32I;
break;
case gpu::FLOAT:
texel.internalFormat = GL_RG32F;
break;
case gpu::UINT16:
texel.internalFormat = GL_RG16UI;
break;
case gpu::INT16:
texel.internalFormat = GL_RG16I;
break;
case gpu::HALF:
texel.type = GL_FLOAT;
texel.internalFormat = GL_RG16F;
break;
case gpu::UINT8:
texel.internalFormat = GL_RG8UI;
break;
case gpu::INT8:
texel.internalFormat = GL_RG8I;
break;
case gpu::NUINT8:
texel.internalFormat = GL_RG8;
break;
case gpu::NINT8:
texel.internalFormat = GL_RG8_SNORM;
break;
case gpu::NUINT32:
case gpu::NINT32:
case gpu::NUINT2:
case gpu::NINT2_10_10_10:
case gpu::COMPRESSED:
case gpu::NUINT16:
case gpu::NINT16:
case gpu::NUM_TYPES: // quiet compiler
Q_UNREACHABLE();
}
break; break;
default: default:
qCWarning(gpugllogging) << "Unknown combination of texel format"; qCWarning(gpugllogging) << "Unknown combination of texel format";

View file

@ -74,7 +74,7 @@ public:
size_t getNumIndices() const { return _indexBuffer.getNumElements(); } size_t getNumIndices() const { return _indexBuffer.getNumElements(); }
// Access vertex position value // Access vertex position value
const Vec3& getPos3(Index index) const { return _vertexBuffer.get<Vec3>(index); } const Vec3& getPos(Index index) const { return _vertexBuffer.get<Vec3>(index); }
enum Topology { enum Topology {
POINTS = 0, POINTS = 0,

View file

@ -21,7 +21,7 @@ int SimpleMeshProxy::getNumVertices() const {
return (int)_mesh->getNumVertices(); return (int)_mesh->getNumVertices();
} }
glm::vec3 SimpleMeshProxy::getPos3(int index) const { glm::vec3 SimpleMeshProxy::getPos(int index) const {
return _mesh->getPos3(index); return _mesh->getPos(index);
} }

View file

@ -26,8 +26,8 @@ public:
int getNumVertices() const override; int getNumVertices() const override;
glm::vec3 getPos3(int index) const override; glm::vec3 getPos(int index) const override;
glm::vec3 getPos3(int index) const override { return getPos(index); } // deprecated
protected: protected:
const MeshPointer _mesh; const MeshPointer _mesh;

View file

@ -576,7 +576,7 @@ void Connection::processControl(ControlPacketPointer controlPacket) {
// where the other end expired our connection. Let's reset. // where the other end expired our connection. Let's reset.
#ifdef UDT_CONNECTION_DEBUG #ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "Got handshake request, stopping SendQueue"; qCDebug(networking) << "Got HandshakeRequest from" << _destination << ", stopping SendQueue";
#endif #endif
_hasReceivedHandshakeACK = false; _hasReceivedHandshakeACK = false;
stopSendQueue(); stopSendQueue();

View file

@ -402,6 +402,10 @@ void Socket::readPendingDatagrams() {
packet->getDataSize(), packet->getDataSize(),
packet->getPayloadSize())) { packet->getPayloadSize())) {
// the connection could not be created or indicated that we should not continue processing this packet // the connection could not be created or indicated that we should not continue processing this packet
#ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "Can't process packet: version" << (unsigned int)NLPacket::versionInHeader(*packet)
<< ", type" << NLPacket::typeInHeader(*packet);
#endif
continue; continue;
} }
} }

View file

@ -188,11 +188,13 @@ bool OffscreenSurface::eventFilter(QObject* originalDestination, QEvent* event)
event->ignore(); event->ignore();
if (QCoreApplication::sendEvent(window->activeFocusItem(), event)) { if (QCoreApplication::sendEvent(window->activeFocusItem(), event)) {
bool eventAccepted = event->isAccepted(); bool eventAccepted = event->isAccepted();
QInputMethodQueryEvent* imqEvent = static_cast<QInputMethodQueryEvent*>(event); if (event->type() == QEvent::InputMethodQuery) {
// this block disables the selection cursor in android which appears in QInputMethodQueryEvent *imqEvent = static_cast<QInputMethodQueryEvent *>(event);
// the top-left corner of the screen // this block disables the selection cursor in android which appears in
if (imqEvent->queries() & Qt::ImEnabled) { // the top-left corner of the screen
imqEvent->setValue(Qt::ImEnabled, QVariant(false)); if (imqEvent->queries() & Qt::ImEnabled) {
imqEvent->setValue(Qt::ImEnabled, QVariant(false));
}
} }
return eventAccepted; return eventAccepted;
} }

View file

@ -88,7 +88,7 @@ class AntialiasingConfig : public render::Job::Config {
Q_PROPERTY(float blend MEMBER blend NOTIFY dirty) Q_PROPERTY(float blend MEMBER blend NOTIFY dirty)
Q_PROPERTY(float sharpen MEMBER sharpen NOTIFY dirty) Q_PROPERTY(float sharpen MEMBER sharpen NOTIFY dirty)
Q_PROPERTY(float covarianceGamma MEMBER covarianceGamma NOTIFY dirty) Q_PROPERTY(float covarianceGamma MEMBER covarianceGamma NOTIFY dirty)
Q_PROPERTY(bool constrainColor MEMBER constrainColor NOTIFY dirty) Q_PROPERTY(bool constrainColor MEMBER constrainColor NOTIFY dirty)
Q_PROPERTY(bool feedbackColor MEMBER feedbackColor NOTIFY dirty) Q_PROPERTY(bool feedbackColor MEMBER feedbackColor NOTIFY dirty)

View file

@ -98,6 +98,12 @@ void CompositeHUD::run(const RenderContextPointer& renderContext) {
// Grab the HUD texture // Grab the HUD texture
#if !defined(DISABLE_QML) #if !defined(DISABLE_QML)
gpu::doInBatch("CompositeHUD", renderContext->args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("CompositeHUD", renderContext->args->_context, [&](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
renderContext->args->getViewFrustum().evalProjectionMatrix(projMat);
renderContext->args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat, true);
if (renderContext->args->_hudOperator) { if (renderContext->args->_hudOperator) {
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE); renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
} }

View file

@ -363,12 +363,13 @@ public:
/**jsdoc /**jsdoc
* Get the position of a vertex in the mesh. * Get the position of a vertex in the mesh.
* @function MeshProxy#getPos3 * @function MeshProxy#getPos
* @param {number} index - Integer index of the mesh vertex. * @param {number} index - Integer index of the mesh vertex.
* @returns {Vec3} Local position of the vertex relative to the mesh. * @returns {Vec3} Local position of the vertex relative to the mesh.
* @deprecated Use the {@link Graphics} API instead. * @deprecated Use the {@link Graphics} API instead.
*/ */
Q_INVOKABLE virtual glm::vec3 getPos3(int index) const = 0; Q_INVOKABLE virtual glm::vec3 getPos(int index) const = 0;
Q_INVOKABLE virtual glm::vec3 getPos3(int index) const { return getPos(index); } // deprecated
}; };
Q_DECLARE_METATYPE(MeshProxy*); Q_DECLARE_METATYPE(MeshProxy*);

View file

@ -17,7 +17,7 @@ var currentSelectedBtn;
var SETTING_CURRENT_MODE_KEY = 'Android/Mode'; var SETTING_CURRENT_MODE_KEY = 'Android/Mode';
var MODE_VR = "VR", MODE_RADAR = "RADAR", MODE_MY_VIEW = "MY VIEW"; var MODE_VR = "VR", MODE_RADAR = "RADAR", MODE_MY_VIEW = "MY VIEW";
var DEFAULT_MODE = MODE_RADAR; var DEFAULT_MODE = MODE_MY_VIEW;
var logEnabled = true; var logEnabled = true;
var radar = Script.require('./radar.js'); var radar = Script.require('./radar.js');