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