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