499352223660974c890c611fec9a0a52163f13b8
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-material.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 // CLASS HEADER
18 #include "scene-graph-material.h"
19
20 // INTERNAL HEADERS
21 #include <dali/public-api/actors/blending.h>
22 #include <dali/public-api/shader-effects/shader-effect.h>
23 #include <dali/devel-api/rendering/material.h>
24 #include <dali/internal/common/internal-constants.h>
25 #include <dali/internal/update/rendering/scene-graph-sampler.h>
26 #include <dali/internal/render/data-providers/sampler-data-provider.h>
27 #include <dali/internal/render/shaders/scene-graph-shader.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace SceneGraph
34 {
35
36 namespace
37 {
38 const unsigned int DEFAULT_BLENDING_OPTIONS( BlendingOptions().GetBitmask() );
39 }
40
41 Material::Material()
42 : mColor( Color::WHITE ),
43   mBlendColor( Color::TRANSPARENT ),
44   mFaceCullingMode(Dali::Material::NONE),
45   mBlendingMode(Dali::BlendingMode::AUTO),
46   mBlendingOptions( DEFAULT_BLENDING_OPTIONS ),
47   mShader(NULL),
48   mBlendPolicy(OPAQUE)
49 {
50   // Observe own property-owner's uniform map
51   AddUniformMapObserver( *this );
52 }
53
54 Material::~Material()
55 {
56   mConnectionObservers.Destroy( *this );
57 }
58
59 void Material::SetShader( Shader* shader )
60 {
61   mShader = shader;
62   mShader->AddUniformMapObserver( *this );
63
64   // Inform NewRenderer about this shader: (Will force a re-load of the
65   // shader from the data providers)
66   mConnectionObservers.ConnectionsChanged(*this);
67 }
68
69 Shader* Material::GetShader() const
70 {
71   // @todo - Fix this - move shader setup to the Renderer connect to stage...
72   return mShader;
73 }
74
75 void Material::AddSampler( Sampler* sampler )
76 {
77   mSamplers.PushBack( sampler );
78
79   sampler->AddConnectionObserver( *this );
80   sampler->AddUniformMapObserver( *this );
81
82   mConnectionObservers.ConnectionsChanged(*this);
83 }
84
85 void Material::RemoveSampler( Sampler* sampler )
86 {
87   Vector<Sampler*>::Iterator match = std::find( mSamplers.Begin(), mSamplers.End(), sampler );
88
89   DALI_ASSERT_DEBUG( mSamplers.End() != match );
90   if( mSamplers.End() != match )
91   {
92     sampler->RemoveConnectionObserver( *this );
93     sampler->RemoveUniformMapObserver( *this );
94     mSamplers.Erase( match );
95     mConnectionObservers.ConnectionsChanged(*this);
96   }
97   else
98   {
99     DALI_ASSERT_DEBUG( 0 && "Sampler not found" );
100   }
101 }
102
103 void Material::PrepareRender( BufferIndex bufferIndex )
104 {
105   mBlendPolicy = OPAQUE;
106
107   // @todo MESH_REWORK Add dirty flags to reduce processing.
108
109   switch(mBlendingMode[bufferIndex])
110   {
111     case BlendingMode::OFF:
112     {
113       mBlendPolicy = OPAQUE;
114       break;
115     }
116     case BlendingMode::ON:
117     {
118       mBlendPolicy = TRANSPARENT;
119       break;
120     }
121     case BlendingMode::AUTO:
122     {
123       bool opaque = true;
124
125       //  @todo: MESH_REWORK - Change hints for new SceneGraphShader:
126       // If shader hint OUTPUT_IS_OPAQUE is enabled, set policy to ALWAYS_OPAQUE
127       // If shader hint OUTPUT_IS_TRANSPARENT is enabled, set policy to ALWAYS_TRANSPARENT
128       // else test remainder, and set policy to either ALWAYS_TRANSPARENT or USE_ACTOR_COLOR
129
130       if( mShader->GeometryHintEnabled( Dali::ShaderEffect::HINT_BLENDING ) )
131       {
132         opaque = false;
133       }
134
135       if( opaque )
136       {
137         // Check the material color:
138         opaque = ( mColor[ bufferIndex ].a >= FULLY_OPAQUE );
139       }
140
141       if( opaque )
142       {
143         // Require that all affecting samplers are opaque
144         unsigned int opaqueCount=0;
145         unsigned int affectingCount=0;
146
147         for( Vector<Sampler*>::ConstIterator iter = mSamplers.Begin();
148              iter != mSamplers.End(); ++iter )
149         {
150           const Sampler* sampler = *iter;
151           if( sampler != NULL )
152           {
153             if( sampler->AffectsTransparency( bufferIndex ) )
154             {
155               affectingCount++;
156               if( sampler->IsFullyOpaque( bufferIndex ) )
157               {
158                 opaqueCount++;
159               }
160             }
161           }
162         }
163         opaque = (opaqueCount == affectingCount);
164       }
165
166       mBlendPolicy = opaque ? Material::USE_ACTOR_COLOR : Material::TRANSPARENT;
167     }
168   }
169 }
170
171 Vector<Sampler*>& Material::GetSamplers()
172 {
173   return mSamplers;
174 }
175
176 Material::BlendPolicy Material::GetBlendPolicy() const
177 {
178   return mBlendPolicy;
179 }
180
181 void Material::SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options )
182 {
183   mBlendingOptions.Set( updateBufferIndex, options );
184 }
185
186 const Vector4& Material::GetBlendColor(BufferIndex bufferIndex) const
187 {
188   return mBlendColor[bufferIndex];
189 }
190
191 BlendingFactor::Type Material::GetBlendSrcFactorRgb( BufferIndex bufferIndex ) const
192 {
193   BlendingOptions blendingOptions;
194   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
195   return blendingOptions.GetBlendSrcFactorRgb();
196 }
197
198 BlendingFactor::Type Material::GetBlendSrcFactorAlpha( BufferIndex bufferIndex ) const
199 {
200   BlendingOptions blendingOptions;
201   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
202   return blendingOptions.GetBlendSrcFactorAlpha();
203 }
204
205 BlendingFactor::Type Material::GetBlendDestFactorRgb( BufferIndex bufferIndex ) const
206 {
207   BlendingOptions blendingOptions;
208   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
209   return blendingOptions.GetBlendDestFactorRgb();
210 }
211
212 BlendingFactor::Type Material::GetBlendDestFactorAlpha( BufferIndex bufferIndex ) const
213 {
214   BlendingOptions blendingOptions;
215   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
216   return blendingOptions.GetBlendDestFactorAlpha();
217 }
218
219 BlendingEquation::Type Material::GetBlendEquationRgb( BufferIndex bufferIndex ) const
220 {
221   BlendingOptions blendingOptions;
222   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
223   return blendingOptions.GetBlendEquationRgb();
224 }
225
226 BlendingEquation::Type Material::GetBlendEquationAlpha( BufferIndex bufferIndex ) const
227 {
228   BlendingOptions blendingOptions;
229   blendingOptions.SetBitmask( mBlendingOptions[ bufferIndex ] );
230   return blendingOptions.GetBlendEquationAlpha();
231 }
232
233 void Material::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
234 {
235 }
236
237 void Material::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
238 {
239 }
240
241 void Material::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
242 {
243   mConnectionObservers.Add(observer);
244 }
245
246 void Material::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
247 {
248   mConnectionObservers.Remove(observer);
249 }
250
251 void Material::UniformMappingsChanged( const UniformMap& mappings )
252 {
253   // Our uniform map, or that of one of the watched children has changed.
254   // Inform connected observers.
255   mConnectionObservers.ConnectedUniformMapChanged();
256 }
257
258 void Material::ConnectionsChanged( PropertyOwner& owner )
259 {
260   mConnectionObservers.ConnectionsChanged(*this);
261 }
262
263 void Material::ConnectedUniformMapChanged( )
264 {
265   mConnectionObservers.ConnectedUniformMapChanged();
266 }
267
268 void Material::ResetDefaultProperties( BufferIndex updateBufferIndex )
269 {
270   mColor.ResetToBaseValue( updateBufferIndex );
271   mBlendColor.ResetToBaseValue( updateBufferIndex );
272   mFaceCullingMode.CopyPrevious( updateBufferIndex );
273
274   mBlendingMode.CopyPrevious( updateBufferIndex );
275   mBlendingOptions.CopyPrevious( updateBufferIndex );
276 }
277
278 } // namespace SceneGraph
279 } // namespace Internal
280 } // namespace Dali