Clean up the code to build successfully on macOS
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / frame-buffer-state-cache.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "frame-buffer-state-cache.h"
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-defines.h>
24
25 namespace Dali
26 {
27
28 namespace
29 {
30
31 const uint32_t INITIAL_FRAMEBUFFER_STATE = 0u;
32
33 }
34
35 namespace Internal
36 {
37
38 FrameBufferStateCache::FrameBufferStateCache()
39 :mCurrentFrameBufferId(0)
40 {
41 }
42
43 FrameBufferStateCache::~FrameBufferStateCache()
44 {
45 }
46
47 GLbitfield FrameBufferStateCache::GetClearMask( GLbitfield mask, bool forceClear, bool scissorTestEnabled )
48 {
49   if( scissorTestEnabled )
50   {
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.
54     return mask;
55   }
56   FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
57   if( !state )
58   {
59     DALI_LOG_ERROR("FrameBuffer not found %d \n", mCurrentFrameBufferId);
60     return mask;
61   }
62
63   // if we are forcing the clear operation, then just update the internal cached values
64   if( forceClear )
65   {
66     SetClearState( state, mask );
67     return mask;
68   }
69
70   // use the cached values
71   if( mask & GL_COLOR_BUFFER_BIT)
72   {
73     // check if color buffer is currently clean
74     if( state->mState & COLOR_BUFFER_CLEAN )
75     {
76       // remove clear color buffer flag from bitmask, no need to clear twice
77       mask&= ~GL_COLOR_BUFFER_BIT;
78     }
79   }
80   if( mask & GL_DEPTH_BUFFER_BIT)
81   {
82     // check if depth buffer is currently clean
83     if( state->mState & DEPTH_BUFFER_CLEAN )
84     {
85       // remove clear depth buffer flag from bitmask, no need to clear twice
86       mask&= ~GL_DEPTH_BUFFER_BIT;
87     }
88   }
89   if( mask & GL_STENCIL_BUFFER_BIT)
90   {
91     // check if stencil buffer is currently clean
92     if( state->mState & STENCIL_BUFFER_CLEAN )
93     {
94       // remove clear stencil buffer flag from bitmask, no need to clear twice
95
96       mask&= ~GL_STENCIL_BUFFER_BIT;
97     }
98   }
99
100   // set the clear state based, what's about to be cleared
101   SetClearState( state, mask );
102
103   return mask;
104 }
105
106 void FrameBufferStateCache::SetCurrentFrameBuffer( GLuint frameBufferId )
107 {
108   mCurrentFrameBufferId = frameBufferId;
109 }
110
111 void FrameBufferStateCache::FrameBuffersDeleted( GLsizei count, const GLuint* const frameBuffers )
112 {
113   for( GLsizei i = 0; i < count; ++i )
114   {
115     DeleteFrameBuffer( frameBuffers[i] );
116   }
117 }
118 void FrameBufferStateCache::FrameBuffersCreated( GLsizei count, const GLuint* const frameBuffers )
119 {
120   for( GLsizei i = 0; i < count; ++i )
121   {
122     // check the frame buffer doesn't exist already
123     GLuint id = frameBuffers[i];
124
125     FrameBufferState* state =  GetFrameBufferState( id );
126     if( state )
127     {
128       DALI_LOG_ERROR("FrameBuffer already exists%d \n", id );
129       // reset its state
130       state->mState = INITIAL_FRAMEBUFFER_STATE;
131       continue;
132     }
133
134     FrameBufferState newFrameBuffer( frameBuffers[i] );
135     mFrameBufferStates.PushBack( newFrameBuffer );
136   }
137 }
138
139 void FrameBufferStateCache::DrawOperation( bool colorBuffer, bool depthBuffer, bool stencilBuffer )
140 {
141   FrameBufferState* state = GetFrameBufferState( mCurrentFrameBufferId );
142   if( !state )
143   {
144     // an error will have already been logged by the clear operation
145     return;
146   }
147
148   if( colorBuffer )
149   {
150     // un-set the clean bit
151     state->mState &= ~COLOR_BUFFER_CLEAN;
152   }
153   if( depthBuffer )
154   {
155     // un-set the clean bit
156     state->mState &= ~DEPTH_BUFFER_CLEAN;
157   }
158   if( stencilBuffer )
159   {
160     // un-set the clean bit
161     state->mState &= ~STENCIL_BUFFER_CLEAN;
162   }
163
164 }
165
166 void FrameBufferStateCache::Reset()
167 {
168   mFrameBufferStates.Clear();
169
170   // create the default frame buffer
171   GLuint id = 0; // 0 == default frame buffer id
172   FrameBuffersCreated( 1, &id );
173 }
174
175 void FrameBufferStateCache::SetClearState( FrameBufferState* state, GLbitfield mask )
176 {
177   if( mask & GL_COLOR_BUFFER_BIT)
178   {
179     // set the color buffer to clean
180     state->mState |= COLOR_BUFFER_CLEAN;
181   }
182   if( mask & GL_DEPTH_BUFFER_BIT)
183   {
184     // set the depth buffer to clean
185     state->mState |= DEPTH_BUFFER_CLEAN;
186   }
187   if( mask & GL_STENCIL_BUFFER_BIT)
188   {
189     // set the stencil buffer to clean
190     state->mState |= STENCIL_BUFFER_CLEAN;
191   }
192 }
193
194 FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState(  GLuint frameBufferId )
195 {
196   for( FrameBufferStateVector::SizeType i = 0; i < mFrameBufferStates.Count(); ++i )
197   {
198     FrameBufferState& state = mFrameBufferStates[i];
199     if( state.mId == frameBufferId )
200     {
201       return &state;
202     }
203   }
204   return nullptr;
205 }
206
207 void FrameBufferStateCache::DeleteFrameBuffer( GLuint frameBufferId )
208 {
209   FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin();
210   FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End();
211
212   for( ; iter != endIter ; ++iter )
213   {
214    if( (*iter).mId == frameBufferId )
215    {
216      mFrameBufferStates.Erase( iter);
217      return;
218    }
219  }
220  DALI_LOG_ERROR("FrameBuffer not found %d \n", frameBufferId);
221 }
222
223 } // namespace Internal
224
225 } // namespace Dali