CBaseTexture *CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int idealWidth, unsigned int idealHeight, bool autoRotate) { #if defined(TARGET_ANDROID) CURL url(texturePath); if (url.GetProtocol() == "androidapp") { XFILE::CFileAndroidApp file; if (file.Open(url)) { unsigned int imgsize = (unsigned int)file.GetLength(); unsigned char* inputBuff = new unsigned char[imgsize]; unsigned int inputBuffSize = file.Read(inputBuff, imgsize); file.Close(); if (inputBuffSize != imgsize) { delete [] inputBuff; return NULL; } CTexture *texture = new CTexture(); unsigned int width = file.GetIconWidth(); unsigned int height = file.GetIconHeight(); texture->LoadFromMemory(width, height, width*4, XB_FMT_RGBA8, true, inputBuff); delete [] inputBuff; return texture; } } #endif CTexture *texture = new CTexture(); if (texture->LoadFromFileInternal(texturePath, idealWidth, idealHeight, autoRotate)) return texture; delete texture; return NULL; }
CBaseTexture *CBaseTexture::LoadFromFile(const std::string& texturePath, unsigned int idealWidth, unsigned int idealHeight, bool requirePixels, const std::string& strMimeType) { #if defined(TARGET_ANDROID) CURL url(texturePath); if (url.IsProtocol("androidapp")) { XFILE::CFileAndroidApp file; if (file.Open(url)) { unsigned char* inputBuff; unsigned int width; unsigned int height; unsigned int inputBuffSize = file.ReadIcon(&inputBuff, &width, &height); file.Close(); if (!inputBuffSize) return NULL; CTexture *texture = new CTexture(); texture->LoadFromMemory(width, height, width*4, XB_FMT_RGBA8, true, inputBuff); delete [] inputBuff; return texture; } } #endif CTexture *texture = new CTexture(); if (texture->LoadFromFileInternal(texturePath, idealWidth, idealHeight, requirePixels, strMimeType)) return texture; delete texture; return NULL; }
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */) { std::string strPath; static CTextureArray emptyTexture; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return emptyTexture; if (size) // we found the texture { for (int i = 0; i < (int)m_vecTextures.size(); ++i) { CTextureMap *pMap = m_vecTextures[i]; if (pMap->GetName() == strTextureName) { //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); return pMap->GetTexture(); } } // Whoops, not there. return emptyTexture; } for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i) { CTextureMap* pMap = i->first; if (pMap->GetName() == strTextureName && i->second > 0) { m_vecTextures.push_back(pMap); m_unusedTextures.erase(i); return pMap->GetTexture(); } } if (checkBundleOnly && bundle == -1) return emptyTexture; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifdef _DEBUG_TEXTURES int64_t start; start = CurrentHostCounter(); #endif if (bundle >= 0 && StringUtils::EndsWithNoCase(strPath, ".gif")) { CTextureMap* pMap = nullptr; CBaseTexture **pTextures = nullptr; int nLoops = 0, width = 0, height = 0; int* Delay = nullptr; int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay); if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); delete[] pTextures; delete[] Delay; return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; pMap = new CTextureMap(strTextureName, width, height, nLoops); for (int iImage = 0; iImage < nImages; ++iImage) { pMap->Add(pTextures[iImage], Delay[iImage]); maxWidth = std::max(maxWidth, pTextures[iImage]->GetWidth()); maxHeight = std::max(maxHeight, pTextures[iImage]->GetHeight()); } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); delete[] pTextures; delete[] Delay; if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } else if (StringUtils::EndsWithNoCase(strPath, ".gif") || StringUtils::EndsWithNoCase(strPath, ".apng")) { CTextureMap* pMap = nullptr; std::string mimeType; if (StringUtils::EndsWithNoCase(strPath, ".gif")) mimeType = "image/gif"; else if (StringUtils::EndsWithNoCase(strPath, ".apng")) mimeType = "image/apng"; XFILE::CFile file; XFILE::auto_buffer buf; CFFmpegImage anim(mimeType); pMap = new CTextureMap(strTextureName, 0, 0, 0); if (file.LoadFile(strPath, buf) <= 0 || !anim.Initialize((uint8_t*)buf.get(), buf.size()) || !pMap) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CURL::GetRedacted(strPath).c_str()); file.Close(); return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; uint64_t maxMemoryUsage = 91238400;// 1920*1080*4*11 bytes, i.e, a total of approx. 12 full hd frames auto frame = anim.ReadFrame(); while (frame) { CTexture *glTexture = new CTexture(); if (glTexture) { glTexture->LoadFromMemory(anim.Width(), anim.Height(), frame->GetPitch(), XB_FMT_A8R8G8B8, true, frame->m_pImage); pMap->Add(glTexture, frame->m_delay); maxWidth = std::max(maxWidth, glTexture->GetWidth()); maxHeight = std::max(maxHeight, glTexture->GetHeight()); } if (pMap->GetMemoryUsage() <= maxMemoryUsage) { frame = anim.ReadFrame(); } else { CLog::Log(LOGDEBUG, "Memory limit (%" PRIu64 " bytes) exceeded, %i frames extracted from file : %s", (maxMemoryUsage/11)*12,pMap->GetTexture().size(), CURL::GetRedacted(strPath).c_str()); break; } } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); file.Close(); if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } CBaseTexture *pTexture = NULL; int width = 0, height = 0; if (bundle >= 0) { if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return emptyTexture; } } else { pTexture = CBaseTexture::LoadFromFile(strPath); if (!pTexture) return emptyTexture; width = pTexture->GetWidth(); height = pTexture->GetHeight(); } if (!pTexture) return emptyTexture; CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); pMap->Add(pTexture, 100); m_vecTextures.push_back(pMap); #ifdef _DEBUG_TEXTURES int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return pMap->GetTexture(); }
void CGUIWindowManager::BuildStencilBuffer(CGUIWindow* pWindow) { #if 0 // test rendering the stencil buffer unsigned int width = g_graphicsContext.GetWidth(); unsigned int height = g_graphicsContext.GetHeight(); #endif // build the topmost controls mask in the stencil buffer g_Windowing.ClearStencilBuffer(0); g_Windowing.EnableStencil(true); g_Windowing.SetColorMask(false, false, false, false); g_Windowing.SetStencilFunc(STENCIL_FUNC_ALWAYS, 1, 1); g_Windowing.SetStencilOp(STENCIL_OP_KEEP, STENCIL_OP_INCR, STENCIL_OP_INCR); if (pWindow) pWindow->Render(); g_Windowing.SetColorMask(true, true, true, true); g_Windowing.SetStencilFunc(STENCIL_FUNC_EQUAL, 0, 1); g_Windowing.SetStencilOp(STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP); if (pWindow) pWindow->Render(); g_Windowing.EnableStencil(false); return; #if 0 // TEST: render the stencil buffer on screen static unsigned char* stencilBuf = NULL; if(stencilBuf == NULL) stencilBuf = new unsigned char[width * height]; static unsigned char* rgbBuf = NULL; if(rgbBuf == NULL) rgbBuf = new unsigned char[width * height * 4]; memset(stencilBuf, 0, width * height); memset(rgbBuf, 0, width * height * 4); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilBuf); int scale = 16; for(unsigned int j = 0; j < height; j++) for(unsigned int i = 0; i < width; i++) { int pos = j * width + i; rgbBuf[4 * pos + 0] = scale * stencilBuf[pos]; rgbBuf[4 * pos + 1] = scale * stencilBuf[pos]; rgbBuf[4 * pos + 2] = scale * stencilBuf[pos]; rgbBuf[4 * pos + 3] = 255; } TransformMatrix mat; g_graphicsContext.PushTransform(mat, true); g_graphicsContext.PushViewPort(0, 0, 0, 0, false); g_graphicsContext.SetClipRegion(0, 0, 0, 0, false); CTexture texture; texture.LoadFromMemory((int)width, (int)height, width * 4, XB_FMT_R8G8B8A8, rgbBuf); CTextureInfo textureInfo(""); textureInfo.blendCenter = false; textureInfo.orientation = 3; // flipy CGUITexture guiTexture(0, 0, (float)width, (float)height, textureInfo, &texture); guiTexture.SetDiffuseColor(0xffffffff); guiTexture.Render(); g_graphicsContext.PopTransform(); g_graphicsContext.PopViewPort(); g_graphicsContext.RestoreClipRegion(); #endif }
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(); }