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