From 09ddad0fe06801feb6f37f899e9a25b8ad84047e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 1 Aug 2016 17:14:45 -0700 Subject: [PATCH] HMD compositing and buffer debugging --- .../display-plugins/OpenGLDisplayPlugin.cpp | 105 +++--- .../src/display-plugins/OpenGLDisplayPlugin.h | 4 +- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 307 +++++++++--------- libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp | 4 +- libraries/gpu-gl/src/gpu/gl/GLBuffer.h | 2 +- libraries/gpu/src/gpu/Batch.cpp | 29 ++ libraries/gpu/src/gpu/Batch.h | 6 +- libraries/gpu/src/gpu/Resource.cpp | 4 + libraries/gpu/src/gpu/Resource.h | 2 + 9 files changed, 251 insertions(+), 212 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index aa5d243183..b26eb70d8c 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -57,7 +57,7 @@ void main(void) { } )SCRIBE"; -QOpenGLContext* mainContext; +extern QThread* RENDER_THREAD; class PresentThread : public QThread, public Dependency { using Mutex = std::mutex; @@ -107,7 +107,6 @@ public: virtual void run() override { OpenGLDisplayPlugin* currentPlugin{ nullptr }; Q_ASSERT(_context); - mainContext = _context->contextHandle(); while (!_shutdown) { if (_pendingMainThreadOperation) { { @@ -214,12 +213,6 @@ private: QGLContext* _context { nullptr }; }; - -OpenGLDisplayPlugin::OpenGLDisplayPlugin() { -} - -extern QThread* RENDER_THREAD; - bool OpenGLDisplayPlugin::activate() { if (!_cursorsData.size()) { auto& cursorManager = Cursor::Manager::instance(); @@ -285,7 +278,6 @@ bool OpenGLDisplayPlugin::activate() { } void OpenGLDisplayPlugin::deactivate() { - auto compositorHelper = DependencyManager::get(); disconnect(compositorHelper.data()); @@ -305,7 +297,6 @@ void OpenGLDisplayPlugin::deactivate() { Parent::deactivate(); } - void OpenGLDisplayPlugin::customizeContext() { auto presentThread = DependencyManager::get(); Q_ASSERT(thread() == presentThread->thread()); @@ -341,6 +332,7 @@ void OpenGLDisplayPlugin::customizeContext() { gpu::Shader::makeProgram(*program); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(gpu::State::DepthTest(false)); + state->setScissorEnable(true); _presentPipeline = gpu::Pipeline::create(program, state); } @@ -384,7 +376,8 @@ void OpenGLDisplayPlugin::uncustomizeContext() { _compositeTexture.reset(); withPresentThreadLock([&] { _currentFrame.reset(); - _newFrameQueue.swap(std::queue()); + std::queue empty; + _newFrameQueue.swap(empty); }); } @@ -431,7 +424,6 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { return false; } - void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) { if (_lockCurrentTexture) { return; @@ -461,45 +453,45 @@ void OpenGLDisplayPlugin::updateFrameData() { } void OpenGLDisplayPlugin::compositeOverlay() { - gpu::Batch batch; - batch.enableStereo(false); - batch.setFramebuffer(_currentFrame->framebuffer); - batch.setPipeline(_overlayPipeline); - batch.setResourceTexture(0, _currentFrame->overlay); - if (isStereo()) { - for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye)); + render([&](gpu::Batch& batch){ + batch.enableStereo(false); + batch.setFramebuffer(_currentFrame->framebuffer); + batch.setPipeline(_overlayPipeline); + batch.setResourceTexture(0, _currentFrame->overlay); + if (isStereo()) { + for_each_eye([&](Eye eye) { + batch.setViewportTransform(eyeViewport(eye)); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); + } else { + batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - } else { - batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); - batch.draw(gpu::TRIANGLE_STRIP, 4); - } - _backend->render(batch); + } + }); } void OpenGLDisplayPlugin::compositePointer() { auto& cursorManager = Cursor::Manager::instance(); const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()]; auto cursorTransform = DependencyManager::get()->getReticleTransform(glm::mat4()); - gpu::Batch batch; - batch.enableStereo(false); - batch.setProjectionTransform(mat4()); - batch.setFramebuffer(_currentFrame->framebuffer); - batch.setPipeline(_cursorPipeline); - batch.setResourceTexture(0, cursorData.texture); - batch.clearViewTransform(); - batch.setModelTransform(cursorTransform); - if (isStereo()) { - for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye)); + render([&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setProjectionTransform(mat4()); + batch.setFramebuffer(_currentFrame->framebuffer); + batch.setPipeline(_cursorPipeline); + batch.setResourceTexture(0, cursorData.texture); + batch.clearViewTransform(); + batch.setModelTransform(cursorTransform); + if (isStereo()) { + for_each_eye([&](Eye eye) { + batch.setViewportTransform(eyeViewport(eye)); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); + } else { + batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - } else { - batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); - batch.draw(gpu::TRIANGLE_STRIP, 4); - } - _backend->render(batch); + } + }); } void OpenGLDisplayPlugin::compositeScene() { @@ -526,15 +518,15 @@ void OpenGLDisplayPlugin::compositeLayers() { } void OpenGLDisplayPlugin::internalPresent() { - gpu::Batch presentBatch; - presentBatch.enableStereo(false); - presentBatch.clearViewTransform(); - presentBatch.setFramebuffer(gpu::FramebufferPointer()); - presentBatch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels())); - presentBatch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); - presentBatch.setPipeline(_presentPipeline); - presentBatch.draw(gpu::TRIANGLE_STRIP, 4); - _backend->render(presentBatch); + render([&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.clearViewTransform(); + batch.setFramebuffer(gpu::FramebufferPointer()); + batch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels())); + batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); + batch.setPipeline(_presentPipeline); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); swapBuffers(); } @@ -586,7 +578,6 @@ float OpenGLDisplayPlugin::presentRate() const { return _presentRate.rate(); } - void OpenGLDisplayPlugin::enableVsync(bool enable) { if (!_vsyncSupported) { return; @@ -602,7 +593,6 @@ void OpenGLDisplayPlugin::enableVsync(bool enable) { #endif } - bool OpenGLDisplayPlugin::isVsyncEnabled() { if (!_vsyncSupported) { return true; @@ -698,3 +688,10 @@ gpu::gl::GLBackend* OpenGLDisplayPlugin::getGLBackend() { } return dynamic_cast(_backend.get()); } + +void OpenGLDisplayPlugin::render(std::function f) { + gpu::Batch batch; + f(batch); + batch.flush(); + _backend->render(batch); +} diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index b24d2e5dbe..b6baf1251e 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -37,8 +37,6 @@ protected: using Condition = std::condition_variable; using TextureEscrow = GLEscrow; public: - OpenGLDisplayPlugin(); - // These must be final to ensure proper ordering of operations // between the main thread and the presentation thread bool activate() override final; @@ -102,6 +100,8 @@ protected: void swapBuffers(); ivec4 eyeViewport(Eye eye) const; + void render(std::function f); + QThread* _presentThread{ nullptr }; std::queue _newFrameQueue; RateCounter<> _droppedFrameRate; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 0dc8cd45f1..c824852810 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -39,6 +39,7 @@ static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate"; static const QString DEVELOPER_MENU_PATH = "Developer>" + DisplayPlugin::MENU_PATH(); static const bool DEFAULT_MONO_VIEW = true; static const glm::mat4 IDENTITY_MATRIX; +static const size_t NUMBER_OF_HANDS = 2; //#define LIVE_SHADER_RELOAD 1 extern glm::vec3 getPoint(float yaw, float pitch); @@ -230,28 +231,29 @@ void HmdDisplayPlugin::OverlayRenderer::updatePipeline() { } void HmdDisplayPlugin::OverlayRenderer::render(HmdDisplayPlugin& plugin) { + updatePipeline(); for_each_eye([&](Eye eye){ uniforms.mvp = mvps[eye]; uniformBuffers[eye]->setSubData(0, uniforms); uniformBuffers[eye]->flush(); }); - gpu::Batch batch; - batch.enableStereo(false); - batch.setResourceTexture(0, plugin._currentFrame->overlay); - batch.setPipeline(pipeline); - batch.setInputFormat(format); - gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); - gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); - batch.setInputBuffer(gpu::Stream::POSITION, posView); - batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); - batch.setIndexBuffer(gpu::UINT16, indices, 0); - for_each_eye([&](Eye eye){ - batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]); - batch.setViewportTransform(plugin.eyeViewport(eye)); - batch.drawIndexed(gpu::TRIANGLES, indexCount); + plugin.render([&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setResourceTexture(0, plugin._currentFrame->overlay); + batch.setPipeline(pipeline); + batch.setInputFormat(format); + gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); + gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); + batch.setInputBuffer(gpu::Stream::POSITION, posView); + batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); + batch.setIndexBuffer(gpu::UINT16, indices, 0); + // FIXME use stereo information input to set both MVPs in the uniforms + for_each_eye([&](Eye eye) { + batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]); + batch.setViewportTransform(plugin.eyeViewport(eye)); + batch.drawIndexed(gpu::TRIANGLES, indexCount); + }); }); - // FIXME use stereo information input to set both MVPs in the uniforms - plugin._backend->render(batch); } void HmdDisplayPlugin::updateLaserProgram() { @@ -303,38 +305,152 @@ void HmdDisplayPlugin::updatePresentPose() { } void HmdDisplayPlugin::compositeScene() { - gpu::Batch batch; - batch.enableStereo(false); - batch.setFramebuffer(_compositeFramebuffer); - - batch.setViewportTransform(ivec4(uvec2(), _renderTargetSize)); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1, 1, 0, 1)); - batch.clearViewTransform(); - batch.setProjectionTransform(mat4()); - - batch.setPipeline(_presentPipeline); - batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); - batch.draw(gpu::TRIANGLE_STRIP, 4); - _backend->render(batch); + render([&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setFramebuffer(_compositeFramebuffer); + batch.setViewportTransform(ivec4(uvec2(), _renderTargetSize)); + batch.setStateScissorRect(ivec4(uvec2(), _renderTargetSize)); + batch.clearViewTransform(); + batch.setProjectionTransform(mat4()); + batch.setPipeline(_presentPipeline); + batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); } void HmdDisplayPlugin::compositeOverlay() { -#if 0 - if (!_currentFrame) { + if (!_currentFrame || !_currentFrame->overlay) { return; } + _overlay.render(*this); +} + +void HmdDisplayPlugin::compositePointer() { + auto& cursorManager = Cursor::Manager::instance(); + const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()]; auto compositorHelper = DependencyManager::get(); - glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix(); + // Reconstruct the headpose from the eye poses + auto headPosition = vec3(_currentPresentFrameInfo.presentPose[3]); + gpu::Batch batch; + render([&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setProjectionTransform(mat4()); + batch.setFramebuffer(_currentFrame->framebuffer); + batch.setPipeline(_cursorPipeline); + batch.setResourceTexture(0, cursorData.texture); + batch.clearViewTransform(); + for_each_eye([&](Eye eye) { + auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye); + auto reticleTransform = compositorHelper->getReticleTransform(eyePose, headPosition); + batch.setViewportTransform(eyeViewport(eye)); + batch.setModelTransform(reticleTransform); + batch.setProjectionTransform(_eyeProjections[eye]); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); + }); +} + +void HmdDisplayPlugin::internalPresent() { + PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount()) + + // Composite together the scene, overlay and mouse cursor + hmdPresent(); + + if (_enablePreview) { + // screen preview mirroring + auto window = _container->getPrimaryWidget(); + auto devicePixelRatio = window->devicePixelRatio(); + auto windowSize = toGlm(window->size()); + windowSize *= devicePixelRatio; + float windowAspect = aspect(windowSize); + float sceneAspect = _enablePreview ? aspect(_renderTargetSize) : _previewAspect; + if (_enablePreview && _monoPreview) { + sceneAspect /= 2.0f; + } + float aspectRatio = sceneAspect / windowAspect; + + uvec2 targetViewportSize = windowSize; + if (aspectRatio < 1.0f) { + targetViewportSize.x *= aspectRatio; + } else { + targetViewportSize.y /= aspectRatio; + } + + uvec2 targetViewportPosition; + if (targetViewportSize.x < windowSize.x) { + targetViewportPosition.x = (windowSize.x - targetViewportSize.x) / 2; + } else if (targetViewportSize.y < windowSize.y) { + targetViewportPosition.y = (windowSize.y - targetViewportSize.y) / 2; + } + + gpu::Batch presentBatch; + presentBatch.enableStereo(false); + presentBatch.clearViewTransform(); + presentBatch.setFramebuffer(gpu::FramebufferPointer()); + presentBatch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0)); + presentBatch.setViewportTransform(ivec4(uvec2(0), windowSize)); + if (_monoPreview) { + presentBatch.setStateScissorRect(ivec4(targetViewportPosition, targetViewportSize)); + targetViewportSize.x *= 2; + presentBatch.setViewportTransform(ivec4(targetViewportPosition, targetViewportSize)); + } else { + presentBatch.setStateScissorRect(ivec4(targetViewportPosition, targetViewportSize)); + presentBatch.setViewportTransform(ivec4(targetViewportPosition, targetViewportSize)); + } + presentBatch.setResourceTexture(0, _compositeTexture); + presentBatch.setPipeline(_presentPipeline); + presentBatch.draw(gpu::TRIANGLE_STRIP, 4); + _backend->render(presentBatch); + swapBuffers(); + } + + postPreview(); +} + +void HmdDisplayPlugin::updateFrameData() { + // Check if we have old frame data to discard + static const uint32_t INVALID_FRAME = (uint32_t)(~0); + uint32_t oldFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME; + + Parent::updateFrameData(); + uint32_t newFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME; + + if (oldFrameIndex != newFrameIndex) { + withPresentThreadLock([&] { + if (oldFrameIndex != INVALID_FRAME) { + auto itr = _frameInfos.find(oldFrameIndex); + if (itr != _frameInfos.end()) { + _frameInfos.erase(itr); + } + } + if (newFrameIndex != INVALID_FRAME) { + _currentPresentFrameInfo = _frameInfos[newFrameIndex]; + } + }); + } + + updatePresentPose(); + + if (_currentFrame) { + auto batchPose = _currentFrame->pose; + auto currentPose = _currentPresentFrameInfo.presentPose; + auto correction = glm::inverse(batchPose) * currentPose; + getGLBackend()->setCameraCorrection(correction); + } + withPresentThreadLock([&] { _presentHandLasers = _handLasers; _presentHandPoses = _handPoses; _presentUiModelTransform = _uiModelTransform; }); + auto compositorHelper = DependencyManager::get(); + glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix(); + std::array handGlowPoints{ { vec2(-1), vec2(-1) } }; // compute the glow point interesections - for (int i = 0; i < NUMBER_OF_HANDS; ++i) { + for (size_t i = 0; i < NUMBER_OF_HANDS; ++i) { if (_presentHandPoses[i] == IDENTITY_MATRIX) { continue; } @@ -382,133 +498,20 @@ void HmdDisplayPlugin::compositeOverlay() { handGlowPoints[i] = yawPitch; } - if (!_currentFrame->overlay) { - return; - } - for_each_eye([&](Eye eye){ + for_each_eye([&](Eye eye) { auto modelView = glm::inverse(_currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye)) * modelMat; _overlay.mvps[eye] = _eyeProjections[eye] * modelView; }); // Setup the uniforms { - _overlay.uniforms.alpha = _compositeOverlayAlpha; - _overlay.uniforms.glowPoints = vec4(handGlowPoints[0], handGlowPoints[1]); - _overlay.uniforms.glowColors[0] = _presentHandLasers[0].color; - _overlay.uniforms.glowColors[1] = _presentHandLasers[1].color; + auto& uniforms = _overlay.uniforms; + uniforms.alpha = _compositeOverlayAlpha; + uniforms.glowPoints = vec4(handGlowPoints[0], handGlowPoints[1]); + uniforms.glowColors[0] = _presentHandLasers[0].color; + uniforms.glowColors[1] = _presentHandLasers[1].color; } - _overlay.render(); -#endif -} - -void HmdDisplayPlugin::compositePointer() { -#if 0 - auto& cursorManager = Cursor::Manager::instance(); - const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()]; - auto compositorHelper = DependencyManager::get(); - // Reconstruct the headpose from the eye poses - auto headPosition = vec3(_currentPresentFrameInfo.presentPose[3]); - gpu::Batch batch; - batch.enableStereo(false); - batch.setProjectionTransform(mat4()); - batch.setFramebuffer(_currentFrame->framebuffer); - batch.setPipeline(_cursorPipeline); - batch.setResourceTexture(0, cursorData.texture); - batch.clearViewTransform(); - for_each_eye([&](Eye eye) { - auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye); - auto reticleTransform = compositorHelper->getReticleTransform(eyePose, headPosition); - batch.setViewportTransform(eyeViewport(eye)); - batch.setModelTransform(reticleTransform); - batch.setProjectionTransform(_eyeProjections[eye]); - batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - _backend->render(batch); -#endif -} - -void HmdDisplayPlugin::internalPresent() { - PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount()) - - // Composite together the scene, overlay and mouse cursor - hmdPresent(); - - /* - // screen preview mirroring - auto window = _container->getPrimaryWidget(); - auto devicePixelRatio = window->devicePixelRatio(); - auto windowSize = toGlm(window->size()); - windowSize *= devicePixelRatio; - float windowAspect = aspect(windowSize); - float sceneAspect = _enablePreview ? aspect(_renderTargetSize) : _previewAspect; - if (_enablePreview && _monoPreview) { - sceneAspect /= 2.0f; - } - float aspectRatio = sceneAspect / windowAspect; - - uvec2 targetViewportSize = windowSize; - if (aspectRatio < 1.0f) { - targetViewportSize.x *= aspectRatio; - } else { - targetViewportSize.y /= aspectRatio; - } - - uvec2 targetViewportPosition; - if (targetViewportSize.x < windowSize.x) { - targetViewportPosition.x = (windowSize.x - targetViewportSize.x) / 2; - } else if (targetViewportSize.y < windowSize.y) { - targetViewportPosition.y = (windowSize.y - targetViewportSize.y) / 2; - } - */ - - if (_enablePreview) { - gpu::Batch presentBatch; - presentBatch.enableStereo(false); - presentBatch.clearViewTransform(); - presentBatch.setFramebuffer(gpu::FramebufferPointer()); - presentBatch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels())); - presentBatch.setResourceTexture(0, _compositeTexture); - presentBatch.setPipeline(_presentPipeline); - presentBatch.draw(gpu::TRIANGLE_STRIP, 4); - _backend->render(presentBatch); - swapBuffers(); - } - - postPreview(); -} - -void HmdDisplayPlugin::updateFrameData() { - // Check if we have old frame data to discard - static const uint32_t INVALID_FRAME = (uint32_t)(~0); - uint32_t oldFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME; - - Parent::updateFrameData(); - uint32_t newFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME; - - if (oldFrameIndex != newFrameIndex) { - withPresentThreadLock([&] { - if (oldFrameIndex != INVALID_FRAME) { - auto itr = _frameInfos.find(oldFrameIndex); - if (itr != _frameInfos.end()) { - _frameInfos.erase(itr); - } - } - if (newFrameIndex != INVALID_FRAME) { - _currentPresentFrameInfo = _frameInfos[newFrameIndex]; - } - }); - } - - updatePresentPose(); - - if (_currentFrame) { - auto batchPose = _currentFrame->pose; - auto currentPose = _currentPresentFrameInfo.presentPose; - auto correction = glm::inverse(batchPose) * currentPose; - getGLBackend()->setCameraCorrection(correction); - } - } glm::mat4 HmdDisplayPlugin::getHeadPose() const { diff --git a/libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp b/libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp index cd0f86a410..11be98b5f9 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp @@ -19,8 +19,8 @@ GLBuffer::~GLBuffer() { GLBuffer::GLBuffer(const Buffer& buffer, GLuint id) : GLObject(buffer, id), - _size((GLuint)buffer._sysmem.getSize()), - _stamp(buffer._sysmem.getStamp()) + _size((GLuint)buffer._renderSysmem.getSize()), + _stamp(buffer._renderSysmem.getStamp()) { Backend::incrementBufferGPUCount(); Backend::updateBufferGPUMemoryUsage(0, _size); diff --git a/libraries/gpu-gl/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl/src/gpu/gl/GLBuffer.h index ecf80c312d..f61cf84a8b 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBuffer.h @@ -19,7 +19,7 @@ public: GLBufferType* object = Backend::getGPUObject(buffer); // Has the storage size changed? - if (!object || object->_stamp != buffer.getSysmem().getStamp()) { + if (!object || object->_stamp != buffer._renderSysmem.getStamp()) { object = new GLBufferType(buffer, object); } diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 266a90636d..ae9cf3ed33 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -660,4 +660,33 @@ void Batch::finish(BufferUpdates& updates) { } updates.push_back({ buffer, buffer->getUpdate() }); } +} + +void Batch::flush() { + if (_objectsBuffer && _objectsBuffer->isDirty()) { + _objectsBuffer->flush(); + } + + for (auto& namedCallData : _namedData) { + for (auto& buffer : namedCallData.second.buffers) { + if (!buffer) { + continue; + } + if (!buffer->isDirty()) { + continue; + } + buffer->flush(); + } + } + + for (auto& bufferCacheItem : _buffers._items) { + const BufferPointer& buffer = bufferCacheItem._data; + if (!buffer) { + continue; + } + if (!buffer->isDirty()) { + continue; + } + buffer->flush(); + } } \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index dca468a515..f2f7d23d69 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -102,9 +102,13 @@ public: ~Batch(); void clear(); + // Call on the main thread to prepare for passing to the render thread void finish(BufferUpdates& updates); - + + // Call on the rendering thread for batches that only exist there + void flush(); + void preExecute(); // Batches may need to override the context level stereo settings diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index d78cc3c0d3..a38b182036 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -283,6 +283,7 @@ void Buffer::markDirty(Size offset, Size bytes) { } Buffer::Update Buffer::getUpdate() const { + ++_getUpdateCount; static Update EMPTY_UPDATE; if (!_pages) { return EMPTY_UPDATE; @@ -315,11 +316,14 @@ Buffer::Update Buffer::getUpdate() const { } void Buffer::applyUpdate(const Update& update) { + ++_applyUpdateCount; _renderPages = update.pages; update.updateOperator(_renderSysmem); } void Buffer::flush() { + ++_getUpdateCount; + ++_applyUpdateCount; _renderPages = _pages; _renderSysmem.resize(_sysmem.getSize()); auto dirtyPages = _pages.getMarkedPages(); diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 01351cb7af..9bff0d6f1e 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -355,6 +355,8 @@ public: mutable PageManager _renderPages; Sysmem _renderSysmem; + mutable std::atomic _getUpdateCount; + mutable std::atomic _applyUpdateCount; protected: void markDirty(Size offset, Size bytes);