2 * Copyright (c) 2015 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 FrameBufferStateCache::FrameBufferStateCache()
32 :mCurrentFrameBufferId(0)
36 FrameBufferStateCache::~FrameBufferStateCache()
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.
49 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
52 DALI_LOG_ERROR("FrameBuffer not found %d \n", mCurrentFrameBufferId);
56 // if we are forcing the clear operation, then just update the internal cached values
59 SetClearState( state, mask );
63 // use the cached values
64 if( mask & GL_COLOR_BUFFER_BIT)
66 // check if color buffer is currently clean
67 if( state->mState & COLOR_BUFFER_CLEAN )
69 // remove clear color buffer flag from bitmask, no need to clear twice
70 mask&= ~GL_COLOR_BUFFER_BIT;
73 if( mask & GL_DEPTH_BUFFER_BIT)
75 // check if depth buffer is currently clean
76 if( state->mState & DEPTH_BUFFER_CLEAN )
78 // remove clear depth buffer flag from bitmask, no need to clear twice
79 mask&= ~GL_DEPTH_BUFFER_BIT;
82 if( mask & GL_STENCIL_BUFFER_BIT)
84 // check if stencil buffer is currently clean
85 if( state->mState & STENCIL_BUFFER_CLEAN )
87 // remove clear stencil buffer flag from bitmask, no need to clear twice
89 mask&= ~GL_STENCIL_BUFFER_BIT;
93 // set the clear state based, what's about to be cleared
94 SetClearState( state, mask );
99 void FrameBufferStateCache::SetCurrentFrameBuffer( GLuint frameBufferId )
101 mCurrentFrameBufferId = frameBufferId;
104 void FrameBufferStateCache::FrameBuffersDeleted( GLsizei count, const GLuint* const frameBuffers )
106 for( GLsizei i = 0; i < count; ++i )
108 DeleteFrameBuffer( frameBuffers[i] );
111 void FrameBufferStateCache::FrameBuffersCreated( GLsizei count, const GLuint* const frameBuffers )
113 for( GLsizei i = 0; i < count; ++i )
115 // check the frame buffer doesn't exist already
116 GLuint id = frameBuffers[i];
118 FrameBufferState* state = GetFrameBufferState( id );
121 DALI_LOG_ERROR("FrameBuffer already exists%d \n", id );
123 state->mState = GetInitialFrameBufferState();
127 FrameBufferState newFrameBuffer( frameBuffers[i], GetInitialFrameBufferState() );
128 mFrameBufferStates.PushBack( newFrameBuffer );
132 void FrameBufferStateCache::DrawOperation( bool colorBuffer, bool depthBuffer, bool stencilBuffer )
134 FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
137 // an error will have already been logged by the clear operation
143 // un-set the clean bit
144 state->mState &= ~COLOR_BUFFER_CLEAN;
148 // un-set the clean bit
149 state->mState &= ~DEPTH_BUFFER_CLEAN;
153 // un-set the clean bit
154 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);
216 unsigned int FrameBufferStateCache::GetInitialFrameBufferState()
218 return COLOR_BUFFER_CLEAN | DEPTH_BUFFER_CLEAN | STENCIL_BUFFER_CLEAN;
222 } // namespace Internal