X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fgraphics%2Fgles-impl%2Fgles-context.cpp;h=13c1bad612c5402ecac4f03200f16782b5b6e73b;hb=ef54e9b4b80c6ccdcb8f3e265076763a66f5114e;hp=31e0713e3a39f986fc605f49fcbba7d418aa1eee;hpb=61819938e94ac360aaa11865ae990c85253e09cd;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index 31e0713..13c1bad 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -28,6 +28,8 @@ #include "gles-graphics-render-pass.h" #include "gles-graphics-render-target.h" +#include + namespace Dali::Graphics::GLES { struct Context::Impl @@ -40,6 +42,39 @@ struct Context::Impl ~Impl() = default; /** + * Binds (and creates) VAO + * + * VAO is fixed per program so it has to be created only once assuming + * that VertexInputState has been set correctly for the pipeline. + * + */ + void BindProgramVAO(GLES::ProgramImpl* program, const VertexInputState& vertexInputState) + { + auto& gl = *mController.GetGL(); + auto iter = mProgramVAOMap.find(program); + if(iter != mProgramVAOMap.end()) + { + if(mProgramVAOCurrentState != iter->second) + { + mProgramVAOCurrentState = iter->second; + gl.BindVertexArray(iter->second); + } + return; + } + + uint32_t vao; + gl.GenVertexArrays(1, &vao); + gl.BindVertexArray(vao); + mProgramVAOMap[program] = vao; + for(const auto& attr : vertexInputState.attributes) + { + gl.EnableVertexAttribArray(attr.location); + } + + mProgramVAOCurrentState = vao; + } + + /** * Sets the initial GL state. */ void InitializeGlState() @@ -165,7 +200,10 @@ struct Context::Impl const GLES::RenderTarget* mCurrentRenderTarget{nullptr}; const GLES::RenderPass* mCurrentRenderPass{nullptr}; - GLStateCache mGlStateCache{}; ///< GL status cache + // Each context must have own VAOs as they cannot be shared + std::map mProgramVAOMap; ///< GL program-VAO map + uint32_t mProgramVAOCurrentState{0u}; ///< Currently bound VAO + GLStateCache mGlStateCache{}; ///< GL status cache bool mGlContextCreated{false}; ///< True if the OpenGL context has been created }; @@ -181,6 +219,8 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) { auto& gl = *mImpl->mController.GetGL(); + static const bool hasGLES3(mImpl->mController.GetGLESVersion() >= GLESVersion::GLES_30); + // early out if neither current nor new pipelines are set // this behaviour may be valid so no assert if(!mImpl->mCurrentPipeline && !mImpl->mNewPipeline) @@ -246,15 +286,25 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) } // for each attribute bind vertices - const auto& pipelineState = mImpl->mNewPipeline->GetCreateInfo(); - const auto& vi = pipelineState.vertexInputState; - for(const auto& attr : vi->attributes) + + const auto& pipelineState = mImpl->mNewPipeline ? mImpl->mNewPipeline->GetCreateInfo() : mImpl->mCurrentPipeline->GetCreateInfo(); + const auto& vertexInputState = pipelineState.vertexInputState; + + if(hasGLES3) + { + mImpl->BindProgramVAO(static_cast(pipelineState.programState->program)->GetImplementation(), *vertexInputState); + } + + for(const auto& attr : vertexInputState->attributes) { // Enable location - mImpl->SetVertexAttributeLocation(attr.location, true); + if(!hasGLES3) + { + mImpl->SetVertexAttributeLocation(attr.location, true); + } const auto& bufferSlot = mImpl->mCurrentVertexBufferBindings[attr.binding]; - const auto& bufferBinding = vi->bufferBindings[attr.binding]; + const auto& bufferBinding = vertexInputState->bufferBindings[attr.binding]; auto glesBuffer = bufferSlot.buffer->GetGLBuffer(); @@ -270,7 +320,7 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) } // Resolve topology - const auto& ia = mImpl->mNewPipeline->GetCreateInfo().inputAssemblyState; + const auto& ia = pipelineState.inputAssemblyState; // Bind uniforms @@ -282,7 +332,11 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) mImpl->mGlStateCache.mFrameBufferStateCache.DrawOperation(mImpl->mGlStateCache.mColorMask, mImpl->mGlStateCache.DepthBufferWriteEnabled(), mImpl->mGlStateCache.StencilBufferWriteEnabled()); - mImpl->FlushVertexAttributeLocations(); + // For GLES3+ we use VAO, for GLES2 internal cache + if(!hasGLES3) + { + mImpl->FlushVertexAttributeLocations(); + } gl.DrawArrays(GLESTopology(ia->topology), drawCall.draw.firstVertex, @@ -297,7 +351,12 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) mImpl->mGlStateCache.mFrameBufferStateCache.DrawOperation(mImpl->mGlStateCache.mColorMask, mImpl->mGlStateCache.DepthBufferWriteEnabled(), mImpl->mGlStateCache.StencilBufferWriteEnabled()); - mImpl->FlushVertexAttributeLocations(); + + // For GLES3+ we use VAO, for GLES2 internal cache + if(!hasGLES3) + { + mImpl->FlushVertexAttributeLocations(); + } auto indexBufferFormat = GLIndexFormat(binding.format).format; gl.DrawElements(GLESTopology(ia->topology), @@ -322,11 +381,13 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) } } -void Context::BindTextures(const std::vector& bindings) +void Context::BindTextures(const Graphics::TextureBinding* bindings, uint32_t count) { // for each texture allocate slot - for(const auto& binding : bindings) + for(auto i = 0u; i < count; ++i) { + auto& binding = bindings[i]; + // Resize binding array if needed if(mImpl->mCurrentTextureBindings.size() <= binding.binding) { @@ -337,14 +398,14 @@ void Context::BindTextures(const std::vector& bindings } } -void Context::BindVertexBuffers(const std::vector& bindings) +void Context::BindVertexBuffers(const GLES::VertexBufferBindingDescriptor* bindings, uint32_t count) { - if(bindings.size() > mImpl->mCurrentVertexBufferBindings.size()) + if(count > mImpl->mCurrentVertexBufferBindings.size()) { - mImpl->mCurrentVertexBufferBindings.resize(bindings.size()); + mImpl->mCurrentVertexBufferBindings.resize(count); } // Copy only set slots - std::copy_if(bindings.begin(), bindings.end(), mImpl->mCurrentVertexBufferBindings.begin(), [](auto& item) { + std::copy_if(bindings, bindings + count, mImpl->mCurrentVertexBufferBindings.begin(), [](auto& item) { return (nullptr != item.buffer); }); } @@ -360,21 +421,22 @@ void Context::BindPipeline(const GLES::Pipeline* newPipeline) mImpl->mNewPipeline = &newPipeline->GetPipeline(); } -void Context::BindUniformBuffers(const std::vector& uboBindings, - const UniformBufferBindingDescriptor& standaloneBindings) +void Context::BindUniformBuffers(const UniformBufferBindingDescriptor* uboBindings, + uint32_t uboCount, + const UniformBufferBindingDescriptor& standaloneBindings) { if(standaloneBindings.buffer) { mImpl->mCurrentStandaloneUBOBinding = standaloneBindings; } - if(uboBindings.size() >= mImpl->mCurrentUBOBindings.size()) + if(uboCount >= mImpl->mCurrentUBOBindings.size()) { - mImpl->mCurrentUBOBindings.resize(uboBindings.size() + 1); + mImpl->mCurrentUBOBindings.resize(uboCount + 1); } - auto it = uboBindings.begin(); - for(auto i = 0u; i < uboBindings.size(); ++i) + auto it = uboBindings; + for(auto i = 0u; i < uboCount; ++i) { if(it->buffer) { @@ -509,106 +571,12 @@ void Context::ResolveUniformBuffers() void Context::ResolveStandaloneUniforms() { - auto& gl = *mImpl->mController.GetGL(); - // Find reflection for program const auto program = static_cast(mImpl->mNewPipeline->GetCreateInfo().programState->program); + const auto ptr = reinterpret_cast(mImpl->mCurrentStandaloneUBOBinding.buffer->GetCPUAllocatedAddress()) + mImpl->mCurrentStandaloneUBOBinding.offset; - const auto& reflection = program->GetReflection(); - - auto extraInfos = reflection.GetStandaloneUniformExtraInfo(); - - const auto ptr = reinterpret_cast(mImpl->mCurrentStandaloneUBOBinding.buffer->GetCPUAllocatedAddress()) + mImpl->mCurrentStandaloneUBOBinding.offset; - - for(const auto& info : extraInfos) - { - auto type = GLTypeConversion(info.type).type; - auto offset = info.offset; - switch(type) - { - case GLType::FLOAT_VEC2: - { - gl.Uniform2fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_VEC3: - { - gl.Uniform3fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_VEC4: - { - gl.Uniform4fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC2: - { - gl.Uniform2iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC3: - { - gl.Uniform3iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC4: - { - gl.Uniform4iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::BOOL: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC2: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC3: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC4: - { - // not supported by DALi - break; - } - case GLType::FLOAT: - { - gl.Uniform1fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT2: - { - gl.UniformMatrix2fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT3: - { - gl.UniformMatrix3fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT4: - { - gl.UniformMatrix4fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::SAMPLER_2D: - { - break; - } - case GLType::SAMPLER_CUBE: - { - break; - } - default: - { - } - } - } + // Update program uniforms + program->GetImplementation()->UpdateStandaloneUniformBlock(ptr); } void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) @@ -648,22 +616,24 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) // Something goes wrong here if Alpha mask is GL_TRUE ColorMask(true); + const auto clearValues = renderPassBegin.clearValues.Ptr(); + if(!mImpl->mGlStateCache.mClearColorSet || - mImpl->mGlStateCache.mClearColor.r != renderPassBegin.clearValues[0].color.r || - mImpl->mGlStateCache.mClearColor.g != renderPassBegin.clearValues[0].color.g || - mImpl->mGlStateCache.mClearColor.b != renderPassBegin.clearValues[0].color.b || - mImpl->mGlStateCache.mClearColor.a != renderPassBegin.clearValues[0].color.a) + mImpl->mGlStateCache.mClearColor.r != clearValues[0].color.r || + mImpl->mGlStateCache.mClearColor.g != clearValues[0].color.g || + mImpl->mGlStateCache.mClearColor.b != clearValues[0].color.b || + mImpl->mGlStateCache.mClearColor.a != clearValues[0].color.a) { - gl.ClearColor(renderPassBegin.clearValues[0].color.r, - renderPassBegin.clearValues[0].color.g, - renderPassBegin.clearValues[0].color.b, - renderPassBegin.clearValues[0].color.a); + gl.ClearColor(clearValues[0].color.r, + clearValues[0].color.g, + clearValues[0].color.b, + clearValues[0].color.a); mImpl->mGlStateCache.mClearColorSet = true; - mImpl->mGlStateCache.mClearColor = Vector4(renderPassBegin.clearValues[0].color.r, - renderPassBegin.clearValues[0].color.g, - renderPassBegin.clearValues[0].color.b, - renderPassBegin.clearValues[0].color.a); + mImpl->mGlStateCache.mClearColor = Vector4(clearValues[0].color.r, + clearValues[0].color.g, + clearValues[0].color.b, + clearValues[0].color.a); } } @@ -748,6 +718,14 @@ void Context::ClearBuffer(uint32_t mask, bool forceClear) } } +void Context::InvalidateDepthStencilBuffers() +{ + auto& gl = *mImpl->mController.GetGL(); + + GLenum attachments[] = {GL_DEPTH, GL_STENCIL}; + gl.InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); +} + void Context::SetScissorTestEnabled(bool scissorEnabled) { if(mImpl->mGlStateCache.mScissorTestEnabled != scissorEnabled)