Dali 3D User Interface Engine
shader-factory.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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
20 
21 // EXTERNAL INCLUDES
22 #include <sstream>
23 
24 // INTERNAL INCLUDES
33 
34 // compile time generated shader strings
35 #include "dali-shaders.h"
36 
37 namespace
38 {
39 const char* VERSION_SEPARATOR = "-";
40 const char* SHADER_SUFFIX = ".dali-bin";
41 }
42 
43 namespace Dali
44 {
45 
46 namespace Internal
47 {
48 
49 namespace
50 {
51 
57 void shaderBinaryFilename( size_t shaderHash, std::string& filename )
58 {
59  std::stringstream binaryShaderFilenameBuilder( std::ios_base::out );
61  << shaderHash
62  << SHADER_SUFFIX;
63  filename = binaryShaderFilenameBuilder.str();
64 }
65 
66 }
67 
69 {
70 }
71 
73 {
74  // Let all the cached objects destroy themselves:
75  for( int i = 0, cacheSize = mShaderBinaryCache.Size(); i < cacheSize; ++i )
76  {
77  if( mShaderBinaryCache[i] )
78  {
79  mShaderBinaryCache[i]->Unreference();
80  }
81  }
82 }
83 
84 ShaderDataPtr ShaderFactory::Load( const std::string& vertexSource, const std::string& fragmentSource, const Dali::Shader::ShaderHints hints, size_t& shaderHash )
85 {
86  // Work out the filename for the binary that the glsl source will be compiled and linked to:
87  shaderHash = CalculateHash( vertexSource.c_str(), fragmentSource.c_str() );
88  std::string binaryShaderFilename;
89  shaderBinaryFilename( shaderHash, binaryShaderFilename );
90 
91  ShaderDataPtr shaderData;
92 
94  for( int i = 0, cacheSize = mShaderBinaryCache.Size(); i < cacheSize; ++i )
95  {
96  if( mShaderBinaryCache[i]->GetHashValue() == shaderHash )
97  {
98  shaderData = mShaderBinaryCache[i];
99 
100  DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "Mem cache hit on path: \"%s\"\n", binaryShaderFilename.c_str() );
101  break;
102  }
103  }
104 
105  // If memory cache failed check the file system for a binary or return a source-only ShaderData:
106  if( shaderData.Get() == NULL )
107  {
108  // Allocate the structure that returns the loaded shader:
109  shaderData = new ShaderData( vertexSource, fragmentSource, hints );
110  shaderData->SetHashValue( shaderHash );
111  shaderData->GetBuffer().Clear();
112 
113  // Try to load the binary (this will fail if the shader source has never been compiled before):
115  Integration::PlatformAbstraction& platformAbstraction = tls.GetPlatformAbstraction();
116  const bool loaded = platformAbstraction.LoadShaderBinaryFile( binaryShaderFilename, shaderData->GetBuffer() );
117 
118  if( loaded )
119  {
120  MemoryCacheInsert( *shaderData );
121  }
122 
123  DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, loaded ?
124  "loaded on path: \"%s\"\n" :
125  "failed to load on path: \"%s\"\n",
126  binaryShaderFilename.c_str());
127  }
128 
129  return shaderData;
130 }
131 
133 {
134  // Save the binary to the file system:
135  std::string binaryShaderFilename;
136  shaderBinaryFilename( shaderData->GetHashValue(), binaryShaderFilename );
137 
139  Integration::PlatformAbstraction& platformAbstraction = tls.GetPlatformAbstraction();
140  const bool saved = platformAbstraction.SaveShaderBinaryFile( binaryShaderFilename, &shaderData->GetBuffer()[0], shaderData->GetBufferSize() );
141 
142  // Save the binary into to memory cache:
143  MemoryCacheInsert( *shaderData );
144 
145  DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, saved ? "Saved to file: %s\n" : "Save to file failed: %s\n", binaryShaderFilename.c_str() );
146  if( saved ) {} // Avoid unused variable warning in release builds
147 }
148 
150 {
152 }
153 
155 {
156  DALI_ASSERT_DEBUG( shaderData.GetBufferSize() > 0 );
157 
158  // Save the binary into to memory cache:
159  if( shaderData.GetBufferSize() > 0 )
160  {
161  mShaderBinaryCache.Reserve( mShaderBinaryCache.Size() + 1 ); // Make sure the push won't throw after we inc the ref count.
162  shaderData.Reference();
163  mShaderBinaryCache.PushBack( &shaderData );
164  DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "CACHED BINARY FOR HASH: %u\n", shaderData.GetHashValue() );
165  }
166 }
167 
168 } // namespace Internal
169 
170 } // namespace Dali
Dali Docs Home
Read more about Dali