X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fgraphics%2Fgles-impl%2Fgles-context.cpp;h=02d32ee40aecd18613d21eaaaf143435ebdbfece;hb=2c55cc6b056f93522e36943d7bbaf770a5aa2170;hp=f38ed4a64add1d10a9623f7d5d66cf6bd9040f6b;hpb=e18cc49d83f5e6bc4ca65c685551084691f2b28a;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 f38ed4a..02d32ee 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -17,9 +17,11 @@ #include "gles-context.h" #include +#include #include #include #include +#include #include "egl-graphics-controller.h" #include "gles-graphics-buffer.h" @@ -27,12 +29,12 @@ #include "gles-graphics-program.h" #include "gles-graphics-render-pass.h" #include "gles-graphics-render-target.h" +#include "gles-texture-dependency-checker.h" #include #include #include - namespace Dali::Graphics::GLES { struct Context::Impl @@ -62,6 +64,13 @@ struct Context::Impl mProgramVAOCurrentState = iter->second; gl.BindVertexArray(iter->second); } + + // We should re-check enable attribute usage because geometry might be changed. + // @todo : We can remove this loop if we enable vertex attrib by shader's information. + for(const auto& attr : vertexInputState.attributes) + { + gl.EnableVertexAttribArray(attr.location); + } return; } @@ -69,6 +78,9 @@ struct Context::Impl gl.GenVertexArrays(1, &vao); gl.BindVertexArray(vao); mProgramVAOMap[program] = vao; + + // @todo : Enable vertex attrib only by shader's information, not with Geometry. + // Currently, vertexInputState.attributes depend on Geometry's VertexBuffer. for(const auto& attr : vertexInputState.attributes) { gl.EnableVertexAttribArray(attr.location); @@ -232,7 +244,7 @@ Context::~Context() } } -void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) +void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall, GLES::TextureDependencyChecker& dependencyChecker) { auto& gl = *mImpl->mController.GetGL(); @@ -256,6 +268,13 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) newProgram = static_cast(mImpl->mNewPipeline->GetCreateInfo().programState->program); } + if(!currentProgram && !newProgram) + { + // Early out if we have no program for this pipeline. + DALI_LOG_ERROR("No program defined for pipeline\n"); + return; + } + if(mImpl->mNewPipeline && mImpl->mCurrentPipeline != mImpl->mNewPipeline) { if(!currentProgram || currentProgram->GetImplementation()->GetGlProgram() != newProgram->GetImplementation()->GetGlProgram()) @@ -290,6 +309,9 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) texture->InitializeResource(); } + // Warning, this may cause glWaitSync to occur on the GPU. + dependencyChecker.CheckNeedsSync(this, texture); + texture->Bind(binding); texture->Prepare(); // @todo also non-const. @@ -593,11 +615,23 @@ void Context::ResolveUniformBuffers() void Context::ResolveStandaloneUniforms() { // 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 GLES::Program* program{nullptr}; + + if(mImpl->mNewPipeline) + { + program = static_cast(mImpl->mNewPipeline->GetCreateInfo().programState->program); + } + else if(mImpl->mCurrentPipeline) + { + program = static_cast(mImpl->mCurrentPipeline->GetCreateInfo().programState->program); + } - // Update program uniforms - program->GetImplementation()->UpdateStandaloneUniformBlock(ptr); + if(program) + { + const auto ptr = reinterpret_cast(mImpl->mCurrentStandaloneUBOBinding.buffer->GetCPUAllocatedAddress()) + mImpl->mCurrentStandaloneUBOBinding.offset; + // Update program uniforms + program->GetImplementation()->UpdateStandaloneUniformBlock(ptr); + } } void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) @@ -617,7 +651,8 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) else if(targetInfo.framebuffer) { // bind framebuffer and swap. - renderTarget.GetFramebuffer()->Bind(); + auto framebuffer = renderTarget.GetFramebuffer(); + framebuffer->Bind(); } // clear (ideally cache the setup) @@ -629,6 +664,7 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) const auto& attachments = *renderPass.GetCreateInfo().attachments; const auto& color0 = attachments[0]; GLuint mask = 0; + if(color0.loadOp == AttachmentLoadOp::CLEAR) { mask |= GL_COLOR_BUFFER_BIT; @@ -639,11 +675,11 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) const auto clearValues = renderPassBegin.clearValues.Ptr(); - if(!mImpl->mGlStateCache.mClearColorSet || - 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) + if(!Dali::Equals(mImpl->mGlStateCache.mClearColor.r, clearValues[0].color.r) || + !Dali::Equals(mImpl->mGlStateCache.mClearColor.g, clearValues[0].color.g) || + !Dali::Equals(mImpl->mGlStateCache.mClearColor.b, clearValues[0].color.b) || + !Dali::Equals(mImpl->mGlStateCache.mClearColor.a, clearValues[0].color.a) || + !mImpl->mGlStateCache.mClearColorSet) { gl.ClearColor(clearValues[0].color.r, clearValues[0].color.g, @@ -691,14 +727,28 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) mImpl->mCurrentRenderTarget = &renderTarget; } -void Context::EndRenderPass() +void Context::EndRenderPass(GLES::TextureDependencyChecker& dependencyChecker) { if(mImpl->mCurrentRenderTarget) { - if(mImpl->mCurrentRenderTarget->GetFramebuffer()) + GLES::Framebuffer* framebuffer = mImpl->mCurrentRenderTarget->GetFramebuffer(); + if(framebuffer) { auto& gl = *mImpl->mController.GetGL(); gl.Flush(); + + /* @todo Full dependency checking would need to store textures in Begin, and create + * fence objects here; but we're going to draw all fbos on shared context in serial, + * so no real need (yet). Might want to consider ensuring order of render passes, + * but that needs doing in the controller, and would need doing before ProcessCommandQueues. + * + * Currently up to the client to create render tasks in the right order. + */ + + /* Create fence sync objects. Other contexts can then wait on these fences before reading + * textures. + */ + dependencyChecker.AddTextures(this, framebuffer); } } } @@ -991,13 +1041,20 @@ void Context::PrepareForNativeRendering() if(!mImpl->mNativeDrawContext) { EGLint configId{0u}; - EGLint size{0u}; - eglGetConfigs(display, nullptr, 0, &size); - std::vector configs; - configs.resize(size); - eglGetConfigs(display, configs.data(), configs.size(), &size); + eglQueryContext(display, mImpl->mController.GetSharedContext(), EGL_CONFIG_ID, &configId); - eglQueryContext(display, context, EGL_CONFIG_ID, &configId); + EGLint configAttribs[3]; + configAttribs[0] = EGL_CONFIG_ID; + configAttribs[1] = configId; + configAttribs[2] = EGL_NONE; + + EGLConfig config; + EGLint numConfigs; + if(eglChooseConfig(display, configAttribs, &config, 1, &numConfigs) != EGL_TRUE) + { + DALI_LOG_ERROR("eglChooseConfig failed!\n"); + return; + } auto version = int(mImpl->mController.GetGLESVersion()); @@ -1008,7 +1065,12 @@ void Context::PrepareForNativeRendering() attribs.push_back(version % 10); attribs.push_back(EGL_NONE); - mImpl->mNativeDrawContext = eglCreateContext(display, configs[configId], EGL_NO_CONTEXT, attribs.data()); + mImpl->mNativeDrawContext = eglCreateContext(display, config, mImpl->mController.GetSharedContext(), attribs.data()); + if(mImpl->mNativeDrawContext == EGL_NO_CONTEXT) + { + DALI_LOG_ERROR("eglCreateContext failed!\n"); + return; + } } eglMakeCurrent(display, drawSurface, readSurface, mImpl->mNativeDrawContext);