diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-09-09 00:00:22 +0300 | 
|---|---|---|
| committer | akleshchev <117672381+akleshchev@users.noreply.github.com> | 2023-09-10 21:49:00 +0300 | 
| commit | cfb69846f1e8309ed86d4a18eb26a889f6dbaccc (patch) | |
| tree | cb5507d1d5a8600f312d3b25d404fd2c50384050 /indra/newview | |
| parent | 46425b2e49377acc186e41c67a793f7f6b7f583b (diff) | |
SL-20261 Allow and resize existing textures as necessary for thumbnails
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.cpp | 132 | ||||
| -rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.h | 9 | ||||
| -rw-r--r-- | indra/newview/llfloatersimplesnapshot.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llfloatersimplesnapshot.h | 1 | ||||
| -rw-r--r-- | indra/newview/llsnapshotlivepreview.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.cpp | 39 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.h | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_texture_ctrl.xml | 2 | 
10 files changed, 197 insertions, 44 deletions
| diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 77212507ab..780130039b 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -512,6 +512,13 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata)                  asset_id = potential_uuid;              }          } + +        LLInventoryObject* obj = self->getInventoryObject(); +        if (obj && obj->getThumbnailUUID() == asset_id) +        { +            // nothing to do +            return; +        }          if (asset_id.notNull())          {              self->assignAndValidateAsset(asset_id); @@ -547,6 +554,8 @@ struct ImageLoadedData      LLUUID mObjectId;      LLHandle<LLFloater> mFloaterHandle;      bool mSilent; +    // Keep image reference to prevent deletion on timeout +    LLPointer<LLViewerFetchedTexture> mTexturep;  };  void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) @@ -576,8 +585,9 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id          data->mThumbnailId = asset_id;          data->mFloaterHandle = getHandle();          data->mSilent = silent; +        data->mTexturep = texturep; -        texturep->setLoadedCallback(onImageLoaded, +        texturep->setLoadedCallback(onImageDataLoaded,              MAX_DISCARD_LEVEL, // Don't need full image, just size data              FALSE,              FALSE, @@ -636,7 +646,7 @@ bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id)  }  //static -void LLFloaterChangeItemThumbnail::onImageLoaded( +void LLFloaterChangeItemThumbnail::onImageDataLoaded(      BOOL success,      LLViewerFetchedTexture *src_vi,      LLImageRaw* src, @@ -678,6 +688,45 @@ void LLFloaterChangeItemThumbnail::onImageLoaded(      delete data;  } +//static +void LLFloaterChangeItemThumbnail::onFullImageLoaded( +    BOOL success, +    LLViewerFetchedTexture* src_vi, +    LLImageRaw* src, +    LLImageRaw* aux_src, +    S32 discard_level, +    BOOL final, +    void* userdata) +{ +    if (!userdata) return; + +    if (!final && success) return; //not done yet + +    ImageLoadedData* data = (ImageLoadedData*)userdata; + +    if (success) +    { +        if (src_vi->getFullWidth() != src_vi->getFullHeight() +            || src_vi->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN) +        { +            if (!data->mSilent) +            { +                LLNotificationsUtil::add("ThumbnailDimentionsLimit"); +            } +        } +        else if (src_vi->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX) +        { +            LLFloaterSimpleSnapshot::uploadThumbnail(src, data->mObjectId, LLUUID::null); +        } +        else +        { +            setThumbnailId(data->mThumbnailId, data->mObjectId); +        } +    } + +    delete data; +} +  void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)  {      // show hourglass cursor when loading inventory window @@ -725,8 +774,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)              texture_floaterp->setBakeTextureEnabled(FALSE);              texture_floaterp->setCanApplyImmediately(false);              texture_floaterp->setCanApply(false, true, false /*Hide 'preview disabled'*/); -            texture_floaterp->setDimentionsLimits(LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX, -                                                 LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN); +            texture_floaterp->setMinDimentionsLimits(LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN);              addDependentFloater(texture_floaterp);          } @@ -743,14 +791,86 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit()      if (floaterp)      {          LLUUID asset_id = floaterp->getAssetID(); -        if (validateAsset(asset_id)) + +        if (asset_id.isNull())          {              setThumbnailId(asset_id); +            return;          } -        else + +        LLInventoryObject* obj = getInventoryObject(); +        if (obj && obj->getThumbnailUUID() == asset_id) +        { +            // nothing to do +            return; +        } + +        LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::findFetchedTexture(asset_id, TEX_LIST_STANDARD); +        if (!texturep) +        { +            LL_WARNS() << "Image " << asset_id << " doesn't exist" << LL_ENDL; +            return; +        } + +        if (texturep->isMissingAsset()) +        { +            LL_WARNS() << "Image " << asset_id << " is missing" << LL_ENDL; +            return; +        } + +        if (texturep->getFullWidth() != texturep->getFullHeight()) +        { +            LLNotificationsUtil::add("ThumbnailDimentionsLimit"); +            return; +        } + +        if (texturep->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN +            && texturep->getFullWidth() > 0)          {              LLNotificationsUtil::add("ThumbnailDimentionsLimit"); +            return; +        } + +        if (texturep->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX +            || texturep->getFullWidth() == 0) +        { +            if (texturep->isFullyLoaded() +                && (texturep->getCachedRawImageLevel() == 0 || texturep->getRawImageLevel() == 0) +                && (texturep->isCachedRawImageReady() || texturep->isRawImageValid())) +            { +                if (texturep->isRawImageValid()) +                { +                    LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(), mItemId, mTaskId); +                } +                else +                { +                    LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(), mItemId, mTaskId); +                } +            } +            else +            { +                ImageLoadedData* data = new ImageLoadedData(); +                data->mObjectId = mItemId; +                data->mThumbnailId = asset_id; +                data->mFloaterHandle = getHandle(); +                data->mSilent = false; +                data->mTexturep = texturep; + +                texturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); +                texturep->setMinDiscardLevel(0); +                texturep->setLoadedCallback(onFullImageLoaded, +                                            0, // Need best quality +                                            TRUE, +                                            FALSE, +                                            (void*)data, +                                            NULL, +                                            FALSE); +                texturep->forceToSaveRawImage(0); +            } +            return;          } + +        setThumbnailId(asset_id);      }  } diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h index 02f934337b..a91e9b8ee9 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.h +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -83,13 +83,20 @@ private:      static void onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle);      void assignAndValidateAsset(const LLUUID &asset_id, bool silent = false); -    static void onImageLoaded(BOOL success, +    static void onImageDataLoaded(BOOL success,          LLViewerFetchedTexture *src_vi,          LLImageRaw* src,          LLImageRaw* aux_src,          S32 discard_level,          BOOL final,          void* userdata); +    static void onFullImageLoaded(BOOL success, +                                  LLViewerFetchedTexture* src_vi, +                                  LLImageRaw* src, +                                  LLImageRaw* aux_src, +                                  S32 discard_level, +                                  BOOL final, +                                  void* userdata);      void showTexturePicker(const LLUUID &thumbnail_id);      void onTexturePickerCommit(); diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp index 757ac605e3..58604c5628 100644 --- a/indra/newview/llfloatersimplesnapshot.cpp +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -398,6 +398,21 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, cons  }  // static +void LLFloaterSimpleSnapshot::uploadThumbnail(LLPointer<LLImageRaw> raw_image, const LLUUID& inventory_id, const LLUUID& task_id) +{ +    std::string temp_file = gDirUtilp->getTempFilename(); +    if (!LLViewerTextureList::createUploadFile(raw_image, temp_file, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN)) +    { +        LLSD notif_args; +        notif_args["REASON"] = LLImage::getLastError().c_str(); +        LLNotificationsUtil::add("CannotUploadTexture", notif_args); +        LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; +        return; +    } +    uploadImageUploadFile(temp_file, inventory_id, task_id); +} + +// static  void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id)  {      LLSD data; diff --git a/indra/newview/llfloatersimplesnapshot.h b/indra/newview/llfloatersimplesnapshot.h index a2bf2946d4..91a81ee5c3 100644 --- a/indra/newview/llfloatersimplesnapshot.h +++ b/indra/newview/llfloatersimplesnapshot.h @@ -63,6 +63,7 @@ public:      void postSave();      static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id); +    static void uploadThumbnail(LLPointer<LLImageRaw> raw_image, const LLUUID& inventory_id, const LLUUID& task_id);      class Impl;      friend class Impl; diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 37ebcd1266..b7a1832b17 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -876,37 +876,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()  bool LLSnapshotLivePreview::createUploadFile(const std::string &out_filename, const S32 max_image_dimentions, const S32 min_image_dimentions)  { -    // make a copy, since convertToUploadFile modifies raw image -    LLPointer<LLImageRaw> raw_image = new LLImageRaw( -        mPreviewImage->getData(), -        mPreviewImage->getWidth(), -        mPreviewImage->getHeight(), -        mPreviewImage->getComponents()); - -    LLPointer<LLImageJ2C> compressedImage = LLViewerTextureList::convertToUploadFile(raw_image, max_image_dimentions); -    if (compressedImage->getWidth() < min_image_dimentions || compressedImage->getHeight() < min_image_dimentions) -    { -        std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", -            min_image_dimentions, -            min_image_dimentions, -            compressedImage->getWidth(), -            compressedImage->getHeight()); -        compressedImage->setLastError(reason); -        return FALSE; -    } -    if (compressedImage.isNull()) -    { -        compressedImage->setLastError("Couldn't convert the image to jpeg2000."); -        LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; -        return false; -    } -    if (!compressedImage->save(out_filename)) -    { -        compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); -        LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; -        return false; -    } -    return true; +    return LLViewerTextureList::createUploadFile(mPreviewImage, out_filename, max_image_dimentions, min_image_dimentions);  }  // We actually estimate the data size so that we do not require actual compression when showing the preview diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index a746744e53..0c3730d084 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1197,15 +1197,12 @@ void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool  	mPreviewSettingChanged = true;  } -void LLFloaterTexturePicker::setDimentionsLimits(S32 max_dim, S32 min_dim) +void LLFloaterTexturePicker::setMinDimentionsLimits(S32 min_dim)  { -    mMaxDim = max_dim;      mMinDim = min_dim;      std::string formatted_dims = llformat("%dx%d", mMinDim, mMinDim);      mResolutionWarning->setTextArg("[MINTEXDIM]", formatted_dims); -    formatted_dims = llformat("%dx%d", mMaxDim, mMaxDim); -    mResolutionWarning->setTextArg("[MAXTEXDIM]", formatted_dims);  }  void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 60543191b6..7239b97552 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -323,7 +323,7 @@ public:  	void onFilterEdit(const std::string& search_string);  	void setCanApply(bool can_preview, bool can_apply, bool inworld_image = true); -    void setDimentionsLimits(S32 max_dim, S32 min_dim); +    void setMinDimentionsLimits(S32 min_dim);  	void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }  	void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }  	void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d10e1ea8c9..f9fe8054a4 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1285,6 +1285,45 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  	<< LL_ENDL;  } +bool LLViewerTextureList::createUploadFile(LLPointer<LLImageRaw> raw_image, +                                           const std::string& out_filename, +                                           const S32 max_image_dimentions, +                                           const S32 min_image_dimentions) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + +    // make a copy, since convertToUploadFile scales raw image +    LLPointer<LLImageRaw> scale_image = new LLImageRaw( +        raw_image->getData(), +        raw_image->getWidth(), +        raw_image->getHeight(), +        raw_image->getComponents()); + +    LLPointer<LLImageJ2C> compressedImage = LLViewerTextureList::convertToUploadFile(scale_image, max_image_dimentions); +    if (compressedImage->getWidth() < min_image_dimentions || compressedImage->getHeight() < min_image_dimentions) +    { +        std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", +                                      min_image_dimentions, +                                      min_image_dimentions, +                                      compressedImage->getWidth(), +                                      compressedImage->getHeight()); +        compressedImage->setLastError(reason); +        return false; +    } +    if (compressedImage.isNull()) +    { +        compressedImage->setLastError("Couldn't convert the image to jpeg2000."); +        LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; +        return false; +    } +    if (!compressedImage->save(out_filename)) +    { +        compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); +        LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; +        return false; +    } +    return true; +}  BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  										 const std::string& out_filename, diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 8fc65fc9ce..82dec6b329 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -92,6 +92,10 @@ class LLViewerTextureList  	friend class LLLocalBitmap;  public: +    static bool createUploadFile(LLPointer<LLImageRaw> 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, diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index 771113d989..8081af6673 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -96,7 +96,7 @@       name="over_limit_lbl"       visible="false"       top_delta="0"> -        Selected texture is [TEXDIM]. Inventory image must be square, between [MINTEXDIM] and [MAXTEXDIM]. +        Selected texture is [TEXDIM]. Inventory image must be square, no less than [MINTEXDIM].      </text>  <!--  middle: inventory mode --> | 
