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