llviewerimage.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLVIEWERIMAGE_H                                      
00033 #define LL_LLVIEWERIMAGE_H
00034 
00035 #include "llimagegl.h"
00036 #include "lltimer.h"
00037 #include "llframetimer.h"
00038 #include "llhost.h"
00039 
00040 #include <map>
00041 #include <list>
00042 
00043 class LLViewerImage;
00044 
00045 typedef void    (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
00046 
00047 class LLVFile;
00048 class LLMessageSystem;
00049  
00050 class LLLoadedCallbackEntry
00051 {
00052 public:
00053         LLLoadedCallbackEntry(loaded_callback_func cb,
00054                                                   S32 discard_level,
00055                                                   BOOL need_imageraw, // Needs image raw for the callback
00056                                                   void* userdata ) 
00057                 : mCallback(cb),
00058                   mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
00059                   mDesiredDiscard(discard_level),
00060                   mNeedsImageRaw(need_imageraw),
00061                   mUserData(userdata)
00062         {
00063         }
00064 
00065         loaded_callback_func    mCallback;
00066         S32                                             mLastUsedDiscard;
00067         S32                                             mDesiredDiscard;
00068         BOOL                                    mNeedsImageRaw;
00069         void*                                   mUserData;
00070 };
00071 
00072 class LLTextureBar;
00073 
00074 class LLViewerImage : public LLImageGL
00075 {
00076         LOG_CLASS(LLViewerImage);
00077 
00078         friend class LLTextureBar; // debug info only
00079         friend class LLTextureView; // debug info only
00080         
00081 public:
00082         static void initClass();
00083         static void cleanupClass();
00084         static void updateClass(const F32 velocity, const F32 angular_velocity);
00085 
00086         static LLViewerImage * getImage(const LLUUID &image_id);
00087                 // lightweight wrapper for gImageList.getImage()
00088 
00089         static BOOL bindTexture(LLImageGL* image, const U32 stage = 0)
00090         {
00091                 if (image)
00092                 {
00093                         return image->bind(stage);
00094                 }
00095                 else
00096                 {
00097                         return sDefaultImagep->bind(stage);
00098                 }
00099         }
00100 
00101         struct Compare
00102         {
00103                 // lhs < rhs
00104                 bool operator()(const LLPointer<LLViewerImage> &lhs, const LLPointer<LLViewerImage> &rhs) const
00105                 {
00106                         const LLViewerImage* lhsp = (const LLViewerImage*)lhs;
00107                         const LLViewerImage* rhsp = (const LLViewerImage*)rhs;
00108                         // greater priority is "less"
00109                         const F32 lpriority = lhsp->getDecodePriority();
00110                         const F32 rpriority = rhsp->getDecodePriority();
00111                         if (lpriority > rpriority) // higher priority
00112                                 return true;
00113                         if (lpriority < rpriority)
00114                                 return false;
00115                         return lhsp < rhsp;
00116                 }
00117         };
00118 
00119         struct CompareByHostAndPriority
00120         {
00121                 // lhs < rhs
00122                 bool operator()(const LLPointer<LLViewerImage> &lhs, const LLPointer<LLViewerImage> &rhs) const
00123                 {
00124                         const LLViewerImage* lhsp = (const LLViewerImage*)lhs;
00125                         const LLViewerImage* rhsp = (const LLViewerImage*)rhs;
00126                         if (lhsp->mTargetHost != rhsp->mTargetHost)
00127                                 return lhsp->mTargetHost < rhsp->mTargetHost;
00128 
00129                         const F32 lpriority = lhsp->getDecodePriority();
00130                         const F32 rpriority = rhsp->getDecodePriority();
00131                         if (lpriority != rpriority)
00132                                 return lpriority > rpriority; // greater priority is "less"
00133 
00134                         return lhsp < rhsp;
00135                 }
00136         };
00137 
00138         struct CompareForRemoval
00139         {
00140                 // lhs < rhs
00141                 bool operator()(const LLPointer<LLViewerImage> &lhs, const LLPointer<LLViewerImage> &rhs) const
00142                 {
00143                         const LLViewerImage* lhsp = (const LLViewerImage*)lhs;
00144                         const LLViewerImage* rhsp = (const LLViewerImage*)rhs;
00145                         // compare bind time
00146                         if (lhsp->mLastBindTime < rhsp->mLastBindTime) // older
00147                                 return true;
00148                         if (lhsp->mLastBindTime > rhsp->mLastBindTime)
00149                                 return false;
00150                         if (lhsp->getDiscardLevel() < rhsp->getDiscardLevel()) // larger
00151                                 return true;
00152                         if (lhsp->getDiscardLevel() > rhsp->getDiscardLevel())
00153                                 return false;
00154                         return lhsp < rhsp;
00155                 }
00156         };
00157 
00158         struct CompareForWorstVisibility 
00159         {
00160                 // lhs < rhs
00161                 bool operator()(const LLPointer<LLViewerImage> &lhs, const LLPointer<LLViewerImage> &rhs) const
00162                 {
00163                         const LLViewerImage* lhsp = (const LLViewerImage*)lhs;
00164                         const LLViewerImage* rhsp = (const LLViewerImage*)rhs;
00165                         F32 lhsvis = ((lhsp->getWidth() * lhsp->getHeight()) / lhsp->mMaxVirtualSize);
00166                         F32 rhsvis = ((rhsp->getWidth() * rhsp->getHeight()) / rhsp->mMaxVirtualSize);
00167                         if (lhsvis > rhsvis) // fewer relative visible pixels
00168                                 return true;
00169                         if (rhsvis < lhsvis)
00170                                 return false;
00171                         return lhsp < rhsp;
00172                 }
00173         };
00174         
00175         enum
00176         {
00177                 MAX_IMAGE_SIZE_DEFAULT = 1024,
00178                 INVALID_DISCARD_LEVEL = 0x7fff
00179         };
00180 
00181 protected:
00182         /*virtual*/ ~LLViewerImage();
00183         
00184 public:
00185         LLViewerImage(const LLString& filename, const LLUUID& id, BOOL usemipmaps = TRUE);
00186         LLViewerImage(const LLUUID& id, BOOL usemipmaps = TRUE);
00187         LLViewerImage(const U32 width, const U32 height, const U8 components, BOOL usemipmaps);
00188         LLViewerImage(const LLImageRaw* raw, BOOL usemipmaps);
00189 
00190         /*virtual*/ void dump();        // debug info to llinfos
00191 
00192         /*virtual*/ BOOL bind(const S32 stage = 0) const;
00193         
00194         void reinit(BOOL usemipmaps = TRUE);
00195 
00196         const LLUUID& getID() { return mID; }
00197 
00198         // New methods for determining image quality/priority
00199         // texel_area_ratio is ("scaled" texel area)/(original texel area), approximately.
00200         void addTextureStats(F32 pixel_area) const
00201         {
00202                 mMaxCosAngle = 1.0f;
00203                 if (pixel_area > mMaxVirtualSize)
00204                 {
00205                         mMaxVirtualSize = pixel_area;
00206                 }
00207         }
00208         void addTextureStats(F32 pixel_area,
00209                                                  F32 texel_area_ratio) const
00210         {
00211                 mMaxCosAngle = 1.0f;
00212                 F32 virtual_size = pixel_area / texel_area_ratio;
00213                 if (virtual_size > mMaxVirtualSize)
00214                 {
00215                         mMaxVirtualSize = virtual_size;
00216                 }
00217         }
00218         void addTextureStats(F32 pixel_area,
00219                                                  F32 texel_area_ratio,
00220                                                  F32 cos_center_angle) const;
00221         void resetTextureStats(BOOL zero = FALSE);
00222 
00223         // Process image stats to determine priority/quality requirements.
00224         void processTextureStats();
00225 
00226         // Set callbacks to get called when the image gets updated with higher 
00227         // resolution versions.
00228         void setLoadedCallback(loaded_callback_func cb,
00229                                                    S32 discard_level,
00230                                                    BOOL keep_imageraw,
00231                                                    void* userdata);
00232 
00233          // ONLY call from LLViewerImageList
00234         BOOL createTexture(S32 usename = 0);
00235 
00236         BOOL needsAux() const                                                   { return mNeedsAux; }
00237         void setNeedsAux(const BOOL needs_aux)                  { mNeedsAux = needs_aux; }
00238 
00239         // setDesiredDiscardLevel is only used by LLViewerImageList
00240         void setDesiredDiscardLevel(S32 discard) { mDesiredDiscardLevel = discard; }
00241         S32  getDesiredDiscardLevel()                    { return mDesiredDiscardLevel; }
00242 
00243         void setMinDiscardLevel(S32 discard)    { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
00244         
00245         // Host we think might have this image, used for baked av textures.
00246         void setTargetHost(LLHost host)                 { mTargetHost = host; }
00247         LLHost getTargetHost() const                    { return mTargetHost; }
00248 
00249         enum
00250         {
00251                 BOOST_NONE                      = 0,
00252                 BOOST_AVATAR_BAKED      = 1,
00253                 BOOST_AVATAR            = 2,
00254                 BOOST_CLOUDS            = 3,
00255                 BOOST_SCULPTED      = 4,
00256                 
00257                 BOOST_HIGH                      = 10,
00258                 BOOST_TERRAIN           = 11, // has to be high priority for minimap / low detail
00259                 BOOST_SELECTED          = 12,
00260                 BOOST_HUD                       = 13,
00261                 BOOST_AVATAR_BAKED_SELF = 14,
00262                 BOOST_UI                        = 15,
00263                 BOOST_PREVIEW           = 16,
00264                 BOOST_MAP                       = 17,
00265                 BOOST_MAP_LAYER         = 18,
00266                 BOOST_AVATAR_SELF       = 19, // needed for baking avatar
00267                 BOOST_MAX_LEVEL
00268         };
00269         void setBoostLevel(S32 level);
00270         S32  getBoostLevel() { return mBoostLevel; }
00271         
00272         F32 getDecodePriority() const { return mDecodePriority; };
00273         F32 calcDecodePriority();
00274         static F32 maxDecodePriority();
00275         
00276         // Set the decode priority for this image...
00277         // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
00278         // the priority list, and cause horrible things to happen.
00279         void setDecodePriority(F32 priority = -1.0f);
00280 
00281         bool updateFetch();
00282         
00283         // Override the computation of discard levels if we know the exact output
00284         // size of the image.  Used for UI textures to not decode, even if we have
00285         // more data.
00286         void setKnownDrawSize(S32 width, S32 height);
00287 
00288         void setIsMissingAsset();
00289         BOOL isMissingAsset()   const           { return mIsMissingAsset; }
00290 
00291         bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
00292         
00293         bool doLoadedCallbacks();
00294 
00295         // returns dimensions of original image for local files (before power of two scaling)
00296         // and returns 0 for all asset system images
00297         S32 getOriginalWidth() { return mOrigWidth; }
00298         S32 getOriginalHeight() { return mOrigHeight; }
00299 
00300 private:
00301         /*virtual*/ void cleanup(); // Cleanup the LLViewerImage (so we can reinitialize it)
00302 
00303         void init(bool firstinit);
00304 
00305         // Used to be in LLImageGL
00306         LLImageRaw* createRawImage(S8 discard_level = 0, BOOL allocate = FALSE);
00307         void destroyRawImage();
00308         
00309 public:
00310         S32 mFullWidth;
00311         S32 mFullHeight;
00312 
00313         S32 mOrigWidth;
00314         S32 mOrigHeight;
00315         LLString mLocalFileName;
00316 
00317         // Data used for calculating required image priority/quality level/decimation
00318         mutable F32 mMaxVirtualSize;    // The largest virtual size of the image, in pixels - how much data to we need?
00319         mutable F32 mMaxCosAngle;               // The largest cos of the angle between camera X vector and the object
00320 
00321         F32 mTexelsPerImage;                    // Texels per image.
00322         F32 mDiscardVirtualSize;                // Virtual size used to calculate desired discard
00323         
00324         S8  mInImageList;                               // TRUE if image is in list (in which case don't reset priority!)
00325         S8  mIsMediaTexture;                    // TRUE if image is being replaced by media (in which case don't update)
00326 
00327         // Various info regarding image requests
00328         S32 mRequestedDiscardLevel;
00329         F32 mRequestedDownloadPriority;
00330         S32 mFetchState;
00331         U32 mFetchPriority;
00332         F32 mDownloadProgress;
00333         F32 mFetchDeltaTime;
00334         F32 mRequestDeltaTime;
00335         S32 mDecodeFrame;
00336         S32 mVisibleFrame; // decode frame where image was last visible
00337         
00338         // Timers
00339         LLFrameTimer mLastPacketTimer;          // Time since last packet.
00340         LLFrameTimer mLastReferencedTimer;
00341 
00342 private:
00343         LLUUID mID;
00344 
00345         S8  mDesiredDiscardLevel;                       // The discard level we'd LIKE to have - if we have it and there's space
00346         S8  mMinDesiredDiscardLevel;            // The minimum discard level we'd like to have
00347         S8  mNeedsCreateTexture;        
00348         S8  mNeedsAux;                                  // We need to decode the auxiliary channels
00349         S8  mDecodingAux;                               // Are we decoding high components
00350         S8  mIsRawImageValid;
00351         S8  mHasFetcher;                                // We've made a fecth request
00352         S8  mIsFetching;                                // Fetch request is active
00353         S8  mFullyLoaded;
00354         mutable S8 mIsMissingAsset;             // True if we know that there is no image asset with this image id in the database.     
00355 
00356         // Override the computation of discard levels if we know the exact output size of the image.
00357         // Used for UI textures to not decode, even if we have more data.
00358         S32 mKnownDrawWidth;
00359         S32     mKnownDrawHeight;
00360 
00361         F32 mDecodePriority;                    // The priority for decoding this image.
00362         S32 mBoostLevel;                                // enum describing priority level
00363         
00364         typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
00365         callback_list_t mLoadedCallbackList;
00366 
00367         LLPointer<LLImageRaw> mRawImage;
00368         S32 mRawDiscardLevel;
00369         S32     mMinDiscardLevel;
00370         F32 mCalculatedDiscardLevel; // Last calculated discard level
00371         
00372         // Used ONLY for cloth meshes right now.  Make SURE you know what you're 
00373         // doing if you use it for anything else! - djs
00374         LLPointer<LLImageRaw> mAuxRawImage;
00375 
00376         LLHost mTargetHost;     // if LLHost::invalid, just request from agent's simulator
00377         
00378 public:
00379         static const U32 sCurrentFileVersion;
00380         // Default textures
00381         static LLPointer<LLViewerImage> sMissingAssetImagep;    // Texture to show for an image asset that is not in the database
00382         static LLPointer<LLViewerImage> sWhiteImagep;   // Texture to show NOTHING (whiteness)
00383         static LLPointer<LLImageGL> sDefaultImagep; // "Default" texture for error cases
00384         static LLPointer<LLViewerImage> sSmokeImagep; // Old "Default" translucent texture
00385         static LLPointer<LLImageGL> sNullImagep; // Null texture for non-textured objects.
00386 
00387         static S32 sImageCount;
00388         static LLTimer sEvaluationTimer;
00389         static F32 sDesiredDiscardBias;
00390         static F32 sDesiredDiscardScale;
00391         static S32 sBoundTextureMemory;
00392         static S32 sTotalTextureMemory;
00393         static S32 sMaxBoundTextureMem;
00394         static S32 sMaxTotalTextureMem;
00395         static BOOL sDontLoadVolumeTextures;
00396 };
00397 
00398 #endif

Generated on Fri May 16 08:34:09 2008 for SecondLife by  doxygen 1.5.5