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