Rendering API clean-up
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-texture-set.cpp
1 /*
2  * Copyright (c) 2016 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 // CLASS HEADER
18 #include "scene-graph-texture-set.h"
19
20 // INTERNAL HEADERS
21 #include <dali/public-api/actors/blending.h>
22 #include <dali/public-api/shader-effects/shader-effect.h>
23 #include <dali/devel-api/rendering/texture-set.h>
24 #include <dali/integration-api/resource-declarations.h>
25 #include <dali/internal/common/internal-constants.h>
26 #include <dali/internal/update/resources/texture-metadata.h>
27 #include <dali/internal/update/resources/resource-manager.h>
28 #include <dali/internal/render/shaders/scene-graph-shader.h>
29 #include <dali/internal/common/memory-pool-object-allocator.h>
30
31 namespace //Unnamed namespace
32 {
33 //Memory pool used to allocate new texture sets. Memory used by this pool will be released when shutting down DALi
34 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::TextureSet> gTextureSetMemoryPool;
35 }
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 namespace SceneGraph
44 {
45
46 TextureSet* TextureSet::New()
47 {
48   return new ( gTextureSetMemoryPool.AllocateRawThreadSafe() ) TextureSet();
49 }
50
51 TextureSet::TextureSet()
52 : mSamplers(),
53   mTextureId(),
54   mConnectionObservers(),
55   mResourcesReady( false ),
56   mFinishedResourceAcquisition( false ),
57   mChanged( true ),
58   mHasAlpha( false )
59 {
60   // Observe own property-owner's uniform map
61   AddUniformMapObserver( *this );
62 }
63
64 TextureSet::~TextureSet()
65 {
66   mConnectionObservers.Destroy( *this );
67 }
68
69 void TextureSet::operator delete( void* ptr )
70 {
71   gTextureSetMemoryPool.FreeThreadSafe( static_cast<TextureSet*>( ptr ) );
72 }
73
74 void TextureSet::Prepare( const ResourceManager& resourceManager )
75 {
76   if( mChanged )
77   {
78     unsigned int opaqueCount = 0;
79     unsigned int completeCount = 0;
80     unsigned int failedCount = 0;
81     unsigned int frameBufferCount = 0;
82     const std::size_t textureCount( mTextureId.Count() );
83     if( textureCount > 0 )
84     {
85       for( unsigned int i(0); i<textureCount; ++i )
86       {
87         const ResourceId textureId = mTextureId[ i ];
88         TextureMetadata* metadata = NULL;
89         if( textureId != Integration::InvalidResourceId )
90         {
91           // if there is metadata, resource is loaded
92           if( resourceManager.GetTextureMetadata( textureId, metadata ) )
93           {
94             DALI_ASSERT_DEBUG( metadata );
95             // metadata is valid pointer from now on
96             if( metadata->IsFullyOpaque() )
97             {
98               ++opaqueCount;
99             }
100
101             if( metadata->IsFramebuffer() )
102             {
103               if( metadata->HasFrameBufferBeenRenderedTo() )
104               {
105                 ++completeCount;
106               }
107               else
108               {
109                 frameBufferCount++;
110               }
111             }
112             else
113             {
114               // loaded so will complete this frame
115               ++completeCount;
116             }
117             // no point checking failure as there is no metadata for failed loads
118           }
119           // if no metadata, loading can be failed
120           else if( resourceManager.HasResourceLoadFailed( textureId ) )
121           {
122             ++failedCount;
123           }
124         }
125         else
126         {
127           //If the texture is not valid it is considerer opaque and complete
128           ++opaqueCount;
129           ++completeCount;
130         }
131       }
132     }
133
134     mHasAlpha = ( opaqueCount != textureCount );
135
136     // ready for rendering when all textures are either successfully loaded or they are FBOs
137     mResourcesReady = (completeCount + frameBufferCount >= textureCount);
138
139     // Texture set is complete if all resources are either loaded or failed or, if they are FBOs have been rendererd to
140     mFinishedResourceAcquisition = ( completeCount + failedCount == textureCount );
141
142     if( mFinishedResourceAcquisition )
143     {
144       // Texture set is now considered not changed
145       mChanged = false;
146     }
147   }
148 }
149
150 void TextureSet::SetImage( size_t index,  ResourceId imageId )
151 {
152   size_t textureCount( mTextureId.Size() );
153   if( textureCount < index + 1 )
154   {
155     mTextureId.Resize( index + 1 );
156     mSamplers.Resize( index + 1 );
157     for( size_t i(textureCount); i<=index; ++i )
158     {
159       mTextureId[i] = Integration::InvalidResourceId;
160       mSamplers[i] = NULL;
161     }
162   }
163
164   mTextureId[index] = imageId;
165   mChanged = true;
166   mConnectionObservers.ConnectionsChanged(*this);
167 }
168
169 void TextureSet::SetSampler( size_t index, Render::Sampler* sampler )
170 {
171   size_t samplerCount( mSamplers.Size() );
172   if( samplerCount < index + 1 )
173   {
174     mSamplers.Resize( index + 1 );
175     mTextureId.Resize( index + 1 );
176     for( size_t i(samplerCount); i<=index; ++i )
177     {
178       mTextureId[i] = Integration::InvalidResourceId;
179       mSamplers[i] = NULL;
180     }
181   }
182
183   mSamplers[index] = sampler;
184
185   mChanged = true;
186   mConnectionObservers.ConnectionsChanged(*this);
187 }
188
189 bool TextureSet::HasAlpha() const
190 {
191   return mHasAlpha;
192 }
193
194 void TextureSet::GetResourcesStatus( bool& resourcesReady, bool& finishedResourceAcquisition )
195 {
196   resourcesReady = mResourcesReady;
197   finishedResourceAcquisition = mFinishedResourceAcquisition;
198 }
199
200 void TextureSet::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
201 {
202 }
203
204 void TextureSet::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
205 {
206 }
207
208 void TextureSet::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
209 {
210   mConnectionObservers.Add(observer);
211 }
212
213 void TextureSet::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
214 {
215   mConnectionObservers.Remove(observer);
216 }
217
218 void TextureSet::UniformMappingsChanged( const UniformMap& mappings )
219 {
220   // Our uniform map  has changed.
221   // Inform connected observers.
222   mConnectionObservers.ConnectedUniformMapChanged();
223 }
224
225 } // namespace SceneGraph
226
227 } // namespace Internal
228
229 } // namespace Dali