Back to index

unity  6.0.0
TextureCache.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2010, 2011 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by Gordon Allott <gord.allott@canonical.com>
00018  *             Tim Penhey <tim.penhey@canonical.com>
00019  */
00020 
00021 #include "TextureCache.h"
00022 
00023 #include <sstream>
00024 #include <NuxCore/Logger.h>
00025 
00026 namespace unity
00027 {
00028 namespace
00029 {
00030 nux::logging::Logger logger("unity.internal.texturecache");
00031 }
00032 
00033 TextureCache::TextureCache()
00034 {
00035 }
00036 
00037 TextureCache::~TextureCache()
00038 {
00039 }
00040 
00041 TextureCache& TextureCache::GetDefault()
00042 {
00043   static TextureCache instance;
00044   return instance;
00045 }
00046 
00047 std::string TextureCache::Hash(std::string const& id, int width, int height)
00048 {
00049   std::ostringstream sout;
00050   sout << id << "-" << width << "x" << height;
00051   return sout.str();
00052 }
00053 
00054 TextureCache::BaseTexturePtr TextureCache::FindTexture(std::string const& texture_id,
00055                                                        int width, int height,
00056                                                        CreateTextureCallback slot)
00057 {
00058   std::string key = Hash(texture_id, width, height);
00059   BaseTexturePtr texture(cache_[key]);
00060 
00061   if (!texture)
00062   {
00063     texture = slot(texture_id, width, height);
00064 
00065     // Now here is the magic.
00066     //
00067     // The slot function is required to return a new texture.  This has an
00068     // internal reference count of one.  The TextureCache wants to hold the
00069     // texture inside the internal map for as long as the object itself
00070     // exists, but it doesn't want any ownership of the texture.  How we
00071     // handle this is to always return a smart pointer for the texture.  These
00072     // smart pointers have the ownership of the texture.
00073     //
00074     // We also hook into the objects OnDestroyed signal to remove it from the
00075     // map.  To avoid a reverse lookup map, we bind the key to the method
00076     // call.  By using a mem_fun rather than a lambda function, and through
00077     // the magic of sigc::trackable, we don't need to remember the connection
00078     // itself.  We get notified when the object is being destroyed, and if we
00079     // are destroyed first, then the sigc::trackable disconnects all methods
00080     // created using mem_fun.
00081 
00082     // Reduce the internal reference count of the texture, so the smart
00083     // pointer is the sole owner of the object.
00084     texture->UnReference();
00085 
00086     cache_[key] = texture.GetPointer();
00087 
00088     auto on_destroy = sigc::mem_fun(this, &TextureCache::OnDestroyNotify);
00089     texture->OnDestroyed.connect(sigc::bind(on_destroy, key));
00090   }
00091 
00092   return texture;
00093 }
00094 
00095 void TextureCache::OnDestroyNotify(nux::Trackable* Object, std::string key)
00096 {
00097   cache_.erase(key);
00098 }
00099 
00100 // Return the current size of the cache.
00101 std::size_t TextureCache::Size() const
00102 {
00103   return cache_.size();
00104 }
00105 
00106 } // namespace unity