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; }
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; }
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)); }
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)); }
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; }
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(); }
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); }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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); } }
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)); }
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 ); }
void TextureBind(CCallParams& p) { CBaseTexture* t = GetTexture(p.AsString(0)); if (t != 0)t->Bind(); }
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; }
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; }
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; }
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(); }
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(); }