diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 80e444462f..49f8fe8a0a 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -1498,6 +1498,9 @@ void Application::cleanupBeforeQuit() {
     DependencyManager::get<ScriptEngines>()->shutdownScripting(); // stop all currently running global scripts
     DependencyManager::destroy<ScriptEngines>();
 
+    _displayPlugin.reset();
+    PluginManager::getInstance()->shutdown();
+
     // Cleanup all overlays after the scripts, as scripts might add more
     _overlays.cleanupAllOverlays();
 
diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp
index f4937c4459..6fa89f299e 100644
--- a/interface/src/ui/ApplicationOverlay.cpp
+++ b/interface/src/ui/ApplicationOverlay.cpp
@@ -258,7 +258,7 @@ void ApplicationOverlay::buildFramebufferObject() {
 
     auto uiSize = qApp->getUiSize();
     if (!_overlayFramebuffer || uiSize != _overlayFramebuffer->getSize()) {
-        _overlayFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+        _overlayFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ApplicationOverlay"));
     }
 
     auto width = uiSize.x;
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
index 4a5021155f..02e5a064f5 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
@@ -356,6 +356,7 @@ void OpenGLDisplayPlugin::customizeContext() {
                         gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), 
                         image.width(), image.height(), 
                         gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
+                cursorData.texture->setSource("cursor texture");
                 auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
                 cursorData.texture->setUsage(usage.build());
                 cursorData.texture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits());
@@ -413,8 +414,6 @@ void OpenGLDisplayPlugin::customizeContext() {
             _cursorPipeline = gpu::Pipeline::create(program, state);
         }
     }
-    auto renderSize = getRecommendedRenderSize();
-    _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
 }
 
 void OpenGLDisplayPlugin::uncustomizeContext() {
@@ -424,6 +423,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() {
     _compositeFramebuffer.reset();
     withPresentThreadLock([&] {
         _currentFrame.reset();
+        _lastFrame = nullptr;
         while (!_newFrameQueue.empty()) {
             _gpuContext->consumeFrameUpdates(_newFrameQueue.front());
             _newFrameQueue.pop();
@@ -559,7 +559,7 @@ void OpenGLDisplayPlugin::compositeScene() {
 void OpenGLDisplayPlugin::compositeLayers() {
     auto renderSize = getRecommendedRenderSize();
     if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
-        _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
+        _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("displayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
     }
 
     {
@@ -611,10 +611,10 @@ void OpenGLDisplayPlugin::present() {
         {
             withPresentThreadLock([&] {
                 _renderRate.increment();
-                if (_currentFrame != _lastFrame) {
+                if (_currentFrame.get() != _lastFrame) {
                     _newFrameRate.increment();
                 }
-                _lastFrame = _currentFrame;
+                _lastFrame = _currentFrame.get();
             });
             // Execute the frame rendering commands
             PROFILE_RANGE_EX("execute", 0xff00ff00, (uint64_t)presentCount())
@@ -755,3 +755,8 @@ void OpenGLDisplayPlugin::render(std::function<void(gpu::Batch& batch)> f) {
     f(batch);
     _gpuContext->executeBatch(batch);
 }
+
+
+OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
+    qDebug() << "Destroying OpenGLDisplayPlugin";
+}
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
index 74f8cdbc10..9369f6d72c 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
@@ -36,6 +36,7 @@ protected:
     using Lock = std::unique_lock<Mutex>;
     using Condition = std::condition_variable;
 public:
+    ~OpenGLDisplayPlugin();
     // These must be final to ensure proper ordering of operations 
     // between the main thread and the presentation thread
     bool activate() override final;
@@ -115,7 +116,7 @@ protected:
     RateCounter<> _renderRate;
 
     gpu::FramePointer _currentFrame;
-    gpu::FramePointer _lastFrame;
+    gpu::Frame* _lastFrame { nullptr };
     gpu::FramebufferPointer _compositeFramebuffer;
     gpu::PipelinePointer _overlayPipeline;
     gpu::PipelinePointer _simplePipeline;
diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
index ad165beba1..9d91b5b5e6 100644
--- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
@@ -125,6 +125,7 @@ void HmdDisplayPlugin::uncustomizeContext() {
         batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
     });
     _overlayRenderer = OverlayRenderer();
+    _previewTexture.reset();
     Parent::uncustomizeContext();
 }
 
@@ -265,6 +266,7 @@ void HmdDisplayPlugin::internalPresent() {
                 gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
                 image.width(), image.height(),
                 gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
+            _previewTexture->setSource("HMD Preview Texture");
             _previewTexture->setUsage(gpu::Texture::Usage::Builder().withColor().build());
             _previewTexture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits());
             _previewTexture->autoGenerateMips(-1);
@@ -634,3 +636,6 @@ void HmdDisplayPlugin::compositeExtra() {
     });
 }
 
+HmdDisplayPlugin::~HmdDisplayPlugin() {
+    qDebug() << "Destroying HmdDisplayPlugin";
+}
diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
index d02fc5af05..505c200e3e 100644
--- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
@@ -23,6 +23,7 @@
 class HmdDisplayPlugin : public OpenGLDisplayPlugin {
     using Parent = OpenGLDisplayPlugin;
 public:
+    ~HmdDisplayPlugin();
     bool isHmd() const override final { return true; }
     float getIPD() const override final { return _ipd; }
     glm::mat4 getEyeToHeadTransform(Eye eye) const override final { return _eyeOffsets[eye]; }
diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp
index 2cd39d49ae..e8ccfce3b2 100755
--- a/libraries/gpu/src/gpu/Framebuffer.cpp
+++ b/libraries/gpu/src/gpu/Framebuffer.cpp
@@ -20,16 +20,17 @@ using namespace gpu;
 Framebuffer::~Framebuffer() {
 }
 
-Framebuffer* Framebuffer::create() {
+Framebuffer* Framebuffer::create(const std::string& name) {
     auto framebuffer = new Framebuffer();
+    framebuffer->setName(name);
     framebuffer->_renderBuffers.resize(MAX_NUM_RENDER_BUFFERS);
     framebuffer->_colorStamps.resize(MAX_NUM_RENDER_BUFFERS, 0);
     return framebuffer;
 }
 
 
-Framebuffer* Framebuffer::create( const Format& colorBufferFormat, uint16 width, uint16 height) {
-    auto framebuffer = Framebuffer::create();
+Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, uint16 width, uint16 height) {
+    auto framebuffer = Framebuffer::create(name);
 
     auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
     colorTexture->setSource("Framebuffer::colorTexture");
@@ -39,13 +40,11 @@ Framebuffer* Framebuffer::create( const Format& colorBufferFormat, uint16 width,
     return framebuffer;
 }
 
-Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) {
-    auto framebuffer = Framebuffer::create();
+Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) {
+    auto framebuffer = Framebuffer::create(name);
 
     auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
-    colorTexture->setSource("Framebuffer::colorTexture");
     auto depthTexture = TexturePointer(Texture::create2D(depthStencilBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
-    depthTexture->setSource("Framebuffer::depthTexture");
     framebuffer->setRenderBuffer(0, colorTexture);
     framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat);
 
@@ -53,11 +52,10 @@ Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format&
 }
 
 Framebuffer* Framebuffer::createShadowmap(uint16 width) {
-    auto framebuffer = Framebuffer::create();
+    auto framebuffer = Framebuffer::create("Shadowmap");
 
     auto depthFormat = Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); // Depth32 texel format
     auto depthTexture = TexturePointer(Texture::create2D(depthFormat, width, width));
-    depthTexture->setSource("Framebuffer::shadowMap");
     Sampler::Desc samplerDesc;
     samplerDesc._borderColor = glm::vec4(1.0f);
     samplerDesc._wrapModeU = Sampler::WRAP_BORDER;
@@ -155,6 +153,10 @@ int Framebuffer::setRenderBuffer(uint32 slot, const TexturePointer& texture, uin
         if (!validateTargetCompatibility(*texture, subresource)) {
             return -1;
         }
+
+        if (texture->source().empty()) {
+            texture->setSource(_name + "::color::" + std::to_string(slot));
+        }
     }
 
     ++_colorStamps[slot];
@@ -216,7 +218,6 @@ uint32 Framebuffer::getRenderBufferSubresource(uint32 slot) const {
 }
 
 bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource) {
-    ++_depthStamp;
     if (isSwapchain()) {
         return false;
     }
@@ -226,8 +227,13 @@ bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const For
         if (!validateTargetCompatibility(*texture)) {
             return false;
         }
+
+        if (texture->source().empty()) {
+            texture->setSource(_name + "::depthStencil");
+        }
     }
 
+    ++_depthStamp;
     updateSize(texture);
 
     // assign the new one
diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h
index 8c26037ada..a65aaf765b 100755
--- a/libraries/gpu/src/gpu/Framebuffer.h
+++ b/libraries/gpu/src/gpu/Framebuffer.h
@@ -88,9 +88,9 @@ public:
     ~Framebuffer();
 
     static Framebuffer* create(const SwapchainPointer& swapchain);
-    static Framebuffer* create();
-    static Framebuffer* create(const Format& colorBufferFormat, uint16 width, uint16 height);
-    static Framebuffer* create(const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height);
+    static Framebuffer* create(const std::string& name);
+    static Framebuffer* create(const std::string& name, const Format& colorBufferFormat, uint16 width, uint16 height);
+    static Framebuffer* create(const std::string& name, const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height);
     static Framebuffer* createShadowmap(uint16 width);
 
     bool isSwapchain() const;
@@ -127,6 +127,8 @@ public:
     uint16 getWidth() const;
     uint16 getHeight() const;
     uint16 getNumSamples() const;
+    const std::string& getName() const { return _name; }
+    void setName(const std::string& name) { _name = name; }
 
     float getAspectRatio() const { return getWidth() / (float) getHeight() ; }
 
@@ -145,6 +147,7 @@ public:
     static Transform evalSubregionTexcoordTransform(const glm::ivec2& sourceSurface, const glm::ivec4& destViewport);
 
 protected:
+    std::string _name;
     SwapchainPointer _swapchain;
 
     Stamp _depthStamp { 0 };
diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp
index 4baf20c338..21b80e2370 100644
--- a/libraries/plugins/src/plugins/PluginManager.cpp
+++ b/libraries/plugins/src/plugins/PluginManager.cpp
@@ -276,4 +276,30 @@ void PluginManager::saveSettings() {
     saveInputPluginSettings(getInputPlugins());
 }
 
+void PluginManager::shutdown() {
+    for (auto inputPlugin : getInputPlugins()) {
+        if (inputPlugin->isActive()) {
+            inputPlugin->deactivate();
+        }
+    }
+
+    for (auto displayPlugins : getDisplayPlugins()) {
+        if (displayPlugins->isActive()) {
+            displayPlugins->deactivate();
+        }
+    }
+
+    auto loadedPlugins = getLoadedPlugins();
+    // Now grab the dynamic plugins
+    for (auto loader : getLoadedPlugins()) {
+        InputProvider* inputProvider = qobject_cast<InputProvider*>(loader->instance());
+        if (inputProvider) {
+            inputProvider->destroyInputPlugins();
+        }
+        DisplayProvider* displayProvider = qobject_cast<DisplayProvider*>(loader->instance());
+        if (displayProvider) {
+            displayProvider->destroyDisplayPlugins();
+        }
+    }
+}
 #endif
diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h
index 30d52298da..83aad7abcd 100644
--- a/libraries/plugins/src/plugins/PluginManager.h
+++ b/libraries/plugins/src/plugins/PluginManager.h
@@ -28,6 +28,8 @@ public:
     void disableInputs(const QStringList& inputs);
     void saveSettings();
     void setContainer(PluginContainer* container) { _container = container; }
+
+    void shutdown();
 private:
     PluginContainer* _container { nullptr };
 };
diff --git a/libraries/plugins/src/plugins/RuntimePlugin.h b/libraries/plugins/src/plugins/RuntimePlugin.h
index 9bf15f344d..bb6f0251c2 100644
--- a/libraries/plugins/src/plugins/RuntimePlugin.h
+++ b/libraries/plugins/src/plugins/RuntimePlugin.h
@@ -19,6 +19,7 @@ public:
     virtual ~DisplayProvider() {}
 
     virtual DisplayPluginList getDisplayPlugins() = 0;
+    virtual void destroyDisplayPlugins() = 0;
 };
 
 #define DisplayProvider_iid "com.highfidelity.plugins.display"
@@ -29,6 +30,7 @@ class InputProvider {
 public:
     virtual ~InputProvider() {}
     virtual InputPluginList getInputPlugins() = 0;
+    virtual void destroyInputPlugins() = 0;
 };
 
 #define InputProvider_iid "com.highfidelity.plugins.input"
diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp
index 3bf887e1b6..d652cbd872 100644
--- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp
+++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp
@@ -75,11 +75,11 @@ void AmbientOcclusionFramebuffer::allocate() {
     auto height = _frameSize.y;
     
     _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion"));
     _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
    
     _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
     _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
 }
 
diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp
index 8147b06846..43b889df64 100644
--- a/libraries/render-utils/src/AntialiasingEffect.cpp
+++ b/libraries/render-utils/src/AntialiasingEffect.cpp
@@ -41,11 +41,10 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
 
     if (!_antialiasingBuffer) {
         // Link the antialiasing FBO to texture
-        _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+        _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing"));
         auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get<FramebufferCache>()->getLightingTexture()->getTexelFormat();
         auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
         _antialiasingTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
-        _antialiasingTexture->setSource("Antialiasing::_antialiasingTexture");
         _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
     }
 
diff --git a/libraries/render-utils/src/DeferredFramebuffer.cpp b/libraries/render-utils/src/DeferredFramebuffer.cpp
index 067687f9ef..e8783e0e0d 100644
--- a/libraries/render-utils/src/DeferredFramebuffer.cpp
+++ b/libraries/render-utils/src/DeferredFramebuffer.cpp
@@ -43,8 +43,8 @@ void DeferredFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depthBuf
 
 void DeferredFramebuffer::allocate() {
 
-    _deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
-    _deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("deferred"));
+    _deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create("deferredDepthColor"));
 
     auto colorFormat = gpu::Element::COLOR_SRGBA_32;
     auto linearFormat = gpu::Element::COLOR_RGBA_32;
@@ -54,11 +54,8 @@ void DeferredFramebuffer::allocate() {
     auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
 
     _deferredColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
-    _deferredColorTexture->setSource("DeferredFramebuffer::_deferredColorTexture");
     _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(linearFormat, width, height, defaultSampler));
-    _deferredNormalTexture->setSource("DeferredFramebuffer::_deferredNormalTexture");
     _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
-    _deferredSpecularTexture->setSource("DeferredFramebuffer::_deferredSpecularTexture");
 
     _deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture);
     _deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture);
@@ -69,7 +66,6 @@ void DeferredFramebuffer::allocate() {
     auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
     if (!_primaryDepthTexture) {
         _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
-        _primaryDepthTexture->setSource("DeferredFramebuffer::_primaryDepthTexture");
     }
 
     _deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
@@ -80,8 +76,7 @@ void DeferredFramebuffer::allocate() {
     auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
 
     _lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, defaultSampler));
-    _lightingTexture->setSource("DeferredFramebuffer::_lightingTexture");
-    _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting"));
     _lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
     _lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
 
diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp
index 2e169e5cc3..02632c15a9 100644
--- a/libraries/render-utils/src/DeferredLightingEffect.cpp
+++ b/libraries/render-utils/src/DeferredLightingEffect.cpp
@@ -346,12 +346,11 @@ void PreparePrimaryFramebuffer::run(const SceneContextPointer& sceneContext, con
     }
 
     if (!_primaryFramebuffer) {
-        _primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+        _primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("deferredPrimary"));
         auto colorFormat = gpu::Element::COLOR_SRGBA_32;
 
         auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
         auto primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, defaultSampler));
-        primaryColorTexture->setSource("PreparePrimaryFramebuffer::primaryColorTexture");
 
 
         _primaryFramebuffer->setRenderBuffer(0, primaryColorTexture);
@@ -359,7 +358,6 @@ void PreparePrimaryFramebuffer::run(const SceneContextPointer& sceneContext, con
 
         auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
         auto primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, defaultSampler));
-        primaryDepthTexture->setSource("PreparePrimaryFramebuffer::primaryDepthTexture");
 
         _primaryFramebuffer->setDepthStencilBuffer(primaryDepthTexture, depthFormat);
     }
diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp
index 8930792d11..27429595b4 100644
--- a/libraries/render-utils/src/FramebufferCache.cpp
+++ b/libraries/render-utils/src/FramebufferCache.cpp
@@ -36,7 +36,7 @@ void FramebufferCache::createPrimaryFramebuffer() {
 
     auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
 
-    _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("selfie"));
     auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));
     _selfieFramebuffer->setRenderBuffer(0, tex);
 
@@ -47,7 +47,7 @@ void FramebufferCache::createPrimaryFramebuffer() {
 gpu::FramebufferPointer FramebufferCache::getFramebuffer() {
     std::unique_lock<std::mutex> lock(_mutex);
     if (_cachedFramebuffers.empty()) {
-        _cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_SRGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));
+        _cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create("cached", gpu::Element::COLOR_SRGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));
     }
     gpu::FramebufferPointer result = _cachedFramebuffers.front();
     _cachedFramebuffers.pop_front();
diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp
index 3e4ec50dee..83f1d4cb23 100644
--- a/libraries/render-utils/src/SubsurfaceScattering.cpp
+++ b/libraries/render-utils/src/SubsurfaceScattering.cpp
@@ -319,7 +319,7 @@ void diffuseProfileGPU(gpu::TexturePointer& profileMap, RenderArgs* args) {
         makePipeline = gpu::Pipeline::create(program, state);
     }
 
-    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("diffuseProfile"));
     makeFramebuffer->setRenderBuffer(0, profileMap);
 
     gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
@@ -356,7 +356,7 @@ void diffuseScatterGPU(const gpu::TexturePointer& profileMap, gpu::TexturePointe
         makePipeline = gpu::Pipeline::create(program, state);
     }
 
-    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("diffuseScatter"));
     makeFramebuffer->setRenderBuffer(0, lut);
 
     gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
@@ -393,7 +393,7 @@ void computeSpecularBeckmannGPU(gpu::TexturePointer& beckmannMap, RenderArgs* ar
         makePipeline = gpu::Pipeline::create(program, state);
     }
 
-    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("computeSpecularBeckmann"));
     makeFramebuffer->setRenderBuffer(0, beckmannMap);
 
     gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp
index e43afd94a9..b461e46c04 100644
--- a/libraries/render-utils/src/SurfaceGeometryPass.cpp
+++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp
@@ -74,22 +74,19 @@ void LinearDepthFramebuffer::allocate() {
     // For Linear Depth:
     _linearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height,
         gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _linearDepthTexture->setSource("LinearDepthFramebuffer::_linearDepthTexture");
-    _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("linearDepth"));
     _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture);
     _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
 
     // For Downsampling:
     _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
         gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _halfLinearDepthTexture->setSource("LinearDepthFramebuffer::_halfLinearDepthTexture");
     _halfLinearDepthTexture->autoGenerateMips(5);
 
     _halfNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
         gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _halfNormalTexture->setSource("LinearDepthFramebuffer::_halfNormalTexture");
 
-    _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("halfLinearDepth"));
     _downsampleFramebuffer->setRenderBuffer(0, _halfLinearDepthTexture);
     _downsampleFramebuffer->setRenderBuffer(1, _halfNormalTexture);
 }
@@ -304,18 +301,15 @@ void SurfaceGeometryFramebuffer::allocate() {
     auto height = _frameSize.y;
 
     _curvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _curvatureTexture->setSource("SurfaceGeometryFramebuffer::_curvatureTexture");
-    _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::curvature"));
     _curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture);
 
     _lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _lowCurvatureTexture->setSource("SurfaceGeometryFramebuffer::_lowCurvatureTexture");
-    _lowCurvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _lowCurvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::lowCurvature"));
     _lowCurvatureFramebuffer->setRenderBuffer(0, _lowCurvatureTexture);
 
     _blurringTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
-    _blurringTexture->setSource("SurfaceGeometryFramebuffer::_blurringTexture");
-    _blurringFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+    _blurringFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::blurring"));
     _blurringFramebuffer->setRenderBuffer(0, _blurringTexture);
 }
 
diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp
index 144e1e0058..f8b5546b92 100644
--- a/libraries/render/src/render/BlurTask.cpp
+++ b/libraries/render/src/render/BlurTask.cpp
@@ -101,7 +101,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
     }
 
     if (!_blurredFramebuffer) {
-        _blurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+        _blurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("blur"));
 
         // attach depthStencil if present in source
         //if (sourceFramebuffer->hasDepthStencil()) {
@@ -124,7 +124,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
         // The job output the blur result in a new Framebuffer spawning here.
         // Let s make sure it s ready for this
         if (!_outputFramebuffer) {
-            _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
+            _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("blurOutput"));
 
             // attach depthStencil if present in source
          /*   if (sourceFramebuffer->hasDepthStencil()) {
diff --git a/plugins/hifiNeuron/src/NeuronProvider.cpp b/plugins/hifiNeuron/src/NeuronProvider.cpp
index b171c5150d..5315ff105e 100644
--- a/plugins/hifiNeuron/src/NeuronProvider.cpp
+++ b/plugins/hifiNeuron/src/NeuronProvider.cpp
@@ -38,6 +38,10 @@ public:
         return _inputPlugins;
     }
 
+    virtual void destroyInputPlugins() override {
+        _inputPlugins.clear();
+    }
+
 private:
     InputPluginList _inputPlugins;
 };
diff --git a/plugins/hifiSdl2/src/SDL2Provider.cpp b/plugins/hifiSdl2/src/SDL2Provider.cpp
index 1c387a9886..c3315dee07 100644
--- a/plugins/hifiSdl2/src/SDL2Provider.cpp
+++ b/plugins/hifiSdl2/src/SDL2Provider.cpp
@@ -37,6 +37,10 @@ public:
         return _inputPlugins;
     }
 
+    virtual void destroyInputPlugins() override {
+        _inputPlugins.clear();
+    }
+
 private:
     InputPluginList _inputPlugins;
 };
diff --git a/plugins/hifiSixense/src/SixenseProvider.cpp b/plugins/hifiSixense/src/SixenseProvider.cpp
index 2958e47848..aded33db24 100644
--- a/plugins/hifiSixense/src/SixenseProvider.cpp
+++ b/plugins/hifiSixense/src/SixenseProvider.cpp
@@ -38,6 +38,9 @@ public:
         return _inputPlugins;
     }
 
+    virtual void destroyInputPlugins() override {
+        _inputPlugins.clear();
+    }
 private:
     InputPluginList _inputPlugins;
 };
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
index 377050064a..7209104a85 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
@@ -126,3 +126,7 @@ void OculusBaseDisplayPlugin::updatePresentPose() {
     //_currentPresentFrameInfo.presentPose = toGlm(trackingState.HeadPose.ThePose);
     _currentPresentFrameInfo.presentPose = _currentPresentFrameInfo.renderPose;
 }
+
+OculusBaseDisplayPlugin::~OculusBaseDisplayPlugin() {
+    qDebug() << "Destroying OculusBaseDisplayPlugin";
+}
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h
index 25629f004a..023f933acf 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.h
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h
@@ -16,6 +16,7 @@
 class OculusBaseDisplayPlugin : public HmdDisplayPlugin {
     using Parent = HmdDisplayPlugin;
 public:
+    ~OculusBaseDisplayPlugin();
     bool isSupported() const override;
 
     // Stereo specific methods
diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp
index 838a4121cd..b5f4d79042 100644
--- a/plugins/oculus/src/OculusDisplayPlugin.cpp
+++ b/plugins/oculus/src/OculusDisplayPlugin.cpp
@@ -46,7 +46,7 @@ void OculusDisplayPlugin::cycleDebugOutput() {
 
 void OculusDisplayPlugin::customizeContext() {
     Parent::customizeContext();
-    _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_SRGBA_32, _renderTargetSize.x, _renderTargetSize.y));
+    _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OculusOutput", gpu::Element::COLOR_SRGBA_32, _renderTargetSize.x, _renderTargetSize.y));
     ovrTextureSwapChainDesc desc = { };
     desc.Type = ovrTexture_2D;
     desc.ArraySize = 1;
@@ -97,6 +97,7 @@ void OculusDisplayPlugin::uncustomizeContext() {
 
     ovr_DestroyTextureSwapChain(_session, _textureSwapChain);
     _textureSwapChain = nullptr;
+    _outputFramebuffer.reset();
     Parent::uncustomizeContext();
 }
 
@@ -163,3 +164,7 @@ QString OculusDisplayPlugin::getPreferredAudioOutDevice() const {
     }
     return AudioClient::friendlyNameForAudioDevice(buffer);
 }
+
+OculusDisplayPlugin::~OculusDisplayPlugin() {
+    qDebug() << "Destroying OculusDisplayPlugin";
+}
diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h
index 80705319c6..4d10fd38a5 100644
--- a/plugins/oculus/src/OculusDisplayPlugin.h
+++ b/plugins/oculus/src/OculusDisplayPlugin.h
@@ -12,6 +12,7 @@
 class OculusDisplayPlugin : public OculusBaseDisplayPlugin {
     using Parent = OculusBaseDisplayPlugin;
 public:
+    ~OculusDisplayPlugin();
     const QString& getName() const override { return NAME; }
 
     void init() override;
diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp
index e723fa839a..47ccc5304e 100644
--- a/plugins/oculus/src/OculusProvider.cpp
+++ b/plugins/oculus/src/OculusProvider.cpp
@@ -62,6 +62,14 @@ public:
         return _inputPlugins;
     }
 
+    virtual void destroyInputPlugins() override {
+        _inputPlugins.clear();
+    }
+
+    virtual void destroyDisplayPlugins() override {
+        _displayPlugins.clear();
+    }
+
 private:
     DisplayPluginList _displayPlugins;
     InputPluginList _inputPlugins;
diff --git a/plugins/oculusLegacy/src/OculusProvider.cpp b/plugins/oculusLegacy/src/OculusProvider.cpp
index 606563e0ad..fbfc66b432 100644
--- a/plugins/oculusLegacy/src/OculusProvider.cpp
+++ b/plugins/oculusLegacy/src/OculusProvider.cpp
@@ -38,6 +38,10 @@ public:
         return _displayPlugins;
     }
 
+    virtual void destroyDisplayPlugins() override {
+        _displayPlugins.clear();
+    }
+
 private:
     DisplayPluginList _displayPlugins;
 };
diff --git a/plugins/openvr/src/OpenVrProvider.cpp b/plugins/openvr/src/OpenVrProvider.cpp
index 66227a9543..944322373a 100644
--- a/plugins/openvr/src/OpenVrProvider.cpp
+++ b/plugins/openvr/src/OpenVrProvider.cpp
@@ -51,6 +51,13 @@ public:
         return _inputPlugins;
     }
 
+    virtual void destroyInputPlugins() override {
+        _inputPlugins.clear();
+    }
+
+    virtual void destroyDisplayPlugins() override {
+        _displayPlugins.clear();
+    }
 
 private:
     DisplayPluginList _displayPlugins;