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
111 if( Shader* shader = mParent->GetAppliedShader() )
113 Integration::ResourceId id = shader->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::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
208 scaling = Vector3::ONE;
211 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
213 ready = mResourcesReady;
216 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
218 std::size_t numTrackedResources = mTrackedResources.Count();
219 if( mHasUntrackedResources || numTrackedResources == 0 )
221 complete = mFinishedResourceAcquisition;
225 // If there are tracked resources and no untracked resources, test the trackers
226 bool trackersComplete = true;
227 for( size_t i=0; i < numTrackedResources; ++i )
229 ResourceId id = mTrackedResources[i];
230 ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
231 if( tracker && ! tracker->IsComplete() )
233 trackersComplete = false;
238 complete = mFinishedResourceAcquisition || trackersComplete;
242 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
244 // Check whether blending needs to be disabled / enabled
246 switch( mBlendingMode )
248 case BlendingMode::OFF:
254 case BlendingMode::AUTO:
256 // Blending if the node is not fully opaque only.
257 blend = !IsFullyOpaque( updateBufferIndex );
260 case BlendingMode::ON:
268 DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
274 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
276 // call the derived class first as it might change its state regarding blending
277 DoPrepareRender( updateBufferIndex );
279 bool blend = IsBlendingOn( updateBufferIndex );
280 ChangeBlending( updateBufferIndex, blend );
283 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
284 : mSceneController(NULL),
285 mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
286 mUsesGeometryScaling( usesGeometryScaling ),
287 mScaleForSizeDirty( true ),
289 mHasSizeAndColorFlag( false ),
290 mResourcesReady( false ),
291 mFinishedResourceAcquisition( false ),
292 mHasUntrackedResources( false ),
293 mCullFaceMode( CullNone ),
294 mSortModifier( 0.0f )
298 RenderableAttachment::~RenderableAttachment()
302 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
304 mSceneController = &sceneController;
306 // Chain to derived attachments
307 ConnectToSceneGraph2( updateBufferIndex );
309 // After derived classes have (potentially) created their renderer
310 GetRenderer().SetCullFace( mCullFaceMode );
313 void RenderableAttachment::OnDestroy()
315 // Chain to derived attachments
318 // SceneController is no longer valid
319 mSceneController = NULL;
322 RenderableAttachment* RenderableAttachment::GetRenderable()
328 } // namespace SceneGraph
330 } // namespace Internal