2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/render/gl-resources/context.h>
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/internal/render/common/render-manager.h>
29 #include <dali/integration-api/debug.h>
37 namespace // unnamed namespace
40 DALI_COMPILE_TIME_ASSERT( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS );
47 const GLenum errorCode;
48 const char* errorString;
50 errorStrings errors[] =
52 { GL_NO_ERROR, "GL_NO_ERROR" },
53 { GL_INVALID_ENUM, "GL_INVALID_ENUM" },
54 { GL_INVALID_VALUE, "GL_INVALID_VALUE" },
55 { GL_INVALID_OPERATION, "GL_INVALID_OPERATION" },
56 { GL_OUT_OF_MEMORY, "GL_OUT_OF_MEMORY" }
59 } // unnamed namespace
62 Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_STATE");
65 Context::Context(Integration::GlAbstraction& glAbstraction)
66 : mGlAbstraction(glAbstraction),
67 mGlContextCreated(false),
71 mDepthBufferEnabled(false),
72 mDepthMaskEnabled(false),
73 mDitherEnabled(true), // This the only GL capability which defaults to true
74 mPolygonOffsetFillEnabled(false),
75 mSampleAlphaToCoverageEnabled(false),
76 mSampleCoverageEnabled(false),
77 mScissorTestEnabled(false),
78 mStencilBufferEnabled(false),
79 mClearColorSet(false),
80 mBoundArrayBufferId(0),
81 mBoundElementArrayBufferId(0),
82 mBoundTransformFeedbackBufferId(0),
83 mActiveTextureUnit( TEXTURE_UNIT_LAST ),
84 mUsingDefaultBlendColor(true),
85 mBlendFuncSeparateSrcRGB(GL_ONE),
86 mBlendFuncSeparateDstRGB(GL_ZERO),
87 mBlendFuncSeparateSrcAlpha(GL_ONE),
88 mBlendFuncSeparateDstAlpha(GL_ZERO),
89 mBlendEquationSeparateModeRGB( GL_FUNC_ADD ),
90 mBlendEquationSeparateModeAlpha( GL_FUNC_ADD ),
92 mClearColor(Color::WHITE), // initial color, never used until it's been set by the user
93 mCullFaceMode(CullNone),
94 mViewPort( 0, 0, 0, 0 ),
105 void Context::GlContextCreated()
107 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
109 DALI_ASSERT_DEBUG(!mGlContextCreated);
111 mGlContextCreated = true;
113 // Set the initial GL state, and check it.
121 void Context::GlContextDestroyed()
123 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
124 mGlContextCreated = false;
127 const char* Context::ErrorToString( GLenum errorCode )
129 for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i)
131 if (errorCode == errors[i].errorCode)
133 return errors[i].errorString;
136 return "Unknown Open GLES error";
139 const Rect< int >& Context::GetViewport()
144 void Context::FlushVertexAttributeLocations()
146 for( unsigned int i = 0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
148 // see if our cached state is different to the actual state
149 if (mVertexAttributeCurrentState[ i ] != mVertexAttributeCachedState[ i ] )
151 // it's different so make the change to the driver
152 // and update the cached state
153 mVertexAttributeCurrentState[ i ] = mVertexAttributeCachedState[ i ];
155 if (mVertexAttributeCurrentState[ i ] )
157 LOG_GL("EnableVertexAttribArray %d\n", i);
158 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
162 LOG_GL("DisableVertexAttribArray %d\n", i);
163 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
170 void Context::SetVertexAttributeLocation(unsigned int location, bool state)
173 if( location >= MAX_ATTRIBUTE_CACHE_SIZE )
175 // not cached, make the gl call through context
178 LOG_GL("EnableVertexAttribArray %d\n", location);
179 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
183 LOG_GL("DisableVertexAttribArray %d\n", location);
184 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
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;
195 void Context::ResetVertexAttributeState()
197 // reset attribute cache
198 for( unsigned int i=0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
200 mVertexAttributeCachedState[ i ] = false;
201 mVertexAttributeCurrentState[ i ] = false;
203 LOG_GL("DisableVertexAttribArray %d\n", i);
204 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
208 void Context::ResetGlState()
210 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::ResetGlState()\n");
211 DALI_ASSERT_DEBUG(mGlContextCreated);
213 mClearColorSet = false;
214 // Render manager will call clear in next render
216 // Reset internal state and Synchronize it with real OpenGL context.
217 // This may seem like overkill, but the GL context is not owned by dali-core,
218 // and no assumptions should be made about the initial state.
220 mGlAbstraction.ColorMask( true, true, true, true );
223 mGlAbstraction.StencilMask( 0xFF );
225 mBlendEnabled = false;
226 mGlAbstraction.Disable(GL_BLEND);
228 mDepthBufferEnabled = false;
229 mGlAbstraction.Disable(GL_DEPTH_TEST);
231 mDepthMaskEnabled = false;
232 mGlAbstraction.DepthMask(GL_FALSE);
234 mDitherEnabled = false; // This the only GL capability which defaults to true
235 mGlAbstraction.Disable(GL_DITHER);
237 mPolygonOffsetFillEnabled = false;
238 mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL);
240 mSampleAlphaToCoverageEnabled = false;
241 mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
243 mSampleCoverageEnabled = false;
244 mGlAbstraction.Disable(GL_SAMPLE_COVERAGE);
246 mScissorTestEnabled = false;
247 mGlAbstraction.Disable(GL_SCISSOR_TEST);
249 mStencilBufferEnabled = false;
250 mGlAbstraction.Disable(GL_STENCIL_TEST);
252 mBoundArrayBufferId = 0;
253 LOG_GL("BindBuffer GL_ARRAY_BUFFER 0\n");
254 mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, mBoundArrayBufferId);
256 mBoundElementArrayBufferId = 0;
257 LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER 0\n");
258 mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBoundElementArrayBufferId);
260 #ifndef EMSCRIPTEN // not in WebGL
261 mBoundTransformFeedbackBufferId = 0;
262 LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER 0\n");
263 mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mBoundTransformFeedbackBufferId);
266 mActiveTextureUnit = TEXTURE_UNIT_LAST;
268 mUsingDefaultBlendColor = true;
269 mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f );
271 mBlendFuncSeparateSrcRGB = GL_ONE;
272 mBlendFuncSeparateDstRGB = GL_ZERO;
273 mBlendFuncSeparateSrcAlpha = GL_ONE;
274 mBlendFuncSeparateDstAlpha = GL_ZERO;
275 mGlAbstraction.BlendFuncSeparate( mBlendFuncSeparateSrcRGB, mBlendFuncSeparateDstRGB,
276 mBlendFuncSeparateSrcAlpha, mBlendFuncSeparateDstAlpha );
278 // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
279 mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
280 mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
281 mGlAbstraction.BlendEquationSeparate( mBlendEquationSeparateModeRGB, mBlendEquationSeparateModeAlpha);
283 mCullFaceMode = CullNone;
284 mGlAbstraction.Disable(GL_CULL_FACE);
285 mGlAbstraction.FrontFace(GL_CCW);
286 mGlAbstraction.CullFace(GL_BACK);
288 // rebind texture units to 0
289 for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
291 mBound2dTextureId[ i ] = 0;
292 // set active texture
293 mGlAbstraction.ActiveTexture( GL_TEXTURE0 + i );
294 mGlAbstraction.BindTexture(GL_TEXTURE_2D, mBound2dTextureId[ i ] );
297 // get maximum texture size
298 mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
300 // reset viewport, this will be set to something useful when rendering
301 mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
303 ResetVertexAttributeState();
305 mFrameBufferStateCache.Reset();
310 void Context::PrintCurrentState()
312 const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
313 DALI_LOG_INFO( gContextLogFilter, Debug::General,
314 "\n----------------- Context State BEGIN -----------------\n"
320 "Polygon Offset Fill = %s\n"
321 "Sample Alpha To Coverage = %s\n"
322 "Sample Coverage = %s\n"
323 "Scissor Test = %s\n"
324 "Stencil Test = %s\n"
325 "----------------- Context State END -----------------\n",
326 mBlendEnabled ? "Enabled" : "Disabled",
327 cullFaceModes[ mCullFaceMode ],
328 mDepthBufferEnabled ? "Enabled" : "Disabled",
329 mDepthMaskEnabled ? "Enabled" : "Disabled",
330 mDitherEnabled ? "Enabled" : "Disabled",
331 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
332 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
333 mSampleCoverageEnabled ? "Enabled" : "Disabled",
334 mScissorTestEnabled ? "Enabled" : "Disabled",
335 mStencilBufferEnabled ? "Enabled" : "Disabled");
338 #endif // DALI_CONTEXT_LOGGING
340 } // namespace Internal