#include "stdafx.h" #include "HLEGraphics/TextureCache.h" #include "SysPosix/Debug/WebDebug.h" #include "SysPosix/Debug/WebDebugTemplate.h" #include "System/Mutex.h" #include "System/DataSink.h" #include "Graphics/PngUtil.h" #ifdef DAEDALUS_DEBUG_DISPLAYLIST static void TextureHandler(void * arg, WebDebugConnection * connection) { const char * params = connection->GetQueryString(); if (!params) return; // Yes, this is pretty dodgy. Any random pointer can be passed in so we // validated ptr against the list of textures below. void * ptr = 0; if (sscanf(params, "ptr=%p", &ptr) != 1) { printf("Couldn't parse pointer: %s\n", params); return; } // NB: maintain a lock for as long as we have a ref to any textures. // If we delete textures on this thread, we'll crash OpenGL. { MutexLock lock(CTextureCache::Get()->GetDebugMutex()); CRefPtr texture; { std::vector textures; CTextureCache::Get()->Snapshot(lock, textures); for (size_t i = 0; i < textures.size(); ++i) { CTextureCache::STextureInfoSnapshot & snap = textures[i]; if ((CNativeTexture*)snap.Texture == ptr) { texture = snap.Texture; break; } } } // Return a 404 if not found if (!texture) { printf("Couldn't find texture %p\n", ptr); return; } connection->BeginResponse(200, -1, "image/png"); PngSaveImage(connection, texture); } connection->EndResponse(); } #endif // DAEDALUS_DEBUG_DISPLAYLIST #ifdef DAEDALUS_DEBUG_DISPLAYLIST static void TextureCacheHandler(void * arg, WebDebugConnection * connection) { connection->BeginResponse(200, -1, "text/html" ); WriteStandardHeader(connection, "Texture Cache"); connection->WriteString( "
\n" "
\n" "
\n" ); connection->WriteString("

Texture Cache

\n"); connection->WriteString(""); connection->WriteString(""); connection->WriteF( "" "" "" "" "" "" "" "\n" ); connection->WriteString(""); connection->WriteString(""); // NB: maintain a lock for as long as we have a ref to any textures. // If we delete textures on this thread, we'll crash OpenGL. { MutexLock lock(CTextureCache::Get()->GetDebugMutex()); std::vector textures; CTextureCache::Get()->Snapshot(lock, textures); for (size_t i = 0; i < textures.size(); ++i) { CTextureCache::STextureInfoSnapshot & snap = textures[i]; const TextureInfo & ti = snap.Info; connection->WriteF( "" "" "" "" "" "" "" "\n", ti.GetFormatName(), ti.GetSizeInBits(), ti.GetPitch(), ti.GetWidth(), ti.GetHeight(), (CNativeTexture *)snap.Texture, (CNativeTexture *)snap.Texture, snap.Texture->GetWidth(), snap.Texture->GetHeight() ); } } connection->WriteString(""); connection->WriteString("
FormatPitchWidthHeightImage
%s/%dbpp%d%d%d
"); connection->WriteString( "
\n" "
\n" "
\n" ); WriteStandardFooter(connection); connection->EndResponse(); } #endif // DAEDALUS_DEBUG_DISPLAYLIST bool TextureCache_RegisterWebDebug() { #ifdef DAEDALUS_DEBUG_DISPLAYLIST WebDebug_Register( "/texture_cache", &TextureCacheHandler, nullptr ); WebDebug_Register( "/texture", &TextureHandler, nullptr ); #endif return true; }