Created renderer objects.
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-renderer.cpp
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 #include "render-renderer.h"
18
19 #include <dali/internal/common/image-sampler.h>
20 #include <dali/internal/render/data-providers/geometry-data-provider.h>
21 #include <dali/internal/render/data-providers/material-data-provider.h>
22 #include <dali/internal/render/data-providers/sampler-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>
26
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace SceneGraph
33 {
34
35 NewRenderer* NewRenderer::New( NodeDataProvider& nodeDataProvider,
36                                const GeometryDataProvider* geometryDataProvider,
37                                const MaterialDataProvider* materialDataProvider)
38 {
39   return new NewRenderer(nodeDataProvider, geometryDataProvider, materialDataProvider);
40 }
41
42
43 NewRenderer::NewRenderer( NodeDataProvider& nodeDataProvider,
44                           const GeometryDataProvider* geometryDataProvider,
45                           const MaterialDataProvider* materialDataProvider)
46 : Renderer( nodeDataProvider ),
47   //mShaderDataProvider( shaderDataProvider ), //@todo Add in after merge with parent class
48   mMaterialDataProvider( materialDataProvider ),
49   mGeometryDataProvider( geometryDataProvider )
50 {
51 }
52
53 NewRenderer::~NewRenderer()
54 {
55 }
56
57 // @todo MESH_REWORK Should we consider changing the providers, or should we instead
58 // create a new renderer when these change?
59 void NewRenderer::SetGeometryDataProvider( const GeometryDataProvider* geometryDataProvider )
60 {
61   mGeometryDataProvider = geometryDataProvider;
62 }
63
64 void NewRenderer::SetMaterialDataProvider( const MaterialDataProvider* materialDataProvider )
65 {
66   mMaterialDataProvider = materialDataProvider;
67 }
68
69
70 // Note - this is currently called from UpdateThread, PrepareRenderInstructions,
71 // as an optimisation.
72 // @todo MESH_REWORK Should use Update thread objects only in PrepareRenderInstructions.
73 bool NewRenderer::RequiresDepthTest() const
74 {
75   return true;
76 }
77
78 bool NewRenderer::CheckResources()
79 {
80   // Query material to check it has texture pointers & image has size
81   // Query geometry to check it has vertex buffers
82
83   // General point though - why would we have a render item in RenderThread with no ready
84   // resources in UpdateThread?
85   return true;
86 }
87
88 void NewRenderer::ResolveGeometryTypes( BufferIndex bufferIndex, GeometryType& outType, ShaderSubTypes& outSubType )
89 {
90   // @todo MESH_REWORK Remove after merge
91
92   // Do nothing
93 }
94
95 bool NewRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix )
96 {
97   // @todo MESH_REWORK Add clipping
98   return false;
99 }
100
101 void NewRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix )
102 {
103   BindTextures( bufferIndex, program, mMaterialDataProvider->GetSamplers() );
104
105   SetUniforms( program );
106
107   mRenderGeometry.UploadAndDraw( mContext, program, bufferIndex, *mGeometryDataProvider );
108 }
109
110 void NewRenderer::GlContextDestroyed()
111 {
112   mRenderGeometry.GlContextDestroyed();
113 }
114
115 void NewRenderer::GlCleanup()
116 {
117 }
118
119 void NewRenderer::SetUniforms( Program& program )
120 {
121   // @todo MESH_REWORK Implement uniform map
122 }
123
124 void NewRenderer::BindTextures(
125   BufferIndex bufferIndex,
126   Program& program,
127   const MaterialDataProvider::Samplers& samplers )
128 {
129   // @todo MESH_REWORK Write a cache of texture units to commonly used sampler textures
130   unsigned int textureUnit = 0;
131
132   for( MaterialDataProvider::Samplers::Iterator iter = samplers.Begin();
133        iter != samplers.End();
134        ++iter )
135   {
136     const SamplerDataProvider* sampler = *iter;
137     ResourceId textureId = sampler->GetTextureId(bufferIndex);
138     Texture* texture = mTextureCache->GetTexture( textureId );
139     if( texture != NULL )
140     {
141       unsigned int textureUnitUniformIndex = GetTextureUnitUniformIndex( program, *sampler );
142       TextureUnit theTextureUnit = static_cast<TextureUnit>(textureUnit);
143       BindTexture( program, textureId, texture, theTextureUnit, textureUnitUniformIndex );
144       ApplySampler( bufferIndex, texture, theTextureUnit, *sampler );
145     }
146
147     ++textureUnit;
148   }
149 }
150
151 void NewRenderer::BindTexture(
152   Program& program,
153   ResourceId id,
154   Texture* texture,
155   TextureUnit textureUnit,
156   unsigned int textureUnitUniformIndex )
157 {
158   DALI_ASSERT_DEBUG( NULL != mTextureCache );
159
160   if( texture != NULL )
161   {
162     mTextureCache->BindTexture( texture, id, GL_TEXTURE_2D, textureUnit );
163
164     // Set sampler uniform location for the texture
165     GLint textureUnitLoc = program.GetUniformLocation( textureUnitUniformIndex );
166     if( Program::UNIFORM_UNKNOWN != textureUnitLoc )
167     {
168       program.SetUniform1i( textureUnitLoc, textureUnit );
169     }
170   }
171 }
172
173 void NewRenderer::ApplySampler(
174   BufferIndex bufferIndex,
175   Texture*    texture,
176   TextureUnit textureUnit,
177   const SamplerDataProvider& sampler )
178 {
179   unsigned int samplerBitfield = ImageSampler::PackBitfield(
180     static_cast< FilterMode::Type >(sampler.GetMinifyFilterMode(bufferIndex)),
181     static_cast< FilterMode::Type >(sampler.GetMagnifyFilterMode(bufferIndex)) );
182
183   texture->ApplySampler( textureUnit, samplerBitfield );
184
185   // @todo MESH_REWORK add support for wrap modes
186 }
187
188 unsigned int NewRenderer::GetTextureUnitUniformIndex(
189   Program& program,
190   const SamplerDataProvider& sampler )
191 {
192   // Find sampler in mSamplerNameCache
193   // If it doesn't exist,
194   //   get the index by calling program.RegisterUniform and store it
195   // If it exists, it's index should be set.
196   // @todo Cache should be reset on scene change
197
198   unsigned int uniformIndex = 0;
199   bool found = false;
200
201   for( unsigned int i=0; i< mTextureUnitUniforms.Count(); ++i )
202   {
203     if( mTextureUnitUniforms[i].sampler == &sampler )
204     {
205       uniformIndex = mTextureUnitUniforms[i].index;
206       found = true;
207     }
208   }
209
210   if( ! found )
211   {
212     TextureUnitUniformIndex textureUnitUniformIndex;
213     textureUnitUniformIndex.sampler = &sampler;
214     textureUnitUniformIndex.index = program.RegisterUniform( sampler.GetUnitName() );
215     mTextureUnitUniforms.PushBack( textureUnitUniformIndex );
216     uniformIndex = textureUnitUniformIndex.index;
217   }
218
219   return uniformIndex;
220 }
221
222
223 } // SceneGraph
224 } // Internal
225 } // Dali