Exemple #1
0
CBaseTexture *CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int idealWidth, unsigned int idealHeight, bool autoRotate)
{
#if defined(TARGET_ANDROID)
  CURL url(texturePath);
  if (url.GetProtocol() == "androidapp")
  {
    XFILE::CFileAndroidApp file;
    if (file.Open(url))
    {
      unsigned int imgsize = (unsigned int)file.GetLength();
      unsigned char* inputBuff = new unsigned char[imgsize];
      unsigned int inputBuffSize = file.Read(inputBuff, imgsize);
      file.Close();
      if (inputBuffSize != imgsize)
      {
        delete [] inputBuff;
        return NULL;
      }
      CTexture *texture = new CTexture();
      unsigned int width = file.GetIconWidth();
      unsigned int height = file.GetIconHeight();
      texture->LoadFromMemory(width, height, width*4, XB_FMT_RGBA8, true, inputBuff);
      delete [] inputBuff;
      return texture;
    }
  }
#endif
  CTexture *texture = new CTexture();
  if (texture->LoadFromFileInternal(texturePath, idealWidth, idealHeight, autoRotate))
    return texture;
  delete texture;
  return NULL;
}
Exemple #2
0
CBaseTexture *CBaseTexture::LoadFromFile(const std::string& texturePath, unsigned int idealWidth, unsigned int idealHeight, bool requirePixels, const std::string& strMimeType)
{
#if defined(TARGET_ANDROID)
  CURL url(texturePath);
  if (url.IsProtocol("androidapp"))
  {
    XFILE::CFileAndroidApp file;
    if (file.Open(url))
    {
      unsigned char* inputBuff;
      unsigned int width;
      unsigned int height;
      unsigned int inputBuffSize = file.ReadIcon(&inputBuff, &width, &height);
      file.Close();
      if (!inputBuffSize)
        return NULL;

      CTexture *texture = new CTexture();
      texture->LoadFromMemory(width, height, width*4, XB_FMT_RGBA8, true, inputBuff);
      delete [] inputBuff;
      return texture;
    }
  }
#endif
  CTexture *texture = new CTexture();
  if (texture->LoadFromFileInternal(texturePath, idealWidth, idealHeight, requirePixels, strMimeType))
    return texture;
  delete texture;
  return NULL;
}
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();
}
Exemple #4
0
void CGUIWindowManager::BuildStencilBuffer(CGUIWindow* pWindow)
{
#if 0
  // test rendering the stencil buffer
  unsigned int width = g_graphicsContext.GetWidth();
  unsigned int height = g_graphicsContext.GetHeight();
#endif

  // build the topmost controls mask in the stencil buffer

  g_Windowing.ClearStencilBuffer(0);

  g_Windowing.EnableStencil(true);
  g_Windowing.SetColorMask(false, false, false, false);
  g_Windowing.SetStencilFunc(STENCIL_FUNC_ALWAYS, 1, 1);
  g_Windowing.SetStencilOp(STENCIL_OP_KEEP, STENCIL_OP_INCR, STENCIL_OP_INCR);

  if (pWindow)
    pWindow->Render();

  g_Windowing.SetColorMask(true, true, true, true);

  g_Windowing.SetStencilFunc(STENCIL_FUNC_EQUAL, 0, 1);
  g_Windowing.SetStencilOp(STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);

  if (pWindow)
    pWindow->Render();

  g_Windowing.EnableStencil(false);


  return;
#if 0

// TEST: render the stencil buffer on screen
  static unsigned char* stencilBuf = NULL;
  if(stencilBuf == NULL)
    stencilBuf = new unsigned char[width * height];

  static unsigned char* rgbBuf = NULL;
  if(rgbBuf == NULL)
    rgbBuf = new unsigned char[width * height * 4];

  memset(stencilBuf, 0, width * height);
  memset(rgbBuf, 0, width * height * 4);

  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glReadPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilBuf);

  int scale = 16;

  for(unsigned int j = 0; j < height; j++)
    for(unsigned int i = 0; i < width; i++)
    {
      int pos = j * width + i;
      rgbBuf[4 * pos + 0] = scale * stencilBuf[pos];
      rgbBuf[4 * pos + 1] = scale * stencilBuf[pos];
      rgbBuf[4 * pos + 2] = scale * stencilBuf[pos];
      rgbBuf[4 * pos + 3] = 255;
    }

  TransformMatrix mat;
  g_graphicsContext.PushTransform(mat, true);
  g_graphicsContext.PushViewPort(0, 0, 0, 0, false);
  g_graphicsContext.SetClipRegion(0, 0, 0, 0, false);

  CTexture texture;
  texture.LoadFromMemory((int)width, (int)height, width * 4,  XB_FMT_R8G8B8A8, rgbBuf);

  CTextureInfo textureInfo("");
  textureInfo.blendCenter = false;
  textureInfo.orientation = 3; // flipy
  CGUITexture guiTexture(0, 0, (float)width, (float)height, textureInfo, &texture);
  guiTexture.SetDiffuseColor(0xffffffff);
  guiTexture.Render();

  g_graphicsContext.PopTransform();
  g_graphicsContext.PopViewPort();
  g_graphicsContext.RestoreClipRegion();
#endif
}
Exemple #5
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();
}