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 mUsingDefaultBlendColor(true),
81 mBoundArrayBufferId(0),
82 mBoundElementArrayBufferId(0),
83 mBoundTransformFeedbackBufferId(0),
84 mActiveTextureUnit( TEXTURE_UNIT_LAST ),
85 mBlendColor(Color::TRANSPARENT),
86 mBlendFuncSeparateSrcRGB(GL_ONE),
87 mBlendFuncSeparateDstRGB(GL_ZERO),
88 mBlendFuncSeparateSrcAlpha(GL_ONE),
89 mBlendFuncSeparateDstAlpha(GL_ZERO),
90 mBlendEquationSeparateModeRGB( GL_FUNC_ADD ),
91 mBlendEquationSeparateModeAlpha( GL_FUNC_ADD ),
93 mClearColor(Color::WHITE), // initial color, never used until it's been set by the user
94 mCullFaceMode(CullNone),
95 mViewPort( 0, 0, 0, 0 ),
106 void Context::GlContextCreated()
108 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
110 DALI_ASSERT_DEBUG(!mGlContextCreated);
112 mGlContextCreated = true;
114 // Set the initial GL state, and check it.
122 void Context::GlContextDestroyed()
124 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
125 mGlContextCreated = false;
128 const char* Context::ErrorToString( GLenum errorCode )
130 for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i)
132 if (errorCode == errors[i].errorCode)
134 return errors[i].errorString;
137 return "Unknown Open GLES error";
140 const Rect< int >& Context::GetViewport()
145 void Context::FlushVertexAttributeLocations()
147 for( unsigned int i = 0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
149 // see if our cached state is different to the actual state
150 if (mVertexAttributeCurrentState[ i ] != mVertexAttributeCachedState[ i ] )
152 // it's different so make the change to the driver
153 // and update the cached state
154 mVertexAttributeCurrentState[ i ] = mVertexAttributeCachedState[ i ];
156 if (mVertexAttributeCurrentState[ i ] )
158 LOG_GL("EnableVertexAttribArray %d\n", i);
159 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
163 LOG_GL("DisableVertexAttribArray %d\n", i);
164 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
171 void Context::SetVertexAttributeLocation(unsigned int location, bool state)
174 if( location >= MAX_ATTRIBUTE_CACHE_SIZE )
176 // not cached, make the gl call through context
179 LOG_GL("EnableVertexAttribArray %d\n", location);
180 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
184 LOG_GL("DisableVertexAttribArray %d\n", location);
185 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
190 // set the cached state, it will be set at the next draw call
191 // if it's different from the current driver state
192 mVertexAttributeCachedState[ location ] = state;
196 void Context::ResetVertexAttributeState()
198 // reset attribute cache
199 for( unsigned int i=0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
201 mVertexAttributeCachedState[ i ] = false;
202 mVertexAttributeCurrentState[ i ] = false;
204 LOG_GL("DisableVertexAttribArray %d\n", i);
205 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
209 void Context::ResetGlState()
211 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::ResetGlState()\n");
212 DALI_ASSERT_DEBUG(mGlContextCreated);
214 mClearColorSet = false;
215 // Render manager will call clear in next render
217 // Reset internal state and Synchronize it with real OpenGL context.
218 // This may seem like overkill, but the GL context is not owned by dali-core,
219 // and no assumptions should be made about the initial state.
221 mGlAbstraction.ColorMask( true, true, true, true );
224 mGlAbstraction.StencilMask( 0xFF );
226 mBlendEnabled = false;
227 mGlAbstraction.Disable(GL_BLEND);
229 mDepthBufferEnabled = false;
230 mGlAbstraction.Disable(GL_DEPTH_TEST);
232 mDepthMaskEnabled = false;
233 mGlAbstraction.DepthMask(GL_FALSE);
235 mDitherEnabled = false; // This the only GL capability which defaults to true
236 mGlAbstraction.Disable(GL_DITHER);
238 mPolygonOffsetFillEnabled = false;
239 mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL);
241 mSampleAlphaToCoverageEnabled = false;
242 mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
244 mSampleCoverageEnabled = false;
245 mGlAbstraction.Disable(GL_SAMPLE_COVERAGE);
247 mScissorTestEnabled = false;
248 mGlAbstraction.Disable(GL_SCISSOR_TEST);
250 mStencilBufferEnabled = false;
251 mGlAbstraction.Disable(GL_STENCIL_TEST);
253 mBoundArrayBufferId = 0;
254 LOG_GL("BindBuffer GL_ARRAY_BUFFER 0\n");
255 mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, mBoundArrayBufferId);
257 mBoundElementArrayBufferId = 0;
258 LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER 0\n");
259 mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBoundElementArrayBufferId);
261 #ifndef EMSCRIPTEN // not in WebGL
262 mBoundTransformFeedbackBufferId = 0;
263 LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER 0\n");
264 mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mBoundTransformFeedbackBufferId);
267 mActiveTextureUnit = TEXTURE_UNIT_LAST;
269 mUsingDefaultBlendColor = true;
270 mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f );
272 mBlendFuncSeparateSrcRGB = GL_ONE;
273 mBlendFuncSeparateDstRGB = GL_ZERO;
274 mBlendFuncSeparateSrcAlpha = GL_ONE;
275 mBlendFuncSeparateDstAlpha = GL_ZERO;
276 mGlAbstraction.BlendFuncSeparate( mBlendFuncSeparateSrcRGB, mBlendFuncSeparateDstRGB,
277 mBlendFuncSeparateSrcAlpha, mBlendFuncSeparateDstAlpha );
279 // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
280 mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
281 mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
282 mGlAbstraction.BlendEquationSeparate( mBlendEquationSeparateModeRGB, mBlendEquationSeparateModeAlpha);
284 mCullFaceMode = CullNone;
285 mGlAbstraction.Disable(GL_CULL_FACE);
286 mGlAbstraction.FrontFace(GL_CCW);
287 mGlAbstraction.CullFace(GL_BACK);
289 // rebind texture units to 0
290 for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
292 mBound2dTextureId[ i ] = 0;
293 // set active texture
294 mGlAbstraction.ActiveTexture( GL_TEXTURE0 + i );
295 mGlAbstraction.BindTexture(GL_TEXTURE_2D, mBound2dTextureId[ i ] );
298 // get maximum texture size
299 mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
301 // reset viewport, this will be set to something useful when rendering
302 mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
304 ResetVertexAttributeState();
306 mFrameBufferStateCache.Reset();
311 void Context::PrintCurrentState()
313 const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
314 DALI_LOG_INFO( gContextLogFilter, Debug::General,
315 "\n----------------- Context State BEGIN -----------------\n"
321 "Polygon Offset Fill = %s\n"
322 "Sample Alpha To Coverage = %s\n"
323 "Sample Coverage = %s\n"
324 "Scissor Test = %s\n"
325 "Stencil Test = %s\n"
326 "----------------- Context State END -----------------\n",
327 mBlendEnabled ? "Enabled" : "Disabled",
328 cullFaceModes[ mCullFaceMode ],
329 mDepthBufferEnabled ? "Enabled" : "Disabled",
330 mDepthMaskEnabled ? "Enabled" : "Disabled",
331 mDitherEnabled ? "Enabled" : "Disabled",
332 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
333 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
334 mSampleCoverageEnabled ? "Enabled" : "Disabled",
335 mScissorTestEnabled ? "Enabled" : "Disabled",
336 mStencilBufferEnabled ? "Enabled" : "Disabled");
339 #endif // DALI_CONTEXT_LOGGING
341 } // namespace Internal