2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "gles-context.h"
19 #include <dali/integration-api/gl-abstraction.h>
20 #include <dali/integration-api/gl-defines.h>
21 #include "gles-graphics-buffer.h"
22 #include "gles-graphics-command-buffer.h"
23 #include "gles-graphics-pipeline.h"
25 namespace Dali::Graphics::GLES
29 Impl(EglGraphicsController& controller)
30 : mController(controller)
36 EglGraphicsController& mController;
38 const GLES::Pipeline* mCurrentPipeline{nullptr}; ///< Currently bound pipeline
39 const GLES::Pipeline* mNewPipeline{nullptr}; ///< New pipeline to be set on flush
41 std::vector<Graphics::TextureBinding> mCurrentTextureBindings{};
42 std::vector<Graphics::SamplerBinding> mCurrentSamplerBindings{};
43 GLES::IndexBufferBindingDescriptor mCurrentIndexBufferBinding{};
45 struct VertexBufferBinding
47 GLES::Buffer* buffer{nullptr};
51 // Currently bound buffers
52 std::vector<VertexBufferBindingDescriptor> mCurrentVertexBufferBindings{};
55 Context::Context(EglGraphicsController& controller)
57 mImpl = std::make_unique<Impl>(controller);
60 Context::~Context() = default;
62 void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall)
64 auto& gl = *mImpl->mController.GetGL();
67 if(mImpl->mNewPipeline)
69 // Execute states if different
70 mImpl->mCurrentPipeline = mImpl->mNewPipeline;
71 mImpl->mNewPipeline = nullptr;
75 for(const auto& binding : mImpl->mCurrentTextureBindings)
77 gl.ActiveTexture(GL_TEXTURE0 + binding.binding);
78 gl.BindTexture(GL_TEXTURE_2D,
79 static_cast<const GLES::Texture*>(binding.texture)
83 // for each attribute bind vertices
84 const auto& pipelineState = mImpl->mCurrentPipeline->GetCreateInfo();
85 const auto& vi = pipelineState.vertexInputState;
86 for(const auto& attr : vi->attributes)
89 gl.EnableVertexAttribArray(attr.location);
90 const auto& bufferSlot = mImpl->mCurrentVertexBufferBindings[attr.binding];
91 const auto& bufferBinding = vi->bufferBindings[attr.binding];
93 auto glesBuffer = bufferSlot.buffer->GetGLBuffer();
96 gl.BindBuffer(GL_ARRAY_BUFFER, glesBuffer);
97 gl.VertexAttribPointer(attr.location,
98 GLVertexFormat(attr.format).size,
99 GLVertexFormat(attr.format).format,
101 bufferBinding.stride,
102 reinterpret_cast<void*>(attr.offset));
106 const auto& ia = mImpl->mCurrentPipeline->GetCreateInfo().inputAssemblyState;
109 switch(drawCall.type)
111 case DrawCallDescriptor::Type::DRAW:
113 gl.DrawArrays(GLESTopology(ia->topology),
114 drawCall.draw.firstVertex,
115 drawCall.draw.vertexCount);
118 case DrawCallDescriptor::Type::DRAW_INDEXED:
120 const auto& binding = mImpl->mCurrentIndexBufferBinding;
121 const auto* glesBuffer = binding.buffer;
122 gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, glesBuffer->GetGLBuffer());
123 auto indexBufferFormat = GLIndexFormat(binding.format).format;
124 gl.DrawElements(GLESTopology(ia->topology),
125 drawCall.drawIndexed.indexCount,
127 reinterpret_cast<void*>(binding.offset));
130 case DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT:
137 void Context::BindTextures(const std::vector<Graphics::TextureBinding>& bindings)
139 // for each texture allocate slot
140 for(const auto& binding : bindings)
142 // Resize binding array if needed
143 if(mImpl->mCurrentTextureBindings.size() <= binding.binding)
145 mImpl->mCurrentTextureBindings.resize(binding.binding + 1);
147 // Store the binding details
148 mImpl->mCurrentTextureBindings[binding.binding] = binding;
152 void Context::BindVertexBuffers(const std::vector<GLES::VertexBufferBindingDescriptor>& bindings)
154 if(bindings.size() > mImpl->mCurrentVertexBufferBindings.size())
156 mImpl->mCurrentVertexBufferBindings.resize(bindings.size());
158 // Copy only set slots
159 std::copy_if(bindings.begin(), bindings.end(), mImpl->mCurrentVertexBufferBindings.begin(), [](auto& item) {
160 return (nullptr != item.buffer);
164 void Context::BindIndexBuffer(const IndexBufferBindingDescriptor& indexBufferBinding)
166 mImpl->mCurrentIndexBufferBinding = indexBufferBinding;
169 void Context::BindPipeline(const GLES::Pipeline* newPipeline)
171 mImpl->mNewPipeline = newPipeline;
174 } // namespace Dali::Graphics::GLES