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