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/integration-api/debug.h>
29 #include <dali/internal/render/common/render-manager.h>
30 #include <dali/devel-api/rendering/material.h>
38 namespace // unnamed namespace
41 DALI_COMPILE_TIME_ASSERT( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS );
48 const GLenum errorCode;
49 const char* errorString;
51 errorStrings errors[] =
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" }
60 } // unnamed namespace
63 Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_STATE");
66 Context::Context(Integration::GlAbstraction& glAbstraction)
67 : mGlAbstraction(glAbstraction),
68 mGlContextCreated(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 ),
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 ),
107 void Context::GlContextCreated()
109 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
111 DALI_ASSERT_DEBUG(!mGlContextCreated);
113 mGlContextCreated = true;
115 // Set the initial GL state, and check it.
123 void Context::GlContextDestroyed()
125 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
126 mGlContextCreated = false;
129 const char* Context::ErrorToString( GLenum errorCode )
131 for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i)
133 if (errorCode == errors[i].errorCode)
135 return errors[i].errorString;
138 return "Unknown Open GLES error";
141 const Rect< int >& Context::GetViewport()
146 void Context::FlushVertexAttributeLocations()
148 for( unsigned int i = 0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
150 // see if our cached state is different to the actual state
151 if (mVertexAttributeCurrentState[ i ] != mVertexAttributeCachedState[ i ] )
153 // it's different so make the change to the driver
154 // and update the cached state
155 mVertexAttributeCurrentState[ i ] = mVertexAttributeCachedState[ i ];
157 if (mVertexAttributeCurrentState[ i ] )
159 LOG_GL("EnableVertexAttribArray %d\n", i);
160 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
164 LOG_GL("DisableVertexAttribArray %d\n", i);
165 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
172 void Context::SetVertexAttributeLocation(unsigned int location, bool state)
175 if( location >= MAX_ATTRIBUTE_CACHE_SIZE )
177 // not cached, make the gl call through context
180 LOG_GL("EnableVertexAttribArray %d\n", location);
181 CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
185 LOG_GL("DisableVertexAttribArray %d\n", location);
186 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
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;
197 void Context::ResetVertexAttributeState()
199 // reset attribute cache
200 for( unsigned int i=0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
202 mVertexAttributeCachedState[ i ] = false;
203 mVertexAttributeCurrentState[ i ] = false;
205 LOG_GL("DisableVertexAttribArray %d\n", i);
206 CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
210 void Context::ResetGlState()
212 DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::ResetGlState()\n");
213 DALI_ASSERT_DEBUG(mGlContextCreated);
215 mClearColorSet = false;
216 // Render manager will call clear in next render
218 // Reset internal state and Synchronize it with real OpenGL context.
219 // This may seem like overkill, but the GL context is not owned by dali-core,
220 // and no assumptions should be made about the initial state.
222 mGlAbstraction.ColorMask( true, true, true, true );
225 mGlAbstraction.StencilMask( 0xFF );
227 mBlendEnabled = false;
228 mGlAbstraction.Disable(GL_BLEND);
230 mDepthBufferEnabled = false;
231 mGlAbstraction.Disable(GL_DEPTH_TEST);
233 mDepthMaskEnabled = false;
234 mGlAbstraction.DepthMask(GL_FALSE);
236 mDitherEnabled = false; // This the only GL capability which defaults to true
237 mGlAbstraction.Disable(GL_DITHER);
239 mPolygonOffsetFillEnabled = false;
240 mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL);
242 mSampleAlphaToCoverageEnabled = false;
243 mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
245 mSampleCoverageEnabled = false;
246 mGlAbstraction.Disable(GL_SAMPLE_COVERAGE);
248 mScissorTestEnabled = false;
249 mGlAbstraction.Disable(GL_SCISSOR_TEST);
251 mStencilBufferEnabled = false;
252 mGlAbstraction.Disable(GL_STENCIL_TEST);
254 mBoundArrayBufferId = 0;
255 LOG_GL("BindBuffer GL_ARRAY_BUFFER 0\n");
256 mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, mBoundArrayBufferId);
258 mBoundElementArrayBufferId = 0;
259 LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER 0\n");
260 mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBoundElementArrayBufferId);
262 #ifndef EMSCRIPTEN // not in WebGL
263 mBoundTransformFeedbackBufferId = 0;
264 LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER 0\n");
265 mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mBoundTransformFeedbackBufferId);
268 mActiveTextureUnit = TEXTURE_UNIT_LAST;
270 mUsingDefaultBlendColor = true;
271 mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f );
273 mBlendFuncSeparateSrcRGB = GL_ONE;
274 mBlendFuncSeparateDstRGB = GL_ZERO;
275 mBlendFuncSeparateSrcAlpha = GL_ONE;
276 mBlendFuncSeparateDstAlpha = GL_ZERO;
277 mGlAbstraction.BlendFuncSeparate( mBlendFuncSeparateSrcRGB, mBlendFuncSeparateDstRGB,
278 mBlendFuncSeparateSrcAlpha, mBlendFuncSeparateDstAlpha );
280 // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
281 mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
282 mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
283 mGlAbstraction.BlendEquationSeparate( mBlendEquationSeparateModeRGB, mBlendEquationSeparateModeAlpha);
285 mCullFaceMode = Dali::Material::NONE;
286 mGlAbstraction.Disable(GL_CULL_FACE);
287 mGlAbstraction.FrontFace(GL_CCW);
288 mGlAbstraction.CullFace(GL_BACK);
290 // rebind texture units to 0
291 for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
293 mBound2dTextureId[ i ] = 0;
294 // set active texture
295 mGlAbstraction.ActiveTexture( GL_TEXTURE0 + i );
296 mGlAbstraction.BindTexture(GL_TEXTURE_2D, mBound2dTextureId[ i ] );
299 // get maximum texture size
300 mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
302 // reset viewport, this will be set to something useful when rendering
303 mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
305 ResetVertexAttributeState();
307 mFrameBufferStateCache.Reset();
312 void Context::PrintCurrentState()
314 const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
315 DALI_LOG_INFO( gContextLogFilter, Debug::General,
316 "\n----------------- Context State BEGIN -----------------\n"
322 "Polygon Offset Fill = %s\n"
323 "Sample Alpha To Coverage = %s\n"
324 "Sample Coverage = %s\n"
325 "Scissor Test = %s\n"
326 "Stencil Test = %s\n"
327 "----------------- Context State END -----------------\n",
328 mBlendEnabled ? "Enabled" : "Disabled",
329 cullFaceModes[ mCullFaceMode ],
330 mDepthBufferEnabled ? "Enabled" : "Disabled",
331 mDepthMaskEnabled ? "Enabled" : "Disabled",
332 mDitherEnabled ? "Enabled" : "Disabled",
333 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
334 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
335 mSampleCoverageEnabled ? "Enabled" : "Disabled",
336 mScissorTestEnabled ? "Enabled" : "Disabled",
337 mStencilBufferEnabled ? "Enabled" : "Disabled");
340 #endif // DALI_CONTEXT_LOGGING
342 } // namespace Internal