Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / shaders / program-controller.cpp
1 /*
2  * Copyright (c) 2018 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/shaders/program-controller.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/gl-defines.h>
23 #include <dali/internal/common/shader-saver.h>
24 #include <dali/internal/render/gl-resources/gl-call-debug.h>
25 #include <dali/internal/render/shaders/program.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 ProgramController::ProgramController( Integration::GlAbstraction& glAbstraction )
34 : mShaderSaver( nullptr ),
35   mGlAbstraction( glAbstraction ),
36   mCurrentProgram( nullptr ),
37   mProgramBinaryFormat( 0 ),
38   mNumberOfProgramBinaryFormats( 0 )
39 {
40   // we have 17 default programs so make room for those and a few custom ones as well
41   mProgramCache.Reserve( 32 );
42 }
43
44 ProgramController::~ProgramController() = default;
45
46 void ProgramController::ResetProgramMatrices()
47 {
48   const ProgramIterator end = mProgramCache.End();
49   for ( ProgramIterator iter = mProgramCache.Begin(); iter != end; ++iter )
50   {
51     Program* program = (*iter)->GetProgram();
52     program->SetProjectionMatrix( nullptr );
53     program->SetViewMatrix( nullptr );
54   }
55 }
56
57 void ProgramController::GlContextCreated()
58 {
59   // reset any potential previous errors
60   LOG_GL( "GetError()\n" );
61   CHECK_GL( mGlAbstraction, mGlAbstraction.GetError() );
62
63   // find out if program binaries are supported and the format enum as well
64   Dali::Vector<GLint> programBinaryFormats;
65
66   CHECK_GL( mGlAbstraction, mGlAbstraction.GetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &mNumberOfProgramBinaryFormats ) );
67   LOG_GL("GetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES) = %d\n", mNumberOfProgramBinaryFormats );
68
69   if( GL_NO_ERROR == mGlAbstraction.GetError() && 0 < mNumberOfProgramBinaryFormats )
70   {
71     programBinaryFormats.Resize( mNumberOfProgramBinaryFormats );
72     CHECK_GL( mGlAbstraction, mGlAbstraction.GetIntegerv(GL_PROGRAM_BINARY_FORMATS_OES, &programBinaryFormats[0] ) );
73     LOG_GL("GetIntegerv(GL_PROGRAM_BINARY_FORMATS_OES) = %d\n", programBinaryFormats[0] );
74     mProgramBinaryFormat = programBinaryFormats[0];
75   }
76 }
77
78 void ProgramController::GlContextDestroyed()
79 {
80   mNumberOfProgramBinaryFormats = 0;
81   mProgramBinaryFormat = 0;
82
83   SetCurrentProgram( nullptr );
84   // Inform programs they are no longer valid
85   const ProgramIterator end = mProgramCache.End();
86   for ( ProgramIterator iter = mProgramCache.Begin(); iter != end; ++iter )
87   {
88     (*iter)->GetProgram()->GlContextDestroyed();
89   }
90 }
91
92 Integration::GlAbstraction& ProgramController::GetGlAbstraction()
93 {
94   return mGlAbstraction;
95 }
96
97 Program* ProgramController::GetProgram( size_t shaderHash )
98 {
99   Program* program = nullptr;
100   const ProgramIterator end = mProgramCache.End();
101   for ( ProgramIterator iter = mProgramCache.Begin(); iter != end; ++iter )
102   {
103     size_t hash = (*iter)->GetHash();
104     if( shaderHash == hash )
105     {
106       program = (*iter)->GetProgram();
107       break;
108     }
109   }
110   return program;
111 }
112
113 void ProgramController::AddProgram( size_t shaderHash, Program* program )
114 {
115   // we expect unique hash values so its event thread sides job to guarantee that
116   // AddProgram is only called after program checks that GetProgram returns NULL
117   mProgramCache.PushBack( new ProgramPair( program, shaderHash ) );
118 }
119
120 Program* ProgramController::GetCurrentProgram()
121 {
122   return mCurrentProgram;
123 }
124
125 void ProgramController::SetCurrentProgram( Program* program )
126 {
127   mCurrentProgram = program;
128 }
129
130 bool ProgramController::IsBinarySupported()
131 {
132   return mNumberOfProgramBinaryFormats > 0;
133 }
134
135 GLenum ProgramController::ProgramBinaryFormat()
136 {
137   return mProgramBinaryFormat;
138 }
139
140 void ProgramController::StoreBinary( Internal::ShaderDataPtr programData )
141 {
142   DALI_ASSERT_DEBUG( programData->GetBufferSize() > 0 );
143   DALI_ASSERT_DEBUG( mShaderSaver && "SetShaderSaver() should have been called during startup." );
144
145   if( mShaderSaver != nullptr )
146   {
147     mShaderSaver->SaveBinary( programData );
148   }
149 }
150
151 void ProgramController::SetShaderSaver( ShaderSaver& shaderSaver )
152 {
153   mShaderSaver = &shaderSaver;
154 }
155
156 void ProgramController::ClearCurrentProgram()
157 {
158   SetCurrentProgram( nullptr );
159 }
160
161 } // namespace Internal
162
163 } // namespace Dali