diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index acd14fc711..3833d8f2d8 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -256,6 +256,11 @@ Item { font.pixelSize: root.fontSize text: "GPU Buffers: " + root.gpuBuffers; } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + text: "QML Texture Memory: " + root.qmlTextureMemory + " MB"; + } Text { color: root.fontColor; font.pixelSize: root.fontSize diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 10773f20c9..7600f0f495 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -287,6 +287,7 @@ void Stats::updateStats(bool force) { STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount()); STAT_UPDATE(gpuTextures, (int)gpu::Context::getTextureGPUCount()); + STAT_UPDATE(qmlTextureMemory, (int)BYTES_TO_MB(OffscreenQmlSurface::getUsedTextureMemory())); // Incoming packets QLocale locale(QLocale::English); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index dec3ef91f5..1d744a29ec 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -89,6 +89,7 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, localLeaves, 0) STATS_PROPERTY(int, gpuBuffers, 0) STATS_PROPERTY(int, gpuTextures, 0) + STATS_PROPERTY(int, qmlTextureMemory, 0) public: static Stats* getInstance(); @@ -176,6 +177,7 @@ signals: void timingStatsChanged(); void gpuBuffersChanged(); void gpuTexturesChanged(); + void qmlTextureMemoryChanged(); private: int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index c45a3323db..1e26f3b8ad 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -108,14 +108,23 @@ public: } } + size_t getUsedTextureMemory() { return _totalTextureUsage; } private: static void waitOnFence(GLsync fence) { glWaitSync(fence, 0, GL_TIMEOUT_IGNORED); glDeleteSync(fence); } + static size_t getMemoryForSize(const uvec2& size) { + // Base size + mips + return static_cast(((size.x * size.y) << 2) * 1.33f); + } + void destroyTexture(GLuint texture) { --_allTextureCount; + auto size = _textureSizes[texture]; + assert(getMemoryForSize(size) < _totalTextureUsage); + _totalTextureUsage -= getMemoryForSize(size); _textureSizes.erase(texture); glDeleteTextures(1, &texture); } @@ -131,6 +140,7 @@ private: glGenTextures(1, &newTexture); ++_allTextureCount; _textureSizes[newTexture] = size; + _totalTextureUsage += getMemoryForSize(size); glBindTexture(GL_TEXTURE_2D, newTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -177,6 +187,7 @@ private: Mutex _mutex; std::list _returnedTextures; uint64_t _lastReport { 0 }; + size_t _totalTextureUsage { 0 }; } offscreenTextures; class UrlHandler : public QObject { @@ -217,6 +228,10 @@ private: friend class OffscreenQmlSurface; }; +size_t OffscreenQmlSurface::getUsedTextureMemory() { + return offscreenTextures.getUsedTextureMemory(); +} + class QmlNetworkAccessManager : public NetworkAccessManager { public: friend class QmlNetworkAccessManagerFactory; diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h index 43f6e44f86..f6168e7b6d 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.h +++ b/libraries/gl/src/gl/OffscreenQmlSurface.h @@ -89,6 +89,7 @@ public: bool fetchTexture(TextureAndFence& textureAndFence); static std::function getDiscardLambda(); + static size_t getUsedTextureMemory(); signals: void focusObjectChanged(QObject* newFocus); diff --git a/scripts/developer/tests/webSpawnTool.js b/scripts/developer/tests/webSpawnTool.js index 596fb08bde..6496fc445a 100644 --- a/scripts/developer/tests/webSpawnTool.js +++ b/scripts/developer/tests/webSpawnTool.js @@ -74,7 +74,8 @@ ENTITY_SPAWNER = function (properties) { for (; n > 0; --n) { entities.push(makeEntity({ type: "Web", - sourceUrl: "https://www.reddit.com/r/random/", + //sourceUrl: "https://www.reddit.com/r/random/", + sourceUrl: "https://en.wikipedia.org/wiki/Special:Random", name: TEST_ENTITY_NAME, position: randomPositionXZ(center, RADIUS), rotation: MyAvatar.orientation,