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