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

This commit is contained in:
samcake 2016-11-10 10:05:03 -08:00
commit 784a0540ed
17 changed files with 214 additions and 100 deletions

View file

@ -278,6 +278,13 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
tree->setWantEditLogging(wantEditLogging);
tree->setWantTerseEditLogging(wantTerseEditLogging);
QString entityScriptSourceWhitelist;
if (readOptionString("entityScriptSourceWhitelist", settingsSectionObject, entityScriptSourceWhitelist)) {
tree->setEntityScriptSourceWhitelist(entityScriptSourceWhitelist);
} else {
tree->setEntityScriptSourceWhitelist("");
}
}
void EntityServer::nodeAdded(SharedNodePointer node) {

View file

@ -1075,6 +1075,14 @@
"default": "3600",
"advanced": true
},
{
"name": "entityScriptSourceWhitelist",
"label": "Entity Scripts Allowed from:",
"help": "The domains that entity scripts are allowed from. A comma separated list of domains that entity scripts are allowed from, if someone attempts to create and entity or edit an entity to have a different domain, it will be rejected. If left blank, any domain is allowed.",
"placeholder": "",
"default": "",
"advanced": true
},
{
"name": "persistFilePath",
"label": "Entities File Path",

View file

@ -387,21 +387,9 @@ Menu::Menu() {
});
#ifdef Q_OS_WIN
#define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5
bool recommendedIncrementalTransfers = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
bool recommendedSparseTextures = recommendedIncrementalTransfers;
qDebug() << "[TEXTURE TRANSFER SUPPORT]"
<< "\n\tidealThreadCount:" << QThread::idealThreadCount()
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures
<< "\n\tRECOMMENDED enableIncrementalTextures:" << recommendedIncrementalTransfers;
gpu::Texture::setEnableIncrementalTextureTransfers(recommendedIncrementalTransfers);
gpu::Texture::setEnableSparseTextures(recommendedSparseTextures);
// Developer > Render > Enable Dynamic Texture Management
// Developer > Render > Enable Sparse Textures
{
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableDynamicTextureManagement, 0, recommendedSparseTextures);
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::SparseTextureManagement, 0, gpu::Texture::getEnableSparseTextures());
connect(action, &QAction::triggered, [&](bool checked) {
qDebug() << "[TEXTURE TRANSFER SUPPORT] --- Enable Dynamic Texture Management menu option:" << checked;
gpu::Texture::setEnableSparseTextures(checked);
@ -410,7 +398,7 @@ Menu::Menu() {
// Developer > Render > Enable Incremental Texture Transfer
{
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableIncrementalTextureTransfer, 0, recommendedIncrementalTransfers);
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::IncrementalTextureTransfer, 0, gpu::Texture::getEnableIncrementalTextureTransfers());
connect(action, &QAction::triggered, [&](bool checked) {
qDebug() << "[TEXTURE TRANSFER SUPPORT] --- Enable Incremental Texture Transfer menu option:" << checked;
gpu::Texture::setEnableIncrementalTextureTransfers(checked);

View file

@ -97,8 +97,6 @@ namespace MenuOption {
const QString EchoLocalAudio = "Echo Local Audio";
const QString EchoServerAudio = "Echo Server Audio";
const QString EnableCharacterController = "Enable avatar collisions";
const QString EnableIncrementalTextureTransfer = "Enable Incremental Texture Transfer";
const QString EnableDynamicTextureManagement = "Enable Dynamic Texture Management";
const QString EnableInverseKinematics = "Enable Inverse Kinematics";
const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
const QString ExpandMyAvatarTiming = "Expand /myAvatar";
@ -114,6 +112,7 @@ namespace MenuOption {
const QString FrameTimer = "Show Timer";
const QString FullscreenMirror = "Mirror";
const QString Help = "Help...";
const QString IncrementalTextureTransfer = "Enable Incremental Texture Transfer";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IndependentMode = "Independent Mode";
const QString ActionMotorControl = "Enable Default Motor Control";
@ -180,6 +179,7 @@ namespace MenuOption {
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode";
const QString SimulateEyeTracking = "Simulate";
const QString SMIEyeTracking = "SMI Eye Tracking";
const QString SparseTextureManagement = "Enable Sparse Texture Management";
const QString Stats = "Stats";
const QString StopAllScripts = "Stop All Scripts";
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";

View file

@ -235,6 +235,14 @@ void Avatar::updateAvatarEntities() {
properties.setParentID(getID());
}
// NOTE: if this avatar entity is not attached to us, strip its entity script completely...
auto attachedScript = properties.getScript();
if (!isMyAvatar() && !attachedScript.isEmpty()) {
qCDebug(interfaceapp) << "removing entity script from avatar attached entity:" << entityID << "old script:" << attachedScript;
QString noScript;
properties.setScript(noScript);
}
EntityItemPointer entity = entityTree->findEntityByEntityItemID(EntityItemID(entityID));
if (entity) {

View file

@ -63,6 +63,11 @@ EntityTree::~EntityTree() {
eraseAllOctreeElements(false);
}
void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) {
_entityScriptSourceWhitelist = entityScriptSourceWhitelist.split(',');
}
void EntityTree::createRootElement() {
_rootElement = createNewElement();
}
@ -925,6 +930,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
quint64 startCreate = 0, endCreate = 0;
quint64 startLogging = 0, endLogging = 0;
const quint64 LAST_EDITED_SERVERSIDE_BUMP = 1; // usec
bool suppressDisallowedScript = false;
_totalEditMessages++;
EntityItemID entityItemID;
@ -935,7 +943,31 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
entityItemID, properties);
endDecode = usecTimestampNow();
const quint64 LAST_EDITED_SERVERSIDE_BUMP = 1; // usec
if (validEditPacket && !_entityScriptSourceWhitelist.isEmpty() && !properties.getScript().isEmpty()) {
bool passedWhiteList = false;
auto entityScript = properties.getScript();
for (const auto& whiteListedPrefix : _entityScriptSourceWhitelist) {
if (entityScript.startsWith(whiteListedPrefix, Qt::CaseInsensitive)) {
passedWhiteList = true;
break;
}
}
if (!passedWhiteList) {
if (wantEditLogging()) {
qCDebug(entities) << "User [" << senderNode->getUUID() << "] attempting to set entity script not on whitelist, edit rejected";
}
// If this was an add, we also want to tell the client that sent this edit that the entity was not added.
if (message.getType() == PacketType::EntityAdd) {
QWriteLocker locker(&_recentlyDeletedEntitiesLock);
_recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID);
validEditPacket = passedWhiteList;
} else {
suppressDisallowedScript = true;
}
}
}
if ((message.getType() == PacketType::EntityAdd ||
(message.getType() == PacketType::EntityEdit && properties.lifetimeChanged())) &&
!senderNode->getCanRez() && senderNode->getCanRezTmp()) {
@ -960,6 +992,12 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
endLookup = usecTimestampNow();
if (existingEntity && message.getType() == PacketType::EntityEdit) {
if (suppressDisallowedScript) {
properties.setLastEdited(properties.getLastEdited() + LAST_EDITED_SERVERSIDE_BUMP);
properties.setScript(existingEntity->getScript());
}
// if the EntityItem exists, then update it
startLogging = usecTimestampNow();
if (wantEditLogging()) {

View file

@ -64,6 +64,7 @@ public:
void setEntityMaxTmpLifetime(float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; }
void setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist);
/// Implements our type specific root element factory
virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override;
@ -342,6 +343,8 @@ protected:
QHash<QUuid, QSet<EntityItemID>> _childrenOfAvatars; // which entities are children of which avatars
float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME };
QStringList _entityScriptSourceWhitelist;
};
#endif // hifi_EntityTree_h

View file

@ -177,7 +177,6 @@ public:
virtual void queueLambda(const std::function<void()> lambda) const;
bool isTextureManagementSparseEnabled() const override { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); }
bool isTextureManagementIncrementalTransferEnabled() const override { return (_textureManagement._incrementalTransferCapable && Texture::getEnableIncrementalTextureTransfers()); }
protected:
@ -369,7 +368,6 @@ protected:
struct TextureManagementStageState {
bool _sparseCapable { false };
bool _incrementalTransferCapable { false };
} _textureManagement;
virtual void initTextureManagementStage() {}

View file

@ -116,7 +116,7 @@ float GLTexture::getMemoryPressure() {
}
// Return the consumed texture memory divided by the available texture memory.
auto consumedGpuMemory = Context::getTextureGPUSparseMemoryUsage();
auto consumedGpuMemory = Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage();
float memoryPressure = (float)consumedGpuMemory / (float)availableTextureMemory;
static Context::Size lastConsumedGpuMemory = 0;
if (memoryPressure > 1.0f && lastConsumedGpuMemory != consumedGpuMemory) {

View file

@ -94,6 +94,7 @@ public:
TransferState _transferState;
uint32_t _allocatedPages { 0 };
uint32_t _lastMipAllocatedPages { 0 };
uint16_t _mipOffset { 0 };
friend class GL45Backend;
};

View file

@ -148,13 +148,9 @@ uint32_t SparseInfo::getPageCount(const uvec3& dimensions) const {
return pageCounts.x * pageCounts.y * pageCounts.z;
}
void GL45Backend::initTextureManagementStage() {
// enable the Sparse Texture on gl45
_textureManagement._sparseCapable = true;
_textureManagement._incrementalTransferCapable = true;
// But now let s refine the behavior based on vendor
std::string vendor { (const char*)glGetString(GL_VENDOR) };
@ -282,20 +278,22 @@ GL45Texture::~GL45Texture() {
if (!_gpuObject.getUsage().isExternal()) {
qCDebug(gpugl45logging) << "Destroying texture " << _id << " from source " << _source.c_str();
}
if (_sparseInfo.sparse) {
Backend::decrementTextureGPUSparseCount();
// Remove this texture from the candidate list of derezzable textures
{
auto mipLevels = usedMipLevels();
Lock lock(texturesByMipCountsMutex);
if (texturesByMipCounts.count(mipLevels)) {
auto& textures = texturesByMipCounts[mipLevels];
textures.erase(this);
if (textures.empty()) {
texturesByMipCounts.erase(mipLevels);
}
// Remove this texture from the candidate list of derezzable textures
if (_transferrable) {
auto mipLevels = usedMipLevels();
Lock lock(texturesByMipCountsMutex);
if (texturesByMipCounts.count(mipLevels)) {
auto& textures = texturesByMipCounts[mipLevels];
textures.erase(this);
if (textures.empty()) {
texturesByMipCounts.erase(mipLevels);
}
}
}
if (_sparseInfo.sparse) {
Backend::decrementTextureGPUSparseCount();
// Experimenation suggests that allocating sparse textures on one context/thread and deallocating
// them on another is buggy. So for sparse textures we need to queue a lambda with the deallocation
@ -355,7 +353,7 @@ void GL45Texture::allocateStorage() const {
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip);
// Get the dimensions, accounting for the downgrade level
Vec3u dimensions = _gpuObject.evalMipDimensions(_minMip);
Vec3u dimensions = _gpuObject.evalMipDimensions(_minMip + _mipOffset);
glTextureStorage2D(_id, usedMipLevels(), _internalFormat, dimensions.x, dimensions.y);
(void)CHECK_GL_ERROR();
}
@ -370,7 +368,7 @@ void GL45Texture::updateSize() const {
Backend::updateTextureGPUSparseMemoryUsage(_size, size);
setSize(_allocatedPages * _sparseInfo.pageBytes);
} else {
setSize(_virtualSize);
setSize(_gpuObject.evalTotalSize(_mipOffset));
}
}
@ -381,15 +379,18 @@ void GL45Texture::startTransfer() {
}
bool GL45Texture::continueTransfer() {
auto backend = _backend.lock();
if (!backend || !backend->isTextureManagementIncrementalTransferEnabled()) {
if (!Texture::getEnableIncrementalTextureTransfers()) {
size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1;
for (uint8_t face = 0; face < maxFace; ++face) {
for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) {
auto size = _gpuObject.evalMipDimensions(mipLevel);
if (_sparseInfo.sparse && mipLevel <= _sparseInfo.maxSparseLevel) {
glTexturePageCommitmentEXT(_id, mipLevel, 0, 0, face, size.x, size.y, 1, GL_TRUE);
_allocatedPages += _sparseInfo.getPageCount(size);
}
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
auto size = _gpuObject.evalMipDimensions(mipLevel);
if (GL_TEXTURE_2D == _target) {
glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
} else if (GL_TEXTURE_CUBE_MAP == _target) {
@ -481,35 +482,30 @@ void GL45Texture::syncSampler() const {
glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]);
glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]);
glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor());
// FIXME account for mip offsets here
auto baseMip = std::max<uint16_t>(sampler.getMipOffset(), _minMip);
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, baseMip);
glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip());
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip() - _mipOffset));
glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
}
void GL45Texture::postTransfer() {
Parent::postTransfer();
if (_sparseInfo.sparse) {
auto mipLevels = usedMipLevels();
if (mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
Lock lock(texturesByMipCountsMutex);
texturesByMipCounts[mipLevels].insert(this);
}
auto mipLevels = usedMipLevels();
if (_transferrable && mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
Lock lock(texturesByMipCountsMutex);
texturesByMipCounts[mipLevels].insert(this);
}
}
void GL45Texture::stripToMip(uint16_t newMinMip) {
if (!_sparseInfo.sparse) {
return;
}
if (newMinMip < _minMip) {
qCWarning(gpugl45logging) << "Cannot decrease the min mip";
return;
}
if (newMinMip > _sparseInfo.maxSparseLevel) {
if (_sparseInfo.sparse && newMinMip > _sparseInfo.maxSparseLevel) {
qCWarning(gpugl45logging) << "Cannot increase the min mip into the mip tail";
return;
}
@ -533,26 +529,60 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
uint8_t maxFace = (uint8_t)((_target == GL_TEXTURE_CUBE_MAP) ? GLTexture::CUBE_NUM_FACES : 1);
for (uint16_t mip = _minMip; mip < newMinMip; ++mip) {
auto id = _id;
auto mipDimensions = _gpuObject.evalMipDimensions(mip);
_textureTransferHelper->queueExecution([id, mip, mipDimensions, maxFace] {
glTexturePageCommitmentEXT(id, mip, 0, 0, 0, mipDimensions.x, mipDimensions.y, maxFace, GL_FALSE);
});
if (_sparseInfo.sparse) {
for (uint16_t mip = _minMip; mip < newMinMip; ++mip) {
auto id = _id;
auto mipDimensions = _gpuObject.evalMipDimensions(mip);
_textureTransferHelper->queueExecution([id, mip, mipDimensions, maxFace] {
glTexturePageCommitmentEXT(id, mip, 0, 0, 0, mipDimensions.x, mipDimensions.y, maxFace, GL_FALSE);
});
auto deallocatedPages = _sparseInfo.getPageCount(mipDimensions) * maxFace;
assert(deallocatedPages < _allocatedPages);
_allocatedPages -= deallocatedPages;
auto deallocatedPages = _sparseInfo.getPageCount(mipDimensions) * maxFace;
assert(deallocatedPages < _allocatedPages);
_allocatedPages -= deallocatedPages;
}
_minMip = newMinMip;
} else {
GLuint oldId = _id;
// Find the distance between the old min mip and the new one
uint16 mipDelta = newMinMip - _minMip;
_mipOffset += mipDelta;
const_cast<uint16&>(_maxMip) -= mipDelta;
auto newLevels = usedMipLevels();
// Create and setup the new texture (allocate)
glCreateTextures(_target, 1, &const_cast<GLuint&>(_id));
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip);
Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset);
glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y);
// Copy the contents of the old texture to the new
GLuint fbo { 0 };
glCreateFramebuffers(1, &fbo);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) {
uint16 sourceMip = targetMip + mipDelta;
Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset);
for (GLenum target : getFaceTargets(_target)) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip);
(void)CHECK_GL_ERROR();
glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y);
(void)CHECK_GL_ERROR();
}
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &oldId);
}
_minMip = newMinMip;
// Re-sync the sampler to force access to the new mip level
syncSampler();
updateSize();
// Re-insert into the texture-by-mips map if appropriate
mipLevels = usedMipLevels();
if (_sparseInfo.sparse && mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
if (mipLevels > 1 && (!_sparseInfo.sparse || _minMip < _sparseInfo.maxSparseLevel)) {
Lock lock(texturesByMipCountsMutex);
texturesByMipCounts[mipLevels].insert(this);
}
@ -569,8 +599,9 @@ void GL45Texture::updateMips() {
}
void GL45Texture::derez() {
assert(_sparseInfo.sparse);
assert(_minMip < _sparseInfo.maxSparseLevel);
if (_sparseInfo.sparse) {
assert(_minMip < _sparseInfo.maxSparseLevel);
}
assert(_minMip < _maxMip);
assert(_transferrable);
stripToMip(_minMip + 1);
@ -594,7 +625,7 @@ void GL45Backend::derezTextures() const {
}
qCDebug(gpugl45logging) << "Allowed texture memory " << Texture::getAllowedGPUMemoryUsage();
qCDebug(gpugl45logging) << "Used texture memory " << Context::getTextureGPUMemoryUsage();
qCDebug(gpugl45logging) << "Used texture memory " << (Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage());
GL45Texture* targetTexture = nullptr;
{
@ -604,5 +635,5 @@ void GL45Backend::derezTextures() const {
}
lock.unlock();
targetTexture->derez();
qCDebug(gpugl45logging) << "New Used texture memory " << Context::getTextureGPUMemoryUsage();
qCDebug(gpugl45logging) << "New Used texture memory " << (Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage());
}

View file

@ -86,7 +86,6 @@ public:
void getStats(ContextStats& stats) const { stats = _stats; }
virtual bool isTextureManagementSparseEnabled() const = 0;
virtual bool isTextureManagementIncrementalTransferEnabled() const = 0;
// These should only be accessed by Backend implementation to repport the buffer and texture allocations,
// they are NOT public calls

View file

@ -10,11 +10,13 @@
//
#include <QtCore/QDebug>
#include "Texture.h"
#include <glm/gtc/constants.hpp>
#include <glm/gtx/component_wise.hpp>
#include <QtCore/QDebug>
#include <QtCore/QThread>
#include <NumericalConstants.h>
@ -31,16 +33,27 @@ std::atomic<uint32_t> Texture::_textureCPUCount{ 0 };
std::atomic<Texture::Size> Texture::_textureCPUMemoryUsage{ 0 };
std::atomic<Texture::Size> Texture::_allowedCPUMemoryUsage { 0 };
std::atomic<bool> Texture::_enableSparseTextures { false };
std::atomic<bool> Texture::_enableIncrementalTextureTransfers { false };
#define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5
bool recommendedIncrementalTransfers = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
bool recommendedSparseTextures = recommendedIncrementalTransfers;
std::atomic<bool> Texture::_enableSparseTextures { recommendedIncrementalTransfers };
std::atomic<bool> Texture::_enableIncrementalTextureTransfers { recommendedSparseTextures };
struct ReportTextureState {
ReportTextureState() {
qDebug() << "[TEXTURE TRANSFER SUPPORT]"
<< "\n\tidealThreadCount:" << QThread::idealThreadCount()
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures
<< "\n\tRECOMMENDED enableIncrementalTextures:" << recommendedIncrementalTransfers;
}
} report;
void Texture::setEnableSparseTextures(bool enabled) {
#ifdef Q_OS_WIN
qDebug() << "[TEXTURE TRANSFER SUPPORT] SETTING - Enable Sparse Textures and Dynamic Texture Management:" << enabled;
_enableSparseTextures = enabled;
if (!_enableIncrementalTextureTransfers && _enableSparseTextures) {
qDebug() << "[TEXTURE TRANSFER SUPPORT] WARNING - Sparse texture management requires incremental texture transfer enabled.";
}
#else
qDebug() << "[TEXTURE TRANSFER SUPPORT] Sparse Textures and Dynamic Texture Management not supported on this platform.";
#endif
@ -50,9 +63,6 @@ void Texture::setEnableIncrementalTextureTransfers(bool enabled) {
#ifdef Q_OS_WIN
qDebug() << "[TEXTURE TRANSFER SUPPORT] SETTING - Enable Incremental Texture Transfer:" << enabled;
_enableIncrementalTextureTransfers = enabled;
if (!_enableIncrementalTextureTransfers && _enableSparseTextures) {
qDebug() << "[TEXTURE TRANSFER SUPPORT] WARNING - Sparse texture management requires incremental texture transfer enabled.";
}
#else
qDebug() << "[TEXTURE TRANSFER SUPPORT] Incremental Texture Transfer not supported on this platform.";
#endif
@ -418,12 +428,18 @@ uint16 Texture::evalDimNumMips(uint16 size) {
return 1 + (uint16) val;
}
static const double LOG_2 = log(2.0);
uint16 Texture::evalNumMips(const Vec3u& dimensions) {
double largerDim = glm::compMax(dimensions);
double val = log(largerDim) / LOG_2;
return 1 + (uint16)val;
}
// The number mips that the texture could have if all existed
// = log2(max(width, height, depth))
uint16 Texture::evalNumMips() const {
double largerDim = std::max(std::max(_width, _height), _depth);
double val = log(largerDim)/log(2.0);
return 1 + (uint16) val;
return evalNumMips({ _width, _height, _depth });
}
bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes) {

View file

@ -369,9 +369,12 @@ public:
// = 1 + log2(max(width, height, depth))
uint16 evalNumMips() const;
static uint16 evalNumMips(const Vec3u& dimensions);
// Eval the size that the mips level SHOULD have
// not the one stored in the Texture
static const uint MIN_DIMENSION = 1;
Vec3u evalMipDimensions(uint16 level) const;
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
@ -388,9 +391,9 @@ public:
uint32 evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); }
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
uint32 evalTotalSize() const {
uint32 evalTotalSize(uint16 startingMip = 0) const {
uint32 size = 0;
uint16 minMipLevel = minMip();
uint16 minMipLevel = std::max(minMip(), startingMip);
uint16 maxMipLevel = maxMip();
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
size += evalMipSize(l);

View file

@ -12,6 +12,7 @@
#include <QtQml>
#include <QMenuBar>
#include <QDebug>
#include "OffscreenUi.h"
@ -58,6 +59,18 @@ public:
_qml->setProperty("visible", _action->isVisible());
}
void clear() {
_qml->setProperty("checkable", 0);
_qml->setProperty("enabled", 0);
_qml->setProperty("text", 0);
_qml->setProperty("shortcut", 0);
_qml->setProperty("checked", 0);
_qml->setProperty("visible", 0);
_action->setUserData(USER_DATA_ID, nullptr);
_qml->setUserData(USER_DATA_ID, nullptr);
}
const QUuid uuid{ QUuid::createUuid() };
@ -217,6 +230,7 @@ void VrMenu::insertAction(QAction* before, QAction* action) {
}
class QQuickMenuBase;
class QQuickMenu1;
void VrMenu::removeAction(QAction* action) {
if (!action) {
@ -228,10 +242,7 @@ void VrMenu::removeAction(QAction* action) {
qWarning("Attempted to remove menu action with no found QML object");
return;
}
QObject* item = findMenuObject(userData->uuid.toString());
QObject* menu = item->parent();
// Proxy QuickItem requests through the QML layer
QQuickMenuBase* qmlItem = reinterpret_cast<QQuickMenuBase*>(item);
QMetaObject::invokeMethod(menu, "removeItem", Qt::DirectConnection, Q_ARG(QQuickMenuBase*, qmlItem));
userData->clear();
delete userData;
}

View file

@ -84,7 +84,7 @@ void Menu::scanMenu(QMenu& menu, settingsAction modifySetting, Settings& setting
groups.pop_back();
}
void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
int menuItemLocation, const QString& grouping) {
QAction* actionBefore = NULL;
QAction* separator;
@ -123,7 +123,7 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QObject* receiver,
const char* member,
QAction::MenuRole role,
int menuItemLocation,
int menuItemLocation,
const QString& grouping) {
QAction* action = NULL;
QAction* actionBefore = NULL;
@ -165,7 +165,7 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QString& actionName,
const QKeySequence& shortcut,
QAction::MenuRole role,
int menuItemLocation,
int menuItemLocation,
const QString& grouping) {
QAction* actionBefore = NULL;
@ -207,7 +207,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMe
const bool checked,
const QObject* receiver,
const char* member,
int menuItemLocation,
int menuItemLocation,
const QString& grouping) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member,
@ -408,6 +408,10 @@ void Menu::removeMenu(const QString& menuName) {
parent->removeAction(action);
} else {
QMenuBar::removeAction(action);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->removeAction(action);
});
}
QMenuBar::repaint();
@ -496,15 +500,15 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) {
void Menu::addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected, QObject* receiver, const char* slot) {
auto menu = addMenu(groupName);
QActionGroup* actionGroup = new QActionGroup(menu);
actionGroup->setExclusive(true);
for (auto action : actionList) {
auto item = addCheckableActionToQMenuAndActionHash(menu, action, 0, action == selected, receiver, slot);
actionGroup->addAction(item);
}
QMenuBar::repaint();
}
@ -582,4 +586,3 @@ void MenuWrapper::insertAction(QAction* before, QAction* action) {
vrMenu->insertAction(before, action);
});
}

View file

@ -598,7 +598,7 @@ protected:
return;
case Qt::Key_End:
gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(256));
gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(64));
return;