2 * Copyright (c) 2019 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 "frame-buffer-state-cache.h"
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-defines.h>
31 const uint32_t INITIAL_FRAMEBUFFER_STATE = 0u;
38 FrameBufferStateCache::FrameBufferStateCache()
39 :mCurrentFrameBufferId(0)
43 FrameBufferStateCache::~FrameBufferStateCache() = default;
45 GLbitfield FrameBufferStateCache::GetClearMask( GLbitfield mask, bool forceClear, bool scissorTestEnabled )
47 if( scissorTestEnabled )
49 // don't do anything if scissor test is enabled, in the future we could
50 // potentially keep track of frame buffer size vs scissor test size to see if the entire
51 // buffer is cleared or not.
54 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
57 DALI_LOG_ERROR("FrameBuffer not found %d \n", mCurrentFrameBufferId);
61 // if we are forcing the clear operation, then just update the internal cached values
64 SetClearState( state, mask );
68 // use the cached values
69 if( mask & GL_COLOR_BUFFER_BIT)
71 // check if color buffer is currently clean
72 if( state->mState & COLOR_BUFFER_CLEAN )
74 // remove clear color buffer flag from bitmask, no need to clear twice
75 mask&= ~GL_COLOR_BUFFER_BIT;
78 if( mask & GL_DEPTH_BUFFER_BIT)
80 // check if depth buffer is currently clean
81 if( state->mState & DEPTH_BUFFER_CLEAN )
83 // remove clear depth buffer flag from bitmask, no need to clear twice
84 mask&= ~GL_DEPTH_BUFFER_BIT;
87 if( mask & GL_STENCIL_BUFFER_BIT)
89 // check if stencil buffer is currently clean
90 if( state->mState & STENCIL_BUFFER_CLEAN )
92 // remove clear stencil buffer flag from bitmask, no need to clear twice
94 mask&= ~GL_STENCIL_BUFFER_BIT;
98 // set the clear state based, what's about to be cleared
99 SetClearState( state, mask );
104 void FrameBufferStateCache::SetCurrentFrameBuffer( GLuint frameBufferId )
106 mCurrentFrameBufferId = frameBufferId;
109 void FrameBufferStateCache::FrameBuffersDeleted( GLsizei count, const GLuint* const frameBuffers )
111 for( GLsizei i = 0; i < count; ++i )
113 DeleteFrameBuffer( frameBuffers[i] );
116 void FrameBufferStateCache::FrameBuffersCreated( GLsizei count, const GLuint* const frameBuffers )
118 for( GLsizei i = 0; i < count; ++i )
120 // check the frame buffer doesn't exist already
121 GLuint id = frameBuffers[i];
123 FrameBufferState* state = GetFrameBufferState( id );
126 DALI_LOG_ERROR("FrameBuffer already exists%d \n", id );
128 state->mState = INITIAL_FRAMEBUFFER_STATE;
132 FrameBufferState newFrameBuffer( frameBuffers[i] );
133 mFrameBufferStates.PushBack( newFrameBuffer );
137 void FrameBufferStateCache::DrawOperation( bool colorBuffer, bool depthBuffer, bool stencilBuffer )
139 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
142 // an error will have already been logged by the clear operation
148 // un-set the clean bit
149 state->mState &= ~COLOR_BUFFER_CLEAN;
153 // un-set the clean bit
154 state->mState &= ~DEPTH_BUFFER_CLEAN;
158 // un-set the clean bit
159 state->mState &= ~STENCIL_BUFFER_CLEAN;
164 void FrameBufferStateCache::Reset()
166 mFrameBufferStates.Clear();
168 // create the default frame buffer
169 GLuint id = 0; // 0 == default frame buffer id
170 FrameBuffersCreated( 1, &id );
173 void FrameBufferStateCache::SetClearState( FrameBufferState* state, GLbitfield mask )
175 if( mask & GL_COLOR_BUFFER_BIT)
177 // set the color buffer to clean
178 state->mState |= COLOR_BUFFER_CLEAN;
180 if( mask & GL_DEPTH_BUFFER_BIT)
182 // set the depth buffer to clean
183 state->mState |= DEPTH_BUFFER_CLEAN;
185 if( mask & GL_STENCIL_BUFFER_BIT)
187 // set the stencil buffer to clean
188 state->mState |= STENCIL_BUFFER_CLEAN;
192 FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState( GLuint frameBufferId )
194 for( FrameBufferStateVector::SizeType i = 0; i < mFrameBufferStates.Count(); ++i )
196 FrameBufferState& state = mFrameBufferStates[i];
197 if( state.mId == frameBufferId )
205 void FrameBufferStateCache::DeleteFrameBuffer( GLuint frameBufferId )
207 FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin();
208 FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End();
210 for( ; iter != endIter ; ++iter )
212 if( (*iter).mId == frameBufferId )
214 mFrameBufferStates.Erase( iter);
218 DALI_LOG_ERROR("FrameBuffer not found %d \n", frameBufferId);
221 } // namespace Internal