/** * @file lltexlayer.h * @brief A texture layer. Used for avatars. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * * Copyright (c) 2002-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #ifndef LL_LLTEXLAYER_H #define LL_LLTEXLAYER_H #include #include "lldynamictexture.h" #include "llwearable.h" #include "llvoavatardefines.h" class LLVOAvatar; class LLVOAvatarSelf; class LLImageTGA; class LLImageRaw; class LLXmlTreeNode; class LLPolyMorphTarget; class LLTexLayerSet; class LLTexLayerSetInfo; class LLTexLayerInfo; class LLTexLayerSetBuffer; class LLTexLayerParamColor; class LLTexLayerParamColorInfo; class LLTexLayerParamAlpha; class LLTexLayerParamAlphaInfo; typedef std::vector param_color_list_t; typedef std::vector param_alpha_list_t; typedef std::vector param_color_info_list_t; typedef std::vector param_alpha_info_list_t; //----------------------------------------------------------------------------- // LLTexLayer // A single texture layer // Only exists for llvoavatarself class LLTexLayer { public: enum ERenderPass { RP_COLOR, RP_BUMP, RP_SHINE }; LLTexLayer(LLTexLayerSet* const layer_set); LLTexLayer(const LLTexLayer &layer); ~LLTexLayer(); const LLTexLayerInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerInfo *info); // This sets mInfo and calls initialization functions BOOL render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph); void requestUpdate(); LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } void deleteCaches(); U8* getAlphaData(); void invalidateMorphMasks(); void setHasMorph(BOOL newval) { mHasMorph = newval; } BOOL isMorphValid() { return mMorphMasksValid; } const std::string& getName() const; ERenderPass getRenderPass() const; const std::string& getGlobalColor() const; BOOL findNetColor(LLColor4* color) const; BOOL renderImageRaw(U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask); BOOL blendAlphaTexture(S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph); BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } BOOL isVisibilityMask() const; static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); private: LLTexLayerSet* const mTexLayerSet; // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order. param_color_list_t mParamColorList; // mGlobalColor name stored in mInfo // mFixedColor value stored in mInfo param_alpha_list_t mParamAlphaList; BOOL mMorphMasksValid; typedef std::map alpha_cache_t; alpha_cache_t mAlphaCache; BOOL mStaticImageInvalid; BOOL mHasMorph; const LLTexLayerInfo *mInfo; }; // Make private class LLTexLayerInfo { friend class LLTexLayer; public: LLTexLayerInfo(); ~LLTexLayerInfo(); BOOL parseXml(LLXmlTreeNode* node); BOOL createVisualParams(LLVOAvatar *avatar); private: std::string mName; BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer, LLTexLayer::ERenderPass mRenderPass; std::string mGlobalColor; LLColor4 mFixedColor; S32 mLocalTexture; std::string mStaticImageFileName; BOOL mStaticImageIsMask; BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask BOOL mIsVisibilityMask; typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t; morph_name_list_t mMorphNameList; param_color_info_list_t mParamColorInfoList; param_alpha_info_list_t mParamAlphaInfoList; }; // // LLTexLayer //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLTexLayerSet // An ordered set of texture layers that get composited into a single texture. // Only exists for llvoavatarself class LLTexLayerSet { friend class LLTexLayerSetBuffer; public: LLTexLayerSet(LLVOAvatarSelf* const avatar); ~LLTexLayerSet(); const LLTexLayerSetInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions BOOL render(S32 x, S32 y, S32 width, S32 height); BOOL renderBump(S32 x, S32 y, S32 width,S32 height); BOOL isBodyRegion(const std::string& region) const; LLTexLayerSetBuffer* getComposite(); void requestUpdate(); void requestUpload(); void cancelUpload(); void updateComposite(); BOOL isLocalTextureDataAvailable() const; BOOL isLocalTextureDataFinal() const; void createComposite(); void destroyComposite(); void setUpdatesEnabled(BOOL b); BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } void deleteCaches(); void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); void renderAlphaMaskTextures(S32 width, S32 height, bool forceClear = false); LLTexLayer* findLayerByName(std::string name); LLVOAvatarSelf* getAvatar() const { return mAvatar; } const std::string getBodyRegion() const; BOOL hasComposite() const { return (mComposite.notNull()); } void setBump(BOOL b) { mHasBump = b; } BOOL hasBump() const { return mHasBump; } LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } void setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } public: static BOOL sHasCaches; private: typedef std::vector layer_list_t; layer_list_t mLayerList; layer_list_t mMaskLayerList; LLPointer mComposite; LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer. BOOL mUpdatesEnabled; BOOL mHasBump; LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; const LLTexLayerSetInfo *mInfo; }; // Contains shared layer set data class LLTexLayerSetInfo { friend class LLTexLayerSet; public: LLTexLayerSetInfo(); ~LLTexLayerSetInfo(); BOOL parseXml(LLXmlTreeNode* node); void createVisualParams(LLVOAvatar *avatar); private: std::string mBodyRegion; S32 mWidth; S32 mHeight; std::string mStaticAlphaFileName; BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName) typedef std::vector layer_info_list_t; layer_info_list_t mLayerInfoList; }; // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump); virtual ~LLTexLayerSetBuffer(); virtual void preRender(BOOL clear_depth); virtual void postRender(BOOL success); virtual BOOL render(); BOOL updateImmediate(); void bindBumpTexture(U32 stage); bool isInitialized(void) const; BOOL needsRender(); void requestUpdate(); void requestUpload(); void cancelUpload(); BOOL uploadPending() { return mUploadPending; } BOOL render( S32 x, S32 y, S32 width, S32 height ); void readBackAndUpload(const U8* baked_bump_data); void createBumpTexture(); static void onTextureUploadComplete(const LLUUID& uuid, void* userdata, S32 result, LLExtStat ext_status); static void dumpTotalByteCount(); virtual void restoreGLTexture(); virtual void destroyGLTexture(); private: void pushProjection() const; void popProjection() const; private: const BOOL mHasBump; LLTexLayerSet* const mTexLayerSet; BOOL mNeedsUpdate; BOOL mNeedsUpload; BOOL mUploadPending; LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) LLPointer mBumpTex; // zero if none static S32 sGLByteCount; static S32 sGLBumpByteCount; }; // // LLTexLayerSet //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLTexLayerStaticImageList // class LLTexLayerStaticImageList : public LLSingleton { public: LLTexLayerStaticImageList(); ~LLTexLayerStaticImageList(); LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); void dumpByteCount(); private: BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw); private: LLStringTable mImageNames; typedef std::map< const char*, LLPointer > texture_map_t; texture_map_t mStaticImageList; typedef std::map< const char*, LLPointer > image_tga_map_t; image_tga_map_t mStaticImageListTGA; S32 mGLBytes; S32 mTGABytes; }; // Used by LLTexLayerSetBuffer for a callback. // Note to anyone merging branches - this supercedes the previous fix // for DEV-31590 "Heap corruption and crash after outfit changes", // here and in lltexlayer.cpp. Equally correct and a bit simpler. class LLBakedUploadData { public: LLBakedUploadData(const LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, const LLUUID& id); ~LLBakedUploadData() {} const LLUUID mID; const LLVOAvatarSelf* mAvatar; // just backlink, don't LLPointer LLTexLayerSet* mTexLayerSet; const U64 mStartTime; // Used to measure time baked texture upload requires }; #endif // LL_LLTEXLAYER_H