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