Increment texture use counts in a separate job to ensure it's done off-thread
authorJonathan Marshall <jmarshall@never.you.mind>
Fri, 25 May 2012 10:38:15 +0000 (22:38 +1200)
committerJonathan Marshall <jmarshall@never.you.mind>
Sat, 26 May 2012 03:54:39 +0000 (15:54 +1200)
xbmc/TextureCache.cpp
xbmc/TextureCache.h
xbmc/TextureCacheJob.cpp
xbmc/TextureCacheJob.h

index 1c8fa0c..ab04ea8 100644 (file)
@@ -217,10 +217,17 @@ bool CTextureCache::AddCachedTexture(const CStdString &url, const CTextureDetail
   return m_database.AddCachedTexture(url, details);
 }
 
-bool CTextureCache::IncrementUseCount(const CTextureDetails &details)
+void CTextureCache::IncrementUseCount(const CTextureDetails &details)
 {
-  CSingleLock lock(m_databaseSection);
-  return m_database.IncrementUseCount(details);
+  static const size_t count_before_update = 100;
+  CSingleLock lock(m_useCountSection);
+  m_useCounts.reserve(count_before_update);
+  m_useCounts.push_back(details);
+  if (m_useCounts.size() >= count_before_update)
+  {
+    AddJob(new CTextureUseCountJob(m_useCounts));
+    m_useCounts.clear();
+  }
 }
 
 bool CTextureCache::SetCachedTextureValid(const CStdString &url, bool updateable)
index 3115033..0ccb789 100644 (file)
@@ -186,12 +186,11 @@ private:
    */
   bool ClearCachedTexture(const CStdString &url, CStdString &cacheFile);
 
-  /*! \brief Increment the use count of a texture in the database
-   Thread-safe wrapper of CTextureDatabase::IncrementUseCount
-   \param details the texture to increment the use count
-   \return true on success, false otherwise
+  /*! \brief Increment the use count of a texture
+   Stores locally before calling CTextureDatabase::IncrementUseCount via a CUseCountJob
+   \sa CUseCountJob, CTextureDatabase::IncrementUseCount
    */
-  bool IncrementUseCount(const CTextureDetails &details);
+  void IncrementUseCount(const CTextureDetails &details);
 
   /*! \brief Set a previously cached texture as valid in the database
    Thread-safe wrapper of CTextureDatabase::SetCachedTextureValid
@@ -209,5 +208,7 @@ private:
   std::set<CStdString> m_processing; ///< currently processing list to avoid 2 jobs being processed at once
   CCriticalSection     m_processingSection;
   CEvent               m_completeEvent; ///< Set whenever a job has finished
+  std::vector<CTextureDetails> m_useCounts; ///< Use count tracking
+  CCriticalSection             m_useCountSection;
 };
 
index d24fcc2..24b873d 100644 (file)
@@ -247,3 +247,31 @@ bool CTextureDDSJob::DoWork()
   }
   return false;
 }
+
+CTextureUseCountJob::CTextureUseCountJob(const std::vector<CTextureDetails> &textures) : m_textures(textures)
+{
+}
+
+bool CTextureUseCountJob::operator==(const CJob* job) const
+{
+  if (strcmp(job->GetType(),GetType()) == 0)
+  {
+    const CTextureUseCountJob* useJob = dynamic_cast<const CTextureUseCountJob*>(job);
+    if (useJob && useJob->m_textures == m_textures)
+      return true;
+  }
+  return false;
+}
+
+bool CTextureUseCountJob::DoWork()
+{
+  CTextureDatabase db;
+  if (db.Open())
+  {
+    db.BeginTransaction();
+    for (std::vector<CTextureDetails>::const_iterator i = m_textures.begin(); i != m_textures.end(); ++i)
+      db.IncrementUseCount(*i);
+    db.CommitTransaction();
+  }
+  return true;
+}
index f342dbe..c405610 100644 (file)
@@ -39,6 +39,12 @@ public:
     width = height = 0;
     updateable = false;
   };
+  bool operator==(const CTextureDetails &right) const
+  {
+    return (id    == right.id    &&
+            file  == right.file  &&
+            width == right.width );
+  };
   int          id;
   std::string  file;
   std::string  hash;
@@ -128,3 +134,18 @@ public:
 
   CStdString m_original;
 };
+
+/* \brief Job class for storing the use count of textures
+ */
+class CTextureUseCountJob : public CJob
+{
+public:
+  CTextureUseCountJob(const std::vector<CTextureDetails> &textures);
+
+  virtual const char* GetType() const { return "usecount"; };
+  virtual bool operator==(const CJob *job) const;
+  virtual bool DoWork();
+
+private:
+  std::vector<CTextureDetails> m_textures;
+};