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