2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
22 #include <dali/integration-api/resource-declarations.h>
23 #include <dali/public-api/actors/renderable-actor.h>
24 #include <dali/internal/update/nodes/node.h>
25 #include <dali/internal/update/resources/resource-manager.h>
26 #include <dali/internal/update/resources/complete-status-manager.h>
27 #include <dali/internal/update/resources/resource-tracker.h>
28 #include <dali/internal/render/queue/render-queue.h>
29 #include <dali/internal/render/renderers/scene-graph-renderer.h>
30 #include <dali/internal/render/shaders/shader.h>
31 #include <dali/internal/common/image-sampler.h>
44 void RenderableAttachment::SetSortModifier(float modifier)
46 // Setting sort modifier makes the node dirty, i.e. we cannot reuse previous frames render items
49 // only do this if we are on-stage
50 mParent->SetDirtyFlag( SortModifierFlag );
52 mSortModifier = modifier;
55 void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
60 BlendingMode::Type RenderableAttachment::GetBlendingMode() const
65 void RenderableAttachment::ChangeBlending( BufferIndex updateBufferIndex, bool useBlend )
67 if ( mUseBlend != useBlend )
71 // Enable/disable blending in the next render
72 typedef MessageValue1< Renderer, bool > DerivedType;
74 // Reserve some memory inside the render queue
75 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
77 // Construct message in the render queue memory; note that delete should not be called on the return value
78 new (slot) DerivedType( &GetRenderer(), &Renderer::SetUseBlend, useBlend );
82 void RenderableAttachment::SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options )
84 // Blending options are forwarded to renderer in render-thread
85 typedef MessageValue1< Renderer, unsigned int > DerivedType;
87 // Reserve some memory inside the render queue
88 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
90 // Construct message in the render queue memory; note that delete should not be called on the return value
91 new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendingOptions, options );
94 void RenderableAttachment::SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color )
96 // Blend color is forwarded to renderer in render-thread
97 typedef MessageValue1< Renderer, Vector4 > DerivedType;
99 // Reserve some memory inside the render queue
100 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
102 // Construct message in the render queue memory; note that delete should not be called on the return value
103 new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendColor, color );
106 void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
108 mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
109 mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
113 Integration::ResourceId id = mShader->GetEffectTextureResourceId();
117 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
119 if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
122 mFinishedResourceAcquisition = false;
123 mResourcesReady = false;
125 // If shader has effect texture and it's not complete and tracked, ensure
126 // we call DoPrepareResources, as the effect texture may become ready in
127 // the ProcessRenderTasks step. Otherwise, may early out.
128 if( mHasUntrackedResources )
136 mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
139 void RenderableAttachment::FollowTracker( Integration::ResourceId id )
141 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
143 if( completeStatusManager.FindResourceTracker(id) != NULL )
146 std::size_t numTrackedResources = mTrackedResources.Count();
147 for( size_t i=0; i < numTrackedResources; ++i )
149 if(mTrackedResources[i] == id)
157 mTrackedResources.PushBack( id );
162 mHasUntrackedResources = true;
166 void RenderableAttachment::SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode )
168 DALI_ASSERT_DEBUG(mSceneController);
169 DALI_ASSERT_DEBUG(mode >= CullNone && mode <= CullFrontAndBack);
171 mCullFaceMode = mode;
173 typedef MessageValue1< Renderer, CullFaceMode > DerivedType;
175 // Reserve some memory inside the render queue
176 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
178 // Construct message in the render queue memory; note that delete should not be called on the return value
179 new (slot) DerivedType( &GetRenderer(), &Renderer::SetCullFace, mode );
182 void RenderableAttachment::SetSampler( BufferIndex updateBufferIndex, unsigned int samplerBitfield )
184 DALI_ASSERT_DEBUG(mSceneController);
186 typedef MessageValue1< Renderer, unsigned int > DerivedType;
188 // Reserve some memory inside the render queue
189 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
191 // Construct message in the render queue memory; note that delete should not be called on the return value
192 new (slot) DerivedType( &GetRenderer(), &Renderer::SetSampler, samplerBitfield );
195 void RenderableAttachment::SetRecalculateScaleForSize()
197 mScaleForSizeDirty = true;
200 void RenderableAttachment::GetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
202 DoGetScaleForSize( nodeSize, scaling );
203 mScaleForSizeDirty = false;
206 void RenderableAttachment::ApplyShader( BufferIndex updateBufferIndex, Shader* shader )
210 // send the message to renderer
211 SendShaderChangeMessage( updateBufferIndex );
213 // tell derived class to do something
214 ShaderChanged( updateBufferIndex );
217 void RenderableAttachment::RemoveShader( BufferIndex updateBufferIndex )
219 // return to default shader
220 mShader = mSceneController->GetDefaultShader();
222 // send the message to renderer
223 SendShaderChangeMessage( updateBufferIndex );
225 // tell derived class to do something
226 ShaderChanged( updateBufferIndex );
229 void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
231 scaling = Vector3::ONE;
234 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
236 ready = mResourcesReady;
239 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
241 std::size_t numTrackedResources = mTrackedResources.Count();
242 if( mHasUntrackedResources || numTrackedResources == 0 )
244 complete = mFinishedResourceAcquisition;
248 // If there are tracked resources and no untracked resources, test the trackers
249 bool trackersComplete = true;
250 for( size_t i=0; i < numTrackedResources; ++i )
252 ResourceId id = mTrackedResources[i];
253 ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
254 if( tracker && ! tracker->IsComplete() )
256 trackersComplete = false;
261 complete = mFinishedResourceAcquisition || trackersComplete;
265 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
267 // Check whether blending needs to be disabled / enabled
269 switch( mBlendingMode )
271 case BlendingMode::OFF:
277 case BlendingMode::AUTO:
279 // Blending if the node is not fully opaque only.
280 blend = !IsFullyOpaque( updateBufferIndex );
283 case BlendingMode::ON:
291 DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
297 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
299 // call the derived class first as it might change its state regarding blending
300 DoPrepareRender( updateBufferIndex );
302 bool blend = IsBlendingOn( updateBufferIndex );
303 ChangeBlending( updateBufferIndex, blend );
306 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
307 : mSceneController(NULL),
310 mSortModifier( 0.0f ),
311 mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
312 mUsesGeometryScaling( usesGeometryScaling ),
313 mScaleForSizeDirty( true ),
315 mHasSizeAndColorFlag( false ),
316 mResourcesReady( false ),
317 mFinishedResourceAcquisition( false ),
318 mHasUntrackedResources( false ),
319 mCullFaceMode( CullNone )
323 RenderableAttachment::~RenderableAttachment()
327 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
329 mSceneController = &sceneController;
330 // get the default shader
331 mShader = mSceneController->GetDefaultShader();
333 // Chain to derived attachments
334 ConnectToSceneGraph2( updateBufferIndex );
336 // After derived classes have (potentially) created their renderer
337 Renderer& renderer = GetRenderer();
338 renderer.SetCullFace( mCullFaceMode );
340 // set the default shader here as well
341 renderer.SetShader( mShader );
344 void RenderableAttachment::OnDestroy()
346 // Chain to derived attachments
349 // SceneController is no longer valid
350 mSceneController = NULL;
353 RenderableAttachment* RenderableAttachment::GetRenderable()
358 void RenderableAttachment::SendShaderChangeMessage( BufferIndex updateBufferIndex )
360 typedef MessageValue1< Renderer, Shader* > DerivedType;
361 // Reserve memory inside the render queue
362 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
363 // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
364 new (slot) DerivedType( &GetRenderer(), &Renderer::SetShader, mShader );
367 } // namespace SceneGraph
369 } // namespace Internal