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

Generated on Thu Jul 1 06:09:27 2010 for Second Life Viewer by  doxygen 1.4.7