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.
19 #include "gles-framebuffer-state-cache.h"
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-defines.h>
25 namespace Dali::Graphics
31 const uint32_t INITIAL_FRAMEBUFFER_STATE = 0u;
34 FrameBufferStateCache::FrameBufferStateCache()
38 FrameBufferStateCache::~FrameBufferStateCache() = default;
40 GLbitfield FrameBufferStateCache::GetClearMask(GLbitfield mask, bool forceClear, bool scissorTestEnabled)
42 if(scissorTestEnabled)
44 // don't do anything if scissor test is enabled, in the future we could
45 // potentially keep track of frame buffer size vs scissor test size to see if the entire
46 // buffer is cleared or not.
50 FrameBufferState* state = GetFrameBufferState(mCurrentFrameBufferId);
53 DALI_LOG_ERROR("FrameBuffer not found %d \n", mCurrentFrameBufferId);
57 // if we are forcing the clear operation, then just update the internal cached values
60 SetClearState(state, mask);
64 // use the cached values
65 if(mask & GL_COLOR_BUFFER_BIT)
67 // check if color buffer is currently clean
68 if(state->mState & COLOR_BUFFER_CLEAN)
70 // remove clear color buffer flag from bitmask, no need to clear twice
71 mask &= ~GL_COLOR_BUFFER_BIT;
74 if(mask & GL_DEPTH_BUFFER_BIT)
76 // check if depth buffer is currently clean
77 if(state->mState & DEPTH_BUFFER_CLEAN)
79 // remove clear depth buffer flag from bitmask, no need to clear twice
80 mask &= ~GL_DEPTH_BUFFER_BIT;
83 if(mask & GL_STENCIL_BUFFER_BIT)
85 // check if stencil buffer is currently clean
86 if(state->mState & STENCIL_BUFFER_CLEAN)
88 // remove clear stencil buffer flag from bitmask, no need to clear twice
90 mask &= ~GL_STENCIL_BUFFER_BIT;
94 // set the clear state based, what's about to be cleared
95 SetClearState(state, mask);
100 void FrameBufferStateCache::SetCurrentFrameBuffer(GLuint frameBufferId)
102 mCurrentFrameBufferId = frameBufferId;
105 void FrameBufferStateCache::FrameBuffersDeleted(GLsizei count, const GLuint* const frameBuffers)
107 for(GLsizei i = 0; i < count; ++i)
109 DeleteFrameBuffer(frameBuffers[i]);
112 void FrameBufferStateCache::FrameBuffersCreated(GLsizei count, const GLuint* const frameBuffers)
114 for(GLsizei i = 0; i < count; ++i)
116 // check the frame buffer doesn't exist already
117 GLuint id = frameBuffers[i];
119 FrameBufferState* state = GetFrameBufferState(id);
122 DALI_LOG_ERROR("FrameBuffer already exists%d \n", id);
124 state->mState = INITIAL_FRAMEBUFFER_STATE;
128 FrameBufferState newFrameBuffer(frameBuffers[i]);
129 mFrameBufferStates.PushBack(newFrameBuffer);
133 void FrameBufferStateCache::DrawOperation(bool colorBuffer, bool depthBuffer, bool stencilBuffer)
135 FrameBufferState* state = GetFrameBufferState(mCurrentFrameBufferId);
138 // an error will have already been logged by the clear operation
144 // un-set the clean bit
145 state->mState &= ~COLOR_BUFFER_CLEAN;
149 // un-set the clean bit
150 state->mState &= ~DEPTH_BUFFER_CLEAN;
154 // un-set the clean bit
155 state->mState &= ~STENCIL_BUFFER_CLEAN;
159 void FrameBufferStateCache::Reset()
161 mFrameBufferStates.Clear();
163 // create the default frame buffer
164 GLuint id = 0; // 0 == default frame buffer id
165 FrameBuffersCreated(1, &id);
168 void FrameBufferStateCache::SetClearState(FrameBufferState* state, GLbitfield mask)
170 if(mask & GL_COLOR_BUFFER_BIT)
172 // set the color buffer to clean
173 state->mState |= COLOR_BUFFER_CLEAN;
175 if(mask & GL_DEPTH_BUFFER_BIT)
177 // set the depth buffer to clean
178 state->mState |= DEPTH_BUFFER_CLEAN;
180 if(mask & GL_STENCIL_BUFFER_BIT)
182 // set the stencil buffer to clean
183 state->mState |= STENCIL_BUFFER_CLEAN;
187 FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState(GLuint frameBufferId)
189 for(FrameBufferStateVector::SizeType i = 0; i < mFrameBufferStates.Count(); ++i)
191 FrameBufferState& state = mFrameBufferStates[i];
192 if(state.mId == frameBufferId)
200 void FrameBufferStateCache::DeleteFrameBuffer(GLuint frameBufferId)
202 FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin();
203 FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End();
205 for(; iter != endIter; ++iter)
207 if((*iter).mId == frameBufferId)
209 mFrameBufferStates.Erase(iter);
213 DALI_LOG_ERROR("FrameBuffer not found %d \n", frameBufferId);
218 } // namespace Dali::Graphics