From fb363180c88cbd21b569b7fe8d5a202ce7cfa7db Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 19 Apr 2016 12:03:57 -0700 Subject: [PATCH 01/28] Starting to expose the number of changes to the input format --- examples/utilities/render/stats.qml | 5 ++++ libraries/gpu/src/gpu/GLBackendInput.cpp | 31 +++++++++++++++++---- libraries/render/src/render/EngineStats.cpp | 1 + libraries/render/src/render/EngineStats.h | 3 ++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/examples/utilities/render/stats.qml b/examples/utilities/render/stats.qml index 6bea341c98..f13282c93e 100644 --- a/examples/utilities/render/stats.qml +++ b/examples/utilities/render/stats.qml @@ -173,6 +173,11 @@ Item { prop: "frameSetPipelineCount", label: "Pipelines", color: "#E2334D" + }, + { + prop: "frameSetInputFormatCount", + label: "Input Formats", + color: "#1AC567" } ] } diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 75f4be3cbe..09ed625ef6 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -12,12 +12,33 @@ using namespace gpu; + +GLBackend::GLInputFormat::GLInputFormat() { +} + +GLBackend::GLInputFormat:: ~GLInputFormat() { + +} + +GLBackend::GLInputFormat* GLBackend::syncGPUObject(const Stream::Format& inputFormat) { + GLInputFormat* object = Backend::getGPUObject(inputFormat); + + if (object) { + return object; + } + + object = new GLInputFormat(); + Backend::setGPUObject(inputFormat, object); +} + void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { Stream::FormatPointer format = batch._streamFormats.get(batch._params[paramOffset]._uint); - - if (format != _input._format) { - _input._format = format; - _input._invalidFormat = true; + GLInputFormat* ifo = GLBackend::syncGPUObject(*format); + if (ifo) { + if (format != _input._format) { + _input._format = format; + _input._invalidFormat = true; + } } } @@ -89,7 +110,7 @@ void GLBackend::syncInputStateCache() { // Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding // Core 43 does :) // FIXME crashing problem with glVertexBindingDivisor / glVertexAttribFormat -#if 1 || (GPU_INPUT_PROFILE == GPU_CORE_41) +#if(GPU_INPUT_PROFILE == GPU_CORE_41) #define NO_SUPPORT_VERTEX_ATTRIB_FORMAT #else #define SUPPORT_VERTEX_ATTRIB_FORMAT diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index a17845134a..39792734ef 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -50,6 +50,7 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte config->frameTextureMemoryUsage = _gpuStats._RSAmountTextureMemoryBounded - gpuStats._RSAmountTextureMemoryBounded; config->frameSetPipelineCount = _gpuStats._PSNumSetPipelines - gpuStats._PSNumSetPipelines; + config->frameSetInputFormatCount = _gpuStats._ISNumFormatChanges - gpuStats._ISNumFormatChanges; config->emitDirty(); } diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index e777e60a4e..a5ebf88498 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -48,6 +48,7 @@ namespace render { Q_PROPERTY(quint32 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY dirty) Q_PROPERTY(quint32 frameSetPipelineCount MEMBER frameSetPipelineCount NOTIFY dirty) + Q_PROPERTY(quint32 frameSetInputFormatCount MEMBER frameSetInputFormatCount NOTIFY dirty) public: @@ -78,6 +79,8 @@ namespace render { quint32 frameSetPipelineCount{ 0 }; + quint32 frameSetInputFormatCount{ 0 }; + void emitDirty() { emit dirty(); } From 33835ba6a10c47f7f475004c6af8b7cd7798fe3e Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 19 Apr 2016 12:04:42 -0700 Subject: [PATCH 02/28] Introducing the INput FOrmat gpu Object to optimize the changes --- libraries/gpu/src/gpu/GLBackend.h | 9 +++++++++ libraries/gpu/src/gpu/Stream.h | 1 + 2 files changed, 10 insertions(+) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 05afb28bf1..6d7a5f2545 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -151,6 +151,15 @@ public: // very specific for now static void syncSampler(const Sampler& sampler, Texture::Type type, const GLTexture* object); + class GLInputFormat : public GPUObject { + public: + + + GLInputFormat(); + ~GLInputFormat(); + }; + GLInputFormat* syncGPUObject(const Stream::Format& inputFormat); + class GLShader : public GPUObject { public: enum Version { diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index c8d9335bf7..950a713cf0 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -106,6 +106,7 @@ public: bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); } + const GPUObjectPointer gpuObject{}; protected: AttributeMap _attributes; ChannelMap _channels; From c62b5a5e5859fc931c3954d75771e63faab56144 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 19 Apr 2016 17:13:00 -0700 Subject: [PATCH 03/28] First pass --- libraries/gpu/src/gpu/GLBackend.h | 4 +++- libraries/gpu/src/gpu/GLBackendInput.cpp | 12 +++++++++++- libraries/gpu/src/gpu/Stream.cpp | 15 +++++++++++++++ libraries/gpu/src/gpu/Stream.h | 7 +++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 6d7a5f2545..a3bedfcba3 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -153,7 +153,7 @@ public: class GLInputFormat : public GPUObject { public: - + std::string key; GLInputFormat(); ~GLInputFormat(); @@ -358,6 +358,7 @@ protected: struct InputStageState { bool _invalidFormat = true; Stream::FormatPointer _format; + std::string _formatKey; typedef std::bitset ActivationCache; ActivationCache _attributeActivation; @@ -385,6 +386,7 @@ protected: InputStageState() : _invalidFormat(true), _format(0), + _formatKey(), _attributeActivation(0), _invalidBuffers(0), _buffers(_invalidBuffers.size(), BufferPointer(0)), diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 09ed625ef6..81e42ba9a0 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -28,6 +28,7 @@ GLBackend::GLInputFormat* GLBackend::syncGPUObject(const Stream::Format& inputFo } object = new GLInputFormat(); + object->key = inputFormat.getKey(); Backend::setGPUObject(inputFormat, object); } @@ -37,7 +38,15 @@ void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { if (ifo) { if (format != _input._format) { _input._format = format; - _input._invalidFormat = true; + if (format) { + if (_input._formatKey != format->getKey()) { + _input._formatKey = format->getKey(); + _input._invalidFormat = true; + } + } else { + _input._invalidFormat = true; + _input._formatKey.clear(); + } } } } @@ -295,6 +304,7 @@ void GLBackend::resetInputStage() { // Reset vertex buffer and format _input._format.reset(); + _input._formatKey.clear(); _input._invalidFormat = false; _input._attributeActivation.reset(); diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 90f2327fc8..93601d204b 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -12,6 +12,8 @@ #include "Stream.h" #include //min max and more +#include +#include using namespace gpu; @@ -39,7 +41,18 @@ const ElementArray& getDefaultElements() { return defaultElements; } +std::string Stream::Attribute::getKey() const { + std::stringstream skey; + + skey << std::hex; + skey << std::setw(8) << std::setfill('0') << (uint32)((((uint32)_slot) << 24) | (((uint32)_channel) << 16) | ((uint32)_element.getRaw())); + skey << _offset; + skey << _frequency; + return skey.str(); +} + void Stream::Format::evaluateCache() { + _key.clear(); _channels.clear(); _elementTotalSize = 0; for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { @@ -49,6 +62,8 @@ void Stream::Format::evaluateCache() { channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset); channel._netSize += attrib.getSize(); _elementTotalSize += attrib.getSize(); + + _key += attrib.getKey(); } } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 950a713cf0..88ed70c78e 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -73,6 +73,9 @@ public: // Size of the uint32 getSize() const { return _element.getSize(); } + + // Generate a string key describing the attribute uniquely + std::string getKey() const; }; // Stream Format is describing how to feed a list of attributes from a bunch of stream buffer channels @@ -106,6 +109,8 @@ public: bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); } + const std::string& getKey() const { return _key; } + const GPUObjectPointer gpuObject{}; protected: AttributeMap _attributes; @@ -113,6 +118,8 @@ public: uint32 _elementTotalSize { 0 }; void evaluateCache(); + + std::string _key; }; typedef std::shared_ptr FormatPointer; From 8eb89b394cb9a91e20a1fe4abc321bbdf86b595d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 20 Apr 2016 12:30:50 -0700 Subject: [PATCH 04/28] Trying to use separate vertex attribute format --- libraries/gpu/src/gpu/GLBackend.h | 5 +++- libraries/gpu/src/gpu/GLBackendTransform.cpp | 29 +++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index a3bedfcba3..a156e7be8b 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -292,7 +292,8 @@ public: static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS; - static const int MAX_NUM_INPUT_BUFFERS = 16; + // The drawcall Info attribute channel is reserved and is the upper bound for the number of availables Input buffers + static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO; size_t getNumInputBuffers() const { return _input._invalidBuffers.size(); } @@ -435,6 +436,8 @@ protected: bool _invalidProj { false }; bool _invalidViewport { false }; + bool _enabledDrawcallInfoBuffer{ false }; + using Pair = std::pair; using List = std::list; List _cameraOffsets; diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 19cb7fb2a9..80b7b226f7 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -206,19 +206,34 @@ void GLBackend::updateTransform(const Batch& batch) { auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); if (batch._currentNamedCall.empty()) { auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + if (_transform._enabledDrawcallInfoBuffer) { + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + _transform._enabledDrawcallInfoBuffer = false; + } glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); - glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, - _transform._drawCallInfoOffsets[batch._currentNamedCall]); - glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + if (!_transform._enabledDrawcallInfoBuffer) { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + // glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + /* glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, + _transform._drawCallInfoOffsets[batch._currentNamedCall]); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + */ + + glVertexAttribIFormat(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0); + glVertexAttribBinding(gpu::Stream::DRAW_CALL_INFO, gpu::Stream::DRAW_CALL_INFO); + glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + _transform._enabledDrawcallInfoBuffer = true; + } + glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr) _transform._drawCallInfoOffsets[batch._currentNamedCall], 0); + // _transform._drawCallInfoOffsets[batch._currentNamedCall]); + } (void)CHECK_GL_ERROR(); } void GLBackend::resetTransformStage() { - + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); + _transform._enabledDrawcallInfoBuffer = false; } From d727e3b493f013d1e0defd67f24d498c59e12ce3 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 20 Apr 2016 19:09:31 -0700 Subject: [PATCH 05/28] Trying to explore the bug with separate vertex format --- .../RenderableParticleEffectEntityItem.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 3 +- libraries/gpu/src/gpu/GLBackendInput.cpp | 94 +++++++++++++------ libraries/gpu/src/gpu/GLBackendTransform.cpp | 31 ++++-- libraries/gpu/src/gpu/Stream.cpp | 1 + 5 files changed, 90 insertions(+), 41 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index a199c6b10e..8f5bb49a1b 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -106,7 +106,7 @@ public: batch.setInputBuffer(0, _particleBuffer, 0, sizeof(ParticlePrimitive)); auto numParticles = _particleBuffer->getSize() / sizeof(ParticlePrimitive); - batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); + // batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); } protected: diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index a156e7be8b..803cefb585 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -366,6 +366,7 @@ protected: typedef std::bitset BuffersState; BuffersState _invalidBuffers; + BuffersState _attribBindingBuffers; Buffers _buffers; Offsets _bufferOffsets; @@ -383,7 +384,7 @@ protected: Offset _indirectBufferStride{ 0 }; GLuint _defaultVAO; - + InputStageState() : _invalidFormat(true), _format(0), diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 81e42ba9a0..0f00fec712 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -133,41 +133,67 @@ void GLBackend::updateInput() { // Assign the vertex format required if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; + _input._attribBindingBuffers.reset(); - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = _elementTypeToGLType[attrib._element.getType()]; - GLuint offset = attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); + const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); + auto& inputChannels = _input._format->getChannels(); + for (auto& channelIt : inputChannels) { + auto bufferChannelNum = (channelIt).first; + const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; + _input._attribBindingBuffers.set(bufferChannelNum); - GLenum perLocationSize = attrib._element.getLocationSize(); + GLuint frequency = 0; + for (unsigned int i = 0; i < channel._slots.size(); i++) { + const Stream::Attribute& attrib = attributes.at(channel._slots[i]); - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - newActivation.set(slot + locNum); - glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); - glVertexAttribBinding(slot + locNum, attrib._channel); + GLuint slot = attrib._slot; + GLuint count = attrib._element.getLocationScalarCount(); + uint8_t locationCount = attrib._element.getLocationCount(); + GLenum type = _elementTypeToGLType[attrib._element.getType()]; + + GLuint offset = attrib._offset;; + GLboolean isNormalized = attrib._element.isNormalized(); + + GLenum perLocationSize = attrib._element.getLocationSize(); + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + auto attriNum = slot + locNum; + newActivation.set(attriNum); + if (!_input._attributeActivation[attriNum]) { + _input._attributeActivation.set(attriNum); + glEnableVertexAttribArray(attriNum); + } + glVertexAttribFormat(attriNum, count, type, isNormalized, offset + locNum * perLocationSize); + // TODO: Support properly the IAttrib version + glVertexAttribBinding(attriNum, attrib._channel); + } + + if (i == 0) { + frequency = attrib._frequency; + } else { + assert(frequency == attrib._frequency); + } + + (void)CHECK_GL_ERROR(); } - glVertexBindingDivisor(attrib._channel, attrib._frequency); + glVertexBindingDivisor(bufferChannelNum, frequency); } - (void) CHECK_GL_ERROR(); + + // Manage Activation what was and what is expected now + // This should only disable VertexAttribs since the one in use have been disabled above + for (size_t i = 0; i < newActivation.size(); i++) { + bool newState = newActivation[i]; + if (newState != _input._attributeActivation[i]) { + if (newState) { + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + } + _input._attributeActivation.flip(i); + } + } + (void)CHECK_GL_ERROR(); } - // Manage Activation what was and what is expected now - for (size_t i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - _input._attributeActivation.flip(i); - } - } - (void) CHECK_GL_ERROR(); _input._invalidFormat = false; _stats._ISNumFormatChanges++; @@ -294,13 +320,21 @@ void GLBackend::resetInputStage() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); (void) CHECK_GL_ERROR(); +#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) + glBindBuffer(GL_ARRAY_BUFFER, 0); + for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { + glDisableVertexAttribArray(i); + } + for (uint32_t i = 0; i < _input._attribBindingBuffers.size(); i++) { + glBindVertexBuffer(i, 0, 0, 0); + } +#else glBindBuffer(GL_ARRAY_BUFFER, 0); - - for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { glDisableVertexAttribArray(i); glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); } +#endif // Reset vertex buffer and format _input._format.reset(); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 80b7b226f7..bf236cd904 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -92,6 +92,9 @@ void GLBackend::syncTransformStateCache() { Mat4 modelView; auto modelViewInv = glm::inverse(modelView); _transform._view.evalFromRawMatrix(modelViewInv); + + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); + _transform._enabledDrawcallInfoBuffer = false; } void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) { @@ -200,6 +203,12 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta (void)CHECK_GL_ERROR(); } +#if(GPU_INPUT_PROFILE == GPU_CORE_41) +#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT +#else +#define SUPPORT_VERTEX_ATTRIB_FORMAT +#endif + void GLBackend::updateTransform(const Batch& batch) { _transform.update(_commandIndex, _stereo); @@ -212,22 +221,26 @@ void GLBackend::updateTransform(const Batch& batch) { } glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { +#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) if (!_transform._enabledDrawcallInfoBuffer) { glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - // glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); - /* glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, - _transform._drawCallInfoOffsets[batch._currentNamedCall]); - glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); - */ - glVertexAttribIFormat(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0); glVertexAttribBinding(gpu::Stream::DRAW_CALL_INFO, gpu::Stream::DRAW_CALL_INFO); glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); _transform._enabledDrawcallInfoBuffer = true; } - glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr) _transform._drawCallInfoOffsets[batch._currentNamedCall], 0); - // _transform._drawCallInfoOffsets[batch._currentNamedCall]); - + glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 0); + +#else + if (!_transform._enabledDrawcallInfoBuffer) { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + _transform._enabledDrawcallInfoBuffer = true; + } + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, _transform._drawCallInfoOffsets[batch._currentNamedCall]); +#endif + } (void)CHECK_GL_ERROR(); diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 93601d204b..cdb972d8bf 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -55,6 +55,7 @@ void Stream::Format::evaluateCache() { _key.clear(); _channels.clear(); _elementTotalSize = 0; + for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { Attribute& attrib = (*it).second; ChannelInfo& channel = _channels[attrib._channel]; From 75f50fce3262ec135aa709dda0e5c6842af52701 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 18 May 2016 09:32:55 -0700 Subject: [PATCH 06/28] Uncomment the particle drawing --- .../src/RenderableParticleEffectEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 2bdccf5846..86c3f5ff35 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -106,7 +106,7 @@ public: batch.setInputBuffer(0, _particleBuffer, 0, sizeof(ParticlePrimitive)); auto numParticles = _particleBuffer->getSize() / sizeof(ParticlePrimitive); - // batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); + batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); } protected: From 281c6dc82ba639688963b672d369f3c282c09c07 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 10:52:58 -0700 Subject: [PATCH 07/28] Always return input from sync --- libraries/gpu/src/gpu/GLBackendInput.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 0f00fec712..437b5c760a 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -23,13 +23,13 @@ GLBackend::GLInputFormat:: ~GLInputFormat() { GLBackend::GLInputFormat* GLBackend::syncGPUObject(const Stream::Format& inputFormat) { GLInputFormat* object = Backend::getGPUObject(inputFormat); - if (object) { - return object; + if (!object) { + object = new GLInputFormat(); + object->key = inputFormat.getKey(); + Backend::setGPUObject(inputFormat, object); } - object = new GLInputFormat(); - object->key = inputFormat.getKey(); - Backend::setGPUObject(inputFormat, object); + return object; } void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { From e8c86a3fe4d1bd901fcd197fe846df0883cb466f Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 10:53:12 -0700 Subject: [PATCH 08/28] Fix warnings in updateInput --- libraries/gpu/src/gpu/GLBackendInput.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 437b5c760a..817f41e660 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -151,12 +151,12 @@ void GLBackend::updateInput() { uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = _elementTypeToGLType[attrib._element.getType()]; - GLuint offset = attrib._offset;; + GLuint offset = (GLuint)attrib._offset;; GLboolean isNormalized = attrib._element.isNormalized(); GLenum perLocationSize = attrib._element.getLocationSize(); - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - auto attriNum = slot + locNum; + for (GLuint locNum = 0; locNum < locationCount; ++locNum) { + GLuint attriNum = (GLuint)(slot + locNum); newActivation.set(attriNum); if (!_input._attributeActivation[attriNum]) { _input._attributeActivation.set(attriNum); @@ -180,7 +180,7 @@ void GLBackend::updateInput() { // Manage Activation what was and what is expected now // This should only disable VertexAttribs since the one in use have been disabled above - for (size_t i = 0; i < newActivation.size(); i++) { + for (GLuint i = 0; i < (GLuint)newActivation.size(); i++) { bool newState = newActivation[i]; if (newState != _input._attributeActivation[i]) { if (newState) { @@ -200,21 +200,16 @@ void GLBackend::updateInput() { } if (_input._invalidBuffers.any()) { - int numBuffers = _input._buffers.size(); - auto buffer = _input._buffers.data(); auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); - for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) { - if (_input._invalidBuffers.test(bufferNum)) { - glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride)); + for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { + if (_input._invalidBuffers.test(buffer)) { + glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); } - buffer++; - vbo++; - offset++; - stride++; } + _input._invalidBuffers.reset(); (void) CHECK_GL_ERROR(); } From df3fb2a0e8244f1157b0abd46f4238afb1090642 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 10:56:48 -0700 Subject: [PATCH 09/28] Guard buffer copy on size --- libraries/gpu/src/gpu/GLBackendBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/GLBackendBuffer.cpp b/libraries/gpu/src/gpu/GLBackendBuffer.cpp index 7098fd1feb..3a533d10b2 100755 --- a/libraries/gpu/src/gpu/GLBackendBuffer.cpp +++ b/libraries/gpu/src/gpu/GLBackendBuffer.cpp @@ -34,7 +34,7 @@ GLBackend::GLBuffer::GLBuffer(const Buffer& buffer, GLBuffer* original) : } glBindBuffer(GL_ARRAY_BUFFER, 0); - if (original) { + if (original && original->_size) { glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer); glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size); From 92e26169f6c7f5e845962a7f743d10565330da85 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 13:55:08 -0700 Subject: [PATCH 10/28] Move define for vao to one header --- libraries/gpu/src/gpu/GLBackend.h | 9 +++++++++ libraries/gpu/src/gpu/GLBackendInput.cpp | 9 --------- libraries/gpu/src/gpu/GLBackendTransform.cpp | 6 ------ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index ae96bc9b97..cf11acba58 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -11,6 +11,15 @@ #ifndef hifi_gpu_GLBackend_h #define hifi_gpu_GLBackend_h +// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding +// Core 43 does :) +#if(GPU_INPUT_PROFILE == GPU_CORE_41) +#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT +#else +#define SUPPORT_VERTEX_ATTRIB_FORMAT +#endif + + #include #include #include diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 817f41e660..b8d044d27a 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -116,15 +116,6 @@ void GLBackend::syncInputStateCache() { glBindVertexArray(_input._defaultVAO); } -// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding -// Core 43 does :) -// FIXME crashing problem with glVertexBindingDivisor / glVertexAttribFormat -#if(GPU_INPUT_PROFILE == GPU_CORE_41) -#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else -#define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif - void GLBackend::updateInput() { #if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) if (_input._invalidFormat) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index ca1e5a5ffa..12936896be 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -201,12 +201,6 @@ void GLBackend::TransformStageState::bindCurrentCamera(int eye) const { } } -#if(GPU_INPUT_PROFILE == GPU_CORE_41) -#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else -#define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif - void GLBackend::updateTransform(const Batch& batch) { _transform.update(_commandIndex, _stereo); From e6664d9441dcdd3383f466c658becbe2397f6d9c Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 13:55:35 -0700 Subject: [PATCH 11/28] Initialize buffers --- libraries/gpu/src/gpu/GLBackend.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index cf11acba58..e3ad0ae843 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -422,8 +422,8 @@ protected: ActivationCache _attributeActivation; typedef std::bitset BuffersState; - BuffersState _invalidBuffers; - BuffersState _attribBindingBuffers; + BuffersState _invalidBuffers{ 0 }; + BuffersState _attribBindingBuffers{ 0 }; Buffers _buffers; Offsets _bufferOffsets; @@ -447,7 +447,6 @@ protected: _format(0), _formatKey(), _attributeActivation(0), - _invalidBuffers(0), _buffers(_invalidBuffers.size(), BufferPointer(0)), _bufferOffsets(_invalidBuffers.size(), 0), _bufferStrides(_invalidBuffers.size(), 0), From 804e6a805e950ed16ece2e8500b49239c797c418 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 13:56:02 -0700 Subject: [PATCH 12/28] Simplify sync --- libraries/gpu/src/gpu/GLBackendInput.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index b8d044d27a..4f4af31da2 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -34,17 +34,13 @@ GLBackend::GLInputFormat* GLBackend::syncGPUObject(const Stream::Format& inputFo void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { Stream::FormatPointer format = batch._streamFormats.get(batch._params[paramOffset]._uint); - GLInputFormat* ifo = GLBackend::syncGPUObject(*format); - if (ifo) { + if(GLBackend::syncGPUObject(*format)) { if (format != _input._format) { _input._format = format; + _input._invalidFormat = true; if (format) { - if (_input._formatKey != format->getKey()) { - _input._formatKey = format->getKey(); - _input._invalidFormat = true; - } + _input._formatKey = format->getKey(); } else { - _input._invalidFormat = true; _input._formatKey.clear(); } } @@ -87,9 +83,6 @@ void GLBackend::do_setInputBuffer(Batch& batch, size_t paramOffset) { } } - - - void GLBackend::initInput() { if(!_input._defaultVAO) { glGenVertexArrays(1, &_input._defaultVAO); From 854c6d839cacc1b329720991a04046439b63ac0d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 13:56:19 -0700 Subject: [PATCH 13/28] Style nit --- libraries/gpu/src/gpu/Stream.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 88ed70c78e..abd8015e1a 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -112,14 +112,14 @@ public: const std::string& getKey() const { return _key; } const GPUObjectPointer gpuObject{}; + protected: AttributeMap _attributes; ChannelMap _channels; uint32 _elementTotalSize { 0 }; + std::string _key; void evaluateCache(); - - std::string _key; }; typedef std::shared_ptr FormatPointer; From ca364c22274693a2ea3a9dfe7040dfa40dc2d8d7 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 13:57:12 -0700 Subject: [PATCH 14/28] Fix vao usage --- libraries/gpu/src/gpu/GLBackendTransform.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 12936896be..2f58337ed0 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -221,8 +221,10 @@ void GLBackend::updateTransform(const Batch& batch) { glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); _transform._enabledDrawcallInfoBuffer = true; } - glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 0); - + // NOTE: A stride of zero in BindVertexBuffer signifies that all elements are sourced from the same location, + // so we must provide a stride. + // This is in contrast to VertexAttrib*Pointer, where a zero signifies tightly-packed elements. + glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 2 * sizeof(GLushort)); #else if (!_transform._enabledDrawcallInfoBuffer) { glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled @@ -232,7 +234,6 @@ void GLBackend::updateTransform(const Batch& batch) { } glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, _transform._drawCallInfoOffsets[batch._currentNamedCall]); #endif - } (void)CHECK_GL_ERROR(); From a55179101e22d0866a0ce90a8df180352f241c3a Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 15:11:29 -0700 Subject: [PATCH 15/28] Fix invalidFormat check --- libraries/gpu/src/gpu/GLBackendInput.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 4f4af31da2..e8927d0d61 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -37,11 +37,14 @@ void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { if(GLBackend::syncGPUObject(*format)) { if (format != _input._format) { _input._format = format; - _input._invalidFormat = true; if (format) { - _input._formatKey = format->getKey(); + if (_input._formatKey != format->getKey()) { + _input._formatKey = format->getKey(); + _input._invalidFormat = true; + } } else { _input._formatKey.clear(); + _input._invalidFormat = true; } } } From a31c76f4e19247aa5fe50663025928feeece8974 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 21 Jul 2016 17:59:46 -0700 Subject: [PATCH 16/28] INtroducing the GPUObject for INputFOrmat for GLBackend --- libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp | 33 +++++++++++++++++++ libraries/gpu-gl/src/gpu/gl/GLInputFormat.h | 29 ++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl/GLInputFormat.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp b/libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp new file mode 100644 index 0000000000..7f42350c3b --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp @@ -0,0 +1,33 @@ +// +// Created by Sam Gateau on 2016/07/21 +// Copyright 2013-2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "GLInputFormat.h" +#include "GLBackend.h" + +using namespace gpu; +using namespace gpu::gl; + + +GLInputFormat::GLInputFormat() { +} + +GLInputFormat:: ~GLInputFormat() { + +} + +GLInputFormat* GLInputFormat::sync(const Stream::Format& inputFormat) { + GLInputFormat* object = Backend::getGPUObject(inputFormat); + + if (!object) { + object = new GLInputFormat(); + object->key = inputFormat.getKey(); + Backend::setGPUObject(inputFormat, object); + } + + return object; +} diff --git a/libraries/gpu-gl/src/gpu/gl/GLInputFormat.h b/libraries/gpu-gl/src/gpu/gl/GLInputFormat.h new file mode 100644 index 0000000000..a14e3d4d91 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl/GLInputFormat.h @@ -0,0 +1,29 @@ +// +// Created by Sam Gateau on 2016/07/21 +// Copyright 2013-2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_gpu_gl_GLInputFormat_h +#define hifi_gpu_gl_GLInputFormat_h + +#include "GLShared.h" + +namespace gpu { +namespace gl { + +class GLInputFormat : public GPUObject { + public: + static GLInputFormat* sync(const Stream::Format& inputFormat); + + GLInputFormat(); + ~GLInputFormat(); + + std::string key; +}; + +} +} + +#endif From ab26f54c91c8fc8d7fe369b3a788f5ef389c1724 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 22 Jul 2016 10:58:09 -0700 Subject: [PATCH 17/28] Trying to separate the vertex format and vertex buffer assignment for GL45Backend --- libraries/gpu-gl/src/gpu/gl/GLBackend.h | 2 +- .../gpu-gl/src/gpu/gl/GLBackendInput.cpp | 145 +----------------- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 1 + .../gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 11 ++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 1 + .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 12 ++ 6 files changed, 27 insertions(+), 145 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index e39f9a1dff..73c8ca7657 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -196,7 +196,7 @@ protected: virtual void initInput() final; virtual void killInput() final; virtual void syncInputStateCache() final; - virtual void resetInputStage() final; + virtual void resetInputStage(); virtual void updateInput(); struct InputStageState { diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp index d390a1e29d..1074833841 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp @@ -97,122 +97,6 @@ void GLBackend::syncInputStateCache() { void GLBackend::updateInput() { -#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) - if (_input._invalidFormat) { - - InputStageState::ActivationCache newActivation; - - // Assign the vertex format required - if (_input._format) { -<<<<<<< HEAD - _input._attribBindingBuffers.reset(); - - const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); - auto& inputChannels = _input._format->getChannels(); - for (auto& channelIt : inputChannels) { - auto bufferChannelNum = (channelIt).first; - const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; - _input._attribBindingBuffers.set(bufferChannelNum); - - GLuint frequency = 0; - for (unsigned int i = 0; i < channel._slots.size(); i++) { - const Stream::Attribute& attrib = attributes.at(channel._slots[i]); - - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = _elementTypeToGLType[attrib._element.getType()]; - - GLuint offset = (GLuint)attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); - - GLenum perLocationSize = attrib._element.getLocationSize(); - for (GLuint locNum = 0; locNum < locationCount; ++locNum) { - GLuint attriNum = (GLuint)(slot + locNum); - newActivation.set(attriNum); - if (!_input._attributeActivation[attriNum]) { - _input._attributeActivation.set(attriNum); - glEnableVertexAttribArray(attriNum); - } - glVertexAttribFormat(attriNum, count, type, isNormalized, offset + locNum * perLocationSize); - // TODO: Support properly the IAttrib version - glVertexAttribBinding(attriNum, attrib._channel); - } - - if (i == 0) { - frequency = attrib._frequency; - } else { - assert(frequency == attrib._frequency); - } - - (void)CHECK_GL_ERROR(); -======= - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; - - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = _elementTypeToGL41Type[attrib._element.getType()]; - GLuint offset = attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); - - GLenum perLocationSize = attrib._element.getLocationSize(); - - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - newActivation.set(slot + locNum); - glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); - glVertexAttribBinding(slot + locNum, attrib._channel); ->>>>>>> 592a50356bf598a4ca49d45c0c30525477831c6d - } - glVertexBindingDivisor(bufferChannelNum, frequency); - } -<<<<<<< HEAD -======= - (void)CHECK_GL_ERROR(); - } ->>>>>>> 592a50356bf598a4ca49d45c0c30525477831c6d - - // Manage Activation what was and what is expected now - // This should only disable VertexAttribs since the one in use have been disabled above - for (GLuint i = 0; i < (GLuint)newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - _input._attributeActivation.flip(i); - } - } - (void)CHECK_GL_ERROR(); - } -<<<<<<< HEAD - -======= - (void)CHECK_GL_ERROR(); ->>>>>>> 592a50356bf598a4ca49d45c0c30525477831c6d - - _input._invalidFormat = false; - _stats._ISNumFormatChanges++; - } - - if (_input._invalidBuffers.any()) { - auto vbo = _input._bufferVBOs.data(); - auto offset = _input._bufferOffsets.data(); - auto stride = _input._bufferStrides.data(); - - for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { - if (_input._invalidBuffers.test(buffer)) { - glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); - } - } - - _input._invalidBuffers.reset(); - (void)CHECK_GL_ERROR(); - } -#else if (_input._invalidFormat || _input._invalidBuffers.any()) { if (_input._invalidFormat) { @@ -303,20 +187,8 @@ void GLBackend::updateInput() { // everything format related should be in sync now _input._invalidFormat = false; } -#endif } -// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding -// Core 43 does :) -// FIXME crashing problem with glVertexBindingDivisor / glVertexAttribFormat -// Once resolved, break this up into the GL 4.1 and 4.5 backends -#if 1 || (GPU_INPUT_PROFILE == GPU_CORE_41) -#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else -#define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif - - void GLBackend::resetInputStage() { // Reset index buffer _input._indexBufferType = UINT32; @@ -325,22 +197,6 @@ void GLBackend::resetInputStage() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); (void) CHECK_GL_ERROR(); -#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) - glBindBuffer(GL_ARRAY_BUFFER, 0); - for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { - glDisableVertexAttribArray(i); - } - for (uint32_t i = 0; i < _input._attribBindingBuffers.size(); i++) { - glBindVertexBuffer(i, 0, 0, 0); - } -#else - glBindBuffer(GL_ARRAY_BUFFER, 0); - for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { - glDisableVertexAttribArray(i); - glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); - } -#endif - // Reset vertex buffer and format _input._format.reset(); _input._formatKey.clear(); @@ -355,6 +211,7 @@ void GLBackend::resetInputStage() { } _input._invalidBuffers.reset(); + // THe vertex array binding MUST be reset in the specific Backend versions as they use different techniques } void GLBackend::do_setIndexBuffer(Batch& batch, size_t paramOffset) { diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 5695ba080e..d9be107052 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -76,6 +76,7 @@ protected: void do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) override; // Input Stage + void resetInputStage() override; void updateInput() override; // Synchronize the state cache of this Backend with the actual real state of the GL Context diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 59c4050af1..376b9e1c2f 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -13,6 +13,17 @@ using namespace gpu; using namespace gpu::gl41; + +void GL41Backend::resetInputStage() { + Parent::resetInputStage(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { + glDisableVertexAttribArray(i); + glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); + } +} + void GL41Backend::updateInput() { if (_input._invalidFormat || _input._invalidBuffers.any()) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index d0dfbd0e41..a43b9d56b5 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -65,6 +65,7 @@ protected: void do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) override; // Input Stage + void resetInputStage() override; void updateInput() override; // Synchronize the state cache of this Backend with the actual real state of the GL Context diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 0fdd14dc84..9c5303e71f 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -14,6 +14,18 @@ using namespace gpu; using namespace gpu::gl45; +void GL45Backend::resetInputStage() { + Parent::resetInputStage(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { + glDisableVertexAttribArray(i); + } + for (uint32_t i = 0; i < _input._attribBindingBuffers.size(); i++) { + glBindVertexBuffer(i, 0, 0, 0); + } +} + void GL45Backend::updateInput() { if (_input._invalidFormat) { From 3a7c33165b70493e0b22c5437d7b01881b2d5594 Mon Sep 17 00:00:00 2001 From: samcake Date: Sat, 23 Jul 2016 20:20:50 -0700 Subject: [PATCH 18/28] add missing include ? --- libraries/gpu/src/gpu/Stream.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index abd8015e1a..0642131edf 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -14,6 +14,7 @@ #include #include #include +#include #include From bcef138545b423ca3415e2d185a6fc6feee9e5fc Mon Sep 17 00:00:00 2001 From: sam Date: Fri, 4 Nov 2016 18:59:30 -0700 Subject: [PATCH 19/28] FIx the context stats --- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 2 -- libraries/gpu/src/gpu/Context.cpp | 32 +++++++++++++++++-- libraries/gpu/src/gpu/Context.h | 6 +++- libraries/render/src/render/EngineStats.cpp | 15 ++++----- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 9c5303e71f..694bbe6f9c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -27,9 +27,7 @@ void GL45Backend::resetInputStage() { } void GL45Backend::updateInput() { - if (_input._invalidFormat) { - InputStageState::ActivationCache newActivation; // Assign the vertex format required diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 46d1b84e47..beb0e1d6bc 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -13,6 +13,23 @@ #include "GPULogging.h" using namespace gpu; + +void ContextStats::evalDelta(const ContextStats& begin, const ContextStats& end) { + _ISNumFormatChanges = end._ISNumFormatChanges - begin._ISNumFormatChanges; + _ISNumInputBufferChanges = end._ISNumInputBufferChanges - begin._ISNumInputBufferChanges; + _ISNumIndexBufferChanges = end._ISNumIndexBufferChanges - begin._ISNumIndexBufferChanges; + + _RSNumTextureBounded = end._RSNumTextureBounded - begin._RSNumTextureBounded; + _RSAmountTextureMemoryBounded = end._RSAmountTextureMemoryBounded - begin._RSAmountTextureMemoryBounded; + + _DSNumAPIDrawcalls = end._DSNumAPIDrawcalls - begin._DSNumAPIDrawcalls; + _DSNumDrawcalls = end._DSNumDrawcalls - begin._DSNumDrawcalls; + _DSNumTriangles= end._DSNumTriangles - begin._DSNumTriangles; + + _PSNumSetPipelines = end._PSNumSetPipelines - begin._PSNumSetPipelines; +} + + Context::CreateBackend Context::_createBackendCallback = nullptr; Context::MakeProgram Context::_makeProgramCallback = nullptr; std::once_flag Context::_initialized; @@ -69,6 +86,10 @@ void Context::consumeFrameUpdates(const FramePointer& frame) const { } void Context::executeFrame(const FramePointer& frame) const { + // Grab the stats at the around the frame and delta to have a consistent sampling + ContextStats beginStats; + getStats(beginStats); + // FIXME? probably not necessary, but safe consumeFrameUpdates(frame); _backend->setStereoState(frame->stereoState); @@ -79,8 +100,9 @@ void Context::executeFrame(const FramePointer& frame) const { } } - // Grab the stats at the end of the frame that just executed so we can have a consistent sampling - getFrameStats(_frameStats); + ContextStats endStats; + getStats(endStats); + _frameStats.evalDelta(beginStats, endStats); } bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) { @@ -126,12 +148,16 @@ void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, cons _backend->downloadFramebuffer(srcFramebuffer, region, destImage); } +void Context::resetStats() const { + _backend->resetStats(); +} + void Context::getStats(ContextStats& stats) const { _backend->getStats(stats); } void Context::getFrameStats(ContextStats& stats) const { - memcpy(&stats, &_frameStats, sizeof(ContextStats)); + stats = _frameStats; } const Backend::TransformCamera& Backend::TransformCamera::recomputeDerived(const Transform& xformView) const { diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index b61ed764d4..c5ab673686 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -45,6 +45,8 @@ public: ContextStats() {} ContextStats(const ContextStats& stats) = default; + + void evalDelta(const ContextStats& begin, const ContextStats& end); }; class Backend { @@ -83,6 +85,7 @@ public: return reinterpret_cast(object.gpuObject.getGPUObject()); } + void resetStats() const { _stats = ContextStats(); } void getStats(ContextStats& stats) const { stats = _stats; } virtual bool isTextureManagementSparseEnabled() const = 0; @@ -124,7 +127,7 @@ protected: } friend class Context; - ContextStats _stats; + mutable ContextStats _stats; StereoState _stereo; }; @@ -202,6 +205,7 @@ public: void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage); // Repporting stats of the context + void resetStats() const; void getStats(ContextStats& stats) const; // Same as above but grabbed at every end of a frame diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index 27d64129cd..2cb23bb41c 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -35,22 +35,21 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte config->textureGPUVirtualMemoryUsage = gpu::Texture::getTextureGPUVirtualMemoryUsage(); config->textureGPUTransferCount = gpu::Texture::getTextureGPUTransferCount(); - gpu::ContextStats gpuStats(_gpuStats); renderContext->args->_context->getFrameStats(_gpuStats); - config->frameAPIDrawcallCount = _gpuStats._DSNumAPIDrawcalls - gpuStats._DSNumAPIDrawcalls; - config->frameDrawcallCount = _gpuStats._DSNumDrawcalls - gpuStats._DSNumDrawcalls; + config->frameAPIDrawcallCount = _gpuStats._DSNumAPIDrawcalls; + config->frameDrawcallCount = _gpuStats._DSNumDrawcalls; config->frameDrawcallRate = config->frameDrawcallCount * frequency; - config->frameTriangleCount = _gpuStats._DSNumTriangles - gpuStats._DSNumTriangles; + config->frameTriangleCount = _gpuStats._DSNumTriangles; config->frameTriangleRate = config->frameTriangleCount * frequency; - config->frameTextureCount = _gpuStats._RSNumTextureBounded - gpuStats._RSNumTextureBounded; + config->frameTextureCount = _gpuStats._RSNumTextureBounded; config->frameTextureRate = config->frameTextureCount * frequency; - config->frameTextureMemoryUsage = _gpuStats._RSAmountTextureMemoryBounded - gpuStats._RSAmountTextureMemoryBounded; + config->frameTextureMemoryUsage = _gpuStats._RSAmountTextureMemoryBounded; - config->frameSetPipelineCount = _gpuStats._PSNumSetPipelines - gpuStats._PSNumSetPipelines; - config->frameSetInputFormatCount = _gpuStats._ISNumFormatChanges - gpuStats._ISNumFormatChanges; + config->frameSetPipelineCount = _gpuStats._PSNumSetPipelines; + config->frameSetInputFormatCount = _gpuStats._ISNumFormatChanges; config->emitDirty(); } From f3e1ed4b88e196043ff03dd4da0ef8f9bfe11e3a Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 14 Nov 2016 11:57:00 -0800 Subject: [PATCH 20/28] Merging and cleaning up the code path for the 2 flavors of gl --- libraries/gpu-gl/src/gpu/gl/GLBackend.h | 6 +- .../gpu-gl/src/gpu/gl/GLBackendInput.cpp | 93 ------------------- .../gpu-gl/src/gpu/gl/GLBackendTransform.cpp | 37 -------- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 3 +- .../src/gpu/gl41/GL41BackendTransform.cpp | 25 +++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 3 +- .../src/gpu/gl45/GL45BackendTransform.cpp | 29 ++++++ 7 files changed, 59 insertions(+), 137 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index a82c3dced2..e9517f64d1 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -221,7 +221,7 @@ protected: virtual void killInput() final; virtual void syncInputStateCache() final; virtual void resetInputStage(); - virtual void updateInput(); + virtual void updateInput() = 0; struct InputStageState { bool _invalidFormat { true }; @@ -268,8 +268,8 @@ protected: void killTransform(); // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncTransformStateCache(); - void updateTransform(const Batch& batch); - void resetTransformStage(); + virtual void updateTransform(const Batch& batch) = 0; + virtual void resetTransformStage(); // Allows for correction of the camera pose to account for changes // between the time when a was recorded and the time(s) when it is diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp index 3951bebd62..7be6c9c401 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp @@ -95,99 +95,6 @@ void GLBackend::syncInputStateCache() { glBindVertexArray(_input._defaultVAO); } -void GLBackend::updateInput() { - if (_input._invalidFormat || _input._invalidBuffers.any()) { - - if (_input._invalidFormat) { - InputStageState::ActivationCache newActivation; - - _stats._ISNumFormatChanges++; - - // Check expected activation - if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; - uint8_t locationCount = attrib._element.getLocationCount(); - for (int i = 0; i < locationCount; ++i) { - newActivation.set(attrib._slot + i); - } - } - } - - // Manage Activation what was and what is expected now - for (unsigned int i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - (void)CHECK_GL_ERROR(); - - _input._attributeActivation.flip(i); - } - } - } - - // now we need to bind the buffers and assign the attrib pointers - if (_input._format) { - const Buffers& buffers = _input._buffers; - const Offsets& offsets = _input._bufferOffsets; - const Offsets& strides = _input._bufferStrides; - - const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); - auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges++; - - GLuint boundVBO = 0; - for (auto& channelIt : inputChannels) { - const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; - if ((channelIt).first < buffers.size()) { - int bufferNum = (channelIt).first; - - if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) { - // GLuint vbo = gpu::GL41Backend::getBufferID((*buffers[bufferNum])); - GLuint vbo = _input._bufferVBOs[bufferNum]; - if (boundVBO != vbo) { - glBindBuffer(GL_ARRAY_BUFFER, vbo); - (void)CHECK_GL_ERROR(); - boundVBO = vbo; - } - _input._invalidBuffers[bufferNum] = false; - - for (unsigned int i = 0; i < channel._slots.size(); i++) { - const Stream::Attribute& attrib = attributes.at(channel._slots[i]); - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; - // GLenum perLocationStride = strides[bufferNum]; - GLenum perLocationStride = attrib._element.getLocationSize(); - GLuint stride = (GLuint)strides[bufferNum]; - GLuint pointer = (GLuint)(attrib._offset + offsets[bufferNum]); - GLboolean isNormalized = attrib._element.isNormalized(); - - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, - reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); - glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency); - } - - // TODO: Support properly the IAttrib version - - (void)CHECK_GL_ERROR(); - } - } - } - } - } - // everything format related should be in sync now - _input._invalidFormat = false; - } -} - void GLBackend::resetInputStage() { // Reset index buffer _input._indexBufferType = UINT32; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp index 6d3c1a5b9b..369785b4f1 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp @@ -138,43 +138,6 @@ void GLBackend::TransformStageState::bindCurrentCamera(int eye) const { } } -void GLBackend::updateTransform(const Batch& batch) { - _transform.update(_commandIndex, _stereo); - - auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); - if (batch._currentNamedCall.empty()) { - auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; - if (_transform._enabledDrawcallInfoBuffer) { - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled - _transform._enabledDrawcallInfoBuffer = false; - } - glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); - } else { -#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) - if (!_transform._enabledDrawcallInfoBuffer) { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - glVertexAttribIFormat(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0); - glVertexAttribBinding(gpu::Stream::DRAW_CALL_INFO, gpu::Stream::DRAW_CALL_INFO); - glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); - _transform._enabledDrawcallInfoBuffer = true; - } - // NOTE: A stride of zero in BindVertexBuffer signifies that all elements are sourced from the same location, - // so we must provide a stride. - // This is in contrast to VertexAttrib*Pointer, where a zero signifies tightly-packed elements. - glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 2 * sizeof(GLushort)); -#else - if (!_transform._enabledDrawcallInfoBuffer) { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); - glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); - _transform._enabledDrawcallInfoBuffer = true; - } - glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, _transform._drawCallInfoOffsets[batch._currentNamedCall]); -#endif - } - - (void)CHECK_GL_ERROR(); -} void GLBackend::resetTransformStage() { glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 3d438c5da5..72e2f5a804 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -83,8 +83,7 @@ protected: // Synchronize the state cache of this Backend with the actual real state of the GL Context void transferTransformState(const Batch& batch) const override; void initTransform() override; - void updateTransform(const Batch& batch); - void resetTransformStage(); + void updateTransform(const Batch& batch) override; // Output stage void do_blit(const Batch& batch, size_t paramOffset) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp index ee803f28c1..21ea906ec8 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp @@ -79,3 +79,28 @@ void GL41Backend::transferTransformState(const Batch& batch) const { // Make sure the current Camera offset is unknown before render Draw _transform._currentCameraOffset = INVALID_OFFSET; } + + +void GL41Backend::updateTransform(const Batch& batch) { + _transform.update(_commandIndex, _stereo); + + auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); + if (batch._currentNamedCall.empty()) { + auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; + if (_transform._enabledDrawcallInfoBuffer) { + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + _transform._enabledDrawcallInfoBuffer = false; + } + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); + } else { + if (!_transform._enabledDrawcallInfoBuffer) { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + _transform._enabledDrawcallInfoBuffer = true; + } + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, _transform._drawCallInfoOffsets[batch._currentNamedCall]); + } + + (void)CHECK_GL_ERROR(); +} \ No newline at end of file diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index e399a9c973..c338d6e641 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -136,8 +136,7 @@ protected: // Synchronize the state cache of this Backend with the actual real state of the GL Context void transferTransformState(const Batch& batch) const override; void initTransform() override; - void updateTransform(const Batch& batch); - void resetTransformStage(); + void updateTransform(const Batch& batch) override; // Output stage void do_blit(const Batch& batch, size_t paramOffset) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp index ace0e73cf9..edd23b1d4c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp @@ -66,3 +66,32 @@ void GL45Backend::transferTransformState(const Batch& batch) const { // Make sure the current Camera offset is unknown before render Draw _transform._currentCameraOffset = INVALID_OFFSET; } + + +void GL45Backend::updateTransform(const Batch& batch) { + _transform.update(_commandIndex, _stereo); + + auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); + if (batch._currentNamedCall.empty()) { + auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; + if (_transform._enabledDrawcallInfoBuffer) { + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + _transform._enabledDrawcallInfoBuffer = false; + } + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); + } else { + if (!_transform._enabledDrawcallInfoBuffer) { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glVertexAttribIFormat(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0); + glVertexAttribBinding(gpu::Stream::DRAW_CALL_INFO, gpu::Stream::DRAW_CALL_INFO); + glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + _transform._enabledDrawcallInfoBuffer = true; + } + // NOTE: A stride of zero in BindVertexBuffer signifies that all elements are sourced from the same location, + // so we must provide a stride. + // This is in contrast to VertexAttrib*Pointer, where a zero signifies tightly-packed elements. + glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 2 * sizeof(GLushort)); + } + + (void)CHECK_GL_ERROR(); +} \ No newline at end of file From 07e8238b0e92a84856ba31031c1e15a090d10ca4 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 14 Nov 2016 12:09:44 -0800 Subject: [PATCH 21/28] REmove uneeded macros --- libraries/gpu-gl/src/gpu/gl/GLBackend.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index e9517f64d1..ef4b75bd75 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -11,15 +11,6 @@ #ifndef hifi_gpu_gl_GLBackend_h #define hifi_gpu_gl_GLBackend_h -// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding -// Core 43 does :) -#if(GPU_INPUT_PROFILE == GPU_CORE_41) -#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else -#define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif - - #include #include #include From 7e9df928f4c75042e03364436c2810d15541638c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Nov 2016 10:49:50 -0800 Subject: [PATCH 22/28] Add jsdoc comments to Menu --- .../src/scripting/MenuScriptingInterface.h | 139 +++++++++++++++++- .../script-engine/src/MenuItemProperties.cpp | 22 ++- 2 files changed, 156 insertions(+), 5 deletions(-) diff --git a/interface/src/scripting/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h index 855b1af13b..b1c389f733 100644 --- a/interface/src/scripting/MenuScriptingInterface.h +++ b/interface/src/scripting/MenuScriptingInterface.h @@ -17,6 +17,30 @@ class MenuItemProperties; +/**jsdoc + * The `Menu` provides access to the menu that is shown at the top of the window + * shown on a user's desktop and the right click menu that is accessible + * in both Desktop and HMD mode. + * + *

Groupings

+ * A `grouping` is a way to group a set of menus and/or menu items together + * so that they can all be set visible or invisible as a group. There are + * 2 available groups: "Advanced" and "Developer" + * These groupings can be toggled in the "Settings" menu. + * + * @namespace Menu + */ + +/** + * CURRENTLY NOT WORKING: + * + *

Action groups

+ * When 1+ menu items are checkable and in the same action group, only 1 can be + * selected at any one time. If another item in the action group is selected, the + * previous will be deselected. This feature provides the ability to create + * "radio-button"-like menus. + */ + class MenuScriptingInterface : public QObject { Q_OBJECT MenuScriptingInterface() { }; @@ -28,33 +52,142 @@ private slots: void menuItemTriggered(); public slots: + /**jsdoc + * Add a new top-level menu. + * @function Menu.addMenu + * @param {string} menuName Name that will be shown in the menu. + * @param {string} grouping Name of the grouping to add this menu to. + */ void addMenu(const QString& menuName, const QString& grouping = QString()); + + /**jsdoc + * Remove a top-level menu. + * @function Menu.removeMenu + * @param {string} menuName Name of the menu to remove. + */ void removeMenu(const QString& menuName); + + /**jsdoc + * Check whether a top-level menu exists. + * @function Menu.menuExists + * @param {string} menuName Name of the menu to check for existence. + * @return {bool} `true` if the menu exists, otherwise `false`. + */ bool menuExists(const QString& menuName); + /**jsdoc + * Add a separator with an unclickable label below it. + * The line will be placed at the bottom of the menu. + * @function Menu.addSeparator + * @param {string} menuName Name of the menu to add a separator to. + * @param {string} separatorName Name of the separator that will be shown (but unclickable) below the separator line. + */ void addSeparator(const QString& menuName, const QString& separatorName); + + /**jsdoc + * Remove a separator and its label from a menu. + * @function Menu.removeSeparator + * @param {string} menuName Name of the menu to remove a separator from. + * @param {string} separatorName Name of the separator to remove. + */ void removeSeparator(const QString& menuName, const QString& separatorName); - + + /**jsdoc + * Add a new menu item to a menu. + * @function Menu.addMenuItem + * @param {Menu.MenuItemProperties} properties + */ void addMenuItem(const MenuItemProperties& properties); + + /**jsdoc + * Add a new menu item to a menu. + * @function Menu.addMenuItem + * @param {string} menuName Name of the menu to add a menu item to. + * @param {string} menuItem Name of the menu item. This is what will be displayed in the menu. + * @param {string} shortcutKey A shortcut key that can be used to trigger the menu item. + */ void addMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey); + + /**jsdoc + * Add a new menu item to a menu. + * @function Menu.addMenuItem + * @param {string} menuName Name of the menu to add a menu item to. + * @param {string} menuItem Name of the menu item. This is what will be displayed in the menu. + */ void addMenuItem(const QString& menuName, const QString& menuitem); + /**jsdoc + * Remove a menu item from a menu. + * @function Menu.removeMenuItem + * @param {string} menuName Name of the menu to remove a menu item from. + * @param {string} menuItem Name of the menu item to remove. + */ void removeMenuItem(const QString& menuName, const QString& menuitem); + + /**jsdoc + * Check if a menu item exists. + * @function Menu.menuItemExists + * @param {string} menuName Name of the menu that the menu item is in. + * @param {string} menuItem Name of the menu item to check for existence of. + * @return {bool} `true` if the menu item exists, otherwise `false`. + */ bool menuItemExists(const QString& menuName, const QString& menuitem); + /** + * Not working, will not document until fixed + */ void addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected = QString()); void removeActionGroup(const QString& groupName); - + + /**jsdoc + * Check whether a checkable menu item is checked. + * @function Menu.isOptionChecked + * @param {string} menuOption The name of the menu item. + * @return `true` if the option is checked, otherwise false. + */ bool isOptionChecked(const QString& menuOption); + + /**jsdoc + * Set a checkable menu item as checked or unchecked. + * @function Menu.setIsOptionChecked + * @param {string} menuOption The name of the menu item to modify. + * @param {bool} isChecked If `true`, the menu item will be checked, otherwise it will not be checked. + */ void setIsOptionChecked(const QString& menuOption, bool isChecked); + /**jsdoc + * Toggle the status of a checkable menu item. If it is checked, it will be unchecked. + * If it is unchecked, it will be checked. + * @function Menu.setIsOptionChecked + * @param {string} menuOption The name of the menu item to toggle. + */ void triggerOption(const QString& menuOption); + /**jsdoc + * Check whether a menu is enabled. If a menu is disabled it will be greyed out + * and unselectable. + * Menus are enabled by default. + * @function Menu.isMenuEnabled + * @param {string} menuName The name of the menu to check. + * @return {bool} `true` if the menu is enabled, otherwise false. + */ bool isMenuEnabled(const QString& menuName); + + /**jsdoc + * Set a menu to be enabled or disabled. + * @function Menu.setMenuEnabled + * @param {string} menuName The name of the menu to modify. + * @param {bool} isEnabled Whether the menu will be enabled or not. + */ void setMenuEnabled(const QString& menuName, bool isEnabled); - + signals: + /**jsdoc + * This is a signal that is emitted when a menu item is clicked. + * @function Menu.menuItemEvent + * @param {string} menuItem Name of the menu item that was triggered. + */ void menuItemEvent(const QString& menuItem); }; diff --git a/libraries/script-engine/src/MenuItemProperties.cpp b/libraries/script-engine/src/MenuItemProperties.cpp index d181aee18d..de76dbc3ca 100644 --- a/libraries/script-engine/src/MenuItemProperties.cpp +++ b/libraries/script-engine/src/MenuItemProperties.cpp @@ -28,7 +28,7 @@ MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& m { } -MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName, +MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName, const KeyEvent& shortcutKeyEvent, bool checkable, bool checked, bool separator) : menuName(menuName), menuItemName(menuItemName), @@ -50,13 +50,31 @@ QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuIt return obj; } +/**jsdoc + * `MenuItemProperties` is a list of properties that can be passed to Menu.addMenuItem + * to create a new menu item. + * + * If none of position, beforeItem, afterItem, or grouping are specified, the + * menu item will be placed in the last position. + * + * @typedef {Object} Menu.MenuItemProperties + * @property {string} menuName Name of the top-level menu + * @property {string} menuItemName Name of the menu item + * @property {bool} isCheckable Whether the menu item is checkable or not + * @property {bool} isChecked Where the menu item is checked or not + * @property {string} shortcutKey An optional shortcut key to trigger the menu item. + * @property {int} position The position to place the new menu item. `0` is the first menu item. + * @property {string} beforeItem The name of the menu item to place this menu item before. + * @property {string} afterItem The name of the menu item to place this menu item after. + * @property {string} grouping The name of grouping to add this menu item to. + */ void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemProperties& properties) { properties.menuName = object.property("menuName").toVariant().toString(); properties.menuItemName = object.property("menuItemName").toVariant().toString(); properties.isCheckable = object.property("isCheckable").toVariant().toBool(); properties.isChecked = object.property("isChecked").toVariant().toBool(); properties.isSeparator = object.property("isSeparator").toVariant().toBool(); - + // handle the shortcut key options in order... QScriptValue shortcutKeyValue = object.property("shortcutKey"); if (shortcutKeyValue.isValid()) { From 179eed5d1140114738381df9ac0259e758f50cf8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Nov 2016 11:56:42 -0800 Subject: [PATCH 23/28] Add Vec2 and Vec3 defiitions to jsdoc --- libraries/script-engine/src/Vec3.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 71b6cf3872..07f2279d02 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -20,6 +20,24 @@ #include "GLMHelpers.h" +/**jsdoc + * A 2-dimensional vector. + * + * @typedef Vec2 + * @property {float} x X-coordinate of the vector. + * @property {float} y Y-coordinate of the vector. + */ + +/**jsdoc + * A 3-dimensional vector. + * + * @typedef Vec3 + * @property {float} x X-coordinate of the vector. + * @property {float} y Y-coordinate of the vector. + * @property {float} z Z-coordinate of the vector. + */ + + /// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API class Vec3 : public QObject { Q_OBJECT From c6b64081fc9c286b3f4fbbd4240e93539181c9b1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Nov 2016 12:01:05 -0800 Subject: [PATCH 24/28] Add Overlays jsdocs --- interface/src/ui/overlays/Overlays.h | 171 +++++++++++++++++++++------ tools/jsdoc/plugins/hifi.js | 1 + 2 files changed, 137 insertions(+), 35 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index e19a6b36a9..b5fe9c12cc 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -39,6 +39,14 @@ Q_DECLARE_METATYPE(OverlayPropertyResult); QScriptValue OverlayPropertyResultToScriptValue(QScriptEngine* engine, const OverlayPropertyResult& value); void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPropertyResult& value); +/**jsdoc + * @typedef Overlays.RayToOverlayIntersectionResult + * @property {bool} intersects True if the PickRay intersected with a 3D overlay. + * @property {Overlays.OverlayID} overlayID The ID of the overlay that was intersected with. + * @property {float} distance The distance from the PickRay origin to the intersection point. + * @property {Vec3} surfaceNormal The normal of the surface that was intersected with. + * @property {Vec3} intersection The point at which the PickRay intersected with the overlay. + */ class RayToOverlayIntersectionResult { public: RayToOverlayIntersectionResult(); @@ -57,6 +65,16 @@ Q_DECLARE_METATYPE(RayToOverlayIntersectionResult); QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, const RayToOverlayIntersectionResult& value); void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, RayToOverlayIntersectionResult& value); +/**jsdoc + * @typedef {int} Overlays.OverlayID + */ + +/**jsdoc + * + * Overlays namespace... + * @namespace Overlays + */ + class Overlays : public QObject { Q_OBJECT @@ -72,57 +90,137 @@ public: Overlay::Pointer getOverlay(unsigned int id) const; OverlayPanel::Pointer getPanel(unsigned int id) const { return _panels[id]; } - void cleanupAllOverlays(); - -public slots: - /// adds an overlay with the specific properties - unsigned int addOverlay(const QString& type, const QVariant& properties); - /// adds an overlay that's already been created unsigned int addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); } unsigned int addOverlay(Overlay::Pointer overlay); - /// clones an existing overlay + void cleanupAllOverlays(); + +public slots: + /**jsdoc + * Add an overlays to the scene. The properties specified will depend + * on the type of overlay that is being created. + * + * @function Overlays.addOverlay + * @param {string} type The type of the overlay to add. + * @param {Overlays.OverlayProperties} The properties of the overlay that you want to add. + * @return {Overlays.OverlayID} The ID of the newly created overlay. + */ + unsigned int addOverlay(const QString& type, const QVariant& properties); + + /**jsdoc + * Create a clone of an existing overlay. + * + * @function Overlays.cloneOverlay + * @param {Overlays.OverlayID} overlayID The ID of the overlay to clone. + * @return {Overlays.OverlayID} The ID of the new overlay. + */ unsigned int cloneOverlay(unsigned int id); - /// edits an overlay updating only the included properties, will return the identified OverlayID in case of - /// successful edit, if the input id is for an unknown overlay this function will have no effect + /**jsdoc + * Edit an overlay's properties. + * + * @function Overlays.editOverlay + * @param {Overlays.OverlayID} overlayID The ID of the overlay to edit. + * @return {bool} `true` if the overlay was found and edited, otherwise false. + */ bool editOverlay(unsigned int id, const QVariant& properties); /// edits an overlay updating only the included properties, will return the identified OverlayID in case of /// successful edit, if the input id is for an unknown overlay this function will have no effect bool editOverlays(const QVariant& propertiesById); - /// deletes an overlay + /**jsdoc + * Delete an overlay. + * + * @function Overlays.deleteOverlay + * @param {Overlays.OverlayID} overlayID The ID of the overlay to delete. + */ void deleteOverlay(unsigned int id); - /// get the string type of the overlay used in addOverlay + /**jsdoc + * Get the type of an overlay. + * + * @function Overlays.getOverlayType + * @param {Overlays.OverlayID} overlayID The ID of the overlay to get the type of. + * @return {string} The type of the overlay if found, otherwise the empty string. + */ QString getOverlayType(unsigned int overlayId) const; + /**jsdoc + * Get the ID of the overlay at a particular point on the HUD/screen. + * + * @function Overlays.getOverlayAtPoint + * @param {Vec2} point The point to check for an overlay. + * @return {Overlays.OverlayID} The ID of the overlay at the point specified. + * If no overlay is found, `0` will be returned. + */ + unsigned int getOverlayAtPoint(const glm::vec2& point); + + /**jsdoc + * Get the value of a an overlay's property. + * + * @function Overlays.getProperty + * @param {Overlays.OverlayID} The ID of the overlay to get the property of. + * @param {string} The name of the property to get the value of. + * @return {Object} The value of the property. If the overlay or the property could + * not be found, `undefined` will be returned. + */ + OverlayPropertyResult getProperty(unsigned int id, const QString& property); + + /*jsdoc + * Find the closest 3D overlay hit by a pick ray. + * + * @function Overlays.findRayIntersection + * @param {PickRay} The PickRay to use for finding overlays. + * @return {Overlays.RayToOverlayIntersectionResult} The result of the ray cast. + */ + RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray); + + /**jsdoc + * Check whether an overlay's assets have been loaded. For example, if the + * overlay is an "image" overlay, this will indicate whether the its image + * has loaded. + * @function Overlays.isLoaded + * @param {Overlays.OverlayID} The ID of the overlay to check. + * @return {bool} `true` if the overlay's assets have been loaded, otherwise `false`. + */ + bool isLoaded(unsigned int id); + + /**jsdoc + * Calculates the size of the given text in the specified overlay if it is a text overlay. + * If it is a 2D text overlay, the size will be in pixels. + * If it is a 3D text overlay, the size will be in meters. + * + * @function Overlays.textSize + * @param {Overlays.OverlayID} The ID of the overlay to measure. + * @param {string} The string to measure. + * @return {Vec2} The size of the text. + */ + QSizeF textSize(unsigned int id, const QString& text) const; + + /**jsdoc + * Get the width of the virtual 2D HUD. + * + * @function Overlays.width + * @return {float} The width of the 2D HUD. + */ + float width() const; + + /**jsdoc + * Get the height of the virtual 2D HUD. + * + * @function Overlays.height + * @return {float} The height of the 2D HUD. + */ + float height() const; + + /// return true if there is an overlay with that id else false + bool isAddedOverlay(unsigned int id); + unsigned int getParentPanel(unsigned int childId) const; void setParentPanel(unsigned int childId, unsigned int panelId); - /// returns the top most 2D overlay at the screen point, or 0 if not overlay at that point - unsigned int getOverlayAtPoint(const glm::vec2& point); - - /// returns the value of specified property, or null if there is no such property - OverlayPropertyResult getProperty(unsigned int id, const QString& property); - - /// returns details about the closest 3D Overlay hit by the pick ray - RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray); - - /// returns whether the overlay's assets are loaded or not - bool isLoaded(unsigned int id); - - /// returns the size of the given text in the specified overlay if it is a text overlay: in pixels if it is a 2D text - /// overlay; in meters if it is a 3D text overlay - QSizeF textSize(unsigned int id, const QString& text) const; - - // Return the size of the virtual screen - float width() const; - float height() const; - - /// adds a panel that has already been created unsigned int addPanel(OverlayPanel::Pointer panel); @@ -138,13 +236,16 @@ public slots: /// deletes a panel and all child overlays void deletePanel(unsigned int panelId); - /// return true if there is an overlay with that id else false - bool isAddedOverlay(unsigned int id); - /// return true if there is a panel with that id else false bool isAddedPanel(unsigned int id) { return _panels.contains(id); } signals: + /**jsdoc + * Emitted when an overlay is deleted + * + * @function Overlays.overlayDeleted + * @param {OverlayID} The ID of the overlay that was deleted. + */ void overlayDeleted(unsigned int id); void panelDeleted(unsigned int id); diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js index 084ff57fb5..8a6d2bf0f2 100644 --- a/tools/jsdoc/plugins/hifi.js +++ b/tools/jsdoc/plugins/hifi.js @@ -16,6 +16,7 @@ exports.handlers = { var dirList = [ '../../interface/src', '../../interface/src/scripting', + '../../interface/src/ui/overlays', '../../libraries/script-engine/src', '../../libraries/networking/src', '../../libraries/animation/src', From 75eafbb3499078d9b9c2308ffb60978e5d6293d9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Nov 2016 12:11:32 -0800 Subject: [PATCH 25/28] Add docs to Paths --- libraries/shared/src/PathUtils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/shared/src/PathUtils.h b/libraries/shared/src/PathUtils.h index 43464fe236..546586fb64 100644 --- a/libraries/shared/src/PathUtils.h +++ b/libraries/shared/src/PathUtils.h @@ -16,6 +16,11 @@ #include "DependencyManager.h" +/**jsdoc + * @namespace Paths + * @readonly + * @property {string} resources The path to the resources directory. + */ class PathUtils : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY From ff7c11d48c800a25450b5b73d6dc5c9be209f84a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 16 Nov 2016 20:14:02 +0000 Subject: [PATCH 26/28] Fixed avatar parent delete issue --- libraries/entities/src/EntityTree.cpp | 13 +++++++++++++ libraries/entities/src/EntityTree.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a03e4b8f08..24496f5637 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -438,6 +438,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign return; } + checkEntity(entityID); emit deletingEntity(entityID); // NOTE: callers must lock the tree before using this method @@ -447,6 +448,17 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign _isDirty = true; } +void EntityTree::checkEntity(const EntityItemID entityID) { + + EntityItemPointer entity = findEntityByEntityItemID(entityID); + + entity->forEachChild([&](SpatiallyNestablePointer child) { + if (child->getNestableType() == NestableType::Avatar) { + child->setParentID(nullptr); + } + }); +} + void EntityTree::deleteEntities(QSet entityIDs, bool force, bool ignoreWarnings) { // NOTE: callers must lock the tree before using this method DeleteEntityOperator theOperator(getThisPointer()); @@ -476,6 +488,7 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } // tell our delete operator about this entityID + checkEntity(entityID); theOperator.addEntityIDToDeleteList(entityID); emit deletingEntity(entityID); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 441b686e3b..c6df9a77bf 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -121,6 +121,8 @@ public: // use this method if you have a pointer to the entity (avoid an extra entity lookup) bool updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr)); + // check if the avatar is a child of this entity, If so set the avatar parentID to null + void checkEntity(const EntityItemID entityID); void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = true); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = true); From 9c4ae9df5ad7d2e2ef2fd08dc2a016aa18bb49c4 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 16 Nov 2016 22:09:22 +0000 Subject: [PATCH 27/28] function name change --- libraries/entities/src/EntityTree.cpp | 6 +++--- libraries/entities/src/EntityTree.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 24496f5637..182061b0d6 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -438,7 +438,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign return; } - checkEntity(entityID); + IsAvatarParentOfEntity(entityID); emit deletingEntity(entityID); // NOTE: callers must lock the tree before using this method @@ -448,7 +448,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign _isDirty = true; } -void EntityTree::checkEntity(const EntityItemID entityID) { +void EntityTree::IsAvatarParentOfEntity(const EntityItemID entityID) { EntityItemPointer entity = findEntityByEntityItemID(entityID); @@ -488,7 +488,7 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } // tell our delete operator about this entityID - checkEntity(entityID); + IsAvatarParentOfEntity(entityID); theOperator.addEntityIDToDeleteList(entityID); emit deletingEntity(entityID); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index c6df9a77bf..f63dac16be 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -122,7 +122,7 @@ public: bool updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr)); // check if the avatar is a child of this entity, If so set the avatar parentID to null - void checkEntity(const EntityItemID entityID); + void IsAvatarParentOfEntity(const EntityItemID entityID); void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = true); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = true); From 66ff81f45066e2b890845ec3e8e0ee58fd38e5dc Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 16 Nov 2016 22:32:15 +0000 Subject: [PATCH 28/28] Another function name change --- libraries/entities/src/EntityTree.cpp | 8 ++++---- libraries/entities/src/EntityTree.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 182061b0d6..e69adbce88 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -438,7 +438,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign return; } - IsAvatarParentOfEntity(entityID); + unhookChildAvatar(entityID); emit deletingEntity(entityID); // NOTE: callers must lock the tree before using this method @@ -448,11 +448,11 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign _isDirty = true; } -void EntityTree::IsAvatarParentOfEntity(const EntityItemID entityID) { +void EntityTree::unhookChildAvatar(const EntityItemID entityID) { EntityItemPointer entity = findEntityByEntityItemID(entityID); - entity->forEachChild([&](SpatiallyNestablePointer child) { + entity->forEachDescendant([&](SpatiallyNestablePointer child) { if (child->getNestableType() == NestableType::Avatar) { child->setParentID(nullptr); } @@ -488,7 +488,7 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } // tell our delete operator about this entityID - IsAvatarParentOfEntity(entityID); + unhookChildAvatar(entityID); theOperator.addEntityIDToDeleteList(entityID); emit deletingEntity(entityID); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index f63dac16be..98598b879b 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -122,7 +122,7 @@ public: bool updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr)); // check if the avatar is a child of this entity, If so set the avatar parentID to null - void IsAvatarParentOfEntity(const EntityItemID entityID); + void unhookChildAvatar(const EntityItemID entityID); void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = true); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = true);