Merge "Refactored shader effect implementation." into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / effects / shader-effect-impl.h
1 #ifndef __DALI_INTERNAL_SHADER_EFFECT_H__
2 #define __DALI_INTERNAL_SHADER_EFFECT_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/ref-object.h>
23 #include <dali/public-api/shader-effects/shader-effect.h>
24 #include <dali/internal/event/effects/shader-declarations.h>
25 #include <dali/internal/event/common/proxy-object.h>
26 #include <dali/internal/render/shaders/uniform-meta.h>
27 #include <dali/internal/event/resources/resource-ticket.h>
28 #include <dali/internal/render/shaders/shader.h>
29
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 class ShaderFactory;
38
39 namespace SceneGraph
40 {
41 class UpdateManager;
42 }
43
44 /**
45  * An abstract base class for a shader effect proxy.
46  * The corresponding scene-graph object is a collection of shader programs,
47  * which can apply the same effect to different geometry types.
48  */
49 class ShaderEffect : public ProxyObject
50 {
51 public:
52
53   typedef Dali::ShaderEffect::UniformCoordinateType UniformCoordinateType;
54
55   /**
56    * Create a new ShaderEffect with no programs
57    * @param hints GeometryHints to define the geometry of the rendered object
58    * @return A smart-pointer to a newly allocated shader effect.
59    */
60   static ShaderEffectPtr New(Dali::ShaderEffect::GeometryHints hints = Dali::ShaderEffect::HINT_NONE);
61
62   /**
63    * Create a new ShaderEffect
64    * @param vertexShader code for the effect. If empty, the default version will be used
65    * @param fragmentShader code for the effect. If empty, the default version will be used
66    * @param type GeometryType
67    * @param hints GeometryHints to define the geometry of the rendered object
68    * @return A smart-pointer to a newly allocated shader effect.
69    */
70   static ShaderEffectPtr New( const std::string& vertexShader,
71                               const std::string& fragmentShader,
72                               GeometryType type,
73                               Dali::ShaderEffect::GeometryHints hints );
74   /**
75    * Create a new ShaderEffect
76    * @param vertexShaderPrefix code for the effect. It will be inserted before the default uniforms.
77    * @param vertexShader code for the effect. If empty, the default version will be used
78    * @param fragmentShaderPrefix code for the effect. It will be inserted before the default uniforms.
79    * @param fragmentShader code for the effect. If empty, the default version will be used
80    * @param type GeometryType
81    * @param hints GeometryHints to define the geometry of the rendered object
82    * @return A smart-pointer to a newly allocated shader effect.
83    */
84   static ShaderEffectPtr NewWithPrefix( const std::string& vertexShaderPrefix,
85                                         const std::string& vertexShader,
86                                         const std::string& fragmentShaderPrefix,
87                                         const std::string& fragmentShader,
88                                         GeometryType type,
89                                         Dali::ShaderEffect::GeometryHints hints );
90
91   /**
92    * Create a new ShaderEffect.
93    * If you pass in an empty string in the following arguments, the default version will be used instead.
94    * @param imageVertexShader code for the effect.
95    * @param imageFragmentShader code for the effect.
96    * @param textVertexShader code for the effect.
97    * @param textFragmentShader code for the effect.
98    * @param texturedMeshVertexShader code for the effect.
99    * @param texturedMeshFragmentShader code for the effect.
100    * @param meshVertexShader code for the effect.
101    * @param meshFragmentShader code for the effect.
102    * @param hints GeometryHints to define the geometry of the rendered object
103    * @return A handle to a shader effect
104    */
105   static ShaderEffectPtr New( const std::string& imageVertexShader,
106                               const std::string& imageFragmentShader,
107                               const std::string& textVertexShader,
108                               const std::string& textFragmentShader,
109                               const std::string& texturedMeshVertexShader,
110                               const std::string& texturedMeshFragmentShader,
111                               const std::string& meshVertexShader,
112                               const std::string& meshFragmentShader,
113                               Dali::ShaderEffect::GeometryHints hints );
114
115   /**
116    * Creates object with data from the property value map
117    * @param [in] map The property value map with fields such as 'vertex-filename' '..'
118    * @return a pointer to a newly created object.
119    */
120   static ShaderEffectPtr New( const Property::Value& map );
121
122   /**
123    * @copydoc Dali::ShaderEffect::SetEffectImage
124    */
125   void SetEffectImage( Dali::Image image );
126
127   /**
128    * @copydoc Dali::ShaderEffect::SetUniform( const std::string& name, Property::Value value, UniformCoordinateType uniformCoordinateType )
129    */
130   void SetUniform( const std::string& name,
131                    Property::Value value,
132                    UniformCoordinateType uniformCoordinateType );
133
134   /**
135    * @copydoc Dali::ShaderEffect::AttachExtension()
136    */
137   void AttachExtension( Dali::ShaderEffect::Extension *object );
138
139   /**
140    * @copydoc Dali::ShaderEffect::GetExtension()
141    */
142   Dali::ShaderEffect::Extension& GetExtension();
143
144   /**
145    * @copydoc Dali::ShaderEffect::GetExtension() const
146    */
147   const Dali::ShaderEffect::Extension& GetExtension() const;
148
149   enum FixedVertexShader
150   {
151     FLEXIBLE,
152     FIXED,
153   };
154
155   /**
156    * Add a GeometryType specific default program to this ShaderEffect
157    * @param[in] geometryType    The GeometryType rendered by the shader program
158    * @param[in] subType         The subtype, one of ShaderSubTypes.
159    * @param[in] vertexSource    The source code for the vertex shader
160    * @param[in] fragmentSource  The source code for the fragment shader
161    */
162   void SetProgram( GeometryType geometryType, ShaderSubTypes subType,
163                    const std::string& vertexSource, const std::string& fragmentSource,
164                    FixedVertexShader fixedVertexShader=FLEXIBLE);
165
166   /**
167    * Add a GeometryType specific default program to this ShaderEffect.
168    * This overload allows the optional prefixing for both the vertex and fragment shader.
169    * A useful prefix may be shader \#defines for conditional compilation.
170    * @param[in] geometryType    The GeometryType rendered by the shader program
171    * @param[in] subType         The subtype, one of ShaderSubTypes.
172    * @param[in] vertexPrefix    The prefix source code for the vertex shader
173    * @param[in] fragmentPrefix  The prefix source code for the fragment shader
174    * @param[in] vertexSource    The source code for the vertex shader
175    * @param[in] fragmentSource  The source code for the fragment shader
176    * @param[in] fixedVertexShader True if this shader doesn't change the vertices
177    */
178   void SetProgram( GeometryType geometryType, ShaderSubTypes subType,
179                    const std::string& vertexPrefix, const std::string& fragmentPrefix,
180                    const std::string& vertexSource, const std::string& fragmentSource,
181                    FixedVertexShader fixedVertexShader=FLEXIBLE);
182
183   /**
184    * Notify ShaderEffect that it's being used by an Actor.
185    */
186   void Connect();
187
188   /**
189    * Notify ShaderEffect that an Actor is no longer using it.
190    */
191   void Disconnect();
192
193 public: // Default property extensions from ProxyObject
194
195   /**
196    * @copydoc Dali::Internal::ProxyObject::IsSceneObjectRemovable()
197    */
198   virtual bool IsSceneObjectRemovable() const;
199
200   /**
201    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyCount()
202    */
203   virtual unsigned int GetDefaultPropertyCount() const;
204
205   /**
206    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
207    */
208   virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
209
210   /**
211    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
212    */
213   virtual const std::string& GetDefaultPropertyName( Property::Index index ) const;
214
215   /**
216    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndex()
217    */
218   virtual Property::Index GetDefaultPropertyIndex( const std::string& name ) const;
219
220   /**
221    * @copydoc Dali::Internal::ProxyObject::IsDefaultPropertyWritable()
222    */
223   virtual bool IsDefaultPropertyWritable( Property::Index index ) const;
224
225   /**
226    * @copydoc Dali::Internal::ProxyObject::IsDefaultPropertyAnimatable()
227    */
228   virtual bool IsDefaultPropertyAnimatable( Property::Index index ) const;
229
230   /**
231    * @copydoc Dali::Internal::ProxyObject::IsDefaultPropertyAConstraintInput()
232    */
233   virtual bool IsDefaultPropertyAConstraintInput( Property::Index index ) const;
234
235   /**
236    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyType()
237    */
238   virtual Property::Type GetDefaultPropertyType( Property::Index index ) const;
239
240   /**
241    * @copydoc Dali::Internal::ProxyObject::SetDefaultProperty()
242    */
243   virtual void SetDefaultProperty( Property::Index index, const Property::Value& propertyValue );
244
245   /**
246    * @copydoc Dali::Internal::ProxyObject::GetDefaultProperty()
247    */
248   virtual Property::Value GetDefaultProperty( Property::Index index ) const;
249
250   /**
251    * @copydoc Dali::Internal::ProxyObject::InstallSceneObjectProperty()
252    */
253   virtual void InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index );
254
255   /**
256    * @copydoc Dali::Internal::ProxyObject::GetSceneObject()
257    */
258   virtual const SceneGraph::PropertyOwner* GetSceneObject() const;
259
260   /**
261    * @copydoc Dali::Internal::ProxyObject::GetSceneObjectAnimatableProperty()
262    */
263   virtual const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty( Property::Index index ) const;
264
265   /**
266    * @copydoc Dali::Internal::ProxyObject::GetSceneObjectInputProperty()
267    */
268   virtual const PropertyInputImpl* GetSceneObjectInputProperty( Property::Index index ) const;
269
270 protected:
271
272   /**
273    * Protected constructor.
274    */
275   ShaderEffect( SceneGraph::UpdateManager& updateManager, ShaderFactory& shaderFactory, SceneGraph::Shader& sceneObject );
276
277   /**
278    * A reference counted object may only be deleted by calling Unreference()
279    */
280   virtual ~ShaderEffect();
281
282 private:
283
284   // No copying allowed, thus these are undefined
285   ShaderEffect( const ShaderEffect& );
286   ShaderEffect& operator=( const ShaderEffect& rhs );
287
288   /**
289    * Set the given program for all shader types set in the geometryType bitfield.
290    * @param[in] geometryType         A GeometryType bitfield
291    * @param[in] vertexShaderPrefix   The prefix source code for the vertex shader
292    * @param[in] vertexShader         The source code for the vertex shader
293    * @param[in] fragmentShaderPrefix The prefix source code for the fragment shader
294    * @param[in] fragmentShader       The source code for the fragment shader
295    */
296   void SetPrograms( GeometryType  geometryTypes,
297                     const std::string& vertexShaderPrefix,
298                     const std::string& vertexShader,
299                     const std::string& fragmentShaderPrefix,
300                     const std::string& fragmentShader );
301
302   /**
303    * Wrap the given prefix and body code around the predefined prefix source for the
304    * given geometry type. Specifying an empty string for the body code means that the
305    * predefined body code is used instead.
306    *
307    * @param[in] geometryType    The GeometryType rendered by the shader program
308    * @param[in] subType         The subtype, one of ShaderSubTypes.
309    * @param[in] vertexPrefix    The prefix source code for the vertex shader
310    * @param[in] fragmentPrefix  The prefix source code for the fragment shader
311    * @param[in] vertexSource    The source code for the vertex shader
312    * @param[in] fragmentSource  The source code for the fragment shader
313    */
314   void SetWrappedProgram( GeometryType geometryType, ShaderSubTypes subType,
315                           const std::string& vertexPrefix, const std::string& fragmentPrefix,
316                           const std::string& vertexSource, const std::string& fragmentSource );
317
318   /**
319    * Send shader program to scene-graph object.
320    * Uses the shader hints to determine whether the vertices are fixed.
321    * @param[in] geometryType    The GeometryType rendered by the shader program
322    * @param[in] subType         The subtype, one of ShaderSubTypes.
323    * @param[in] vertexSource    The source code for the vertex shader
324    * @param[in] fragmentSource  The source code for the fragment shader
325    * @param[in] fixedVertexShader True if this shader doesn't change the vertices
326    */
327   void SetProgramImpl( GeometryType geometryType, ShaderSubTypes subType,
328                        const std::string& vertexSource, const std::string& fragmentSource,
329                        FixedVertexShader fixedVertexShader );
330
331 private: // Data
332
333   SceneGraph::UpdateManager& mUpdateManager;            ///< reference to the update manager
334   ShaderFactory& mShaderFactory;                        ///< reference to the shader factory
335
336   SceneGraph::Shader* mSceneObject;                     ///< pointer to the scene shader, should not be changed on this thread
337
338   Dali::Image mImage;                                   ///< Client-side handle for the effect image
339
340   CustomUniformMetaLookup mCustomMetadata;            ///< Used for accessing metadata for custom Shader properties
341
342   IntrusivePtr<Dali::ShaderEffect::Extension> mExtension;
343
344   std::vector<ResourceTicketPtr>  mTickets;             ///< Collection of shader program tickets
345
346   unsigned int  mConnectionCount;                       ///< number of on-stage ImageActors using this shader effect
347
348   // Default properties
349   typedef std::map<std::string, Property::Index> DefaultPropertyLookup;
350   static DefaultPropertyLookup* mDefaultPropertyLookup;
351 };
352
353 } // namespace Internal
354
355 // Helpers for public-api forwarding methods
356
357 inline Internal::ShaderEffect& GetImplementation(Dali::ShaderEffect& effect)
358 {
359   DALI_ASSERT_ALWAYS(effect && "ShaderEffect handle is empty");
360
361   BaseObject& handle = effect.GetBaseObject();
362
363   return static_cast<Internal::ShaderEffect&>(handle);
364 }
365
366 inline const Internal::ShaderEffect& GetImplementation(const Dali::ShaderEffect& effect)
367 {
368   DALI_ASSERT_ALWAYS(effect && "ShaderEffect handle is empty");
369
370   const BaseObject& handle = effect.GetBaseObject();
371
372   return static_cast<const Internal::ShaderEffect&>(handle);
373 }
374
375 } // namespace Dali
376
377 #endif // __DALI_INTERNAL_SHADER_EFFECT_H__