2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "render-renderer.h"
19 #include <dali/internal/common/image-sampler.h>
20 #include <dali/internal/event/common/property-input-impl.h>
21 #include <dali/internal/update/common/uniform-map.h>
22 #include <dali/internal/render/data-providers/render-data-provider.h>
23 #include <dali/internal/render/gl-resources/texture.h>
24 #include <dali/internal/render/gl-resources/texture-cache.h>
25 #include <dali/internal/render/shaders/program.h>
34 NewRenderer* NewRenderer::New( NodeDataProvider& nodeDataProvider,
35 RenderDataProvider* dataProvider,
36 RenderGeometry* renderGeometry )
38 return new NewRenderer(nodeDataProvider, dataProvider, renderGeometry);
42 NewRenderer::NewRenderer( NodeDataProvider& nodeDataProvider,
43 RenderDataProvider* dataProvider,
44 RenderGeometry* renderGeometry )
45 : Renderer( nodeDataProvider ),
46 mRenderDataProvider( dataProvider ),
47 mRenderGeometry( renderGeometry ),
48 mUpdateAttributesLocation( true )
52 NewRenderer::~NewRenderer()
56 void NewRenderer::SetRenderDataProvider( RenderDataProvider* dataProvider )
58 mRenderDataProvider = dataProvider;
59 mUpdateAttributesLocation = true;
62 void NewRenderer::SetGeometry( RenderGeometry* renderGeometry )
64 mRenderGeometry = renderGeometry;
65 mUpdateAttributesLocation = true;
68 // Note - this is currently called from UpdateThread, PrepareRenderInstructions,
69 // as an optimisation.
70 // @todo MESH_REWORK Should use Update thread objects only in PrepareRenderInstructions.
71 bool NewRenderer::RequiresDepthTest() const
76 bool NewRenderer::CheckResources()
78 // Query material to check it has texture pointers & image has size
79 // Query geometry to check it has vertex buffers
81 // General point though - why would we have a render item in RenderThread with no ready
82 // resources in UpdateThread?
86 bool NewRenderer::IsOutsideClipSpace( Context& context, const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix )
88 // @todo MESH_REWORK Add clipping
92 void NewRenderer::DoSetUniforms( Context& context, BufferIndex bufferIndex, Shader* shader, Program* program, unsigned int programIndex )
94 // Do nothing, we're going to set up the uniforms with our own code instead
97 void NewRenderer::DoSetCullFaceMode( Context& context, BufferIndex bufferIndex )
101 void NewRenderer::DoSetBlending( Context& context, BufferIndex bufferIndex )
103 context.SetBlend(mUseBlend); // @todo MESH_REWORK Should use a RendererDataProvider
107 const MaterialDataProvider& material = mRenderDataProvider->GetMaterial();
109 context.SetCustomBlendColor( material.GetBlendColor( bufferIndex ) );
111 // Set blend source & destination factors
112 context.BlendFuncSeparate( material.GetBlendSrcFactorRgb( bufferIndex ),
113 material.GetBlendDestFactorRgb( bufferIndex ),
114 material.GetBlendSrcFactorAlpha( bufferIndex ),
115 material.GetBlendDestFactorAlpha( bufferIndex ) );
117 // Set blend equations
118 context.BlendEquationSeparate( material.GetBlendEquationRgb( bufferIndex ),
119 material.GetBlendEquationAlpha( bufferIndex ) );
123 void NewRenderer::DoRender( Context& context, TextureCache& textureCache, BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix )
125 BindTextures( textureCache, bufferIndex, program, mRenderDataProvider->GetSamplers() );
127 SetUniforms( bufferIndex, program );
129 if( mUpdateAttributesLocation || mRenderGeometry->AttributesChanged() )
131 mRenderGeometry->GetAttributeLocationFromProgram( mAttributesLocation, program, bufferIndex );
132 mUpdateAttributesLocation = false;
135 mRenderGeometry->UploadAndDraw( context, bufferIndex, mAttributesLocation );
138 void NewRenderer::GlContextDestroyed()
140 mRenderGeometry->GlContextDestroyed();
143 void NewRenderer::GlCleanup()
147 void NewRenderer::SetUniforms( BufferIndex bufferIndex, Program& program )
149 // Check if the map has changed
150 DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" );
152 const UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
154 if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) )
156 const CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
158 unsigned int numberOfMaps = uniformMap.Count();
159 mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
160 mUniformIndexMap.Resize( numberOfMaps );
162 // Remap uniform indexes to property value addresses
163 for( unsigned int mapIndex = 0 ; mapIndex < numberOfMaps ; ++mapIndex )
165 mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr;
166 mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName );
170 // Set uniforms in local map
171 for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
172 end = mUniformIndexMap.End() ;
176 SetUniformFromProperty( bufferIndex, program, *iter );
179 // @todo MESH_REWORK On merge, copy code from renderer to setup standard matrices and color
181 GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE );
184 Vector3 size = mDataProvider.GetRenderSize( bufferIndex );
185 program.SetUniform3f( sizeLoc, size.x, size.y, size.z );
189 void NewRenderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map )
191 GLint location = program.GetUniformLocation(map.uniformIndex);
192 if( Program::UNIFORM_UNKNOWN != location )
194 // switch based on property type to use correct GL uniform setter
195 switch ( map.propertyValue->GetType() )
197 case Property::INTEGER:
199 program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) );
202 case Property::FLOAT:
204 program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) );
207 case Property::VECTOR2:
209 Vector2 value( map.propertyValue->GetVector2( bufferIndex ) );
210 program.SetUniform2f( location, value.x, value.y );
214 case Property::VECTOR3:
216 Vector3 value( map.propertyValue->GetVector3( bufferIndex ) );
217 program.SetUniform3f( location, value.x, value.y, value.z );
221 case Property::VECTOR4:
223 Vector4 value( map.propertyValue->GetVector4( bufferIndex ) );
224 program.SetUniform4f( location, value.x, value.y, value.z, value.w );
228 case Property::ROTATION:
230 Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) );
231 program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w );
235 case Property::MATRIX:
237 const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
238 program.SetUniformMatrix4fv(location, 1, value.AsFloat() );
242 case Property::MATRIX3:
244 const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
245 program.SetUniformMatrix3fv(location, 1, value.AsFloat() );
251 // Other property types are ignored
258 void NewRenderer::BindTextures(
259 TextureCache& textureCache,
260 BufferIndex bufferIndex,
262 const RenderDataProvider::Samplers& samplers )
264 // @todo MESH_REWORK Write a cache of texture units to commonly used sampler textures
265 unsigned int textureUnit = 0;
267 for( RenderDataProvider::Samplers::Iterator iter = samplers.Begin();
268 iter != samplers.End();
271 const SamplerDataProvider* sampler = *iter;
272 ResourceId textureId = sampler->GetTextureId(bufferIndex);
273 Texture* texture = textureCache.GetTexture( textureId );
274 if( texture != NULL )
276 unsigned int textureUnitUniformIndex = GetTextureUnitUniformIndex( program, *sampler );
277 TextureUnit theTextureUnit = static_cast<TextureUnit>(textureUnit);
278 BindTexture( textureCache, program, textureId, texture, theTextureUnit, textureUnitUniformIndex );
279 ApplySampler( bufferIndex, texture, theTextureUnit, *sampler );
286 void NewRenderer::BindTexture(
287 TextureCache& textureCache,
291 TextureUnit textureUnit,
292 unsigned int textureUnitUniformIndex )
294 if( texture != NULL )
296 textureCache.BindTexture( texture, id, GL_TEXTURE_2D, textureUnit );
298 // Set sampler uniform location for the texture
299 GLint textureUnitLoc = program.GetUniformLocation( textureUnitUniformIndex );
300 if( Program::UNIFORM_UNKNOWN != textureUnitLoc )
302 program.SetUniform1i( textureUnitLoc, textureUnit );
307 void NewRenderer::ApplySampler(
308 BufferIndex bufferIndex,
310 TextureUnit textureUnit,
311 const SamplerDataProvider& sampler )
313 unsigned int samplerBitfield = ImageSampler::PackBitfield(
314 static_cast< FilterMode::Type >(sampler.GetMinifyFilterMode(bufferIndex)),
315 static_cast< FilterMode::Type >(sampler.GetMagnifyFilterMode(bufferIndex)) );
317 texture->ApplySampler( textureUnit, samplerBitfield );
319 // @todo MESH_REWORK add support for wrap modes
322 unsigned int NewRenderer::GetTextureUnitUniformIndex(
324 const SamplerDataProvider& sampler )
326 // Find sampler in mSamplerNameCache
327 // If it doesn't exist,
328 // get the index by calling program.RegisterUniform and store it
329 // If it exists, it's index should be set.
330 // @todo Cache should be reset on scene change
332 unsigned int uniformIndex = 0;
335 for( unsigned int i=0; i< mTextureUnitUniforms.Count(); ++i )
337 if( mTextureUnitUniforms[i].sampler == &sampler )
339 uniformIndex = mTextureUnitUniforms[i].index;
346 TextureUnitUniformIndex textureUnitUniformIndex;
347 textureUnitUniformIndex.sampler = &sampler;
348 textureUnitUniformIndex.index = program.RegisterUniform( sampler.GetTextureUnitUniformName() );
349 mTextureUnitUniforms.PushBack( textureUnitUniformIndex );
350 uniformIndex = textureUnitUniformIndex.index;