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