예제 #1
0
CBaseTexture *CTextureCacheJob::LoadImage(const CStdString &image, unsigned int width, unsigned int height, const std::string &additional_info)
{
  if (additional_info == "music")
  { // special case for embedded music images
    MUSIC_INFO::EmbeddedArt art;
    if (CMusicThumbLoader::GetEmbeddedThumb(image, art))
      return CBaseTexture::LoadFromFileInMemory(&art.data[0], art.size, art.mime, width, height);
  }

  // Validate file URL to see if it is an image
  CFileItem file(image, false);
  if (!(file.IsPicture() && !(file.IsZIP() || file.IsRAR() || file.IsCBR() || file.IsCBZ() ))
      && !file.GetMimeType().Left(6).Equals("image/") && !file.GetMimeType().Equals("application/octet-stream")) // ignore non-pictures
    return NULL;

  CBaseTexture *texture = CBaseTexture::LoadFromFile(image, width, height, g_guiSettings.GetBool("pictures.useexifrotation"));
  if (!texture)
    return NULL;

  // EXIF bits are interpreted as: <flipXY><flipY*flipX><flipX>
  // where to undo the operation we apply them in reverse order <flipX>*<flipY*flipX>*<flipXY>
  // When flipped we have an additional <flipX> on the left, which is equivalent to toggling the last bit
  if (additional_info == "flipped")
    texture->SetOrientation(texture->GetOrientation() ^ 1);

  return texture;
}
예제 #2
0
파일: Picture.cpp 프로젝트: Elzevir/xbmc
bool CPicture::CreateTiledThumb(const std::vector<std::string> &files, const std::string &thumb)
{
  if (!files.size())
    return false;

  unsigned int num_across = (unsigned int)ceil(sqrt((float)files.size()));
  unsigned int num_down = (files.size() + num_across - 1) / num_across;

  unsigned int tile_width = g_advancedSettings.m_imageRes / num_across;
  unsigned int tile_height = g_advancedSettings.m_imageRes / num_down;
  unsigned int tile_gap = 1;
  bool success = false;

  // create a buffer for the resulting thumb
  uint32_t *buffer = (uint32_t *)calloc(g_advancedSettings.m_imageRes * g_advancedSettings.m_imageRes, 4);
  for (unsigned int i = 0; i < files.size(); ++i)
  {
    int x = i % num_across;
    int y = i / num_across;
    // load in the image
    unsigned int width = tile_width - 2*tile_gap, height = tile_height - 2*tile_gap;
    CBaseTexture *texture = CTexture::LoadFromFile(files[i], width, height, true);
    if (texture && texture->GetWidth() && texture->GetHeight())
    {
      GetScale(texture->GetWidth(), texture->GetHeight(), width, height);

      // scale appropriately
      uint32_t *scaled = new uint32_t[width * height];
      if (ScaleImage(texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(),
                     (uint8_t *)scaled, width, height, width * 4))
      {
        if (!texture->GetOrientation() || OrientateImage(scaled, width, height, texture->GetOrientation()))
        {
          success = true; // Flag that we at least had one successful image processed
          // drop into the texture
          unsigned int posX = x*tile_width + (tile_width - width)/2;
          unsigned int posY = y*tile_height + (tile_height - height)/2;
          uint32_t *dest = buffer + posX + posY*g_advancedSettings.m_imageRes;
          uint32_t *src = scaled;
          for (unsigned int y = 0; y < height; ++y)
          {
            memcpy(dest, src, width*4);
            dest += g_advancedSettings.m_imageRes;
            src += width;
          }
        }
      }
      delete[] scaled;
    }
    delete texture;
  }
  // now save to a file
  if (success)
    success = CreateThumbnailFromSurface((uint8_t *)buffer, g_advancedSettings.m_imageRes, g_advancedSettings.m_imageRes,
                                      g_advancedSettings.m_imageRes * 4, thumb);

  free(buffer);
  return success;
}
예제 #3
0
void TextureCreate(CCallParams& p) //создание текстуры и загрузка картинки
{
	CBaseOglControl* ctrl = CBaseOglControl::controls[WindowFromDC(wglGetCurrentDC())];
	if (0 == ctrl || p.AsString(0) == "")return;
	ctrl->Collection().TextureList().Create(p.AsString(0));
	CBaseTexture* tex = GetTexture(p.AsString(0));
	if (tex != 0) tex->LoadTexture(p.AsString(1));
}
예제 #4
0
void TextureCreateEmpty (CCallParams& p)
{
	CBaseOglControl* ctrl = CBaseOglControl::controls[WindowFromDC(wglGetCurrentDC())];
	if (0 == ctrl || p.AsString(0) == "")return;
	ctrl->Collection().TextureList().Create(p.AsString(0));
	CBaseTexture* tex = GetTexture(p.AsString(0));
	if (tex != 0) tex->CreateEmpty(p.AsInt(1), p.AsInt(2));
}
예제 #5
0
void CGUITextureD3D::Begin(color_t color)
{
  CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
  LPDIRECT3DDEVICE9 p3DDevice = g_Windowing.Get3DDevice();

  texture->LoadToGPU();
  if (m_diffuse.size())
    m_diffuse.m_textures[0]->LoadToGPU();
  // Set state to render the image
  p3DDevice->SetTexture( 0, texture->GetTextureObject() );
  p3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  p3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  p3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  p3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  p3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  p3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
  p3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
  if (m_diffuse.size())
  {
    p3DDevice->SetTexture( 1, m_diffuse.m_textures[0]->GetTextureObject() );
    p3DDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    p3DDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    p3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    p3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
    p3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
    p3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    p3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
    p3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
    p3DDevice->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
    p3DDevice->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
    p3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
    p3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  }
  else
  {
    p3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
    p3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  }
  p3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
  p3DDevice->SetRenderState( D3DRS_ALPHAREF, 0 );
  p3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
  p3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
  p3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  p3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
  p3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  p3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  p3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  p3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  p3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  p3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);

  p3DDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 );
  m_col = color;
}
예제 #6
0
void CGUITextureGL::Begin(UTILS::Color color)
{
  CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
  texture->LoadToGPU();
  if (m_diffuse.size())
    m_diffuse.m_textures[0]->LoadToGPU();

  texture->BindToUnit(0);

  // Setup Colors
  m_col[0] = (GLubyte)GET_R(color);
  m_col[1] = (GLubyte)GET_G(color);
  m_col[2] = (GLubyte)GET_B(color);
  m_col[3] = (GLubyte)GET_A(color);

  bool hasAlpha = m_texture.m_textures[m_currentFrame]->HasAlpha() || m_col[3] < 255;

  if (m_diffuse.size())
  {
    if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255 )
    {
      m_renderSystem->EnableShader(SM_MULTI);
    }
    else
    {
      m_renderSystem->EnableShader(SM_MULTI_BLENDCOLOR);
    }

    hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();

    m_diffuse.m_textures[0]->BindToUnit(1);
  }
  else
  {
    if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255)
    {
      m_renderSystem->EnableShader(SM_TEXTURE_NOBLEND);
    }
    else
    {
      m_renderSystem->EnableShader(SM_TEXTURE);
    }
  }

  if (hasAlpha)
  {
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
    glEnable(GL_BLEND);
  }
  else
  {
    glDisable(GL_BLEND);
  }
  m_packedVertices.clear();
  m_idx.clear();
}
예제 #7
0
void CGUITextureD3D::Begin(color_t color)
{
  CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
  texture->LoadToGPU();

  if (m_diffuse.size()) 
	  m_diffuse.m_textures[0]->LoadToGPU();

  m_col = color;

  DX::Windowing().SetAlphaBlendEnable(true);
}
예제 #8
0
bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
{
  // unwrap the URL as required
  std::string additional_info;
  unsigned int width, height;
  CPictureScalingAlgorithm::Algorithm scalingAlgorithm;
  std::string image = DecodeImageURL(m_url, width, height, scalingAlgorithm, additional_info);

  m_details.updateable = additional_info != "music" && UpdateableURL(image);

  // generate the hash
  m_details.hash = GetImageHash(image);
  if (m_details.hash.empty())
    return false;
  else if (m_details.hash == m_oldHash)
    return true;

#if defined(HAS_OMXPLAYER)
  if (COMXImage::CreateThumb(image, width, height, additional_info, CTextureCache::GetCachedPath(m_cachePath + ".jpg")))
  {
    m_details.width = width;
    m_details.height = height;
    m_details.file = m_cachePath + ".jpg";
    if (out_texture)
      *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, "" /* already flipped */);
    CLog::Log(LOGDEBUG, "Fast %s image '%s' to '%s': %p", m_oldHash.empty() ? "Caching" : "Recaching", CURL::GetRedacted(image).c_str(), m_details.file.c_str(), out_texture);
    return true;
  }
#endif
  CBaseTexture *texture = LoadImage(image, width, height, additional_info, true);
  if (texture)
  {
    if (texture->HasAlpha())
      m_details.file = m_cachePath + ".png";
    else
      m_details.file = m_cachePath + ".jpg";

    CLog::Log(LOGDEBUG, "%s image '%s' to '%s':", m_oldHash.empty() ? "Caching" : "Recaching", CURL::GetRedacted(image).c_str(), m_details.file.c_str());

    if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file), scalingAlgorithm))
    {
      m_details.width = width;
      m_details.height = height;
      if (out_texture) // caller wants the texture
        *out_texture = texture;
      else
        delete texture;
      return true;
    }
  }
  delete texture;
  return false;
}
예제 #9
0
CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight)
{
  newHeight = CBaseTexture::PadPow2(newHeight);

  CBaseTexture* newTexture = new CTexture(m_textureWidth, newHeight, XB_FMT_A8);

  if (!newTexture || newTexture->GetPixels() == NULL)
  {
    CLog::Log(LOGERROR, "GUIFontTTFGL::CacheCharacter: Error creating new cache texture for size %f", m_height);
    return NULL;
  }
  m_textureHeight = newTexture->GetHeight();
  m_textureWidth = newTexture->GetWidth();

  memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch());
  if (m_texture)
  {
    unsigned char* src = (unsigned char*) m_texture->GetPixels();
    unsigned char* dst = (unsigned char*) newTexture->GetPixels();
    for (unsigned int y = 0; y < m_texture->GetHeight(); y++)
    {
      memcpy(dst, src, m_texture->GetPitch());
      src += m_texture->GetPitch();
      dst += newTexture->GetPitch();
    }
    delete m_texture;
  }

  return newTexture;
}
예제 #10
0
bool CTextureDDSJob::DoWork()
{
  if (URIUtils::GetExtension(m_original).Equals(".dds"))
    return false;
  CBaseTexture *texture = CBaseTexture::LoadFromFile(m_original);
  if (texture)
  { // convert to DDS
    CDDSImage dds;
    CLog::Log(LOGDEBUG, "Creating DDS version of: %s", m_original.c_str());
    bool ret = dds.Create(URIUtils::ReplaceExtension(m_original, ".dds"), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(), texture->GetPixels(), 40);
    delete texture;
    return ret;
  }
  return false;
}
예제 #11
0
void CGUITextureGL::Begin(color_t color)
{
  m_col[0] = (GLubyte)GET_R(color);
  m_col[1] = (GLubyte)GET_G(color);
  m_col[2] = (GLubyte)GET_B(color);
  m_col[3] = (GLubyte)GET_A(color);

  CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
  glActiveTextureARB(GL_TEXTURE0_ARB);
  texture->LoadToGPU();
  if (m_diffuse.size())
    m_diffuse.m_textures[0]->LoadToGPU();

  glBindTexture(GL_TEXTURE_2D, texture->GetTextureObject());
  glEnable(GL_TEXTURE_2D);

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);          // Turn Blending On
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  // diffuse coloring
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  VerifyGLState();

  if (m_diffuse.size())
  {
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glBindTexture(GL_TEXTURE_2D, m_diffuse.m_textures[0]->GetTextureObject());
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
    VerifyGLState();
  }
  //glDisable(GL_TEXTURE_2D); // uncomment these 2 lines to switch to wireframe rendering
  //glBegin(GL_LINE_LOOP);
  glBegin(GL_QUADS);
}
예제 #12
0
bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
{
  // unwrap the URL as required
  bool flipped;
  unsigned int width, height;
  CStdString image = DecodeImageURL(m_url, width, height, flipped);

  m_details.updateable = UpdateableURL(image);

  // generate the hash
  m_details.hash = GetImageHash(image);
  if (m_details.hash.empty())
    return false;
  else if (m_details.hash == m_oldHash)
    return true;

  CBaseTexture *texture = LoadImage(image, width, height, flipped);
  if (texture)
  {
    if (texture->HasAlpha())
      m_details.file = m_cachePath + ".png";
    else
      m_details.file = m_cachePath + ".jpg";

    if (width > 0 && height > 0)
      CLog::Log(LOGDEBUG, "%s image '%s' at %dx%d with orientation %d as '%s'", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(),
                width, height, texture->GetOrientation(), m_details.file.c_str());
    else
      CLog::Log(LOGDEBUG, "%s image '%s' fullsize with orientation %d as '%s'", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(),
                texture->GetOrientation(), m_details.file.c_str());

    if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file)))
    {
      m_details.width = width;
      m_details.height = height;
      if (out_texture) // caller wants the texture
        *out_texture = texture;
      else
        delete texture;
      return true;
    }
  }
  delete texture;
  return false;
}
예제 #13
0
bool CEdenVideoArtUpdater::CacheTexture(std::string &originalUrl, const std::string &cachedFile, const std::string &label, std::string &type)
{
  if (!CFile::Exists(cachedFile))
  {
    CLog::Log(LOGERROR, "%s No cached art for item %s (should be %s)", __FUNCTION__, label.c_str(), cachedFile.c_str());
    return false;
  }
  if (originalUrl.empty())
  {
    originalUrl = GetThumb(cachedFile, "http://unknown/video/", true);
    CLog::Log(LOGERROR, "%s No original url for item %s, but cached art exists, using %s", __FUNCTION__, label.c_str(), originalUrl.c_str());
  }

  CTextureDetails details;
  details.updateable = false;
  details.hash = "NOHASH";
  type = "thumb"; // unknown art type

  CBaseTexture *texture = CTextureCacheJob::LoadImage(cachedFile, 0, 0, "");
  if (texture)
  {
    if (texture->HasAlpha())
      details.file = CTextureCache::GetCacheFile(originalUrl) + ".png";
    else
      details.file = CTextureCache::GetCacheFile(originalUrl) + ".jpg";

    CLog::Log(LOGDEBUG, "Caching image '%s' ('%s') to '%s' for item '%s'", originalUrl.c_str(), cachedFile.c_str(), details.file.c_str(), label.c_str());

    uint32_t width = 0, height = 0;
    if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(details.file)))
    {
      details.width = width;
      details.height = height;
      type = CVideoInfoScanner::GetArtTypeFromSize(details.width, details.height);
      delete texture;
      m_textureDB.AddCachedTexture(originalUrl, details);
      return true;
    }
  }
  CLog::Log(LOGERROR, "Can't cache image '%s' ('%s') for item '%s'", originalUrl.c_str(), cachedFile.c_str(), label.c_str());
  return false;
}
예제 #14
0
bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
{
  // unwrap the URL as required
  std::string additional_info;
  unsigned int width, height;
  CStdString image = DecodeImageURL(m_url, width, height, additional_info);

  m_details.updateable = additional_info != "music" && UpdateableURL(image);

  // generate the hash
  m_details.hash = GetImageHash(image);
  if (m_details.hash.empty())
    return false;
  else if (m_details.hash == m_oldHash)
    return true;

  CBaseTexture *texture = LoadImage(image, width, height, additional_info);
  if (texture)
  {
    if (texture->HasAlpha())
      m_details.file = m_cachePath + ".png";
    else
      m_details.file = m_cachePath + ".jpg";

    CLog::Log(LOGDEBUG, "%s image '%s' to '%s':", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(), m_details.file.c_str());

    if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file)))
    {
      m_details.width = width;
      m_details.height = height;
      if (out_texture) // caller wants the texture
        *out_texture = texture;
      else
        delete texture;
      return true;
    }
  }
  delete texture;
  return false;
}
예제 #15
0
bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction)
{
  RESOLUTION_INFO& desktop = g_settings.m_ResInfo[RES_DESKTOP];

  if (fullScreen &&
      (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight ||
       res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen))
  {
    //on the first call to SDL_SetVideoMode, SDL stores the current displaymode
    //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode
    //before the first call to SDL_SetVideoMode, SDL changes the displaymode back
    //to the wrong mode on exit

    CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first");
    if (!SetFullScreen(true, desktop, false))
      return false;
  }

  if(!SetFullScreen(fullScreen, res, false))
    return false;

  CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon.png");

  if (iconTexture)
    SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL);
  SDL_WM_SetCaption("XBMC Media Center", NULL);
  delete iconTexture;

  // register XRandR Events
#if defined(HAS_XRANDR)
  int iReturn;
  XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn);
  XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask);
#endif

  m_bWindowCreated = true;
  return true;
}
예제 #16
0
void CBackgroundPicLoader::Process()
{
  unsigned int totalTime = 0;
  unsigned int count = 0;
  while (!m_bStop)
  { // loop around forever, waiting for the app to call LoadPic
    if (AbortableWait(m_loadPic,10) == WAIT_SIGNALED)
    {
      if (m_pCallback)
      {
        unsigned int start = XbmcThreads::SystemClockMillis();
        CBaseTexture* texture = new CTexture();
        unsigned int originalWidth = 0;
        unsigned int originalHeight = 0;
        texture->LoadFromFile(m_strFileName, m_maxWidth, m_maxHeight, g_guiSettings.GetBool("pictures.useexifrotation"), &originalWidth, &originalHeight);
        totalTime += XbmcThreads::SystemClockMillis() - start;
        count++;
        // tell our parent
        bool bFullSize = ((int)texture->GetWidth() < m_maxWidth) && ((int)texture->GetHeight() < m_maxHeight);
        if (!bFullSize)
        {
          int iSize = texture->GetWidth() * texture->GetHeight() - MAX_PICTURE_SIZE;
          if ((iSize + (int)texture->GetWidth() > 0) || (iSize + (int)texture->GetHeight() > 0))
            bFullSize = true;
          if (!bFullSize && texture->GetWidth() == g_Windowing.GetMaxTextureSize())
            bFullSize = true;
          if (!bFullSize && texture->GetHeight() == g_Windowing.GetMaxTextureSize())
            bFullSize = true;
        }
        m_pCallback->OnLoadPic(m_iPic, m_iSlideNumber, texture, originalWidth, originalHeight, bFullSize);
        m_isLoading = false;
      }
    }
  }
  if (count > 0)
    CLog::Log(LOGDEBUG, "Time for loading %u images: %u ms, average %u ms",
              count, totalTime, totalTime / count);
}
예제 #17
0
void CBackgroundPicLoader::Process()
{
  unsigned int totalTime = 0;
  unsigned int count = 0;
  while (!m_bStop)
  { // loop around forever, waiting for the app to call LoadPic
    if (AbortableWait(m_loadPic,10) == WAIT_SIGNALED)
    {
      if (m_pCallback)
      {
        unsigned int start = XbmcThreads::SystemClockMillis();
        CBaseTexture* texture = CTexture::LoadFromFile(m_strFileName, m_maxWidth, m_maxHeight);
        totalTime += XbmcThreads::SystemClockMillis() - start;
        count++;
        // tell our parent
        bool bFullSize = false;
        if (texture)
        {
          bFullSize = ((int)texture->GetWidth() < m_maxWidth) && ((int)texture->GetHeight() < m_maxHeight);
          if (!bFullSize)
          {
            int iSize = texture->GetWidth() * texture->GetHeight() - MAX_PICTURE_SIZE;
            if ((iSize + (int)texture->GetWidth() > 0) || (iSize + (int)texture->GetHeight() > 0))
              bFullSize = true;
            if (!bFullSize && texture->GetWidth() == CServiceBroker::GetRenderSystem()->GetMaxTextureSize())
              bFullSize = true;
            if (!bFullSize && texture->GetHeight() == CServiceBroker::GetRenderSystem()->GetMaxTextureSize())
              bFullSize = true;
          }
        }
        m_pCallback->OnLoadPic(m_iPic, m_iSlideNumber, m_strFileName, texture, bFullSize);
        m_isLoading = false;
      }
    }
  }
  if (count > 0)
    CLog::Log(LOGDEBUG, "Time for loading %u images: %u ms, average %u ms",
              count, totalTime, totalTime / count);
}
예제 #18
0
CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight)
{
  newHeight = CBaseTexture::PadPow2(newHeight);

  CBaseTexture* newTexture = new CTexture(m_textureWidth, newHeight, XB_FMT_A8);

  if (!newTexture || newTexture->GetPixels() == NULL)
  {
    CLog::Log(LOGERROR, "GUIFontTTFGL::CacheCharacter: Error creating new cache texture for size %f", m_height);
    delete newTexture;
    return NULL;
  }
  m_textureHeight = newTexture->GetHeight();
  m_textureScaleY = 1.0f / m_textureHeight;
  m_textureWidth = newTexture->GetWidth();
  m_textureScaleX = 1.0f / m_textureWidth;
  if (m_textureHeight < newHeight)
    CLog::Log(LOGWARNING, "%s: allocated new texture with height of %d, requested %d", __FUNCTION__, m_textureHeight, newHeight);
  m_staticCache.Flush();
  m_dynamicCache.Flush();

  memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch());
  if (m_texture)
  {
    m_updateY1 = 0;
    m_updateY2 = m_texture->GetHeight();

    unsigned char* src = (unsigned char*) m_texture->GetPixels();
    unsigned char* dst = (unsigned char*) newTexture->GetPixels();
    for (unsigned int y = 0; y < m_texture->GetHeight(); y++)
    {
      memcpy(dst, src, m_texture->GetPitch());
      src += m_texture->GetPitch();
      dst += newTexture->GetPitch();
    }
    delete m_texture;
  }

  m_textureStatus = TEXTURE_REALLOCATED;

  return newTexture;
}
예제 #19
0
void CGUITextureGLES::Begin(color_t color)
{
    CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
    glActiveTexture(GL_TEXTURE0);
    texture->LoadToGPU();
    if (m_diffuse.size())
        m_diffuse.m_textures[0]->LoadToGPU();

    glBindTexture(GL_TEXTURE_2D, texture->GetTextureObject());

    // Setup Colors
    for (int i = 0; i < 4; i++)
    {
        m_col[i][0] = (GLubyte)GET_R(color);
        m_col[i][1] = (GLubyte)GET_G(color);
        m_col[i][2] = (GLubyte)GET_B(color);
        m_col[i][3] = (GLubyte)GET_A(color);
    }

    bool hasAlpha = m_texture.m_textures[m_currentFrame]->HasAlpha() || m_col[0][3] < 255;

    if (m_diffuse.size())
    {
        if (m_col[0][0] == 255 && m_col[0][1] == 255 && m_col[0][2] == 255 && m_col[0][3] == 255 )
        {
            g_Windowing.EnableGUIShader(SM_MULTI);
        }
        else
        {
            g_Windowing.EnableGUIShader(SM_MULTI_BLENDCOLOR);
        }

        hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, m_diffuse.m_textures[0]->GetTextureObject());

        GLint tex1Loc = g_Windowing.GUIShaderGetCoord1();
        glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, 0, m_tex1);
        glEnableVertexAttribArray(tex1Loc);

        hasAlpha = true;
    }
    else
    {
        if ( hasAlpha )
        {
            g_Windowing.EnableGUIShader(SM_TEXTURE);
        }
        else
        {
            g_Windowing.EnableGUIShader(SM_TEXTURE_NOBLEND);
        }
    }

    GLint posLoc  = g_Windowing.GUIShaderGetPos();
    GLint colLoc  = g_Windowing.GUIShaderGetCol();
    GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, m_vert);
    if(colLoc >= 0)
        glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, m_col);
    glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, m_tex0);

    glEnableVertexAttribArray(posLoc);
    if(colLoc >= 0)
        glEnableVertexAttribArray(colLoc);
    glEnableVertexAttribArray(tex0Loc);

    if ( hasAlpha )
    {
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        glEnable( GL_BLEND );
    }
    else
    {
        glDisable(GL_BLEND);
    }
}
예제 #20
0
void TextureTransparent(CCallParams& p)
{
	CBaseTexture* spr = GetTexture(p.AsString(0));
	if (spr == 0)return;
	spr->SetTransparent(p.AsInt(1), p.AsInt(2), p.AsInt(3));
}
예제 #21
0
void CGUITextureD3D::Begin(color_t color)
{
  int unit = 0;
  CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
  LPDIRECT3DDEVICE9 p3DDevice = g_Windowing.Get3DDevice();

  texture->LoadToGPU();
  if (m_diffuse.size())
    m_diffuse.m_textures[0]->LoadToGPU();
  // Set state to render the image
  texture->BindToUnit(unit);
  p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_MODULATE );
  p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_TEXTURE   );
  p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_DIFFUSE   );
  p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP  , D3DTOP_MODULATE );
  p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE   );
  p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE   );
  unit++;

  if (m_diffuse.size())
  {
    m_diffuse.m_textures[0]->BindToUnit(1);
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_TEXTURE   );
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_CURRENT   );
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_MODULATE );
    p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE   );
    p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_CURRENT   );
    p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP  , D3DTOP_MODULATE );
    unit++;
  }

  if(g_Windowing.UseLimitedColor())
  {
    m_col = D3DCOLOR_RGBA(GET_R(color) * (235 - 16) / 255
                        , GET_G(color) * (235 - 16) / 255
                        , GET_B(color) * (235 - 16) / 255
                        , GET_A(color));
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_ADD );
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_CURRENT) ;
    p3DDevice->SetRenderState( D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(16,16,16, 0) );
    p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_TFACTOR );
    unit++;
  }
  else
    m_col = color;

  p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_DISABLE);
  p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

  p3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
  p3DDevice->SetRenderState( D3DRS_ALPHAREF, 0 );
  p3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
  p3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
  p3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  p3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
  p3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  p3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  p3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  p3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  p3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  p3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);

  p3DDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 );
}
예제 #22
0
void TextureBind(CCallParams& p)
{
	CBaseTexture* t = GetTexture(p.AsString(0));
	if (t != 0)t->Bind();
}
예제 #23
0
CBaseTexture* CGUIFontTTFDX::ReallocTexture(unsigned int& newHeight)
{
  CBaseTexture* pNewTexture = new CDXTexture(m_textureWidth, newHeight, XB_FMT_A8);
  pNewTexture->CreateTextureObject();
  LPDIRECT3DTEXTURE9 newTexture = pNewTexture->GetTextureObject();

  if (newTexture == NULL)
  {
    CLog::Log(LOGERROR, __FUNCTION__" - failed to create the new texture h=%d w=%d", m_textureWidth, newHeight);
    SAFE_DELETE(pNewTexture);
    return NULL;
  }

  // Use a speedup texture in system memory when main texture in default pool+dynamic
  // Otherwise the texture would have to be copied from vid mem to sys mem, which is too slow for subs while playing video.
  CD3DTexture* newSpeedupTexture = NULL;
  if (g_Windowing.DefaultD3DPool() == D3DPOOL_DEFAULT && g_Windowing.DefaultD3DUsage() == D3DUSAGE_DYNAMIC)
  {
    newSpeedupTexture = new CD3DTexture();

    if (!newSpeedupTexture->Create(m_textureWidth, newHeight, 1, 0, D3DFMT_A8, D3DPOOL_SYSTEMMEM))
    {
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      return NULL;
    }
  }

  LPDIRECT3DSURFACE9 pSource, pTarget;
  HRESULT hr;
  // There might be data to copy from the previous texture
  if ((newSpeedupTexture && m_speedupTexture) || (newTexture && m_texture))
  {
    if (m_speedupTexture)
    {
      m_speedupTexture->GetSurfaceLevel(0, &pSource);
      newSpeedupTexture->GetSurfaceLevel(0, &pTarget);
    }
    else
    {
      m_texture->GetTextureObject()->GetSurfaceLevel(0, &pSource);
      newTexture->GetSurfaceLevel(0, &pTarget);
    }

    D3DLOCKED_RECT srclr, dstlr;
    if(FAILED(pSource->LockRect( &srclr, NULL, 0 ))
    || FAILED(pTarget->LockRect( &dstlr, NULL, 0 )))
    {
      CLog::Log(LOGERROR, __FUNCTION__" - failed to lock surfaces");
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      pSource->Release();
      pTarget->Release();
      return NULL;
    }

    unsigned char *dst = (unsigned char *)dstlr.pBits;
    unsigned char *src = (unsigned char *)srclr.pBits;
    unsigned int dstPitch = dstlr.Pitch;
    unsigned int srcPitch = srclr.Pitch;
    unsigned int minPitch = std::min(srcPitch, dstPitch);

    if (srcPitch == dstPitch)
    {
      memcpy(dst, src, srcPitch * m_textureHeight);
    }
    else
    {
      for (unsigned int y = 0; y < m_textureHeight; y++)
      {
        memcpy(dst, src, minPitch);
        src += srcPitch;
        dst += dstPitch;
      }
    }
    pSource->UnlockRect();
    pTarget->UnlockRect();

    pSource->Release();
    pTarget->Release();
  }

  // Upload from speedup texture to main texture
  if (newSpeedupTexture && m_speedupTexture)
  {
    LPDIRECT3DSURFACE9 pSource, pTarget;
    newSpeedupTexture->GetSurfaceLevel(0, &pSource);
    newTexture->GetSurfaceLevel(0, &pTarget);
    const RECT rect = { 0, 0, m_textureWidth, m_textureHeight };
    const POINT point = { 0, 0 };

    hr = g_Windowing.Get3DDevice()->UpdateSurface(pSource, &rect, pTarget, &point);
    SAFE_RELEASE(pSource);
    SAFE_RELEASE(pTarget);

    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Failed to upload from sysmem to vidmem (0x%08X)", hr);
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      return NULL;
    }
  }

  SAFE_DELETE(m_texture);
  SAFE_DELETE(m_speedupTexture);
  m_textureHeight = newHeight;
  m_speedupTexture = newSpeedupTexture;

  return pNewTexture;
}
예제 #24
0
bool CWinSystemX11::CreateIconPixmap()
{
  int depth;
  XImage *img = NULL;
  Visual *vis;
  XWindowAttributes wndattribs;
  XVisualInfo visInfo;
  double rRatio;
  double gRatio;
  double bRatio;
  int outIndex = 0;
  unsigned int i,j;
  unsigned char *buf;
  uint32_t *newBuf = 0;
  size_t numNewBufBytes;

  // Get visual Info
  XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs);
  visInfo.visualid = wndattribs.visual->visualid;
  int nvisuals = 0;
  XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals);
  if (nvisuals != 1)
  {
    CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual");
    return false;
  }
  visInfo = visuals[0];
  XFree(visuals);

  depth = visInfo.depth;
  vis = visInfo.visual;

  if (depth < 15)
  {
    CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth");
    return false;
  }

  rRatio = vis->red_mask / 255.0;
  gRatio = vis->green_mask / 255.0;
  bRatio = vis->blue_mask / 255.0;

  CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon256x256.png");

  if (!iconTexture)
    return false;

  buf = iconTexture->GetPixels();

  if (depth>=24)
    numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight()));
  else
    numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight()));

  newBuf = (uint32_t*)malloc(numNewBufBytes);
  if (!newBuf)
  {
    CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed");
    return false;
  }

  for (i=0; i<iconTexture->GetHeight();++i)
  {
    for (j=0; j<iconTexture->GetWidth();++j)
    {
      unsigned int pos = i*iconTexture->GetPitch()+j*4;
      unsigned int r, g, b;
      r = (buf[pos+2] * rRatio);
      g = (buf[pos+1] * gRatio);
      b = (buf[pos+0] * bRatio);
      r &= vis->red_mask;
      g &= vis->green_mask;
      b &= vis->blue_mask;
      newBuf[outIndex] = r | g | b;
      ++outIndex;
    }
  }
  img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf,
                     iconTexture->GetWidth(), iconTexture->GetHeight(),
                     (depth>=24)?32:16, 0);
  if (!img)
  {
    CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image");
    free(newBuf);
    return false;
  }
  if (!XInitImage(img))
  {
    CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed");
    XDestroyImage(img);
    return false;
  }

  // set byte order
  union
  {
    char c[sizeof(short)];
    short s;
  } order;
  order.s = 1;
  if ((1 == order.c[0]))
  {
    img->byte_order = LSBFirst;
  }
  else
  {
    img->byte_order = MSBFirst;
  }

  // create icon pixmap from image
  m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth);
  GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL);
  XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height);
  XFreeGC(m_dpy, gc);
  XDestroyImage(img); // this also frees newBuf

  delete iconTexture;

  return true;
}
예제 #25
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;
}
예제 #26
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();
}
예제 #27
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();
}