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/resources/resource-manager.h>
26 #include <dali/devel-api/common/map-wrapper.h>
27 #include <dali/devel-api/common/set-wrapper.h>
28 #include <dali/public-api/math/vector2.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/message.h>
33 #include <dali/internal/common/image-attributes.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/resources/resource-type-path.h>
37 #include <dali/internal/event/resources/resource-client.h>
39 #include <dali/internal/update/common/discard-queue.h>
40 #include <dali/internal/update/resources/bitmap-metadata.h>
41 #include <dali/internal/render/queue/render-queue.h>
43 #include <dali/internal/render/common/texture-cache-dispatcher.h>
44 #include <dali/internal/render/common/post-process-resource-dispatcher.h>
46 using namespace Dali::Integration;
48 using Dali::Internal::SceneGraph::DiscardQueue;
49 using Dali::Internal::SceneGraph::RenderQueue;
50 using Dali::Internal::SceneGraph::TextureCacheDispatcher;
57 typedef std::set<ResourceId> LiveRequestContainer;
58 typedef LiveRequestContainer::iterator LiveRequestIter;
59 typedef LiveRequestContainer::size_type LiveRequestSize;
61 typedef std::map<ResourceId, ResourceTypeId> DeadRequestContainer;
62 typedef DeadRequestContainer::iterator DeadRequestIter;
63 typedef std::pair<ResourceId, ResourceTypeId> DeadRequestPair;
65 typedef std::vector<ResourceId> NotifyQueue;
66 typedef NotifyQueue::iterator NotifyQueueIter;
68 typedef std::map<ResourceId, BitmapMetadata> BitmapMetadataCache;
69 typedef BitmapMetadataCache::iterator BitmapMetadataIter;
70 typedef std::pair<ResourceId, BitmapMetadata> BitmapMetadataPair;
72 typedef std::map<ResourceId, ShaderDataPtr> ShaderCache;
73 typedef ShaderCache::iterator ShaderCacheIter;
74 typedef ShaderCache::size_type ShaderCacheSize;
75 typedef std::pair<ResourceId, ShaderDataPtr> ShaderDataPair;
77 static inline bool RemoveId( LiveRequestContainer& container, ResourceId id )
79 return container.erase(id) != 0;
82 struct ResourceManager::ResourceManagerImpl
84 ResourceManagerImpl( PlatformAbstraction& platformAbstraction,
85 NotificationManager& notificationManager,
86 SceneGraph::TextureCacheDispatcher& textureCacheDispatcher,
87 ResourcePostProcessList& resourcePostProcessQueue,
88 SceneGraph::PostProcessResourceDispatcher& postProcessResourceDispatcher,
89 DiscardQueue& discardQueue,
90 RenderQueue& renderQueue )
91 : mPlatformAbstraction(platformAbstraction),
92 mNotificationManager(notificationManager),
93 mResourceClient(NULL),
94 mTextureCacheDispatcher(textureCacheDispatcher),
95 mResourcePostProcessQueue(resourcePostProcessQueue),
96 mPostProcessResourceDispatcher(postProcessResourceDispatcher),
97 mDiscardQueue(discardQueue),
98 mRenderQueue(renderQueue),
99 mNotificationCount(0),
104 ~ResourceManagerImpl()
108 PlatformAbstraction& mPlatformAbstraction;
109 NotificationManager& mNotificationManager;
110 ResourceClient* mResourceClient; // (needs to be a ptr - it's not instantiated yet)
111 TextureCacheDispatcher& mTextureCacheDispatcher;
112 ResourcePostProcessList& mResourcePostProcessQueue;
113 SceneGraph::PostProcessResourceDispatcher& mPostProcessResourceDispatcher;
114 DiscardQueue& mDiscardQueue; ///< Unwanted resources are added here during UpdateCache()
115 RenderQueue& mRenderQueue;
116 unsigned int mNotificationCount;
117 bool cacheUpdated; ///< returned by UpdateCache(). Set true in NotifyTickets to indicate a change in a resource
120 * These containers are used to processs requests, and ResourceCache callbacks.
121 * The live request containers are simply sets of integer resource ids.
122 * The ID of a new request will be placed in the loading container.
123 * If the Ticket is destroyed during the load, the ID will be removed.
124 * If the load fails, the ID will be moved to the failed container.
125 * When the Ticket is notified of the failure, the ID will be removed.
126 * If the load succeeds, the ID will be moved to the new-completed container.
127 * When the Ticket is notified of the completion, the ID will be moved to the old-completed container.
128 * If a Ticket is destroyed after a successful load, the ID will be moved to the dead container.
129 * When the resources are eventually deleted, the ID will be removed from the dead container.
131 LiveRequestContainer loadingRequests;
132 LiveRequestContainer newCompleteRequests;
133 LiveRequestContainer oldCompleteRequests;
134 LiveRequestContainer newFailedRequests;
135 LiveRequestContainer oldFailedRequests;
136 DeadRequestContainer deadRequests;
137 LiveRequestContainer saveRequests; ///< copy of id's being saved (must also be in newCompleteRequests or oldCompleteRequests)
138 LiveRequestContainer completeSaveRequests; ///< successful save ids are moved from saveRequests to here
141 * This is the resource cache. It's filled/emptied from within Core::Update()
143 BitmapMetadataCache mBitmapMetadata;
144 ShaderCache mShaders;
147 ResourceManager::ResourceManager( PlatformAbstraction& platformAbstraction,
148 NotificationManager& notificationManager,
149 TextureCacheDispatcher& textureCacheDispatcher,
150 ResourcePostProcessList& resourcePostProcessQueue,
151 SceneGraph::PostProcessResourceDispatcher& postProcessResourceDispatcher,
152 DiscardQueue& discardQueue,
153 RenderQueue& renderQueue )
155 mImpl = new ResourceManagerImpl( platformAbstraction,
157 textureCacheDispatcher,
158 resourcePostProcessQueue,
159 postProcessResourceDispatcher,
164 ResourceManager::~ResourceManager()
169 /********************************************************************************
170 ************************ ResourceClient direct interface **********************
171 ********************************************************************************/
173 void ResourceManager::SetClient( ResourceClient& client )
175 mImpl->mResourceClient = &client;
178 /********************************************************************************
179 ************************ UpdateManager direct interface ***********************
180 ********************************************************************************/
182 bool ResourceManager::UpdateCache( BufferIndex updateBufferIndex )
184 DALI_LOG_INFO(Debug::Filter::gResource, Debug::Verbose, "ResourceManager: UpdateCache(bufferIndex:%u)\n", updateBufferIndex);
186 // 1) Move unwanted resources to the DiscardQueue
188 DiscardDeadResources( updateBufferIndex );
190 // 2) Fill the resource cache
191 mImpl->cacheUpdated = false;
193 mImpl->mPlatformAbstraction.GetResources(*this);
195 return mImpl->cacheUpdated;
198 void ResourceManager::PostProcessResources( BufferIndex updateBufferIndex )
200 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
201 DALI_LOG_INFO(Debug::Filter::gResource, Debug::Verbose, "ResourceManager: PostProcessResources()\n");
203 unsigned int numIds = mImpl->mResourcePostProcessQueue[ updateBufferIndex ].size();
206 // process the list where RenderManager put post process requests
207 for (i = 0; i < numIds; ++i)
209 ResourcePostProcessRequest ppRequest = mImpl->mResourcePostProcessQueue[ updateBufferIndex ][i];
210 switch(ppRequest.postProcess)
212 case ResourcePostProcessRequest::UPLOADED:
214 SendToClient( UploadedMessage( *mImpl->mResourceClient, ppRequest.id ) );
217 case ResourcePostProcessRequest::SAVE:
219 SendToClient( SaveResourceMessage( *mImpl->mResourceClient, ppRequest.id ) );
223 case ResourcePostProcessRequest::DELETED:
225 // TextureObservers handled in TextureCache
231 mImpl->mResourcePostProcessQueue[ updateBufferIndex ].clear();
235 /********************************************************************************
236 *************************** CoreImpl direct interface *************************
237 ********************************************************************************/
239 bool ResourceManager::ResourcesToProcess()
241 bool workTodo = false;
243 // need to make sure we have passed all the notifications to the event handling side
244 workTodo |= !mImpl->newCompleteRequests.empty();
245 workTodo |= !mImpl->newFailedRequests.empty();
246 // check if there's something still loading
247 workTodo |= !mImpl->loadingRequests.empty();
248 workTodo |= !mImpl->saveRequests.empty();
254 /********************************************************************************
255 ********************************* Message handlers *****************************
256 ********************************************************************************/
258 void ResourceManager::HandleLoadResourceRequest( ResourceId id, const ResourceTypePath& typePath, LoadResourcePriority priority )
260 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleLoadResourceRequest(id:%u, path:%s, type.id:%d)\n", id, typePath.path.c_str(), typePath.type->id);
262 // Add ID to the loading set
263 mImpl->loadingRequests.insert(id);
265 // Make the load request last
266 mImpl->mPlatformAbstraction.LoadResource(ResourceRequest(id, *typePath.type, typePath.path, priority));
269 void ResourceManager::HandleDecodeResourceRequest(
271 const ResourceTypePath& typePath,
272 RequestBufferPtr buffer,
273 Integration::LoadResourcePriority priority )
275 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleDecodeResourceRequest(id:%u, buffer.size:%u, type.id:%u)\n", id, buffer->GetVector().Size(), typePath.type->id);
277 // Add ID to the loading set
278 mImpl->loadingRequests.insert(id);
280 // Make the load request, stuffing the buffer of encoded bytes into the same field used when saving resources:
281 mImpl->mPlatformAbstraction.LoadResource(ResourceRequest(id, *typePath.type, "", buffer, priority));
284 void ResourceManager::HandleAddBitmapImageRequest( ResourceId id, BitmapPtr bitmap )
286 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
287 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddBitmapImageRequest(id:%u)\n", id);
289 mImpl->oldCompleteRequests.insert(id);
290 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New( bitmap.Get() )));
291 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForBitmap( id, bitmap.Get() );
294 void ResourceManager::HandleAddNativeImageRequest(ResourceId id, NativeImageInterfacePtr nativeImage)
296 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
297 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddNativeImageRequest(id:%u)\n", id);
299 mImpl->oldCompleteRequests.insert(id);
301 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New(nativeImage)));
302 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForNativeImage( id, nativeImage );
305 void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat )
307 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
308 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddFrameBufferImageRequest(id:%u)\n", id);
310 mImpl->oldCompleteRequests.insert(id);
312 BitmapMetadata bitmapMetadata = BitmapMetadata::New(width, height, Pixel::HasAlpha(pixelFormat));
313 bitmapMetadata.SetIsFramebuffer(true);
314 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, bitmapMetadata));
316 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, width, height, pixelFormat, bufferFormat );
319 void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, NativeImageInterfacePtr nativeImage )
321 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
322 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddFrameBufferImageRequest(id:%u)\n", id);
324 mImpl->oldCompleteRequests.insert(id);
326 BitmapMetadata bitmapMetadata = BitmapMetadata::New(nativeImage);
327 bitmapMetadata.SetIsNativeImage(true);
328 bitmapMetadata.SetIsFramebuffer(true);
329 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, bitmapMetadata));
331 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, nativeImage );
334 void ResourceManager::HandleAllocateTextureRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat )
336 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAllocateTextureRequest(id:%u)\n", id);
338 mImpl->oldCompleteRequests.insert(id);
339 mImpl->mTextureCacheDispatcher.DispatchCreateTexture( id, width, height, pixelFormat, true /* true = clear the texture */ );
342 void ResourceManager::HandleLoadShaderRequest( ResourceId id, const ResourceTypePath& typePath )
344 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleLoadShaderRequest(id:%u, path:%s)\n", id, typePath.path.c_str());
346 const ShaderResourceType* shaderType = dynamic_cast<const ShaderResourceType*>(typePath.type);
347 DALI_ASSERT_DEBUG(shaderType);
351 ShaderDataPtr shaderData(new ShaderData(shaderType->vertexShader, shaderType->fragmentShader));
353 mImpl->mPlatformAbstraction.LoadShaderBinFile(typePath.path, shaderData->GetBuffer());
355 // Add the ID to the completed set
356 mImpl->newCompleteRequests.insert(id);
358 // Cache the resource
359 mImpl->mShaders.insert(ShaderDataPair(id, shaderData));
361 // Let NotificationManager know that the resource manager needs to do some processing
366 void ResourceManager::HandleUpdateBitmapAreaRequest( ResourceId textureId, const RectArea& area )
370 mImpl->mTextureCacheDispatcher.DispatchUpdateTextureArea( textureId, area );
374 void ResourceManager::HandleUploadBitmapRequest( ResourceId destId, Integration::BitmapPtr bitmap, std::size_t xOffset, std::size_t yOffset )
376 if( destId && bitmap )
378 mImpl->mTextureCacheDispatcher.DispatchUpdateTexture( destId, bitmap, xOffset, yOffset );
382 void ResourceManager::HandleUploadBitmapRequest( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset )
384 if( destId && srcId )
386 mImpl->mTextureCacheDispatcher.DispatchUpdateTexture( destId, srcId, xOffset, yOffset );
390 void ResourceManager::HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, LoadResourcePriority priority, bool resetFinishedStatus )
392 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
393 DALI_LOG_INFO( Debug::Filter::gResource, Debug::General, "ResourceManager: HandleReloadRequest(id:%u, path:%s)\n", id, typePath.path.c_str() );
395 bool resourceIsAlreadyLoading = true;
397 if( resetFinishedStatus )
399 if( ! RemoveId( mImpl->newCompleteRequests, id ) )
401 RemoveId( mImpl->oldCompleteRequests, id );
405 // ID might be in the loading set
406 LiveRequestIter iter = mImpl->loadingRequests.find( id );
407 if ( iter == mImpl->loadingRequests.end() )
409 // Add ID to the loading set
410 mImpl->loadingRequests.insert(id);
411 resourceIsAlreadyLoading = false;
414 if ( !resourceIsAlreadyLoading )
416 // load resource again
417 mImpl->mPlatformAbstraction.LoadResource(ResourceRequest(id, *typePath.type, typePath.path, priority));
418 SendToClient( LoadingMessage( *mImpl->mResourceClient, id ) );
422 void ResourceManager::HandleSaveResourceRequest( ResourceId id, const ResourceTypePath& typePath )
424 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleSaveResourceRequest(id:%u, path:%s)\n", id, typePath.path.c_str());
426 bool resourceFound = false;
428 // ID must be in the complete sets
429 LiveRequestIter iter = mImpl->newCompleteRequests.find(id);
430 if (iter != mImpl->newCompleteRequests.end())
432 resourceFound = true;
436 LiveRequestIter iter = mImpl->oldCompleteRequests.find(id);
437 if (iter != mImpl->oldCompleteRequests.end())
439 resourceFound = true;
445 ResourcePointer resource;
446 DALI_ASSERT_DEBUG( typePath.type != NULL );
448 switch( typePath.type->id )
454 case ResourceNativeImage:
458 case ResourceTargetImage:
464 resource = GetShaderData(id);
470 if( resource ) // i.e. if it's a saveable resource
472 mImpl->saveRequests.insert(id);
474 ResourceRequest request(id, *typePath.type, typePath.path, resource);
475 mImpl->mPlatformAbstraction.SaveResource(request);
480 void ResourceManager::HandleDiscardResourceRequest( ResourceId deadId, ResourceTypeId typeId )
482 bool wasComplete = false;
483 bool wasLoading = false;
485 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleDiscardResourceRequest(id:%u)\n", deadId);
487 // remove copies of the deadId from completed/failed saving sets
488 RemoveId(mImpl->completeSaveRequests, deadId);
490 // Search for the ID in one of the live containers
491 // IDs are only briefly held in the new-completed or failed containers; check those last
492 // Try removing from the old-completed requests
493 bool foundLiveRequest = wasComplete = RemoveId(mImpl->oldCompleteRequests, deadId);
495 // Try removing from the loading requests
496 if (!foundLiveRequest)
498 foundLiveRequest = wasLoading = RemoveId(mImpl->loadingRequests, deadId);
501 // Try removing from the new completed requests
502 if (!foundLiveRequest)
504 foundLiveRequest = wasComplete = RemoveId(mImpl->newCompleteRequests, deadId);
507 // Try removing from the new failed requests
508 if (!foundLiveRequest)
510 foundLiveRequest = RemoveId(mImpl->newFailedRequests, deadId);
513 // Try removing from the old failed requests
514 if (!foundLiveRequest)
516 foundLiveRequest = RemoveId(mImpl->oldFailedRequests, deadId);
519 // ID should be in one of the live sets
520 if (!foundLiveRequest)
522 DALI_LOG_WARNING("HandleDiscardResourceRequest: ID should be in one of the live sets!\n");
524 DALI_ASSERT_DEBUG(foundLiveRequest);
528 if(typeId == ResourceBitmap ||
529 typeId == ResourceNativeImage ||
530 typeId == ResourceTargetImage )
532 // remove the meta data
533 mImpl->mBitmapMetadata.erase( deadId );
535 // destroy the texture
536 mImpl->mTextureCacheDispatcher.DispatchDiscardTexture( deadId );
540 // Move ID from completed to dead set
541 mImpl->deadRequests.insert(DeadRequestPair(deadId, typeId));
547 mImpl->mPlatformAbstraction.CancelLoad(deadId, typeId);
551 void ResourceManager::HandleCreateGlTextureRequest(ResourceId id)
553 mImpl->mTextureCacheDispatcher.DispatchCreateGlTexture( id );
556 /********************************************************************************
557 ******************** Update thread object direct interface ********************
558 ********************************************************************************/
560 bool ResourceManager::IsResourceLoaded(ResourceId id)
566 LiveRequestIter iter = mImpl->newCompleteRequests.find(id);
567 if( iter != mImpl->newCompleteRequests.end() )
573 iter = mImpl->oldCompleteRequests.find(id);
574 if( iter != mImpl->oldCompleteRequests.end() )
584 bool ResourceManager::IsResourceLoadFailed(ResourceId id)
586 bool loadFailed = false;
590 LiveRequestIter iter = mImpl->newFailedRequests.find(id);
591 if( iter != mImpl->newFailedRequests.end() )
597 iter = mImpl->oldFailedRequests.find(id);
598 if( iter != mImpl->oldFailedRequests.end() )
608 BitmapMetadata ResourceManager::GetBitmapMetadata(ResourceId id)
610 BitmapMetadata metadata;
614 BitmapMetadataIter iter = mImpl->mBitmapMetadata.find(id);
615 if( iter != mImpl->mBitmapMetadata.end() )
617 metadata = iter->second;
624 ShaderDataPtr ResourceManager::GetShaderData(ResourceId id)
626 ShaderDataPtr shaderData;
627 ShaderCacheIter iter = mImpl->mShaders.find(id);
628 if(iter != mImpl->mShaders.end())
630 shaderData = iter->second;
635 /********************************************************************************
636 ************************* ResourceCache Implementation ************************
637 ********************************************************************************/
639 void ResourceManager::LoadResponse( ResourceId id, ResourceTypeId type, ResourcePointer resource, LoadStatus loadStatus )
641 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
642 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: LoadResponse(id:%u, status=%s)\n", id, loadStatus==RESOURCE_LOADING?"LOADING":loadStatus==RESOURCE_PARTIALLY_LOADED?"PARTIAL":"COMPLETE");
644 // ID might be in the loading set
645 LiveRequestIter iter = mImpl->loadingRequests.find(id);
647 if ( iter != mImpl->loadingRequests.end() )
649 if( loadStatus == RESOURCE_COMPLETELY_LOADED )
651 // Remove from the loading set
652 mImpl->loadingRequests.erase(iter);
654 // Add the ID to the new-completed set, and store the resource
655 mImpl->newCompleteRequests.insert(id);
662 DALI_ASSERT_DEBUG( loadStatus == RESOURCE_COMPLETELY_LOADED && "Partial results not handled for image loading.\n" );
663 Bitmap* const bitmap = static_cast<Bitmap*>( resource.Get() );
666 DALI_LOG_ERROR( "Missing bitmap in loaded resource with id %u.\n", id );
669 unsigned int bitmapWidth = bitmap->GetImageWidth();
670 unsigned int bitmapHeight = bitmap->GetImageHeight();
672 if( Bitmap::PackedPixelsProfile * packedBitmap = bitmap->GetPackedPixelsProfile() )
674 bitmapWidth = packedBitmap->GetBufferWidth();
675 bitmapHeight = packedBitmap->GetBufferHeight();
677 ImageAttributes attrs = ImageAttributes::New( bitmapWidth, bitmapHeight ); ///!< Issue #AHC01
678 UpdateImageTicket (id, attrs);
680 // Check for reloaded bitmap
681 BitmapMetadataIter iter = mImpl->mBitmapMetadata.find(id);
682 if (iter != mImpl->mBitmapMetadata.end())
684 iter->second.Update(bitmap);
685 mImpl->mTextureCacheDispatcher.DispatchUpdateTexture( id, bitmap );
689 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForBitmap( id, bitmap );
690 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New(bitmap)));
696 case ResourceNativeImage:
698 NativeImageInterfacePtr nativeImg( static_cast<NativeImageInterface*>(resource.Get()) );
700 ImageAttributes attrs = ImageAttributes::New(nativeImg->GetWidth(), nativeImg->GetHeight());
702 mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New(nativeImg)));
703 mImpl->mTextureCacheDispatcher.DispatchCreateTextureForNativeImage( id, nativeImg );
705 UpdateImageTicket (id, attrs);
709 case ResourceTargetImage:
716 mImpl->mShaders.insert(ShaderDataPair(id, static_cast<ShaderData*>(resource.Get())));
722 // Let ResourceClient know that the resource manager has loaded something that its clients might want to hear about:
725 // flag that a load has completed and the cache updated
726 mImpl->cacheUpdated = true;
730 // This warning can fire if a cancelled load is forgotten here while already complete on a resource thread:
731 DALI_LOG_WARNING( "Received a notification for an untracked resource: (id:%u, status=%s)\n", id, loadStatus==RESOURCE_LOADING?"LOADING":loadStatus==RESOURCE_PARTIALLY_LOADED?"PARTIAL":"COMPLETE");
735 void ResourceManager::SaveComplete(ResourceId id, ResourceTypeId type)
737 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
738 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: SaveComplete(id:%u)\n", id);
740 // ID must be in the saving set
741 LiveRequestIter iter = mImpl->saveRequests.find(id);
743 if (iter != mImpl->saveRequests.end())
745 // Remove from the saving set
746 mImpl->saveRequests.erase(iter);
748 // If resource has not been discarded..
749 if( mImpl->deadRequests.find(id) == mImpl->deadRequests.end() )
751 SendToClient( SavingSucceededMessage( *mImpl->mResourceClient, id ) );
754 mImpl->cacheUpdated = true;
758 void ResourceManager::LoadFailed(ResourceId id, ResourceFailure failure)
760 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: LoadFailed(id:%u)\n", id);
762 // ID might be in the loading set
763 LiveRequestIter iter = mImpl->loadingRequests.find(id);
765 if (iter != mImpl->loadingRequests.end())
767 // Remove from the loading set
768 mImpl->loadingRequests.erase(iter);
770 // Add the ID to the failed set, this will trigger a notification during UpdateTickets
771 mImpl->newFailedRequests.insert(id);
773 // Let NotificationManager know that the resource manager needs to do some processing
776 mImpl->cacheUpdated = true;
780 void ResourceManager::SaveFailed(ResourceId id, ResourceFailure failure)
782 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
783 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: SaveFailed(id:%u)\n", id);
785 // ID must be in the saving set
786 LiveRequestIter iter = mImpl->saveRequests.find(id);
788 if (iter != mImpl->saveRequests.end())
790 // Remove from the saving set
791 mImpl->saveRequests.erase(iter);
793 // If resource has not been discarded..
795 if( mImpl->deadRequests.find(id) == mImpl->deadRequests.end() )
797 SendToClient( SavingFailedMessage( *mImpl->mResourceClient, id ) );
800 mImpl->cacheUpdated = true;
804 /********************************************************************************
805 ********************************* Private Methods *****************************
806 ********************************************************************************/
808 void ResourceManager::NotifyTickets()
810 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
811 // Success notifications
812 for (LiveRequestIter iter = mImpl->newCompleteRequests.begin(); iter != mImpl->newCompleteRequests.end(); ++iter)
814 // Move to oldCompleteRequests
815 mImpl->oldCompleteRequests.insert(*iter);
817 SendToClient( LoadingSucceededMessage( *mImpl->mResourceClient, *iter ) );
819 mImpl->newCompleteRequests.clear();
821 // Failure notifications
822 for (LiveRequestIter iter = mImpl->newFailedRequests.begin(); iter != mImpl->newFailedRequests.end(); ++iter)
824 // Move to oldFailedRequests
825 mImpl->oldFailedRequests.insert(*iter);
827 // We should have a matching request ticket
828 SendToClient( LoadingFailedMessage( *mImpl->mResourceClient, *iter ) );
830 mImpl->newFailedRequests.clear();
833 void ResourceManager::UpdateImageTicket( ResourceId id, ImageAttributes& attributes ) ///!< Issue #AHC01
835 DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
836 // ResourceLoader should load images considering the requested size
837 DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: UpdateImageTicket(id:%u)\n", id);
839 // Let NotificationManager know that the resource manager needs to do some processing
840 SendToClient( UpdateImageTicketMessage( *mImpl->mResourceClient, id, attributes) );
843 void ResourceManager::SendToClient( MessageBase* message )
845 mImpl->mNotificationManager.QueueMessage( message );
848 void ResourceManager::DiscardDeadResources( BufferIndex updateBufferIndex )
850 for (DeadRequestIter iter = mImpl->deadRequests.begin(); iter != mImpl->deadRequests.end(); )
852 // Delay destroying ids in saveRequests
853 if( mImpl->saveRequests.find(iter->first) != mImpl->saveRequests.end())
860 * We should find a resource of the correct type, and move it to the DiscardQueue.
862 switch (iter->second)
865 case ResourceNativeImage:
866 case ResourceTargetImage:
871 ShaderCacheIter shaderIter = mImpl->mShaders.find(iter->first);
872 DALI_ASSERT_DEBUG( mImpl->mShaders.end() != shaderIter );
873 // shader data is owned through intrusive pointers so no need for discard queue
874 mImpl->mShaders.erase( shaderIter );
879 // Erase the item and increment the iterator
880 mImpl->deadRequests.erase(iter++);
884 } // namespace Internal