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()
47 GLbitfield FrameBufferStateCache::GetClearMask( GLbitfield mask, bool forceClear, bool scissorTestEnabled )
49 if( scissorTestEnabled )
51 // don't do anything if scissor test is enabled, in the future we could
52 // potentially keep track of frame buffer size vs scissor test size to see if the entire
53 // buffer is cleared or not.
56 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
59 DALI_LOG_ERROR("FrameBuffer not found %d \n", mCurrentFrameBufferId);
63 // if we are forcing the clear operation, then just update the internal cached values
66 SetClearState( state, mask );
70 // use the cached values
71 if( mask & GL_COLOR_BUFFER_BIT)
73 // check if color buffer is currently clean
74 if( state->mState & COLOR_BUFFER_CLEAN )
76 // remove clear color buffer flag from bitmask, no need to clear twice
77 mask&= ~GL_COLOR_BUFFER_BIT;
80 if( mask & GL_DEPTH_BUFFER_BIT)
82 // check if depth buffer is currently clean
83 if( state->mState & DEPTH_BUFFER_CLEAN )
85 // remove clear depth buffer flag from bitmask, no need to clear twice
86 mask&= ~GL_DEPTH_BUFFER_BIT;
89 if( mask & GL_STENCIL_BUFFER_BIT)
91 // check if stencil buffer is currently clean
92 if( state->mState & STENCIL_BUFFER_CLEAN )
94 // remove clear stencil buffer flag from bitmask, no need to clear twice
96 mask&= ~GL_STENCIL_BUFFER_BIT;
100 // set the clear state based, what's about to be cleared
101 SetClearState( state, mask );
106 void FrameBufferStateCache::SetCurrentFrameBuffer( GLuint frameBufferId )
108 mCurrentFrameBufferId = frameBufferId;
111 void FrameBufferStateCache::FrameBuffersDeleted( GLsizei count, const GLuint* const frameBuffers )
113 for( GLsizei i = 0; i < count; ++i )
115 DeleteFrameBuffer( frameBuffers[i] );
118 void FrameBufferStateCache::FrameBuffersCreated( GLsizei count, const GLuint* const frameBuffers )
120 for( GLsizei i = 0; i < count; ++i )
122 // check the frame buffer doesn't exist already
123 GLuint id = frameBuffers[i];
125 FrameBufferState* state = GetFrameBufferState( id );
128 DALI_LOG_ERROR("FrameBuffer already exists%d \n", id );
130 state->mState = INITIAL_FRAMEBUFFER_STATE;
134 FrameBufferState newFrameBuffer( frameBuffers[i] );
135 mFrameBufferStates.PushBack( newFrameBuffer );
139 void FrameBufferStateCache::DrawOperation( bool colorBuffer, bool depthBuffer, bool stencilBuffer )
141 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
144 // an error will have already been logged by the clear operation
150 // un-set the clean bit
151 state->mState &= ~COLOR_BUFFER_CLEAN;
155 // un-set the clean bit
156 state->mState &= ~DEPTH_BUFFER_CLEAN;
160 // un-set the clean bit
161 state->mState &= ~STENCIL_BUFFER_CLEAN;
166 void FrameBufferStateCache::Reset()
168 mFrameBufferStates.Clear();
170 // create the default frame buffer
171 GLuint id = 0; // 0 == default frame buffer id
172 FrameBuffersCreated( 1, &id );
175 void FrameBufferStateCache::SetClearState( FrameBufferState* state, GLbitfield mask )
177 if( mask & GL_COLOR_BUFFER_BIT)
179 // set the color buffer to clean
180 state->mState |= COLOR_BUFFER_CLEAN;
182 if( mask & GL_DEPTH_BUFFER_BIT)
184 // set the depth buffer to clean
185 state->mState |= DEPTH_BUFFER_CLEAN;
187 if( mask & GL_STENCIL_BUFFER_BIT)
189 // set the stencil buffer to clean
190 state->mState |= STENCIL_BUFFER_CLEAN;
194 FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState( GLuint frameBufferId )
196 for( FrameBufferStateVector::SizeType i = 0; i < mFrameBufferStates.Count(); ++i )
198 FrameBufferState& state = mFrameBufferStates[i];
199 if( state.mId == frameBufferId )
207 void FrameBufferStateCache::DeleteFrameBuffer( GLuint frameBufferId )
209 FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin();
210 FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End();
212 for( ; iter != endIter ; ++iter )
214 if( (*iter).mId == frameBufferId )
216 mFrameBufferStates.Erase( iter);
220 DALI_LOG_ERROR("FrameBuffer not found %d \n", frameBufferId);
223 } // namespace Internal