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