[dali_2.0.2] Merge branch 'devel/master'
[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() = default;
115
116 void Context::GlContextCreated()
117 {
118   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
119
120   if( !mGlContextCreated )
121   {
122     mGlContextCreated = true;
123
124     // Set the initial GL state, and check it.
125     InitializeGlState();
126
127 #ifdef DEBUG_ENABLED
128     PrintCurrentState();
129 #endif
130   }
131 }
132
133 void Context::GlContextDestroyed()
134 {
135   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
136   mGlContextCreated = false;
137 }
138
139 const char* Context::ErrorToString( GLenum errorCode )
140 {
141   for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i)
142   {
143     if (errorCode == errors[i].errorCode)
144     {
145       return errors[i].errorString;
146     }
147   }
148   return "Unknown Open GLES error";
149 }
150
151 const Rect< int >& Context::GetViewport()
152 {
153   return mViewPort;
154 }
155
156 void Context::FlushVertexAttributeLocations()
157 {
158   for( unsigned int i = 0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
159   {
160     // see if our cached state is different to the actual state
161     if (mVertexAttributeCurrentState[ i ] != mVertexAttributeCachedState[ i ] )
162     {
163       // it's different so make the change to the driver
164       // and update the cached state
165       mVertexAttributeCurrentState[ i ] = mVertexAttributeCachedState[ i ];
166
167       if (mVertexAttributeCurrentState[ i ] )
168       {
169         LOG_GL("EnableVertexAttribArray %d\n", i);
170         CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
171       }
172       else
173       {
174         LOG_GL("DisableVertexAttribArray %d\n", i);
175         CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
176       }
177     }
178   }
179
180 }
181
182 void Context::SetVertexAttributeLocation(unsigned int location, bool state)
183 {
184
185   if( location >= MAX_ATTRIBUTE_CACHE_SIZE )
186   {
187     // not cached, make the gl call through context
188     if ( state )
189     {
190        LOG_GL("EnableVertexAttribArray %d\n", location);
191        CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
192     }
193     else
194     {
195       LOG_GL("DisableVertexAttribArray %d\n", location);
196       CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
197     }
198   }
199   else
200   {
201     // set the cached state, it will be set at the next draw call
202     // if it's different from the current driver state
203     mVertexAttributeCachedState[ location ] = state;
204   }
205 }
206
207 void Context::InitializeGlState()
208 {
209   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::InitializeGlState()\n");
210   DALI_ASSERT_DEBUG(mGlContextCreated);
211
212   mClearColorSet = false;
213   mColorMask = true;
214   mStencilMask = 0xFF;
215   mBlendEnabled = false;
216   mDepthBufferEnabled = false;
217   mDepthMaskEnabled = false;
218   mPolygonOffsetFillEnabled = false;
219   mSampleAlphaToCoverageEnabled = false;
220   mSampleCoverageEnabled = false;
221   mScissorTestEnabled = false;
222   mStencilBufferEnabled = false;
223   mDitherEnabled = false; // This and GL_MULTISAMPLE are the only GL capability which defaults to true
224   mGlAbstraction.Disable(GL_DITHER);
225
226   mBoundArrayBufferId = 0;
227   mBoundElementArrayBufferId = 0;
228   mBoundTransformFeedbackBufferId = 0;
229   mActiveTextureUnit = TEXTURE_UNIT_IMAGE;
230
231   mUsingDefaultBlendColor = true; //Default blend color is (0,0,0,0)
232
233   mBlendFuncSeparateSrcRGB = GL_ONE;
234   mBlendFuncSeparateDstRGB = GL_ZERO;
235   mBlendFuncSeparateSrcAlpha = GL_ONE;
236   mBlendFuncSeparateDstAlpha = GL_ZERO;
237
238   // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
239   mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
240   mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
241
242   mCullFaceMode = FaceCullingMode::NONE; //By default cullface is disabled, front face is set to CCW and cull face is set to back
243
244   // get maximum texture size
245   mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
246
247   // reset viewport, this will be set to something useful when rendering
248   mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
249
250   //Initialze vertex attribute cache
251   memset( &mVertexAttributeCachedState, 0, sizeof(mVertexAttributeCachedState) );
252   memset( &mVertexAttributeCurrentState, 0, sizeof(mVertexAttributeCurrentState) );
253
254   //Initialize bound 2d texture cache
255   memset( &mBoundTextureId, 0, sizeof(mBoundTextureId) );
256
257   mFrameBufferStateCache.Reset();
258 }
259
260 #ifdef DEBUG_ENABLED
261
262 void Context::PrintCurrentState()
263 {
264   const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
265   DALI_LOG_INFO( gContextLogFilter, Debug::General,
266                 "\n----------------- Context State BEGIN -----------------\n"
267                 "Blend = %s\n"
268                 "Cull Face = %s\n"
269                 "Depth Test = %s\n"
270                 "Depth Mask = %s\n"
271                 "Dither = %s\n"
272                 "Polygon Offset Fill = %s\n"
273                 "Sample Alpha To Coverage = %s\n"
274                 "Sample Coverage = %s\n"
275                 "Scissor Test = %s\n"
276                 "Stencil Test = %s\n"
277                 "----------------- Context State END -----------------\n",
278                 mBlendEnabled ? "Enabled" : "Disabled",
279                 cullFaceModes[ mCullFaceMode ],
280                 mDepthBufferEnabled ? "Enabled" : "Disabled",
281                 mDepthMaskEnabled ? "Enabled" : "Disabled",
282                 mDitherEnabled ? "Enabled" : "Disabled",
283                 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
284                 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
285                 mSampleCoverageEnabled ? "Enabled" : "Disabled",
286                 mScissorTestEnabled ? "Enabled" : "Disabled",
287                 mStencilBufferEnabled ? "Enabled" : "Disabled");
288 }
289
290 #endif // DALI_CONTEXT_LOGGING
291
292 } // namespace Internal
293
294 } // namespace Dali