Shader & Program cleanup, Part 2: Stop calling render thread methods from update...
[platform/core/uifw/dali-core.git] / dali / internal / render / shaders / shader.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_SHADER_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_SHADER_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/common/dali-vector.h>
23 #include <dali/internal/common/buffer-index.h>
24 #include <dali/internal/common/event-to-update.h>
25 #include <dali/internal/render/gl-resources/gl-resource-owner.h>
26 #include <dali/internal/render/gl-resources/texture-declarations.h>
27 #include <dali/internal/render/common/render-manager.h>
28 #include <dali/internal/update/common/property-owner.h>
29 #include <dali/internal/event/effects/shader-declarations.h>
30 #include <dali/integration-api/shader-data.h>
31 #include <dali/public-api/shader-effects/shader-effect.h>
32 #include <dali/internal/common/type-abstraction-enums.h>
33
34 namespace Dali
35 {
36
37 namespace Integration
38 {
39 typedef unsigned int ResourceId;
40 } // namespace Integration
41
42 namespace Internal
43 {
44
45 class ProgramController;
46 class Program;
47
48 namespace SceneGraph
49 {
50
51 class RenderQueue;
52 class UniformMeta;
53 class TextureCache;
54
55 /**
56  * A base class for a collection of shader programs, to apply an effect to different geometry types.
57  * This class is also the default shader so its easier to override default behaviour
58  */
59 class Shader : public PropertyOwner
60 {
61 public:
62
63   /**
64    * This container contains pointers to the programs for each sub-type of a given geometry type.
65    * If a custom shader has overridden the subtypes (e.g. mesh custom shader),
66    * then the flag is used to indicate that there is only one shader in the
67    * vector that should be used.
68    * Note, it does not own the Programs it contains.
69    */
70   struct ProgramContainer
71   {
72   public:
73     /**
74      * Constructor
75      */
76     ProgramContainer()
77     : mUseDefaultForAllSubtypes(false)
78     {
79     }
80
81     /**
82      * Array lookup
83      * @param[in] position The array index
84      */
85     Program*& operator[]( size_t position )
86     {
87       return mSubPrograms[position];
88     }
89
90     /**
91      * Resize the container
92      * @param[in] length The new size of the container
93      */
94     void Resize(size_t length)
95     {
96       mSubPrograms.Resize( length, NULL );
97     }
98
99     /**
100      * Get the number of elements in the container
101      * @return count of the number of elements in the container
102      */
103     size_t Count() const
104     {
105       return mSubPrograms.Count();
106     }
107
108     Dali::Vector<Program*> mSubPrograms; ///< The programs for each subtype
109     bool mUseDefaultForAllSubtypes;      ///< TRUE if the first program should be used for all subtypes
110   };
111
112   /**
113    * Constructor
114    * @param hints Geometry hints
115    */
116   Shader( Dali::ShaderEffect::GeometryHints& hints );
117
118   /**
119    * Virtual destructor
120    */
121   virtual ~Shader();
122
123   /**
124    * Second stage initialization, called when added to the UpdateManager
125    * @param renderQueue Used to queue messages from update to render thread.
126    * @param textureCache Used to retrieve effect textures when rendering.
127    */
128   void Initialize( RenderQueue& renderQueue, TextureCache& textureCache );
129
130   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131   // The following methods are called during UpdateManager::Update()
132   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
133
134   /**
135    * Query whether a shader geometry hint is set.
136    * @pre The shader has been initialized.
137    * @param[in] hint The geometry hint to check.
138    * @return True if the given geometry hint is set.
139    */
140   bool GeometryHintEnabled( Dali::ShaderEffect::GeometryHints hint ) const
141   {
142     return mGeometryHints & hint;
143   }
144
145   /**
146    * Retrieve the set of geometry hints.
147    * @return The hints.
148    */
149   Dali::ShaderEffect::GeometryHints GetGeometryHints() const
150   {
151     return mGeometryHints;
152   }
153
154   /**
155    * Set the geometry hints.
156    * @param[in] hints The hints.
157    */
158   void SetGeometryHints( Dali::ShaderEffect::GeometryHints hints )
159   {
160     mGeometryHints = hints;
161   }
162
163   /**
164    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties
165    */
166   virtual void ResetDefaultProperties( BufferIndex updateBufferIndex )
167   {
168     // no default properties
169   }
170
171   /**
172    * Set the ID used to access textures
173    * @pre This method is not thread-safe, and should only be called from the update-thread.
174    * @param[in] updateBufferIndex The current update buffer index.
175    * @param[in] textureId The texture ID.
176    */
177   void ForwardTextureId( BufferIndex updateBufferIndex, Integration::ResourceId textureId );
178
179   /**
180    * Gets the effect texture resource ID
181    * This is zero if there is effect texture
182    * @return the resource Id
183    */
184   Integration::ResourceId GetEffectTextureResourceId();
185
186   /**
187    * Forwards the meta data from the update thread to the render thread for actual
188    * installation. (Installation is to a std::vector, which is not thread safe)
189    * @sa InstallUniformMetaInRender
190    * @pre This method should only be called from the update thread.
191    * @param[in] updateBufferIndex The current update buffer index.
192    * @param[in] meta A pointer to a UniformMeta to be owned by the Shader.
193    */
194   void ForwardUniformMeta( BufferIndex updateBufferIndex, UniformMeta* meta );
195
196   /**
197    * Forwards coordinate type to render
198    * @sa InstallUniformMetaInRender
199    * @pre This method should only be called from the update thread.
200    * @param[in] updateBufferIndex The current update buffer index.
201    * @param[in] index of the metadata.
202    * @param[in] type the coordinate type.
203    */
204   void ForwardCoordinateType( BufferIndex updateBufferIndex, unsigned int index, Dali::ShaderEffect::UniformCoordinateType type );
205
206   /**
207    * Forwards the grid density.
208    * @pre This method is not thread-safe, and should only be called from the update thread.
209    * @param[in] updateBufferIndex The current update buffer index.
210    * @param[in] density The grid density.
211    */
212   void ForwardGridDensity( BufferIndex updateBufferIndex, float density );
213
214   /**
215    * Forwards hints.
216    * @pre This method is not thread-safe, and should only be called from the update thread.
217    * @param[in] updateBufferIndex The current update buffer index.
218    * @param[in] hint The geometry hints.
219    */
220   void ForwardHints( BufferIndex updateBufferIndex, Dali::ShaderEffect::GeometryHints hint );
221
222   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223   // The following methods are called in Render thread
224   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225
226   /**
227    * Set the ID used to access textures
228    * @pre This method is not thread-safe, and should only be called from the render thread.
229    * @param[in] textureId The texture ID.
230    */
231   void SetTextureId( Integration::ResourceId textureId );
232
233   /**
234    * Get the texture id, that will be used in the next call to Shader::Apply()
235    * @return textureId The texture ID
236    */
237   Integration::ResourceId GetTextureIdToRender();
238
239   /**
240    * Sets grid density
241    * @pre This method is not thread-safe, and should only be called from the update thread.
242    * @param[in] value The grid density
243    */
244   void SetGridDensity(float value);
245
246   /**
247    * Get the grid density ID.
248    * @pre This method is not thread-safe, and should only be called from the render thread.
249    * @return The grid density.
250    */
251   float GetGridDensity();
252
253   /**
254    * Installs metadata related to a newly installed uniform property.
255    * @pre This method is not thread-safe, and should only be called from the render-thread.
256    * @param[in] meta A pointer to a UniformMeta to be owned by the Shader.
257    */
258   void InstallUniformMetaInRender( UniformMeta* meta );
259
260   /**
261    * Sets the uniform coordinate type
262    * @param index of the uniform
263    * @param type to set
264    */
265   void SetCoordinateTypeInRender( unsigned int index, Dali::ShaderEffect::UniformCoordinateType type );
266
267   /**
268    * Set the program for a geometry type and subtype
269    * @param[in] geometryType      The type of the object (geometry) that is to be rendered.
270    * @param[in] subType           The subtype, one of ShaderSubTypes.
271    * @param[in] resourceId        The resource ID for the program.
272    * @param[in] shaderData        The program's vertex/fragment source and optionally compiled bytecode
273    * @param[in] programCache      Owner of the Programs
274    * @param[in] modifiesGeometry  True if the vertex shader changes geometry
275    */
276   void SetProgram( GeometryType geometryType,
277                    Internal::ShaderSubTypes subType,
278                    Integration::ResourceId resourceId,
279                    Integration::ShaderDataPtr shaderData,
280                    ProgramCache* programCache,
281                    bool modifiesGeometry );
282
283   /**
284    * Determine if subtypes are required for the given geometry type
285    * @param[in] geometryType The type of the object (geometry) that is to be rendered.
286    * @return TRUE if subtypes are required, FALSE if there is only one subtype available
287    */
288   bool AreSubtypesRequired(GeometryType geometryType);
289
290   /**
291    * Get the program associated with the given type and subtype
292    * @param[in]  context      the context used to render.
293    * @param[in]  type         the type of the object (geometry) that is being rendered.
294    * @param[in]  subType      Identifier for geometry types with specialised default shaders
295    * @param[out] programIndex returns the program index to be passed onto SetUniforms.
296    * @return the program to use.
297    */
298   Program* GetProgram( Context& context,
299                        GeometryType type,
300                        ShaderSubTypes subType,
301                        unsigned int& programIndex );
302
303   /**
304    * Sets the shader specific uniforms including custom uniforms
305    * @pre The shader has been initialized.
306    * @pre This method is not thread-safe, and should only be called from the render-thread.
307    * @param[in] context The context used to render.
308    * @param[in] program to use.
309    * @param[in] bufferIndex The buffer to read shader properties from.
310    * @param[in] type        the type of the object (geometry) that is being rendered.
311    * @param[in] subType     Identifier for geometry types with specialised default shaders
312    */
313   void SetUniforms( Context& context,
314                     Program& program,
315                     BufferIndex bufferIndex,
316                     unsigned int programIndex,
317                     ShaderSubTypes subType = SHADER_DEFAULT );
318
319 private: // Data
320
321   Dali::ShaderEffect::GeometryHints mGeometryHints;    ///< shader geometry hints for building the geometry
322   float                          mGridDensity;      ///< grid density
323   Texture*                       mTexture;          ///< Raw Pointer to Texture
324   Integration::ResourceId        mRenderTextureId;  ///< Copy of the texture ID for the render thread
325   Integration::ResourceId        mUpdateTextureId;  ///< Copy of the texture ID for update thread
326
327   std::vector<ProgramContainer>  mPrograms;         ///< 2D array of Program*. Access by [Log<GEOMETRY_TYPE_XXX>::value][index]. An index of 0 selects the default program for that geometry type.
328
329   typedef OwnerContainer< UniformMeta* > UniformMetaContainer;
330   UniformMetaContainer           mUniformMetadata;     ///< A container of owned UniformMeta values; one for each property in PropertyOwner::mDynamicProperties
331
332   // These members are only safe to access during UpdateManager::Update()
333   RenderQueue*                   mRenderQueue;                   ///< Used for queuing a message for the next Render
334
335   // These members are only safe to access in render thread
336   TextureCache*                  mTextureCache; // Used for retrieving textures in the render thread
337 };
338
339 // Messages for Shader, to be processed in Update thread.
340 void SetTextureIdMessage( EventToUpdate& eventToUpdate, const Shader& shader, Integration::ResourceId textureId );
341 void SetGridDensityMessage( EventToUpdate& eventToUpdate, const Shader& shader, float density );
342 void SetHintsMessage( EventToUpdate& eventToUpdate, const Shader& shader, Dali::ShaderEffect::GeometryHints hint );
343 void InstallUniformMetaMessage( EventToUpdate& eventToUpdate, const Shader& shader, UniformMeta& meta );
344 void SetCoordinateTypeMessage( EventToUpdate& eventToUpdate, const Shader& shader, unsigned int index, Dali::ShaderEffect::UniformCoordinateType type );
345
346 } // namespace SceneGraph
347
348 } // namespace Internal
349
350 } // namespace Dali
351
352 #endif // __DALI_INTERNAL_SCENE_GRAPH_SHADER_H__