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