Clean up the code to build successfully on macOS
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / context.cpp
1 /*
2  * Copyright (c) 2020 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 <dali/internal/render/gl-resources/context.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cstring>
24 #include <type_traits>
25
26 // INTERNAL INCLUDES
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/rendering/texture-set.h>
29 #include <dali/integration-api/platform-abstraction.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/internal/render/common/render-manager.h>
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace // unnamed namespace
40 {
41
42 static_assert( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS, "TEXTURE_UNIT_LAST is greater than Context::MAX_TEXTURE_UNITS" );
43
44 /**
45  * GL error strings
46  */
47 struct errorStrings
48 {
49   const GLenum errorCode;
50   const char* errorString;
51 };
52 errorStrings errors[] =
53 {
54    { GL_NO_ERROR,           "GL_NO_ERROR" },
55    { GL_INVALID_ENUM,       "GL_INVALID_ENUM" },
56    { GL_INVALID_VALUE,      "GL_INVALID_VALUE" },
57    { GL_INVALID_OPERATION,  "GL_INVALID_OPERATION" },
58    { GL_OUT_OF_MEMORY,      "GL_OUT_OF_MEMORY" }
59 };
60
61 } // unnamed namespace
62
63 #ifdef DEBUG_ENABLED
64 Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_STATE");
65 #endif
66
67 Context::Context( Integration::GlAbstraction& glAbstraction )
68 : Context( glAbstraction, nullptr )
69 {
70 }
71
72 Context::Context( Integration::GlAbstraction& glAbstraction, OwnerContainer< Context* >* contexts )
73 : mGlAbstraction(glAbstraction),
74   mGlContextCreated(false),
75   mColorMask(true),
76   mStencilMask(0xFF),
77   mBlendEnabled(false),
78   mDepthBufferEnabled(false),
79   mDepthMaskEnabled(false),
80   mDitherEnabled(true), // This the only GL capability which defaults to true
81   mPolygonOffsetFillEnabled(false),
82   mSampleAlphaToCoverageEnabled(false),
83   mSampleCoverageEnabled(false),
84   mScissorTestEnabled(false),
85   mStencilBufferEnabled(false),
86   mClearColorSet(false),
87   mUsingDefaultBlendColor(true),
88   mBoundArrayBufferId(0),
89   mBoundElementArrayBufferId(0),
90   mBoundTransformFeedbackBufferId(0),
91   mActiveTextureUnit( TEXTURE_UNIT_LAST ),
92   mBlendColor(Color::TRANSPARENT),
93   mBlendFuncSeparateSrcRGB(GL_ONE),
94   mBlendFuncSeparateDstRGB(GL_ZERO),
95   mBlendFuncSeparateSrcAlpha(GL_ONE),
96   mBlendFuncSeparateDstAlpha(GL_ZERO),
97   mBlendEquationSeparateModeRGB( GL_FUNC_ADD ),
98   mBlendEquationSeparateModeAlpha( GL_FUNC_ADD ),
99   mStencilFunc( GL_ALWAYS ),
100   mStencilFuncRef( 0 ),
101   mStencilFuncMask( 0xFFFFFFFF ),
102   mStencilOpFail( GL_KEEP ),
103   mStencilOpDepthFail( GL_KEEP ),
104   mStencilOpDepthPass( GL_KEEP ),
105   mDepthFunction( GL_LESS ),
106   mMaxTextureSize(0),
107   mClearColor(Color::WHITE),    // initial color, never used until it's been set by the user
108   mCullFaceMode( FaceCullingMode::NONE ),
109   mViewPort( 0, 0, 0, 0 ),
110   mSceneContexts( contexts )
111 {
112 }
113
114 Context::~Context()
115 {
116 }
117
118 void Context::GlContextCreated()
119 {
120   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
121
122   if( !mGlContextCreated )
123   {
124     mGlContextCreated = true;
125
126     // Set the initial GL state, and check it.
127     InitializeGlState();
128
129 #ifdef DEBUG_ENABLED
130     PrintCurrentState();
131 #endif
132   }
133 }
134
135 void Context::GlContextDestroyed()
136 {
137   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
138   mGlContextCreated = false;
139 }
140
141 const char* Context::ErrorToString( GLenum errorCode )
142 {
143   for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i)
144   {
145     if (errorCode == errors[i].errorCode)
146     {
147       return errors[i].errorString;
148     }
149   }
150   return "Unknown Open GLES error";
151 }
152
153 const Rect< int >& Context::GetViewport()
154 {
155   return mViewPort;
156 }
157
158 void Context::FlushVertexAttributeLocations()
159 {
160   for( unsigned int i = 0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
161   {
162     // see if our cached state is different to the actual state
163     if (mVertexAttributeCurrentState[ i ] != mVertexAttributeCachedState[ i ] )
164     {
165       // it's different so make the change to the driver
166       // and update the cached state
167       mVertexAttributeCurrentState[ i ] = mVertexAttributeCachedState[ i ];
168
169       if (mVertexAttributeCurrentState[ i ] )
170       {
171         LOG_GL("EnableVertexAttribArray %d\n", i);
172         CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
173       }
174       else
175       {
176         LOG_GL("DisableVertexAttribArray %d\n", i);
177         CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
178       }
179     }
180   }
181
182 }
183
184 void Context::SetVertexAttributeLocation(unsigned int location, bool state)
185 {
186
187   if( location >= MAX_ATTRIBUTE_CACHE_SIZE )
188   {
189     // not cached, make the gl call through context
190     if ( state )
191     {
192        LOG_GL("EnableVertexAttribArray %d\n", location);
193        CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
194     }
195     else
196     {
197       LOG_GL("DisableVertexAttribArray %d\n", location);
198       CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
199     }
200   }
201   else
202   {
203     // set the cached state, it will be set at the next draw call
204     // if it's different from the current driver state
205     mVertexAttributeCachedState[ location ] = state;
206   }
207 }
208
209 void Context::InitializeGlState()
210 {
211   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::InitializeGlState()\n");
212   DALI_ASSERT_DEBUG(mGlContextCreated);
213
214   mClearColorSet = false;
215   mColorMask = true;
216   mStencilMask = 0xFF;
217   mBlendEnabled = false;
218   mDepthBufferEnabled = false;
219   mDepthMaskEnabled = false;
220   mPolygonOffsetFillEnabled = false;
221   mSampleAlphaToCoverageEnabled = false;
222   mSampleCoverageEnabled = false;
223   mScissorTestEnabled = false;
224   mStencilBufferEnabled = false;
225   mDitherEnabled = false; // This and GL_MULTISAMPLE are the only GL capability which defaults to true
226   mGlAbstraction.Disable(GL_DITHER);
227
228   mBoundArrayBufferId = 0;
229   mBoundElementArrayBufferId = 0;
230   mBoundTransformFeedbackBufferId = 0;
231   mActiveTextureUnit = TEXTURE_UNIT_IMAGE;
232
233   mUsingDefaultBlendColor = true; //Default blend color is (0,0,0,0)
234
235   mBlendFuncSeparateSrcRGB = GL_ONE;
236   mBlendFuncSeparateDstRGB = GL_ZERO;
237   mBlendFuncSeparateSrcAlpha = GL_ONE;
238   mBlendFuncSeparateDstAlpha = GL_ZERO;
239
240   // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
241   mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
242   mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
243
244   mCullFaceMode = FaceCullingMode::NONE; //By default cullface is disabled, front face is set to CCW and cull face is set to back
245
246   // get maximum texture size
247   mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
248
249   // reset viewport, this will be set to something useful when rendering
250   mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
251
252   //Initialze vertex attribute cache
253   memset( &mVertexAttributeCachedState, 0, sizeof(mVertexAttributeCachedState) );
254   memset( &mVertexAttributeCurrentState, 0, sizeof(mVertexAttributeCurrentState) );
255
256   //Initialize bound 2d texture cache
257   memset( &mBoundTextureId, 0, sizeof(mBoundTextureId) );
258
259   mFrameBufferStateCache.Reset();
260 }
261
262 #ifdef DEBUG_ENABLED
263
264 void Context::PrintCurrentState()
265 {
266   const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
267   DALI_LOG_INFO( gContextLogFilter, Debug::General,
268                 "\n----------------- Context State BEGIN -----------------\n"
269                 "Blend = %s\n"
270                 "Cull Face = %s\n"
271                 "Depth Test = %s\n"
272                 "Depth Mask = %s\n"
273                 "Dither = %s\n"
274                 "Polygon Offset Fill = %s\n"
275                 "Sample Alpha To Coverage = %s\n"
276                 "Sample Coverage = %s\n"
277                 "Scissor Test = %s\n"
278                 "Stencil Test = %s\n"
279                 "----------------- Context State END -----------------\n",
280                 mBlendEnabled ? "Enabled" : "Disabled",
281                 cullFaceModes[ mCullFaceMode ],
282                 mDepthBufferEnabled ? "Enabled" : "Disabled",
283                 mDepthMaskEnabled ? "Enabled" : "Disabled",
284                 mDitherEnabled ? "Enabled" : "Disabled",
285                 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
286                 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
287                 mSampleCoverageEnabled ? "Enabled" : "Disabled",
288                 mScissorTestEnabled ? "Enabled" : "Disabled",
289                 mStencilBufferEnabled ? "Enabled" : "Disabled");
290 }
291
292 #endif // DALI_CONTEXT_LOGGING
293
294 } // namespace Internal
295
296 } // namespace Dali