Beispiel #1
0
void CGUITextureManager::PreLoad(const CStdString& strTextureName)
{
  if (strTextureName.c_str()[1] == ':' || strTextureName == "-")
    return ;

  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == strTextureName)
      return ;
  }

  for (int bundle = 0; bundle < 2; bundle++)
  {
    for (list<CStdString>::iterator i = m_PreLoadNames[bundle].begin(); i != m_PreLoadNames[bundle].end(); ++i)
    {
      if (*i == strTextureName)
        return ;
    }

    if (m_TexBundle[bundle].HasFile(strTextureName))
    {
      m_PreLoadNames[bundle].push_back(strTextureName);
      return;
    }
  }
}
Beispiel #2
0
bool CGUITextureManager::HasTexture(const CStdString &textureName, CStdString *path, int *bundle, int *size)
{
  // default values
  if (bundle) *bundle = -1;
  if (size) *size = 0;
  if (path) *path = textureName;

  if (textureName == "-")
    return false;
  if (textureName.Find("://") >= 0)
    return false;

  // first check of texture exists...
  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == textureName)
    {
      for (int i = 0; i < 2; i++)
      {
        if (m_iNextPreload[i] != m_PreLoadNames[i].end() && (*m_iNextPreload[i] == textureName))
        {
          ++m_iNextPreload[i];
          // preload next file
          if (m_iNextPreload[i] != m_PreLoadNames[i].end())
            m_TexBundle[i].PreloadFile(*m_iNextPreload[i]);
        }
      }
      if (size) *size = pMap->size();
      return true;
    }
  }

  for (int i = 0; i < 2; i++)
  {
    if (m_iNextPreload[i] != m_PreLoadNames[i].end() && (*m_iNextPreload[i] == textureName))
    {
      if (bundle) *bundle = i;
      ++m_iNextPreload[i];
      // preload next file
      if (m_iNextPreload[i] != m_PreLoadNames[i].end())
        m_TexBundle[i].PreloadFile(*m_iNextPreload[i]);
      return true;
    }
    else if (m_TexBundle[i].HasFile(textureName))
    {
      if (bundle) *bundle = i;
      return true;
    }
  }

  CStdString fullPath = GetTexturePath(textureName);
  if (path)
    *path = fullPath;

  return !fullPath.IsEmpty();
}
Beispiel #3
0
int CGUITextureManager::GetDelay(const CStdString& strTextureName, int iPicture) const
{
  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == strTextureName)
    {
      return pMap->GetDelay(iPicture);
    }
  }
  return 100;
}
Beispiel #4
0
CGLTexture* CGUITextureManager::GetTexture(const CStdString& strTextureName, int iItem, int& iWidth, int& iHeight, SDL_Palette*& pPal, bool &linearTexture)  
#endif
{
  //  CLog::Log(LOGINFO, " refcount++ for  GetTexture(%s)\n", strTextureName.c_str());
  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == strTextureName)
    {
      //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
      return pMap->GetTexture(iItem, iWidth, iHeight, pPal, linearTexture);
    }
  }
  return NULL;
}
Beispiel #5
0
const CTextureArray& CGUITextureManager::GetTexture(const CStdString& strTextureName)
{
  static CTextureArray emptyTexture;
  //  CLog::Log(LOGINFO, " refcount++ for  GetTexture(%s)\n", strTextureName.c_str());
  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == strTextureName)
    {
      //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
      return pMap->GetTexture();
    }
  }
  return emptyTexture;
}
Beispiel #6
0
void CGUITextureManager::Cleanup()
{
  CSingleLock lock(g_graphicsContext);

  ivecTextures i;
  i = m_vecTextures.begin();
  while (i != m_vecTextures.end())
  {
    CTextureMap* pMap = *i;
    CLog::Log(LOGWARNING, "%s: Having to cleanup texture %s", __FUNCTION__, pMap->GetName().c_str());
    delete pMap;
    i = m_vecTextures.erase(i);
  }
  for (int i = 0; i < 2; i++)
    m_TexBundle[i].Cleanup();
}
Beispiel #7
0
void CGUITextureManager::Cleanup()
{
  CSingleLock lock(g_graphicsContext);

  ivecTextures i;
  i = m_vecTextures.begin();
  while (i != m_vecTextures.end())
  {
    CTextureMap* pMap = *i;
    CLog::Log(LOGWARNING, "%s: Having to cleanup texture %s", __FUNCTION__, pMap->GetName().c_str());
    delete pMap;
    i = m_vecTextures.erase(i);
  }

  m_TexBundle[0] = CTextureBundle(true);
  m_TexBundle[1] = CTextureBundle();
  FreeUnusedTextures();
}
Beispiel #8
0
bool CGUITextureManager::HasTexture(const std::string &textureName, std::string *path, int *bundle, int *size)
{
  CSingleLock lock(m_section);

  // default values
  if (bundle) *bundle = -1;
  if (size) *size = 0;
  if (path) *path = textureName;

  if (textureName.empty())
    return false;

  if (!CanLoad(textureName))
    return false;

  // Check our loaded and bundled textures - we store in bundles using \\.
  std::string bundledName = CTextureBundle::Normalize(textureName);
  for (int i = 0; i < (int)m_vecTextures.size(); ++i)
  {
    CTextureMap *pMap = m_vecTextures[i];
    if (pMap->GetName() == textureName)
    {
      if (size) *size = 1;
      return true;
    }
  }

  for (int i = 0; i < 2; i++)
  {
    if (m_TexBundle[i].HasFile(bundledName))
    {
      if (bundle) *bundle = i;
      return true;
    }
  }

  std::string fullPath = GetTexturePath(textureName);
  if (path)
    *path = fullPath;

  return !fullPath.empty();
}
Beispiel #9
0
void CGUITextureManager::Flush()
{
    CSingleLock lock(g_graphicsContext);

    ivecTextures i;
    i = m_vecTextures.begin();
    while (i != m_vecTextures.end())
    {
        CTextureMap* pMap = *i;
        pMap->Flush();
        if (pMap->IsEmpty() )
        {
            delete pMap;
            i = m_vecTextures.erase(i);
        }
        else
        {
            ++i;
        }
    }
}
Beispiel #10
0
void CGUITextureManager::Flush()
{
  CSingleLock lock(CServiceBroker::GetWinSystem()->GetGfxContext());

  ivecTextures i;
  i = m_vecTextures.begin();
  while (i != m_vecTextures.end())
  {
    CTextureMap* pMap = *i;
    pMap->Flush();
    if (pMap->IsEmpty() )
    {
      delete pMap;
      i = m_vecTextures.erase(i);
    }
    else
    {
      ++i;
    }
  }
}
Beispiel #11
0
void CGUITextureManager::ReleaseTexture(const CStdString& strTextureName, int iPicture)
{
  CSingleLock lock(g_graphicsContext);

#ifndef _LINUX
  MEMORYSTATUS stat;
  GlobalMemoryStatus(&stat);
  DWORD dwMegFree = stat.dwAvailPhys / (1024 * 1024);
  if (dwMegFree > 29)
  {
    // dont release skin textures, they are reloaded each time
    //if (strTextureName.GetAt(1) != ':') return;
    //CLog::Log(LOGINFO, "release:%s", strTextureName.c_str());
  }
#endif

  ivecTextures i;
  i = m_vecTextures.begin();
  while (i != m_vecTextures.end())
  {
    CTextureMap* pMap = *i;
    if (pMap->GetName() == strTextureName)
    {
      pMap->Release(iPicture);

      if (pMap->IsEmpty() )
      {
        //CLog::Log(LOGINFO, "  cleanup:%s", strTextureName.c_str());
        delete pMap;
        i = m_vecTextures.erase(i);
      }
      return;
    }
    ++i;
  }
  CLog::Log(LOGWARNING, "%s: Unable to release texture %s", __FUNCTION__, strTextureName.c_str());
}
Beispiel #12
0
void CGUITextureManager::ReleaseTexture(const std::string& strTextureName, bool immediately /*= false */)
{
    CSingleLock lock(g_graphicsContext);

    ivecTextures i;
    i = m_vecTextures.begin();
    while (i != m_vecTextures.end())
    {
        CTextureMap* pMap = *i;
        if (pMap->GetName() == strTextureName)
        {
            if (pMap->Release())
            {
                //CLog::Log(LOGINFO, "  cleanup:%s", strTextureName.c_str());
                // add to our textures to free
                m_unusedTextures.push_back(std::make_pair(pMap, immediately ? 0 : XbmcThreads::SystemClockMillis()));
                i = m_vecTextures.erase(i);
            }
            return;
        }
        ++i;
    }
    CLog::Log(LOGWARNING, "%s: Unable to release texture %s", __FUNCTION__, strTextureName.c_str());
}
Beispiel #13
0
void CGUITextureManager::ReleaseTexture(const CStdString& strTextureName)
{
  CSingleLock lock(g_graphicsContext);

  ivecTextures i;
  i = m_vecTextures.begin();
  while (i != m_vecTextures.end())
  {
    CTextureMap* pMap = *i;
    if (pMap->GetName() == strTextureName)
    {
      if (pMap->Release())
      {
        //CLog::Log(LOGINFO, "  cleanup:%s", strTextureName.c_str());
        // add to our textures to free
        m_unusedTextures.push_back(pMap);
        i = m_vecTextures.erase(i);
      }
      return;
    }
    ++i;
  }
  CLog::Log(LOGWARNING, "%s: Unable to release texture %s", __FUNCTION__, strTextureName.c_str());
}
Beispiel #14
0
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */)
{
    std::string strPath;
    static CTextureArray emptyTexture;
    int bundle = -1;
    int size = 0;
    if (!HasTexture(strTextureName, &strPath, &bundle, &size))
        return emptyTexture;

    if (size) // we found the texture
    {
        for (int i = 0; i < (int)m_vecTextures.size(); ++i)
        {
            CTextureMap *pMap = m_vecTextures[i];
            if (pMap->GetName() == strTextureName)
            {
                //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
                return pMap->GetTexture();
            }
        }
        // Whoops, not there.
        return emptyTexture;
    }

    for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i)
    {
        CTextureMap* pMap = i->first;
        if (pMap->GetName() == strTextureName && i->second > 0)
        {
            m_vecTextures.push_back(pMap);
            m_unusedTextures.erase(i);
            return pMap->GetTexture();
        }
    }

    if (checkBundleOnly && bundle == -1)
        return emptyTexture;

    //Lock here, we will do stuff that could break rendering
    CSingleLock lock(g_graphicsContext);

#ifdef _DEBUG_TEXTURES
    int64_t start;
    start = CurrentHostCounter();
#endif

    if (bundle >= 0 && StringUtils::EndsWithNoCase(strPath, ".gif"))
    {
        CTextureMap* pMap = nullptr;
        CBaseTexture **pTextures = nullptr;
        int nLoops = 0, width = 0, height = 0;
        int* Delay = nullptr;
        int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay);
        if (!nImages)
        {
            CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
            delete[] pTextures;
            delete[] Delay;
            return emptyTexture;
        }

        unsigned int maxWidth = 0;
        unsigned int maxHeight = 0;
        pMap = new CTextureMap(strTextureName, width, height, nLoops);
        for (int iImage = 0; iImage < nImages; ++iImage)
        {
            pMap->Add(pTextures[iImage], Delay[iImage]);
            maxWidth = std::max(maxWidth, pTextures[iImage]->GetWidth());
            maxHeight = std::max(maxHeight, pTextures[iImage]->GetHeight());
        }

        pMap->SetWidth((int)maxWidth);
        pMap->SetHeight((int)maxHeight);

        delete[] pTextures;
        delete[] Delay;

        if (pMap)
        {
            m_vecTextures.push_back(pMap);
            return pMap->GetTexture();
        }
    }
    else if (StringUtils::EndsWithNoCase(strPath, ".gif") ||
             StringUtils::EndsWithNoCase(strPath, ".apng"))
    {
        CTextureMap* pMap = nullptr;

        std::string mimeType;
        if (StringUtils::EndsWithNoCase(strPath, ".gif"))
            mimeType = "image/gif";
        else if (StringUtils::EndsWithNoCase(strPath, ".apng"))
            mimeType = "image/apng";

        XFILE::CFile file;
        XFILE::auto_buffer buf;
        CFFmpegImage anim(mimeType);
        pMap = new CTextureMap(strTextureName, 0, 0, 0);

        if (file.LoadFile(strPath, buf) <= 0 ||
                !anim.Initialize((uint8_t*)buf.get(), buf.size()) || !pMap)
        {
            CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CURL::GetRedacted(strPath).c_str());
            file.Close();
            return emptyTexture;
        }

        unsigned int maxWidth = 0;
        unsigned int maxHeight = 0;
        uint64_t maxMemoryUsage = 91238400;// 1920*1080*4*11 bytes, i.e, a total of approx. 12 full hd frames

        auto frame = anim.ReadFrame();
        while (frame)
        {
            CTexture *glTexture = new CTexture();
            if (glTexture)
            {
                glTexture->LoadFromMemory(anim.Width(), anim.Height(), frame->GetPitch(), XB_FMT_A8R8G8B8, true, frame->m_pImage);
                pMap->Add(glTexture, frame->m_delay);
                maxWidth = std::max(maxWidth, glTexture->GetWidth());
                maxHeight = std::max(maxHeight, glTexture->GetHeight());
            }

            if (pMap->GetMemoryUsage() <= maxMemoryUsage)
            {
                frame = anim.ReadFrame();
            }
            else
            {
                CLog::Log(LOGDEBUG, "Memory limit (%" PRIu64 " bytes) exceeded, %i frames extracted from file : %s", (maxMemoryUsage/11)*12,pMap->GetTexture().size(), CURL::GetRedacted(strPath).c_str());
                break;
            }
        }

        pMap->SetWidth((int)maxWidth);
        pMap->SetHeight((int)maxHeight);

        file.Close();

        if (pMap)
        {
            m_vecTextures.push_back(pMap);
            return pMap->GetTexture();
        }
    }

    CBaseTexture *pTexture = NULL;
    int width = 0, height = 0;
    if (bundle >= 0)
    {
        if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height))
        {
            CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
            return emptyTexture;
        }
    }
    else
    {
        pTexture = CBaseTexture::LoadFromFile(strPath);
        if (!pTexture)
            return emptyTexture;
        width = pTexture->GetWidth();
        height = pTexture->GetHeight();
    }

    if (!pTexture) return emptyTexture;

    CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0);
    pMap->Add(pTexture, 100);
    m_vecTextures.push_back(pMap);

#ifdef _DEBUG_TEXTURES
    int64_t end, freq;
    end = CurrentHostCounter();
    freq = CurrentHostFrequency();
    char temp[200];
    sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
    OutputDebugString(temp);
#endif

    return pMap->GetTexture();
}
Beispiel #15
0
int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleOnly /*= false */)
{
  CStdString strPath;
  int bundle = -1;
  int size = 0;
  if (!HasTexture(strTextureName, &strPath, &bundle, &size))
    return 0;

  if (size) // we found the texture
    return size;

  if (checkBundleOnly && bundle == -1)
    return 0;

  //Lock here, we will do stuff that could break rendering
  CSingleLock lock(g_graphicsContext);

#ifdef _DEBUG
  int64_t start;
  start = CurrentHostCounter();
#endif

  if (strPath.Right(4).ToLower() == ".gif")
  {
    CTextureMap* pMap;

    if (bundle >= 0)
    {
      CBaseTexture **pTextures;
      int nLoops = 0, width = 0, height = 0;
      int* Delay;
      int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay);
      if (!nImages)
      {
        CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
        return 0;
      }

      pMap = new CTextureMap(strTextureName, width, height, nLoops);
      for (int iImage = 0; iImage < nImages; ++iImage)
      {
        pMap->Add(pTextures[iImage], Delay[iImage]);
      }

      delete [] pTextures;
      delete [] Delay;
    }
    else
    {
      CAnimatedGifSet AnimatedGifSet;
      int iImages = AnimatedGifSet.LoadGIF(strPath.c_str());
      if (iImages == 0)
      {
        CStdString rootPath = strPath.Left(g_SkinInfo->Path().GetLength());
        if (0 == rootPath.CompareNoCase(g_SkinInfo->Path()))
          CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
        return 0;
      }
      int iWidth = AnimatedGifSet.FrameWidth;
      int iHeight = AnimatedGifSet.FrameHeight;

      // fixup our palette
      COLOR *palette = AnimatedGifSet.m_vecimg[0]->Palette;
      // set the alpha values to fully opaque
      for (int i = 0; i < 256; i++)
        palette[i].x = 0xff;
      // and set the transparent colour
      if (AnimatedGifSet.m_vecimg[0]->Transparency && AnimatedGifSet.m_vecimg[0]->Transparent >= 0)
        palette[AnimatedGifSet.m_vecimg[0]->Transparent].x = 0;

      pMap = new CTextureMap(strTextureName, iWidth, iHeight, AnimatedGifSet.nLoops);

      for (int iImage = 0; iImage < iImages; iImage++)
      {
        CTexture *glTexture = new CTexture();
        if (glTexture)
        {
          CAnimatedGif* pImage = AnimatedGifSet.m_vecimg[iImage];
          glTexture->LoadPaletted(pImage->Width, pImage->Height, pImage->BytesPerRow, XB_FMT_A8R8G8B8, (unsigned char *)pImage->Raster, palette);
          pMap->Add(glTexture, pImage->Delay);
        }
      } // of for (int iImage=0; iImage < iImages; iImage++)
    }

#ifdef _DEBUG
    int64_t end, freq;
    end = CurrentHostCounter();
    freq = CurrentHostFrequency();
    char temp[200];
    sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
    OutputDebugString(temp);
#endif

    m_vecTextures.push_back(pMap);
    return 1;
  } // of if (strPath.Right(4).ToLower()==".gif")

  CBaseTexture *pTexture = NULL;
  int width = 0, height = 0;
  if (bundle >= 0)
  {
    if (FAILED(m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)))
    {
      CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
      return 0;
    }
  }
  else
  {
    pTexture = new CTexture();
    if(!pTexture->LoadFromFile(strPath))
      return 0;
    width = pTexture->GetWidth();
    height = pTexture->GetHeight();
  }

  if (!pTexture) return 0;

  CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0);
  pMap->Add(pTexture, 100);
  m_vecTextures.push_back(pMap);

#ifdef _DEBUG_TEXTURES
  int64_t end, freq;
  end = CurrentHostCounter();
  freq = CurrentHostFrequency();
  char temp[200];
  sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
  OutputDebugString(temp);
#endif

  return 1;
}
Beispiel #16
0
int CGUITextureManager::Load(const CStdString& strTextureName, DWORD dwColorKey, bool checkBundleOnly /*= false */)
{
  CStdString strPath;
  int bundle = -1;
  int size = 0;
  if (!HasTexture(strTextureName, &strPath, &bundle, &size))
    return 0;

  if (size) // we found the texture
    return size;

  // See if texture is being overridden.
  CStdString strTextureFile = strTextureName;
  CStdString strTextureOverridePath1;
  CStdString strTextureOverridePath2;
  CStdString strExt = CUtil::GetExtension(strTextureFile);
  CUtil::RemoveExtension(strTextureFile);
  
  // Check original format and JPEG.
  strTextureOverridePath1.Format("%s/media/%s%s", _P("Q:"), strTextureFile.c_str(), strExt.c_str());
  strTextureOverridePath2.Format("%s/media/%s.jpg", _P("Q:"), strTextureFile.c_str(), strExt.c_str());
  
  if (checkBundleOnly && bundle == -1)
    return 0;

  if (XFILE::CFile::Exists(strTextureOverridePath1))
    { strPath = strTextureOverridePath1; bundle = -1; }
  else if (XFILE::CFile::Exists(strTextureOverridePath2))
    { strPath = strTextureOverridePath2; bundle = -1; }
  else if (bundle == -1)
    strPath = GetTexturePath(strTextureName);
  else
    strPath = strTextureName;

  //Lock here, we will do stuff that could break rendering
  CSingleLock lock(g_graphicsContext);

#ifndef HAS_SDL
  LPDIRECT3DTEXTURE8 pTexture;
  LPDIRECT3DPALETTE8 pPal = 0;
#else
  SDL_Surface* pTexture;
  SDL_Palette* pPal = NULL;
#endif

#ifdef _DEBUG
  LARGE_INTEGER start;
  QueryPerformanceCounter(&start);
#endif

  D3DXIMAGE_INFO info;

  if (strPath.Right(4).ToLower() == ".gif")
  {
    CTextureMap* pMap;

    if (bundle >= 0)
    {
#ifndef HAS_SDL    
      LPDIRECT3DTEXTURE8* pTextures;
#else
      SDL_Surface** pTextures;
#endif
      int nLoops = 0;
      int* Delay;
#ifndef HAS_SDL
      int nImages = m_TexBundle[bundle].LoadAnim(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTextures, &pPal, nLoops, &Delay);
#else
      int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &info, &pTextures, &pPal, nLoops, &Delay);
#endif        
      if (!nImages)
      {
        CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
        return 0;
      }

      pMap = new CTextureMap(strTextureName);
      for (int iImage = 0; iImage < nImages; ++iImage)
      {
        CTexture* pclsTexture = new CTexture(pTextures[iImage], info.Width, info.Height, true, 100, pPal);
        pclsTexture->SetDelay(Delay[iImage]);
        pclsTexture->SetLoops(nLoops);
        pMap->Add(pclsTexture);
#ifndef HAS_SDL
        delete pTextures[iImage];
#else
        SDL_FreeSurface(pTextures[iImage]);
#endif
      }

      delete [] pTextures;
      delete [] Delay;
    }
    else
    {
      CAnimatedGifSet AnimatedGifSet;
      int iImages = AnimatedGifSet.LoadGIF(strPath.c_str());
      if (iImages == 0)
      {
        if (!strnicmp(strPath.c_str(), "q:\\skin", 7))
          CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
        return 0;
      }
      int iWidth = AnimatedGifSet.FrameWidth;
      int iHeight = AnimatedGifSet.FrameHeight;

      int iPaletteSize = (1 << AnimatedGifSet.m_vecimg[0]->BPP);
      pMap = new CTextureMap(strTextureName);

      for (int iImage = 0; iImage < iImages; iImage++)
      {
        int w = iWidth;
        int h = iHeight;

#if defined(HAS_SDL)
        pTexture = SDL_CreateRGBSurface(SDL_HWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        if (pTexture)
#else
        if (D3DXCreateTexture(g_graphicsContext.Get3DDevice(), w, h, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED, &pTexture) == D3D_OK)
#endif
        {
          CAnimatedGif* pImage = AnimatedGifSet.m_vecimg[iImage];
#ifndef HAS_SDL          
          D3DLOCKED_RECT lr;
          RECT rc = { 0, 0, pImage->Width, pImage->Height };
          if ( D3D_OK == pTexture->LockRect( 0, &lr, &rc, 0 ))
#else
          if (SDL_LockSurface(pTexture) != -1)
#endif          
          {
            COLOR *palette = AnimatedGifSet.m_vecimg[0]->Palette;
            // set the alpha values to fully opaque
            for (int i = 0; i < iPaletteSize; i++)
              palette[i].x = 0xff;
            // and set the transparent colour
            if (AnimatedGifSet.m_vecimg[0]->Transparency && AnimatedGifSet.m_vecimg[0]->Transparent >= 0)
              palette[AnimatedGifSet.m_vecimg[0]->Transparent].x = 0;
            
#ifdef HAS_SDL
            // Allocate memory for the actual pixels in the surface and set the surface
            BYTE* pixels = (BYTE*) malloc(w * h * 4);
            pTexture->pixels = pixels;
#endif            
            for (int y = 0; y < pImage->Height; y++)
            {
#ifndef HAS_SDL            
              BYTE *dest = (BYTE *)lr.pBits + y * lr.Pitch;
#else
              BYTE *dest = (BYTE *)pixels + (y * w * 4); 
#endif
              BYTE *source = (BYTE *)pImage->Raster + y * pImage->BytesPerRow;
              for (int x = 0; x < pImage->Width; x++)
              {
                COLOR col = palette[*source++];
                *dest++ = col.b;
                *dest++ = col.g;
                *dest++ = col.r;
                *dest++ = col.x;
              }
            }

#ifndef HAS_SDL
            pTexture->UnlockRect( 0 );
#else
            SDL_UnlockSurface(pTexture);
#endif            

            CTexture* pclsTexture = new CTexture(pTexture, iWidth, iHeight, false, 100, pPal);
            pclsTexture->SetDelay(pImage->Delay);
            pclsTexture->SetLoops(AnimatedGifSet.nLoops);

#ifdef HAS_SDL
            free(pixels);
#endif

#ifdef HAS_SDL_2D
            SDL_FreeSurface(pTexture);
#endif
            
            pMap->Add(pclsTexture);
          }
        }
      } // of for (int iImage=0; iImage < iImages; iImage++)
    }

#ifdef _DEBUG
    LARGE_INTEGER end, freq;
    QueryPerformanceCounter(&end);
    QueryPerformanceFrequency(&freq);
    char temp[200];
    sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : "");
    OutputDebugString(temp);
#endif

    m_vecTextures.push_back(pMap);
    return pMap->size();
  } // of if (strPath.Right(4).ToLower()==".gif")

  if (bundle >= 0)
  {
#ifndef HAS_SDL
    if (FAILED(m_TexBundle[bundle].LoadTexture(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTexture, &pPal)))
#else    
    if (FAILED(m_TexBundle[bundle].LoadTexture(strTextureName, &info, &pTexture, &pPal)))
#endif    
    {
      CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
      return 0;
    }
  }
  else
  {
    // normal picture
    // convert from utf8
    CStdString texturePath;
    g_charsetConverter.utf8ToStringCharset(_P(strPath), texturePath);
    
#ifndef HAS_SDL
    if ( D3DXCreateTextureFromFileEx(g_graphicsContext.Get3DDevice(), texturePath.c_str(),
                                      D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED,
                                      D3DX_FILTER_NONE , D3DX_FILTER_NONE, dwColorKey, &info, NULL, &pTexture) != D3D_OK)
    {
      if (!strnicmp(strPath.c_str(), "q:\\skin", 7))
        CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
      return 0;

    }
#else
    SDL_Surface *original = IMG_Load(texturePath.c_str());
    CPicture pic;
    if (!original && !(original = pic.Load(texturePath, MAX_PICTURE_WIDTH, MAX_PICTURE_HEIGHT)))
    {
        CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
        return 0;
    }
    // make sure the texture format is correct
    SDL_PixelFormat format;
    format.palette = 0; format.colorkey = 0; format.alpha = 0;
    format.BitsPerPixel = 32; format.BytesPerPixel = 4;
    format.Amask = 0xff000000; format.Ashift = 24;
    format.Rmask = 0x00ff0000; format.Rshift = 16;
    format.Gmask = 0x0000ff00; format.Gshift = 8;
    format.Bmask = 0x000000ff; format.Bshift = 0;
#ifdef HAS_SDL_OPENGL
    pTexture = SDL_ConvertSurface(original, &format, SDL_SWSURFACE);
#else
    pTexture = SDL_ConvertSurface(original, &format, SDL_HWSURFACE);
#endif
    SDL_FreeSurface(original);
    if (!pTexture)
    {
      CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
      return 0;
    }
    info.Width = pTexture->w;
    info.Height = pTexture->h;
#endif
  }

  CTextureMap* pMap = new CTextureMap(strTextureName);
  CTexture* pclsTexture = new CTexture(pTexture, info.Width, info.Height, bundle >= 0, 100, pPal);
  pMap->Add(pclsTexture);
  m_vecTextures.push_back(pMap);

#ifdef HAS_SDL_OPENGL
  SDL_FreeSurface(pTexture);
#endif    

#ifdef _DEBUG
  LARGE_INTEGER end, freq;
  QueryPerformanceCounter(&end);
  QueryPerformanceFrequency(&freq);
  char temp[200];
  sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : "");
  OutputDebugString(temp);
#endif

  return 1;
}
Beispiel #17
0
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */)
{
  std::string strPath;
  static CTextureArray emptyTexture;
  int bundle = -1;
  int size = 0;
  if (!HasTexture(strTextureName, &strPath, &bundle, &size))
    return emptyTexture;

  if (size) // we found the texture
  {
    for (int i = 0; i < (int)m_vecTextures.size(); ++i)
    {
      CTextureMap *pMap = m_vecTextures[i];
      if (pMap->GetName() == strTextureName)
      {
        //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
        return pMap->GetTexture();
      }
    }
    // Whoops, not there.
    return emptyTexture;
  }

  for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i)
  {
    CTextureMap* pMap = i->first;
    if (pMap->GetName() == strTextureName && i->second > 0)
    {
      m_vecTextures.push_back(pMap);
      m_unusedTextures.erase(i);
      return pMap->GetTexture();
    }
  }

  if (checkBundleOnly && bundle == -1)
    return emptyTexture;

  //Lock here, we will do stuff that could break rendering
  CSingleLock lock(g_graphicsContext);

#ifdef _DEBUG_TEXTURES
  int64_t start;
  start = CurrentHostCounter();
#endif

  if (StringUtils::EndsWithNoCase(strPath, ".gif"))
  {
    CTextureMap* pMap = nullptr;

    if (bundle >= 0)
    {
      CBaseTexture **pTextures;
      int nLoops = 0, width = 0, height = 0;
      int* Delay;
      int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay);
      if (!nImages)
      {
        CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
        delete [] pTextures;
        delete [] Delay;
        return emptyTexture;
      }

      pMap = new CTextureMap(strTextureName, width, height, nLoops);
      for (int iImage = 0; iImage < nImages; ++iImage)
      {
        pMap->Add(pTextures[iImage], Delay[iImage]);
      }

      delete [] pTextures;
      delete [] Delay;
    }
    else
    {
#if defined(HAS_GIFLIB)
      Gif gif;
      if(!gif.LoadGif(strPath.c_str()))
      {
        if (StringUtils::StartsWith(strPath, g_SkinInfo->Path()))
          CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
        return emptyTexture;
      }

      pMap = new CTextureMap(strTextureName, gif.Width(), gif.Height(), gif.GetNumLoops());

      for (auto frame : gif.GetFrames())
      {
        CTexture *glTexture = new CTexture();
        if (glTexture)
        {
          glTexture->LoadFromMemory(gif.Width(), gif.Height(), gif.GetPitch(), XB_FMT_A8R8G8B8, false, frame->m_pImage);
          pMap->Add(glTexture, frame->m_delay);
        }
      }
#endif//HAS_GIFLIB
    }

    if (pMap)
    {
      m_vecTextures.push_back(pMap);
      return pMap->GetTexture();
    }
  } // of if (strPath.Right(4).ToLower()==".gif")

  CBaseTexture *pTexture = NULL;
  int width = 0, height = 0;
  if (bundle >= 0)
  {
    if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height))
    {
      CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
      return emptyTexture;
    }
  }
  else
  {
    pTexture = CBaseTexture::LoadFromFile(strPath);
    if (!pTexture)
      return emptyTexture;
    width = pTexture->GetWidth();
    height = pTexture->GetHeight();
  }

  if (!pTexture) return emptyTexture;

  CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0);
  pMap->Add(pTexture, 100);
  m_vecTextures.push_back(pMap);

#ifdef _DEBUG_TEXTURES
  int64_t end, freq;
  end = CurrentHostCounter();
  freq = CurrentHostFrequency();
  char temp[200];
  sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
  OutputDebugString(temp);
#endif

  return pMap->GetTexture();
}