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