Remove RenderableActor
[platform/core/uifw/dali-core.git] / dali / internal / update / node-attachments / scene-graph-renderable-attachment.cpp
1 /*
2  * Copyright (c) 2014 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/update/node-attachments/scene-graph-renderable-attachment.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/resource-declarations.h>
23 #include <dali/public-api/actors/image-actor.h>
24 #include <dali/internal/update/manager/prepare-render-instructions.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/internal/update/resources/resource-manager.h>
27 #include <dali/internal/update/resources/complete-status-manager.h>
28 #include <dali/internal/update/resources/resource-tracker.h>
29 #include <dali/internal/render/queue/render-queue.h>
30 #include <dali/internal/render/renderers/scene-graph-renderer.h>
31 #include <dali/internal/render/shaders/scene-graph-shader.h>
32 #include <dali/internal/common/image-sampler.h>
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 namespace SceneGraph
41 {
42
43 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
44 : mSceneController(NULL), //@todo MESH_REWORK Pass in where required rather than store
45   mShader( NULL ),
46   mTrackedResources(),
47   mSortModifier( 0.0f ),
48   mBlendingMode( Dali::ImageActor::DEFAULT_BLENDING_MODE ),
49   mUsesGeometryScaling( usesGeometryScaling ),
50   mScaleForSizeDirty( true ),
51   mUseBlend( false ),
52   mHasSizeAndColorFlag( false ),
53   mResourcesReady( false ),
54   mFinishedResourceAcquisition( false ),
55   mHasUntrackedResources( false )
56 {
57 }
58
59 RenderableAttachment::~RenderableAttachment()
60 {
61 }
62
63 void RenderableAttachment::Initialize( SceneController& sceneController, BufferIndex updateBufferIndex )
64 {
65   mSceneController = &sceneController;
66
67   // Chain to derived attachments
68   Initialize2( updateBufferIndex );
69 }
70
71 void RenderableAttachment::OnDestroy()
72 {
73   // Chain to derived attachments
74   OnDestroy2();
75
76   // SceneController is no longer valid
77   mSceneController = NULL;
78 }
79
80 void RenderableAttachment::SetRecalculateScaleForSize()
81 {
82   mScaleForSizeDirty = true;
83 }
84
85 void RenderableAttachment::GetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
86 {
87   DoGetScaleForSize( nodeSize, scaling );
88   mScaleForSizeDirty = false;
89 }
90
91 bool RenderableAttachment::ResolveVisibility( BufferIndex updateBufferIndex )
92 {
93   mHasSizeAndColorFlag = false;
94   const Vector4& color = mParent->GetWorldColor( updateBufferIndex );
95   if( color.a > FULLY_TRANSPARENT )               // not fully transparent
96   {
97     const float MAX_NODE_SIZE = float(1u<<30);
98     const Vector3& size = mParent->GetSize( updateBufferIndex );
99     if( ( size.width > Math::MACHINE_EPSILON_1000 ) &&  // width is greater than a very small number
100         ( size.height > Math::MACHINE_EPSILON_1000 ) )  // height is greater than a very small number
101     {
102       if( ( size.width < MAX_NODE_SIZE ) &&             // width is smaller than the maximum allowed size
103           ( size.height < MAX_NODE_SIZE ) )             // height is smaller than the maximum allowed size
104       {
105         mHasSizeAndColorFlag = true;
106       }
107       else
108       {
109         DALI_LOG_ERROR("Actor size should not be bigger than %f.\n", MAX_NODE_SIZE );
110         DALI_LOG_ACTOR_TREE( mParent );
111       }
112     }
113   }
114   return mHasSizeAndColorFlag;
115 }
116
117 void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
118 {
119   scaling = Vector3::ONE;
120 }
121
122 void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
123 {
124   mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
125   mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
126
127   if( mShader )
128   {
129     Integration::ResourceId id = mShader->GetEffectTextureResourceId();
130
131     if( id != 0 )
132     {
133       CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
134
135       if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
136       {
137         FollowTracker(id);
138         mFinishedResourceAcquisition = false;
139         mResourcesReady = false;
140
141         // If shader has effect texture and it's not complete and tracked, ensure
142         // we call DoPrepareResources, as the effect texture may become ready in
143         // the ProcessRenderTasks step.  Otherwise, may early out.
144         if( mHasUntrackedResources )
145         {
146           return;
147         }
148       }
149     }
150   }
151
152   mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
153 }
154
155 void RenderableAttachment::FollowTracker( Integration::ResourceId id )
156 {
157   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
158
159   if( completeStatusManager.FindResourceTracker(id) != NULL )
160   {
161     bool found = false;
162     std::size_t numTrackedResources = mTrackedResources.Count();
163     for( size_t i=0; i < numTrackedResources; ++i )
164     {
165       if(mTrackedResources[i] == id)
166       {
167         found = true;
168         break;
169       }
170     }
171     if( ! found )
172     {
173       mTrackedResources.PushBack( id );
174     }
175   }
176   else
177   {
178     mHasUntrackedResources = true;
179   }
180 }
181
182
183 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
184 {
185   ready = mResourcesReady;
186   complete = false;
187
188   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
189
190   std::size_t numTrackedResources = mTrackedResources.Count();
191   if( mHasUntrackedResources || numTrackedResources == 0 )
192   {
193     complete = mFinishedResourceAcquisition;
194   }
195   else
196   {
197     // If there are tracked resources and no untracked resources, test the trackers
198     bool trackersComplete = true;
199     for( size_t i=0; i < numTrackedResources; ++i )
200     {
201       ResourceId id = mTrackedResources[i];
202       ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
203       if( tracker  && ! tracker->IsComplete() )
204       {
205         trackersComplete = false;
206         break;
207       }
208     }
209
210     complete = mFinishedResourceAcquisition || trackersComplete;
211   }
212 }
213
214 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
215 {
216   // call the derived class first as it might change its state regarding blending
217   DoPrepareRender( updateBufferIndex );
218
219   // @todo MESH_REWORK Remove remainder of method after removing ImageAttachment
220
221   bool blend = !IsFullyOpaque( updateBufferIndex );
222
223   if ( mUseBlend != blend )
224   {
225     mUseBlend = blend;
226
227     // Enable/disable blending in the next render
228     typedef MessageValue1< Renderer, bool > DerivedType;
229
230     // Reserve some memory inside the render queue
231     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
232
233     // Construct message in the render queue memory; note that delete should not be called on the return value
234     new (slot) DerivedType( &GetRenderer(), &Renderer::SetUseBlend, blend );
235   }
236 }
237
238 RenderableAttachment* RenderableAttachment::GetRenderable()
239 {
240   return this;
241 }
242
243 void RenderableAttachment::SetSortModifier(float modifier)
244 {
245   // Setting sort modifier makes the node dirty, i.e. we cannot reuse previous frames render items
246   if( mParent )
247   {
248     // only do this if we are on-stage
249     mParent->SetDirtyFlag( SortModifierFlag );
250   }
251   mSortModifier = modifier;
252 }
253
254 void RenderableAttachment::SetSortAttributes( BufferIndex bufferIndex, RendererWithSortAttributes& sortAttributes )
255 {
256   sortAttributes.shader = mShader;
257   sortAttributes.material = NULL;
258   sortAttributes.geometry = NULL;
259 }
260
261 } // namespace SceneGraph
262
263 } // namespace Internal
264
265 } // namespace Dali