[dali_1.2.38] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / render / common / render-manager.cpp
1 /*
2  * Copyright (c) 2016 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
18 // CLASS HEADER
19 #include <dali/internal/render/common/render-manager.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/sampling.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/render-tasks/render-task.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/internal/common/owner-pointer.h>
29 #include <dali/internal/render/common/render-algorithms.h>
30 #include <dali/internal/render/common/render-debug.h>
31 #include <dali/internal/render/common/render-tracker.h>
32 #include <dali/internal/render/common/render-instruction-container.h>
33 #include <dali/internal/render/common/render-instruction.h>
34 #include <dali/internal/render/gl-resources/context.h>
35 #include <dali/internal/render/queue/render-queue.h>
36 #include <dali/internal/render/renderers/render-frame-buffer.h>
37 #include <dali/internal/render/renderers/render-geometry.h>
38 #include <dali/internal/render/renderers/render-renderer.h>
39 #include <dali/internal/render/renderers/render-sampler.h>
40 #include <dali/internal/render/shaders/program-controller.h>
41
42 namespace Dali
43 {
44
45 namespace Internal
46 {
47
48 namespace SceneGraph
49 {
50
51 typedef OwnerContainer< Render::Renderer* >    RendererOwnerContainer;
52 typedef RendererOwnerContainer::Iterator       RendererOwnerIter;
53
54 typedef OwnerContainer< Render::Geometry* >    GeometryOwnerContainer;
55 typedef GeometryOwnerContainer::Iterator       GeometryOwnerIter;
56
57 typedef OwnerContainer< Render::Sampler* >    SamplerOwnerContainer;
58 typedef SamplerOwnerContainer::Iterator       SamplerOwnerIter;
59
60 typedef OwnerContainer< Render::Texture* >   TextureOwnerContainer;
61 typedef TextureOwnerContainer::Iterator         TextureOwnerIter;
62
63 typedef OwnerContainer< Render::FrameBuffer* >  FrameBufferOwnerContainer;
64 typedef FrameBufferOwnerContainer::Iterator     FrameBufferOwnerIter;
65
66 typedef OwnerContainer< Render::PropertyBuffer* > PropertyBufferOwnerContainer;
67 typedef PropertyBufferOwnerContainer::Iterator    PropertyBufferOwnerIter;
68
69 typedef OwnerContainer< Render::RenderTracker* > RenderTrackerContainer;
70 typedef RenderTrackerContainer::Iterator         RenderTrackerIter;
71 typedef RenderTrackerContainer::ConstIterator    RenderTrackerConstIter;
72
73 /**
74  * Structure to contain internal data
75  */
76 struct RenderManager::Impl
77 {
78   Impl( Integration::GlAbstraction& glAbstraction,
79         Integration::GlSyncAbstraction& glSyncAbstraction )
80   : context( glAbstraction ),
81     glSyncAbstraction( glSyncAbstraction ),
82     renderQueue(),
83     instructions(),
84     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
85     frameCount( 0 ),
86     renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
87     defaultSurfaceRect(),
88     rendererContainer(),
89     samplerContainer(),
90     textureContainer(),
91     frameBufferContainer(),
92     renderersAdded( false ),
93     programController( glAbstraction )
94   {
95   }
96
97   ~Impl()
98   {
99   }
100
101   void AddRenderTracker( Render::RenderTracker* renderTracker )
102   {
103     DALI_ASSERT_DEBUG( renderTracker != NULL );
104     mRenderTrackers.PushBack( renderTracker );
105   }
106
107   void RemoveRenderTracker( Render::RenderTracker* renderTracker )
108   {
109     DALI_ASSERT_DEBUG( renderTracker != NULL );
110     for(RenderTrackerIter iter = mRenderTrackers.Begin(), end = mRenderTrackers.End(); iter != end; ++iter)
111     {
112       if( *iter == renderTracker )
113       {
114         mRenderTrackers.Erase( iter );
115         break;
116       }
117     }
118   }
119
120   void UpdateTrackers()
121   {
122     for(RenderTrackerIter iter = mRenderTrackers.Begin(), end = mRenderTrackers.End(); iter != end; ++iter)
123     {
124       (*iter)->PollSyncObject();
125     }
126   }
127
128   // the order is important for destruction,
129   // programs are owned by context at the moment.
130   Context                       context;                  ///< holds the GL state
131   Integration::GlSyncAbstraction& glSyncAbstraction;      ///< GL sync abstraction
132   RenderQueue                   renderQueue;              ///< A message queue for receiving messages from the update-thread.
133
134   // Render instructions describe what should be rendered during RenderManager::Render()
135   // Owned by RenderManager. Update manager updates instructions for the next frame while we render the current one
136   RenderInstructionContainer    instructions;
137
138   Vector4                       backgroundColor;          ///< The glClear color used at the beginning of each frame.
139
140   unsigned int                  frameCount;               ///< The current frame count
141   BufferIndex                   renderBufferIndex;        ///< The index of the buffer to read from; this is opposite of the "update" buffer
142
143   Rect<int>                     defaultSurfaceRect;       ///< Rectangle for the default surface we are rendering to
144
145   RendererOwnerContainer        rendererContainer;        ///< List of owned renderers
146   SamplerOwnerContainer         samplerContainer;         ///< List of owned samplers
147   TextureOwnerContainer         textureContainer;         ///< List of owned textures
148   FrameBufferOwnerContainer     frameBufferContainer;     ///< List of owned framebuffers
149   PropertyBufferOwnerContainer  propertyBufferContainer;  ///< List of owned property buffers
150   GeometryOwnerContainer        geometryContainer;        ///< List of owned Geometries
151
152   bool                          renderersAdded;
153
154   RenderTrackerContainer        mRenderTrackers;          ///< List of render trackers
155
156   ProgramController             programController;        ///< Owner of the GL programs
157
158 };
159
160 RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction,
161                                    Integration::GlSyncAbstraction& glSyncAbstraction )
162 {
163   RenderManager* manager = new RenderManager;
164   manager->mImpl = new Impl( glAbstraction,
165                              glSyncAbstraction );
166   return manager;
167 }
168
169 RenderManager::RenderManager()
170 : mImpl(NULL)
171 {
172 }
173
174 RenderManager::~RenderManager()
175 {
176   delete mImpl;
177 }
178
179 RenderQueue& RenderManager::GetRenderQueue()
180 {
181   return mImpl->renderQueue;
182 }
183
184 void RenderManager::ContextCreated()
185 {
186   mImpl->context.GlContextCreated();
187   mImpl->programController.GlContextCreated();
188
189   // renderers, textures and gpu buffers cannot reinitialize themselves
190   // so they rely on someone reloading the data for them
191 }
192
193 void RenderManager::ContextDestroyed()
194 {
195   mImpl->context.GlContextDestroyed();
196   mImpl->programController.GlContextDestroyed();
197
198   //Inform textures
199   for( TextureOwnerIter iter = mImpl->textureContainer.Begin(); iter != mImpl->textureContainer.End(); ++iter )
200   {
201     (*iter)->GlContextDestroyed();
202   }
203
204   //Inform framebuffers
205   for( FrameBufferOwnerIter iter = mImpl->frameBufferContainer.Begin(); iter != mImpl->frameBufferContainer.End(); ++iter )
206   {
207     (*iter)->GlContextDestroyed();
208   }
209
210   // inform renderers
211   RendererOwnerContainer::Iterator end = mImpl->rendererContainer.End();
212   RendererOwnerContainer::Iterator iter = mImpl->rendererContainer.Begin();
213   for( ; iter != end; ++iter )
214   {
215     GlResourceOwner* renderer = *iter;
216     renderer->GlContextDestroyed(); // Clear up vertex buffers
217   }
218 }
219
220 void RenderManager::SetShaderSaver( ShaderSaver& upstream )
221 {
222   mImpl->programController.SetShaderSaver( upstream );
223 }
224
225 RenderInstructionContainer& RenderManager::GetRenderInstructionContainer()
226 {
227   return mImpl->instructions;
228 }
229
230 void RenderManager::SetBackgroundColor( const Vector4& color )
231 {
232   mImpl->backgroundColor = color;
233 }
234
235 void RenderManager::SetDefaultSurfaceRect(const Rect<int>& rect)
236 {
237   mImpl->defaultSurfaceRect = rect;
238 }
239
240 void RenderManager::AddRenderer( Render::Renderer* renderer )
241 {
242   // Initialize the renderer as we are now in render thread
243   renderer->Initialize( mImpl->context );
244
245   mImpl->rendererContainer.PushBack( renderer );
246
247   if( !mImpl->renderersAdded )
248   {
249     mImpl->renderersAdded = true;
250   }
251 }
252
253 void RenderManager::RemoveRenderer( Render::Renderer* renderer )
254 {
255   DALI_ASSERT_DEBUG( NULL != renderer );
256
257   RendererOwnerContainer& renderers = mImpl->rendererContainer;
258
259   // Find the renderer
260   for ( RendererOwnerIter iter = renderers.Begin(); iter != renderers.End(); ++iter )
261   {
262     if ( *iter == renderer )
263     {
264       renderers.Erase( iter ); // Renderer found; now destroy it
265       break;
266     }
267   }
268 }
269
270 void RenderManager::AddSampler( Render::Sampler* sampler )
271 {
272   mImpl->samplerContainer.PushBack( sampler );
273 }
274
275 void RenderManager::RemoveSampler( Render::Sampler* sampler )
276 {
277   DALI_ASSERT_DEBUG( NULL != sampler );
278
279   SamplerOwnerContainer& samplers = mImpl->samplerContainer;
280
281   // Find the sampler
282   for ( SamplerOwnerIter iter = samplers.Begin(); iter != samplers.End(); ++iter )
283   {
284     if ( *iter == sampler )
285     {
286       samplers.Erase( iter ); // Sampler found; now destroy it
287       break;
288     }
289   }
290 }
291
292 void RenderManager::AddTexture( Render::Texture* texture )
293 {
294   mImpl->textureContainer.PushBack( texture );
295   texture->Initialize(mImpl->context);
296 }
297
298 void RenderManager::RemoveTexture( Render::Texture* texture )
299 {
300   DALI_ASSERT_DEBUG( NULL != texture );
301
302   TextureOwnerContainer& textures = mImpl->textureContainer;
303
304   // Find the texture
305   for ( TextureOwnerIter iter = textures.Begin(); iter != textures.End(); ++iter )
306   {
307     if ( *iter == texture )
308     {
309       texture->Destroy( mImpl->context );
310       textures.Erase( iter ); // Texture found; now destroy it
311       break;
312     }
313   }
314 }
315
316 void RenderManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
317 {
318   texture->Upload( mImpl->context, pixelData, params );
319 }
320
321 void RenderManager::GenerateMipmaps( Render::Texture* texture )
322 {
323   texture->GenerateMipmaps( mImpl->context );
324 }
325
326 void RenderManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
327 {
328   sampler->mMinificationFilter = static_cast<Dali::FilterMode::Type>(minFilterMode);
329   sampler->mMagnificationFilter = static_cast<Dali::FilterMode::Type>(magFilterMode );
330 }
331
332 void RenderManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
333 {
334   sampler->mRWrapMode = static_cast<Dali::WrapMode::Type>(rWrapMode);
335   sampler->mSWrapMode = static_cast<Dali::WrapMode::Type>(sWrapMode);
336   sampler->mTWrapMode = static_cast<Dali::WrapMode::Type>(tWrapMode);
337 }
338
339 void RenderManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
340 {
341   mImpl->frameBufferContainer.PushBack( frameBuffer );
342   frameBuffer->Initialize(mImpl->context);
343 }
344
345 void RenderManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer )
346 {
347   DALI_ASSERT_DEBUG( NULL != frameBuffer );
348
349   FrameBufferOwnerContainer& framebuffers = mImpl->frameBufferContainer;
350
351   // Find the sampler
352   for ( FrameBufferOwnerIter iter = framebuffers.Begin(); iter != framebuffers.End(); ++iter )
353   {
354     if ( *iter == frameBuffer )
355     {
356       frameBuffer->Destroy( mImpl->context );
357       framebuffers.Erase( iter ); // frameBuffer found; now destroy it
358       break;
359     }
360   }
361 }
362
363 void RenderManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
364 {
365   frameBuffer->AttachColorTexture( mImpl->context, texture, mipmapLevel, layer );
366 }
367
368 void RenderManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
369 {
370   mImpl->propertyBufferContainer.PushBack( propertyBuffer );
371 }
372
373 void RenderManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
374 {
375   DALI_ASSERT_DEBUG( NULL != propertyBuffer );
376
377   PropertyBufferOwnerContainer& propertyBuffers = mImpl->propertyBufferContainer;
378
379   // Find the sampler
380   for ( PropertyBufferOwnerIter iter = propertyBuffers.Begin(); iter != propertyBuffers.End(); ++iter )
381   {
382     if ( *iter == propertyBuffer )
383     {
384       propertyBuffers.Erase( iter ); // Property buffer found; now destroy it
385       break;
386     }
387   }
388 }
389
390 void RenderManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
391 {
392   propertyBuffer->SetFormat( format );
393 }
394
395 void RenderManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
396 {
397   propertyBuffer->SetData( data, size );
398 }
399
400 void RenderManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
401 {
402   geometry->SetIndexBuffer( indices );
403 }
404
405 void RenderManager::AddGeometry( Render::Geometry* geometry )
406 {
407   mImpl->geometryContainer.PushBack( geometry );
408 }
409
410 void RenderManager::RemoveGeometry( Render::Geometry* geometry )
411 {
412   DALI_ASSERT_DEBUG( NULL != geometry );
413
414   GeometryOwnerContainer& geometries = mImpl->geometryContainer;
415
416   // Find the geometry
417   for ( GeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter )
418   {
419     if ( *iter == geometry )
420     {
421       geometries.Erase( iter ); // Geometry found; now destroy it
422       break;
423     }
424   }
425 }
426
427 void RenderManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
428 {
429   DALI_ASSERT_DEBUG( NULL != geometry );
430
431   GeometryOwnerContainer& geometries = mImpl->geometryContainer;
432
433   // Find the renderer
434   for ( GeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter )
435   {
436     if ( *iter == geometry )
437     {
438       (*iter)->AddPropertyBuffer( propertyBuffer );
439       break;
440     }
441   }
442 }
443
444 void RenderManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
445 {
446   DALI_ASSERT_DEBUG( NULL != geometry );
447
448   GeometryOwnerContainer& geometries = mImpl->geometryContainer;
449
450   // Find the renderer
451   for ( GeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter )
452   {
453     if ( *iter == geometry )
454     {
455       (*iter)->RemovePropertyBuffer( propertyBuffer );
456       break;
457     }
458   }
459 }
460
461 void RenderManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
462 {
463   geometry->SetType( Render::Geometry::Type(geometryType) );
464 }
465
466 void RenderManager::AddRenderTracker( Render::RenderTracker* renderTracker )
467 {
468   mImpl->AddRenderTracker(renderTracker);
469 }
470
471 void RenderManager::RemoveRenderTracker( Render::RenderTracker* renderTracker )
472 {
473   mImpl->RemoveRenderTracker(renderTracker);
474 }
475
476 ProgramCache* RenderManager::GetProgramCache()
477 {
478   return &(mImpl->programController);
479 }
480
481 void RenderManager::Render( Integration::RenderStatus& status )
482 {
483   DALI_PRINT_RENDER_START( mImpl->renderBufferIndex );
484
485   // Core::Render documents that GL context must be current before calling Render
486   DALI_ASSERT_DEBUG( mImpl->context.IsGlContextCreated() );
487
488   // Increment the frame count at the beginning of each frame
489   ++(mImpl->frameCount);
490
491   // Process messages queued during previous update
492   mImpl->renderQueue.ProcessMessages( mImpl->renderBufferIndex );
493
494   // switch rendering to adaptor provided (default) buffer
495   mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 );
496
497   mImpl->context.Viewport( mImpl->defaultSurfaceRect.x,
498                            mImpl->defaultSurfaceRect.y,
499                            mImpl->defaultSurfaceRect.width,
500                            mImpl->defaultSurfaceRect.height );
501
502   mImpl->context.ClearColor( mImpl->backgroundColor.r,
503                              mImpl->backgroundColor.g,
504                              mImpl->backgroundColor.b,
505                              mImpl->backgroundColor.a );
506
507   mImpl->context.ClearStencil( 0 );
508
509   // Clear the entire color, depth and stencil buffers for the default framebuffer.
510   // It is important to clear all 3 buffers, for performance on deferred renderers like Mali
511   // e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit",
512   // and then stall. That problem is only noticeable when rendering a large number of vertices per frame.
513   mImpl->context.SetScissorTest( false );
514   mImpl->context.ColorMask( true );
515   mImpl->context.DepthMask( true );
516   mImpl->context.StencilMask( 0xFF ); // 8 bit stencil mask, all 1's
517   mImpl->context.Clear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,  Context::FORCE_CLEAR );
518
519   // reset the program matrices for all programs once per frame
520   // this ensures we will set view and projection matrix once per program per camera
521   mImpl->programController.ResetProgramMatrices();
522
523   size_t count = mImpl->instructions.Count( mImpl->renderBufferIndex );
524   for ( size_t i = 0; i < count; ++i )
525   {
526     RenderInstruction& instruction = mImpl->instructions.At( mImpl->renderBufferIndex, i );
527
528     DoRender( instruction );
529   }
530   GLenum attachments[] = { GL_DEPTH, GL_STENCIL };
531   mImpl->context.InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
532
533   mImpl->UpdateTrackers();
534
535   //Notify RenderGeometries that rendering has finished
536   for ( GeometryOwnerIter iter = mImpl->geometryContainer.Begin(); iter != mImpl->geometryContainer.End(); ++iter )
537   {
538     (*iter)->OnRenderFinished();
539   }
540
541   /**
542    * The rendering has finished; swap to the next buffer.
543    * Ideally the update has just finished using this buffer; otherwise the render thread
544    * should block until the update has finished.
545    */
546   mImpl->renderBufferIndex = (0 != mImpl->renderBufferIndex) ? 0 : 1;
547
548   DALI_PRINT_RENDER_END();
549 }
550
551 void RenderManager::DoRender( RenderInstruction& instruction )
552 {
553   Rect<int> viewportRect;
554   Vector4   clearColor;
555
556   if ( instruction.mIsClearColorSet )
557   {
558     clearColor = instruction.mClearColor;
559   }
560   else
561   {
562     clearColor = Dali::RenderTask::DEFAULT_CLEAR_COLOR;
563   }
564
565   if( instruction.mFrameBuffer != 0 )
566   {
567     instruction.mFrameBuffer->Bind( mImpl->context );
568     if ( instruction.mIsViewportSet )
569     {
570       // For glViewport the lower-left corner is (0,0)
571       const int y = ( instruction.mFrameBuffer->GetHeight() - instruction.mViewport.height ) - instruction.mViewport.y;
572       viewportRect.Set( instruction.mViewport.x,  y, instruction.mViewport.width, instruction.mViewport.height );
573     }
574     else
575     {
576       viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() );
577     }
578   }
579   else // !(instruction.mOffscreenTexture)
580   {
581     // switch rendering to adaptor provided (default) buffer
582     mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 );
583
584     // Check whether a viewport is specified, otherwise the full surface size is used
585     if ( instruction.mIsViewportSet )
586     {
587       // For glViewport the lower-left corner is (0,0)
588       const int y = ( mImpl->defaultSurfaceRect.height - instruction.mViewport.height ) - instruction.mViewport.y;
589       viewportRect.Set( instruction.mViewport.x,  y, instruction.mViewport.width, instruction.mViewport.height );
590     }
591     else
592     {
593       viewportRect = mImpl->defaultSurfaceRect;
594     }
595   }
596
597   mImpl->context.Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
598
599   if ( instruction.mIsClearColorSet )
600   {
601     mImpl->context.ClearColor( clearColor.r,
602                                clearColor.g,
603                                clearColor.b,
604                                clearColor.a );
605
606     // Clear the viewport area only
607     mImpl->context.SetScissorTest( true );
608     mImpl->context.Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height );
609     mImpl->context.ColorMask( true );
610     mImpl->context.Clear( GL_COLOR_BUFFER_BIT , Context::CHECK_CACHED_VALUES );
611     mImpl->context.SetScissorTest( false );
612   }
613
614   Render::ProcessRenderInstruction( instruction,
615                                     mImpl->context,
616                                     mImpl->renderBufferIndex );
617
618   if( instruction.mRenderTracker && ( instruction.mFrameBuffer != NULL ) )
619   {
620     // This will create a sync object every frame this render tracker
621     // is alive (though it should be now be created only for
622     // render-once render tasks)
623     instruction.mRenderTracker->CreateSyncObject( mImpl->glSyncAbstraction );
624     instruction.mRenderTracker = NULL; // Only create once.
625   }
626 }
627
628 } // namespace SceneGraph
629
630 } // namespace Internal
631
632 } // namespace Dali