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>
42 void RenderableAttachment::SetSortModifier(float modifier)
44 // Setting sort modifier makes the node dirty, i.e. we cannot reuse previous frames render items
47 // only do this if we are on-stage
48 mParent->SetDirtyFlag( SortModifierFlag );
50 mSortModifier = modifier;
53 void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
58 BlendingMode::Type RenderableAttachment::GetBlendingMode() const
63 void RenderableAttachment::ChangeBlending( BufferIndex updateBufferIndex, bool useBlend )
65 if ( mUseBlend != useBlend )
69 // Enable/disable blending in the next render
70 typedef MessageValue1< Renderer, bool > DerivedType;
72 // Reserve some memory inside the render queue
73 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
75 // Construct message in the render queue memory; note that delete should not be called on the return value
76 new (slot) DerivedType( &GetRenderer(), &Renderer::SetUseBlend, useBlend );
80 void RenderableAttachment::SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options )
82 // Blending options are forwarded to renderer in render-thread
83 typedef MessageValue1< Renderer, unsigned int > DerivedType;
85 // Reserve some memory inside the render queue
86 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
88 // Construct message in the render queue memory; note that delete should not be called on the return value
89 new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendingOptions, options );
92 void RenderableAttachment::SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color )
94 // Blend color is forwarded to renderer in render-thread
95 typedef MessageValue1< Renderer, Vector4 > DerivedType;
97 // Reserve some memory inside the render queue
98 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
100 // Construct message in the render queue memory; note that delete should not be called on the return value
101 new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendColor, color );
104 void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
106 mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
107 mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
111 Integration::ResourceId id = mShader->GetEffectTextureResourceId();
115 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
117 if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
120 mFinishedResourceAcquisition = false;
121 mResourcesReady = false;
123 // If shader has effect texture and it's not complete and tracked, ensure
124 // we call DoPrepareResources, as the effect texture may become ready in
125 // the ProcessRenderTasks step. Otherwise, may early out.
126 if( mHasUntrackedResources )
134 mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
137 void RenderableAttachment::FollowTracker( Integration::ResourceId id )
139 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
141 if( completeStatusManager.FindResourceTracker(id) != NULL )
144 std::size_t numTrackedResources = mTrackedResources.Count();
145 for( size_t i=0; i < numTrackedResources; ++i )
147 if(mTrackedResources[i] == id)
155 mTrackedResources.PushBack( id );
160 mHasUntrackedResources = true;
164 void RenderableAttachment::SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode )
166 DALI_ASSERT_DEBUG(mSceneController);
167 DALI_ASSERT_DEBUG(mode >= CullNone && mode <= CullFrontAndBack);
169 mCullFaceMode = mode;
171 typedef MessageValue1< Renderer, CullFaceMode > DerivedType;
173 // Reserve some memory inside the render queue
174 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
176 // Construct message in the render queue memory; note that delete should not be called on the return value
177 new (slot) DerivedType( &GetRenderer(), &Renderer::SetCullFace, mode );
180 void RenderableAttachment::SetSampler( BufferIndex updateBufferIndex, unsigned int samplerBitfield )
182 DALI_ASSERT_DEBUG(mSceneController);
184 typedef MessageValue1< Renderer, unsigned int > DerivedType;
186 // Reserve some memory inside the render queue
187 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
189 // Construct message in the render queue memory; note that delete should not be called on the return value
190 new (slot) DerivedType( &GetRenderer(), &Renderer::SetSampler, samplerBitfield );
193 void RenderableAttachment::SetRecalculateScaleForSize()
195 mScaleForSizeDirty = true;
198 void RenderableAttachment::GetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
200 DoGetScaleForSize( nodeSize, scaling );
201 mScaleForSizeDirty = false;
204 void RenderableAttachment::ApplyShader( BufferIndex updateBufferIndex, Shader* shader )
208 // send the message to renderer
209 SendShaderChangeMessage( updateBufferIndex );
211 // tell derived class to do something
212 ShaderChanged( updateBufferIndex );
215 void RenderableAttachment::RemoveShader( BufferIndex updateBufferIndex )
217 // return to default shader
220 // send the message to renderer
221 SendShaderChangeMessage( updateBufferIndex );
223 // tell derived class to do something
224 ShaderChanged( updateBufferIndex );
227 bool RenderableAttachment::ResolveVisibility( BufferIndex updateBufferIndex )
229 mHasSizeAndColorFlag = false;
230 const Vector4& color = mParent->GetWorldColor( updateBufferIndex );
231 if( color.a > FULLY_TRANSPARENT ) // not fully transparent
233 const float MAX_NODE_SIZE = float(1u<<30);
234 const Vector3& size = mParent->GetSize( updateBufferIndex );
235 if( ( size.width > Math::MACHINE_EPSILON_1000 ) && // width is greater than a very small number
236 ( size.height > Math::MACHINE_EPSILON_1000 ) ) // height is greater than a very small number
238 if( ( size.width < MAX_NODE_SIZE ) && // width is smaller than the maximum allowed size
239 ( size.height < MAX_NODE_SIZE ) ) // height is smaller than the maximum allowed size
241 mHasSizeAndColorFlag = true;
245 DALI_LOG_ERROR("Actor size should not be bigger than %f.\n", MAX_NODE_SIZE );
246 DALI_LOG_ACTOR_TREE( mParent );
250 return mHasSizeAndColorFlag;
253 void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
255 scaling = Vector3::ONE;
258 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
260 ready = mResourcesReady;
263 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
265 std::size_t numTrackedResources = mTrackedResources.Count();
266 if( mHasUntrackedResources || numTrackedResources == 0 )
268 complete = mFinishedResourceAcquisition;
272 // If there are tracked resources and no untracked resources, test the trackers
273 bool trackersComplete = true;
274 for( size_t i=0; i < numTrackedResources; ++i )
276 ResourceId id = mTrackedResources[i];
277 ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
278 if( tracker && ! tracker->IsComplete() )
280 trackersComplete = false;
285 complete = mFinishedResourceAcquisition || trackersComplete;
289 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
291 // Check whether blending needs to be disabled / enabled
293 switch( mBlendingMode )
295 case BlendingMode::OFF:
301 case BlendingMode::AUTO:
303 // Blending if the node is not fully opaque only.
304 blend = !IsFullyOpaque( updateBufferIndex );
307 case BlendingMode::ON:
315 DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
321 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
323 // call the derived class first as it might change its state regarding blending
324 DoPrepareRender( updateBufferIndex );
326 bool blend = IsBlendingOn( updateBufferIndex );
327 ChangeBlending( updateBufferIndex, blend );
330 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
331 : mSceneController(NULL),
334 mSortModifier( 0.0f ),
335 mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
336 mUsesGeometryScaling( usesGeometryScaling ),
337 mScaleForSizeDirty( true ),
339 mHasSizeAndColorFlag( false ),
340 mResourcesReady( false ),
341 mFinishedResourceAcquisition( false ),
342 mHasUntrackedResources( false ),
343 mCullFaceMode( CullNone )
347 RenderableAttachment::~RenderableAttachment()
351 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
353 mSceneController = &sceneController;
355 // Chain to derived attachments
356 ConnectToSceneGraph2( updateBufferIndex );
358 // After derived classes have (potentially) created their renderer
359 Renderer& renderer = GetRenderer();
360 renderer.SetCullFace( mCullFaceMode );
362 // set the default shader here as well
363 renderer.SetShader( mShader );
366 void RenderableAttachment::OnDestroy()
368 // Chain to derived attachments
371 // SceneController is no longer valid
372 mSceneController = NULL;
375 RenderableAttachment* RenderableAttachment::GetRenderable()
380 void RenderableAttachment::SendShaderChangeMessage( BufferIndex updateBufferIndex )
382 typedef MessageValue1< Renderer, Shader* > DerivedType;
383 // Reserve memory inside the render queue
384 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
385 // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
386 new (slot) DerivedType( &GetRenderer(), &Renderer::SetShader, mShader );
389 } // namespace SceneGraph
391 } // namespace Internal