/** * @file llviewertexturelist.h * @brief Object for managing the list of images within a region * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LL_LLVIEWERTEXTURELIST_H #define LL_LLVIEWERTEXTURELIST_H #include "lluuid.h" //#include "message.h" #include "llgl.h" #include "llviewertexture.h" #include "llui.h" #include #include #include "lluiimage.h" const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; const bool MIPMAP_YES = true; const bool MIPMAP_NO = false; const bool GL_TEXTURE_YES = true; const bool GL_TEXTURE_NO = false; const bool IMMEDIATE_YES = true; const bool IMMEDIATE_NO = false; class LLImageJ2C; class LLMessageSystem; class LLTextureView; typedef void (*LLImageCallback)(bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, bool final, void* userdata); enum ETexListType { TEX_LIST_STANDARD = 0, TEX_LIST_SCALE }; struct LLTextureKey { LLTextureKey(); LLTextureKey(LLUUID id, ETexListType tex_type); LLUUID textureId; ETexListType textureType; friend bool operator<(const LLTextureKey& key1, const LLTextureKey& key2) { if (key1.textureId != key2.textureId) { return key1.textureId < key2.textureId; } else { return key1.textureType < key2.textureType; } } }; class LLViewerTextureList { friend class LLTextureView; friend class LLViewerTextureManager; friend class LLLocalBitmap; public: static bool createUploadFile(LLPointer raw_image, const std::string& out_filename, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, const S32 min_image_dimentions = 0); static bool createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, const S32 min_image_dimentions = 0, bool force_square = false); static LLPointer convertToUploadFile(LLPointer raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, bool force_square = false, bool force_lossless = false); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); public: LLViewerTextureList(); ~LLViewerTextureList(); void init(); void shutdown(); void dump(); void destroyGL(); bool isInitialized() const {return mInitialized;} void findTexturesByID(const LLUUID &image_id, std::vector &output); LLViewerFetchedTexture *findImage(const LLUUID &image_id, ETexListType tex_type); LLViewerFetchedTexture *findImage(const LLTextureKey &search_key); // Using image stats, determine what images are necessary, and perform image updates. void updateImages(F32 max_time); void forceImmediateUpdate(LLViewerFetchedTexture* imagep) ; // Decode and create textures for all images currently in list. void decodeAllImages(F32 max_decode_time); void handleIRCallback(void **data, const S32 number); S32 getNumImages() { return static_cast(mImageList.size()); } // Local UI images // Local UI images void doPreloadImages(); // Network images. Needs caps and cache to work void doPrefetchImages(); void clearFetchingRequests(); // do some book keeping on the specified texture // - updates decode priority // - updates desired discard level // - cleans up textures that haven't been referenced in awhile void updateImageDecodePriority(LLViewerFetchedTexture* imagep, bool flush_images = true); private: F32 updateImagesCreateTextures(F32 max_time); F32 updateImagesFetchTextures(F32 max_time); void updateImagesUpdateStats(); F32 updateImagesLoadingFastCache(F32 max_time); void addImage(LLViewerFetchedTexture *image, ETexListType tex_type); void deleteImage(LLViewerFetchedTexture *image); void addImageToList(LLViewerFetchedTexture *image); void removeImageFromList(LLViewerFetchedTexture *image); LLViewerFetchedTexture * getImage(const LLUUID &image_id, FTType f_type = FTT_DEFAULT, bool usemipmap = true, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, LLHost request_from_host = LLHost() ); LLViewerFetchedTexture * getImageFromFile(const std::string& filename, FTType f_type = FTT_LOCAL_FILE, bool usemipmap = true, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); LLViewerFetchedTexture* getImageFromUrl(const std::string& url, FTType f_type, bool usemipmap = true, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); LLImageRaw* getRawImageFromMemory(const U8* data, U32 size, std::string_view mimetype); LLViewerFetchedTexture* getImageFromMemory(const U8* data, U32 size, std::string_view mimetype); LLViewerFetchedTexture* createImage(const LLUUID &image_id, FTType f_type, bool usemipmap = true, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, LLHost request_from_host = LLHost() ); // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host) { return getImage(image_id, f_type, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } public: typedef std::unordered_set > image_list_t; typedef std::queue > image_queue_t; // images that have been loaded but are waiting to be uploaded to GL image_queue_t mCreateTextureList; // images that must be downscaled quickly so we don't run out of memory image_queue_t mDownScaleQueue; image_list_t mCallbackList; image_list_t mFastCacheList; bool mForceResetTextureStats; // to make "for (auto& imagep : gTextureList)" work const image_list_t::const_iterator begin() const { return mImageList.cbegin(); } const image_list_t::const_iterator end() const { return mImageList.cend(); } private: typedef std::map< LLTextureKey, LLPointer > uuid_map_t; uuid_map_t mUUIDMap; LLTextureKey mLastUpdateKey; image_list_t mImageList; // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon std::unordered_set > mImagePreloads; bool mInitialized ; LLFrameTimer mForceDecodeTimer; private: static S32 sNumImages; static void (*sUUIDCallback)(void**, const LLUUID &); LOG_CLASS(LLViewerTextureList); }; class LLUIImageList : public LLImageProviderInterface, public LLSingleton { LLSINGLETON_EMPTY_CTOR(LLUIImageList); public: // LLImageProviderInterface /*virtual*/ LLPointer getUIImageByID(const LLUUID& id, S32 priority) override; /*virtual*/ LLPointer getUIImage(const std::string& name, S32 priority) override; void cleanUp() override; bool initFromFile(); LLPointer preloadUIImage(const std::string& name, const std::string& filename, bool use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle stype); static void onUIImageLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, bool final, void* userdata ); private: LLPointer loadUIImageByName(const std::string& name, const std::string& filename, bool use_mips = false, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI, LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER); LLPointer loadUIImageByID(const LLUUID& id, bool use_mips = false, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI, LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER); LLPointer loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, bool use_mips = false, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER); struct LLUIImageLoadData { std::string mImageName; LLRect mImageScaleRegion; LLRect mImageClipRegion; }; typedef std::map< std::string, LLPointer > uuid_ui_image_map_t; uuid_ui_image_map_t mUIImages; // //keep a copy of UI textures to prevent them to be deleted. //mGLTexturep of each UI texture equals to some LLUIImage.mImage. std::list< LLPointer > mUITextureList ; }; const bool GLTEXTURE_TRUE = true; const bool GLTEXTURE_FALSE = false; const bool MIPMAP_TRUE = true; const bool MIPMAP_FALSE = false; extern LLViewerTextureList gTextureList; #endif