From 7faa19b29792b558a50b1da2bdfc483f6cc839dd Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 26 Nov 2012 17:04:05 +0100 Subject: [PATCH] Large snapshot update (part 1) This commit concentrates on remembering what parameters where used for the last snapshot (the actual source, not the formatted one), thus - the parameters passed to rawSnapshot() - and then shows this snapshot as if it was just made whenever the UI parameter selection matches. The result is that the user can make a snapshot, save it (for example) to their harddisk and then change the destination and upload the same thing as snapshot. The code tries hard to make this possible by automatically adjusting the UI parameters to match every time the destination is changed PROVIDED it was already saved or uploaded before. If a snapshot wasn't saved and one changes destination then this currently doesn't happen (by you could manually make the parameters match, and still upload it). Also, if the resolution is changed for a particular destination then it won't automatically adjust it again. Obviously, snapshots are no longer refreshed when changing destination etc. You have to explicitly click "Refresh Snapshot" before the last one is deleted / replaced. The Debug Setting variables reflect the (last) manual choices in most cases (set in the onCommit functions). If such a choice is not allowed for a different destination then the UI is changed to reflect the current behavior and the checkbox is disabled so the user can't change it anymore. Then, if they change destination back - the Debug Setting variable is used to remember their last preference. A new Debug Setting has been added for this purpose: SnapshotLayerType (colors or depth). The old mSnapshotUpToDate has been removed and replaced with mShowFreezeFrameSnapshot. The old getSnapshotUpToDate() now returns something else (than mShowFreezeFrameSnapshot), namely whether or not the current raw snapshot was taken with the same parameters as are currently set in the UI. The unused functions getImageAspect() and getAspect() were removed. mCurImageIndex has been deleted. Index 0 now means "the last snapshot" and index 1 is temporarily used for the Falling Away animation. mDataSize was renamed to mFormattedDataSize. The size spinner arrows are now disabled too whenever the spinner edit field is disabled. A bug in Freeze Time was fixed, where avatars would still rotate around their axis in place (and without that their attachments moved!) Pressing ESC would return keyboard control to "walking" for the own avatar with the above as result for the own avatar. We now intercept ESC and use it (in Freeze Time mode) to return to the cammable preview when a 2D preview was being shown. --- indra/newview/app_settings/settings.xml | 11 + indra/newview/llfloatersnapshot.cpp | 728 ++++++++++++------ indra/newview/llfloatersnapshot.h | 1 + indra/newview/llviewerwindow.cpp | 38 +- indra/newview/llviewerwindow.h | 5 +- indra/newview/llvoavatar.cpp | 7 + .../default/xui/en-us/floater_snapshot.xml | 44 +- 7 files changed, 555 insertions(+), 279 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2d6d0185f..6ad0c7bdf 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -13431,6 +13431,17 @@ Found in Advanced->Rendering->Info Displays Value 0 + SnapshotLayerType + + Comment + Save snapshots in this format (0 = Colors, 1 = Depth) + Persist + 1 + Type + S32 + Value + 0 + SnapshotLocalLastResolution Comment diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 49e376ffa..e7700cd65 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -121,6 +121,12 @@ public: SNAPSHOT_LOCAL }; + U32 typeToMask(ESnapshotType type) const { return 1 << type; } + void addUsedBy(ESnapshotType type) { mUsedBy |= typeToMask(type); } + bool isUsedBy(ESnapshotType type) const { return (mUsedBy & typeToMask(type)) != 0; } + bool isUsed(void) const { return mUsedBy; } + void addManualOverride(ESnapshotType type) { mManualSizeOverride |= typeToMask(type); } + bool isOverriddenBy(ESnapshotType type) const { return (mManualSizeOverride & typeToMask(type)) != 0; } LLSnapshotLivePreview(const LLRect& rect); ~LLSnapshotLivePreview(); @@ -130,30 +136,34 @@ public: void setSize(S32 w, S32 h); void getSize(S32& w, S32& h) const; - S32 getDataSize() const { return mDataSize; } + void getUsedSize(S32& w, S32& h) const; + S32 getDataSize() const { return mFormattedDataSize; } void setMaxImageSize(S32 size) ; S32 getMaxImageSize() {return mMaxImageSize ;} ESnapshotType getSnapshotType() const { return mSnapshotType; } LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } - BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } + BOOL rawSnapshotUsesTiling(F32 supersample = 1.f) const; + BOOL getSnapshotUpToDateExceptForSize() const; + BOOL getSnapshotUpToDate() const; BOOL isSnapshotActive() { return mSnapshotActive; } LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; } S32 getThumbnailWidth() const { return mThumbnailWidth ; } S32 getThumbnailHeight() const { return mThumbnailHeight ; } BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; } BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;} + bool getShowFreezeFrameSnapshot() const { return mShowFreezeFrameSnapshot; } LLViewerTexture* getCurrentImage(); - F32 getImageAspect(); - F32 getAspect() ; LLRect getImageRect(); BOOL isImageScaled(); void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; } void setSnapshotQuality(S32 quality); - void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } + void setSnapshotBufferType(LLFloaterSnapshot* floater, LLViewerWindow::ESnapshotType type); + void showFreezeFrameSnapshot(bool show); void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f); + void saveFeed(); LLFloaterPostcard* savePostcard(); void saveTexture(); void saveLocal(); @@ -183,21 +193,29 @@ private: BOOL mThumbnailUpdateLock ; BOOL mThumbnailUpToDate ; - S32 mCurImageIndex; LLPointer mPreviewImage; LLPointer mPreviewImageEncoded; LLPointer mFormattedImage; LLFrameTimer mSnapshotDelayTimer; + U32 mUsedBy; + U32 mManualSizeOverride; S32 mShineCountdown; LLFrameTimer mShineAnimTimer; F32 mFlashAlpha; BOOL mNeedsFlash; LLVector3d mPosTakenGlobal; S32 mSnapshotQuality; - S32 mDataSize; + S32 mFormattedDataSize; ESnapshotType mSnapshotType; LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat; - BOOL mSnapshotUpToDate; + S32 mUpToDateWidth; + S32 mUpToDateHeight; + BOOL mUpToDateUsesTiling; + BOOL mUpToDateRenderUI; + BOOL mUpToDateRenderHUD; + LLViewerWindow::ESnapshotType mUpToDateBufferType; + S32 mUpToDateMaxImageSize; + BOOL mShowFreezeFrameSnapshot; LLFrameTimer mFallAnimTimer; LLVector3 mCameraPos; LLQuaternion mCameraRot; @@ -209,25 +227,86 @@ public: BOOL mKeepAspectRatio ; }; +void LLSnapshotLivePreview::setSnapshotBufferType(LLFloaterSnapshot* floater, LLViewerWindow::ESnapshotType type) +{ + mSnapshotBufferType = type; + switch(type) + { + case LLViewerWindow::SNAPSHOT_TYPE_COLOR: + floater->childSetValue("layer_types", "colors"); + break; + case LLViewerWindow::SNAPSHOT_TYPE_DEPTH: + floater->childSetValue("layer_types", "depth"); + break; + } +} + +// *Currently* LLViewerWindow::rawSnapshot does the exact same thing whether or not +// mKeepAspectRatio is set or not, except for maybe turning on tiling. This function +// determines if that will happen. +BOOL LLSnapshotLivePreview::rawSnapshotUsesTiling(F32 supersample) const +{ + // Assume the width used is the same as last time. Note that when we + // get here via getSnapshotUpToDate() or rawSnapshot() then these are + // just mWidth[0] and mHeight[0]. + S32 image_width = mUpToDateWidth; + S32 image_height = mUpToDateHeight; + // Use same code here as rawSnapshot to determine if tiling will be used. + LLRect const window_rect = gSavedSettings.getBOOL("RenderUIInSnapshot") ? gViewerWindow->getWindowRectRaw() : gViewerWindow->getWorldViewRectRaw(); +#if 1//SHY_MOD // screenshot improvement + F32 internal_scale = llmin(llmax(supersample,1.f),3.f); + // render at specified internal resolution. >1 results in supersampling. + image_height *= internal_scale; + image_width *= internal_scale; +#endif //shy_mod + return mKeepAspectRatio && + (image_width > window_rect.getWidth() || + image_height > window_rect.getHeight()); +} + +BOOL LLSnapshotLivePreview::getSnapshotUpToDateExceptForSize() const +{ + return mUpToDateUsesTiling == rawSnapshotUsesTiling() && + mUpToDateRenderUI == gSavedSettings.getBOOL("RenderUIInSnapshot") && + mUpToDateRenderHUD == gSavedSettings.getBOOL("RenderHUDInSnapshot") && + mUpToDateBufferType == mSnapshotBufferType && + mUpToDateMaxImageSize != 0 && mUpToDateMaxImageSize <= mMaxImageSize; +} + +BOOL LLSnapshotLivePreview::getSnapshotUpToDate() const +{ + return mUpToDateWidth == mWidth[0] && + mUpToDateHeight == mHeight[0] && + getSnapshotUpToDateExceptForSize(); +} + std::set LLSnapshotLivePreview::sList; LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : LLView(std::string("snapshot_live_preview"), rect, FALSE), mColor(1.f, 0.f, 0.f, 0.5f), - mCurImageIndex(0), mPreviewImage(NULL), mThumbnailImage(NULL) , mThumbnailWidth(0), mThumbnailHeight(0), mPreviewImageEncoded(NULL), mFormattedImage(NULL), + mUsedBy(0), + mManualSizeOverride(0), mShineCountdown(0), mFlashAlpha(0.f), mNeedsFlash(TRUE), mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")), - mDataSize(0), + mFormattedDataSize(0), mSnapshotType(SNAPSHOT_FEED), mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))), - mSnapshotUpToDate(FALSE), + mUpToDateWidth(0), + mUpToDateHeight(0), + mUpToDateUsesTiling(FALSE), + mUpToDateRenderUI(FALSE), + mUpToDateRenderHUD(FALSE), + mUpToDateBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), + mUpToDateMaxImageSize(0), + mShowFreezeFrameSnapshot(FALSE), mCameraPos(LLViewerCamera::getInstance()->getOrigin()), mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), mSnapshotActive(FALSE), @@ -279,77 +358,63 @@ void LLSnapshotLivePreview::setMaxImageSize(S32 size) LLViewerTexture* LLSnapshotLivePreview::getCurrentImage() { - return mViewerImage[mCurImageIndex]; -} - -F32 LLSnapshotLivePreview::getAspect() -{ - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); - F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); - - if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) - { - return image_aspect_ratio; - } - else - { - return window_aspect_ratio; - } -} - -F32 LLSnapshotLivePreview::getImageAspect() -{ - if (!mViewerImage[mCurImageIndex]) - { - return 0.f; - } - - return getAspect() ; + return mViewerImage[0]; } LLRect LLSnapshotLivePreview::getImageRect() { - return mImageRect[mCurImageIndex]; + return mImageRect[0]; } BOOL LLSnapshotLivePreview::isImageScaled() { - return mImageScaled[mCurImageIndex]; + return mImageScaled[0]; +} + +void LLSnapshotLivePreview::showFreezeFrameSnapshot(bool show) +{ + DoutEntering(dc::notice, "LLSnapshotLivePreview::showFreezeFrameSnapshot(" << show << ")"); + // If we stop to show the fullscreen "freeze frame" snapshot, play the "fall away" animation. + if (mShowFreezeFrameSnapshot && !show) + { + Dout(dc::notice, "Starting Fall Animation."); + mViewerImage[1] = mViewerImage[0]; + mImageScaled[1] = mImageScaled[0]; + mImageRect[1] = mImageRect[0]; + mWidth[1] = mWidth[0]; + mHeight[1] = mHeight[0]; + mFallAnimTimer.start(); + } + mShowFreezeFrameSnapshot = show; } void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) -{ - if (mSnapshotUpToDate) - { - S32 old_image_index = mCurImageIndex; - mCurImageIndex = (mCurImageIndex + 1) % 2; - mWidth[mCurImageIndex] = mWidth[old_image_index]; - mHeight[mCurImageIndex] = mHeight[old_image_index]; - mFallAnimTimer.start(); - } - mSnapshotUpToDate = FALSE; +{ + DoutEntering(dc::notice, "LLSnapshotLivePreview::updateSnapshot(" << new_snapshot << ", " << new_thumbnail << ", " << delay << ")"); - LLRect& rect = mImageRect[mCurImageIndex]; + LLRect& rect = mImageRect[0]; rect.set(0, getRect().getHeight(), getRect().getWidth(), 0); - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); + F32 image_aspect_ratio = ((F32)mWidth[0]) / ((F32)mHeight[0]); F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); - if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) + if (mKeepAspectRatio) { if (image_aspect_ratio > window_aspect_ratio) { // trim off top and bottom - S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio); - rect.mBottom += (getRect().getHeight() - new_height) / 2; - rect.mTop -= (getRect().getHeight() - new_height) / 2; + S32 height_diff = getRect().getHeight() - llround((F32)getRect().getWidth() / image_aspect_ratio); + S32 half_height_diff = height_diff / 2; + rect.mBottom += half_height_diff; + rect.mTop -= height_diff - half_height_diff; } else if (image_aspect_ratio < window_aspect_ratio) { // trim off left and right - S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio); - rect.mLeft += (getRect().getWidth() - new_width) / 2; - rect.mRight -= (getRect().getWidth() - new_width) / 2; + S32 width_diff = getRect().getWidth() - llround((F32)getRect().getHeight() * image_aspect_ratio); + S32 half_width_diff = width_diff / 2; + rect.mLeft += half_width_diff; + rect.mRight -= width_diff - half_width_diff; } } @@ -385,7 +450,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ; glLineWidth(line_width) ; - //draw four alpha rectangles to cover areas outside of the snapshot image + // Draw two alpha rectangles to cover areas outside of the snapshot image. if(!mKeepAspectRatio) { LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; @@ -417,23 +482,23 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) //called when the frame is frozen. void LLSnapshotLivePreview::draw() { - if (mViewerImage[mCurImageIndex].notNull() && + if (mViewerImage[0].notNull() && mPreviewImageEncoded.notNull() && - mSnapshotUpToDate) + mShowFreezeFrameSnapshot) { LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); gl_rect_2d(getRect(), bg_color); - LLRect &rect = mImageRect[mCurImageIndex]; - LLRect shadow_rect = mImageRect[mCurImageIndex]; + LLRect &rect = mImageRect[0]; + LLRect shadow_rect = mImageRect[0]; shadow_rect.stretch(BORDER_WIDTH); gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10); LLColor4 image_color(1.f, 1.f, 1.f, 1.f); gGL.color4fv(image_color.mV); - gGL.getTexUnit(0)->bind(mViewerImage[mCurImageIndex]); + gGL.getTexUnit(0)->bind(mViewerImage[0]); // calculate UV scale - F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f); - F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f); + F32 uv_width = mImageScaled[0] ? 1.f : llmin((F32)mWidth[0] / (F32)mViewerImage[0]->getWidth(), 1.f); + F32 uv_height = mImageScaled[0] ? 1.f : llmin((F32)mHeight[0] / (F32)mViewerImage[0]->getHeight(), 1.f); gGL.pushMatrix(); { gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f); @@ -531,7 +596,7 @@ void LLSnapshotLivePreview::draw() { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(1.f, 1.f, 1.f, 1.f); - LLRect outline_rect = mImageRect[mCurImageIndex]; + LLRect outline_rect = mImageRect[0]; gGL.begin(LLRender::QUADS); { gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); @@ -560,22 +625,21 @@ void LLSnapshotLivePreview::draw() // draw old image dropping away if (mFallAnimTimer.getStarted()) { - S32 old_image_index = (mCurImageIndex + 1) % 2; - if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) + if (mViewerImage[1].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) { F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME; F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f); LLColor4 image_color(1.f, 1.f, 1.f, alpha); gGL.color4fv(image_color.mV); - gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]); + gGL.getTexUnit(0)->bind(mViewerImage[1]); // calculate UV scale // *FIX get this to work with old image - BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull(); - F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f; - F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f; + BOOL rescale = !mImageScaled[1] && mViewerImage[0].notNull(); + F32 uv_width = rescale ? llmin((F32)mWidth[1] / (F32)mViewerImage[0]->getWidth(), 1.f) : 1.f; + F32 uv_height = rescale ? llmin((F32)mHeight[1] / (F32)mViewerImage[0]->getHeight(), 1.f) : 1.f; gGL.pushMatrix(); { - LLRect& rect = mImageRect[old_image_index]; + LLRect& rect = mImageRect[1]; gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f); gGL.begin(LLRender::QUADS); @@ -612,7 +676,7 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare BOOL LLSnapshotLivePreview::setThumbnailImageSize() { - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(mWidth[0] < 10 || mHeight[0] < 10) { return FALSE ; } @@ -646,11 +710,11 @@ BOOL LLSnapshotLivePreview::setThumbnailImageSize() S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ; if(!mKeepAspectRatio) { - F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ; - F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ; + F32 ratio_x = (F32)mWidth[0] / window_width ; + F32 ratio_y = (F32)mHeight[0] / window_height ; - //if(mWidth[mCurImageIndex] > window_width || - // mHeight[mCurImageIndex] > window_height ) + //if(mWidth[0] > window_width || + // mHeight[0] > window_height ) { if(ratio_x > ratio_y) { @@ -686,7 +750,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) { return ; } - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(mWidth[0] < 10 || mHeight[0] < 10) { return ; } @@ -701,6 +765,8 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) return ; } + Dout(dc::notice, "LLSnapshotLivePreview::generateThumbnailImage: Actually making a new thumbnail!"); + if(mThumbnailImage) { resetThumbnailImage() ; @@ -749,6 +815,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { previewp->mCameraPos = new_camera_pos; previewp->mCameraRot = new_camera_rot; + previewp->showFreezeFrameSnapshot(false); // request a new snapshot whenever the camera moves, with a time delay BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); previewp->updateSnapshot( @@ -779,22 +846,36 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) } previewp->setVisible(FALSE); + Dout(dc::notice, "[1] preview DISabled (" << (void*)previewp); previewp->setEnabled(FALSE); previewp->getWindow()->incBusyCount(); - previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; + previewp->mImageScaled[0] = FALSE; // grab the raw image and encode it into desired format - if(gViewerWindow->rawSnapshot( + Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Actually making a new snapshot!"); + previewp->mFormattedDataSize = 0; // The size of (to be generated) formatted image is unknown. + previewp->mUsedBy = 0; // This snapshot wasn't used yet. + previewp->mManualSizeOverride = 0; + + // Remember with what parameters this snapshot was taken. + previewp->mUpToDateWidth = previewp->mWidth[0]; // These two must be set BEFORE calling rawSnapshotUsesTiling(). + previewp->mUpToDateHeight = previewp->mHeight[0]; + previewp->mUpToDateRenderUI = gSavedSettings.getBOOL("RenderUIInSnapshot"); + previewp->mUpToDateRenderHUD = gSavedSettings.getBOOL("RenderHUDInSnapshot"); + previewp->mUpToDateBufferType = previewp->mSnapshotBufferType; + previewp->mUpToDateUsesTiling = previewp->rawSnapshotUsesTiling(); + + if((previewp->mUpToDateMaxImageSize = gViewerWindow->rawSnapshot( previewp->mPreviewImage, - previewp->mWidth[previewp->mCurImageIndex], - previewp->mHeight[previewp->mCurImageIndex], - previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), - previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, - gSavedSettings.getBOOL("RenderUIInSnapshot"), + previewp->mUpToDateWidth, + previewp->mUpToDateHeight, + previewp->mKeepAspectRatio, + previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, // UNUSED + previewp->mUpToDateRenderUI, FALSE, - previewp->mSnapshotBufferType, - previewp->getMaxImageSize())) + previewp->mUpToDateBufferType, + previewp->getMaxImageSize()))) { previewp->mPreviewImageEncoded->resize( previewp->mPreviewImage->getWidth(), @@ -811,15 +892,18 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->mPreviewImage->getComponents()); scaled->biasedScaleToPowerOfTwo(512); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; + previewp->mImageScaled[0] = TRUE; if (formatted->encode(scaled, 0.f)) { - previewp->mDataSize = formatted->getDataSize(); + previewp->mFormattedDataSize = formatted->getDataSize(); + Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Making a new mPreviewImageEncoded (J2C)!"); formatted->decode(previewp->mPreviewImageEncoded, 0); } } else { + Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Making a new mFormattedImage!"); + // delete any existing image previewp->mFormattedImage = NULL; // now create the new one of the appropriate format. @@ -841,14 +925,16 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) } if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0)) { - previewp->mDataSize = previewp->mFormattedImage->getDataSize(); + previewp->mFormattedDataSize = previewp->mFormattedImage->getDataSize(); // special case BMP to copy instead of decode otherwise decode will crash. if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP) { + Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Making a new mPreviewImageEncoded (BMP)!"); previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage); } else { + Dout(dc::notice, "LLSnapshotLivePreview::onIdle: Making a new mPreviewImageEncoded (" << format << ")!"); previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0); } } @@ -867,7 +953,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { // go ahead and shrink image to appropriate power of 2 for display scaled->biasedScaleToPowerOfTwo(1024); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; + previewp->mImageScaled[0] = TRUE; } else { @@ -875,8 +961,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) scaled->expandToPowerOfTwo(1024, FALSE); } - previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); - LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; + previewp->mViewerImage[0] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); + LLPointer curr_preview_image = previewp->mViewerImage[0]; gGL.getTexUnit(0)->bind(curr_preview_image); if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE) { @@ -888,7 +974,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) } curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP); - previewp->mSnapshotUpToDate = TRUE; + previewp->mShowFreezeFrameSnapshot = TRUE; //Resize to thumbnail. { previewp->mThumbnailUpToDate = TRUE ; @@ -907,7 +993,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) } previewp->getWindow()->decBusyCount(); // only show fullscreen preview when in freeze frame mode - previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame")); + Dout(dc::notice, "Preview setVisible(" << gSavedSettings.getBOOL("FreezeTime") << ")"); + previewp->setVisible(gSavedSettings.getBOOL("FreezeTime")); previewp->mSnapshotDelayTimer.stop(); previewp->mSnapshotActive = FALSE; @@ -921,19 +1008,31 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) void LLSnapshotLivePreview::setSize(S32 w, S32 h) { - mWidth[mCurImageIndex] = w; - mHeight[mCurImageIndex] = h; + Dout(dc::notice, "LLSnapshotLivePreview::setSize(" << w << ", " << h << ")"); + mWidth[0] = w; + mHeight[0] = h; } void LLSnapshotLivePreview::getSize(S32& w, S32& h) const { - w = mWidth[mCurImageIndex]; - h = mHeight[mCurImageIndex]; + w = mWidth[0]; + h = mHeight[0]; +} + +void LLSnapshotLivePreview::getUsedSize(S32& w, S32& h) const +{ + w = mUpToDateWidth; + h = mUpToDateHeight; +} + +void LLSnapshotLivePreview::saveFeed() +{ + addUsedBy(SNAPSHOT_FEED); } LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() { - if(mViewerImage[mCurImageIndex].isNull()) + if(mViewerImage[0].isNull()) { //this should never happen!! llwarns << "The snapshot image has not been generated!" << llendl ; @@ -945,7 +1044,7 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() LLVector2 image_scale(1.f, 1.f); if (!isImageScaled()) { - image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight())); + image_scale.setVec(llmin(1.f, (F32)mWidth[0] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[0] / (F32)getCurrentImage()->getHeight())); } LLImageJPEG* jpg = dynamic_cast(mFormattedImage.get()); @@ -954,12 +1053,13 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() llwarns << "Formatted image not a JPEG" << llendl; return NULL; } - LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal); + LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[0], image_scale, mPosTakenGlobal); // relinquish lifetime of jpeg image to postcard floater mFormattedImage = NULL; - mDataSize = 0; + mFormattedDataSize = 0; updateSnapshot(FALSE, FALSE); + addUsedBy(SNAPSHOT_POSTCARD); return floater; } @@ -1010,7 +1110,8 @@ void LLSnapshotLivePreview::saveTexture() LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); - mDataSize = 0; + mFormattedDataSize = 0; + addUsedBy(SNAPSHOT_TEXTURE); } void LLSnapshotLivePreview::saveLocal() @@ -1019,8 +1120,9 @@ void LLSnapshotLivePreview::saveLocal() // Relinquish image memory. Save button will be disabled as a side-effect. mFormattedImage = NULL; - mDataSize = 0; + mFormattedDataSize = 0; updateSnapshot(FALSE, FALSE); + addUsedBy(SNAPSHOT_LOCAL); } ///---------------------------------------------------------------------------- @@ -1055,8 +1157,11 @@ public: static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data); static void onCommitQuality(LLUICtrl* ctrl, void* data); - static void onCommitResolution(LLUICtrl* ctrl, void* data) { updateResolution(ctrl, data); } - static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE); + static void onCommitFeedResolution(LLUICtrl* ctrl, void* data); + static void onCommitPostcardResolution(LLUICtrl* ctrl, void* data); + static void onCommitTextureResolution(LLUICtrl* ctrl, void* data); + static void onCommitLocalResolution(LLUICtrl* ctrl, void* data); + static void updateResolution(LLUICtrl* ctrl, void* data, bool update_controls = true); static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); @@ -1066,7 +1171,7 @@ public: static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); - static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); + static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls = true); static void updateControls(LLFloaterSnapshot* floater); static void updateLayout(LLFloaterSnapshot* floater); static void updateResolutionTextEntry(LLFloaterSnapshot* floater); @@ -1077,7 +1182,6 @@ public: private: static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater); - static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ; @@ -1134,27 +1238,12 @@ LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFlo return index; } - - // static -LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) -{ - LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - LLSD value = floater->childGetValue("layer_types"); - const std::string id = value.asString(); - if (id == "colors") - type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - else if (id == "depth") - type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH; - return type; -} - -// static -void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname) +void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls) { LLComboBox* combo = floater->getChild(comboname); combo->setVisible(TRUE); - updateResolution(combo, floater, FALSE); // to sync spinners with combo + updateResolution(combo, floater, update_controls); // to sync spinners with combo } //static @@ -1166,7 +1255,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution { - previewp->mKeepAspectRatio = TRUE; + checkAspectRatio(floaterp, 0); // 0 means current window size. floaterp->getChild("feed_size_combo")->setCurrentByIndex(0); gSavedSettings.setS32("SnapshotFeedLastResolution", 0); @@ -1181,12 +1270,16 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) gSavedSettings.setS32("SnapshotLocalLastResolution", 0); LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + S32 w, h; + previewp->getSize(w, h); + if (gViewerWindow->getWindowDisplayWidth() != w || gViewerWindow->getWindowDisplayHeight() != h) + { + previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + updateControls(floaterp); + } } - bool use_freeze_frame = floaterp->childGetValue("freeze_frame_check").asBoolean(); - - if (use_freeze_frame) + if (gSavedSettings.getBOOL("UseFreezeFrame")) { // stop all mouse events at fullscreen preview layer floaterp->getParent()->setMouseOpaque(TRUE); @@ -1198,6 +1291,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) if (previewp) { previewp->setVisible(TRUE); + Dout(dc::notice, "[1] preview ENabled (" << (void*)previewp); previewp->setEnabled(TRUE); } @@ -1226,6 +1320,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) if (previewp) { previewp->setVisible(FALSE); + Dout(dc::notice, "[2] preview DISabled (" << (void*)previewp); previewp->setEnabled(FALSE); } @@ -1251,6 +1346,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) // static void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) { + DoutEntering(dc::notice, "LLFloaterSnapshot::Impl::updateControls()"); std::string fee = gHippoGridManager->getConnectedGrid()->getUploadFee(); if (gSavedSettings.getBOOL("TemporaryUpload")) { @@ -1258,10 +1354,11 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) } floater->childSetLabelArg("upload_btn", "[UPLOADFEE]", fee); + LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType"); LLRadioGroup* snapshot_type_radio = floater->getChild("snapshot_type_radio"); if (snapshot_type_radio) { - snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType")); + snapshot_type_radio->setSelectedIndex(shot_type); const child_list_t *childs = snapshot_type_radio->getChildList(); if (childs) @@ -1277,20 +1374,47 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) } } } - LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); - ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater); LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); - LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); + ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); floater->childSetVisible("feed_size_combo", FALSE); floater->childSetVisible("postcard_size_combo", FALSE); floater->childSetVisible("texture_size_combo", FALSE); floater->childSetVisible("local_size_combo", FALSE); - floater->getChild("feed_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastResolution")); - floater->getChild("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); - floater->getChild("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); - floater->getChild("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); - floater->getChild("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); + LLSnapshotLivePreview* previewp = getPreviewView(floater); + if (previewp) + { + LLViewerWindow::ESnapshotType layer_type = + (shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL) ? + (LLViewerWindow::ESnapshotType)gSavedSettings.getS32("SnapshotLayerType") : + LLViewerWindow::SNAPSHOT_TYPE_COLOR; + // Do this before calling setResolution(). + previewp->setSnapshotBufferType(floater, layer_type); + } + BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot"); + if (is_advance) + { + switch(shot_type) + { + case LLSnapshotLivePreview::SNAPSHOT_FEED: + setResolution(floater, "feed_size_combo", false); + break; + case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: + setResolution(floater, "postcard_size_combo", false); + break; + case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: + setResolution(floater, "texture_size_combo", false); + break; + case LLSnapshotLivePreview::SNAPSHOT_LOCAL: + setResolution(floater, "local_size_combo", false); + break; + default: + break; + } + } + updateResolutionTextEntry(floater); + + floater->getChild("local_format_combo")->selectNthItem(shot_format); floater->childSetVisible("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE); floater->childSetVisible("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD); @@ -1299,7 +1423,6 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff); floater->childSetEnabled("layer_types", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); - BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot"); BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL; BOOL show_slider = shot_type == LLSnapshotLivePreview::SNAPSHOT_FEED || @@ -1324,72 +1447,45 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->childSetVisible("image_quality_slider", is_advance && show_slider); floater->childSetVisible("temp_check", is_advance); - LLSnapshotLivePreview* previewp = getPreviewView(floater); BOOL got_bytes = previewp && previewp->getDataSize() > 0; - BOOL got_snap = previewp->getSnapshotUpToDate(); BOOL is_texture = shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE; - floater->childSetEnabled("feed_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_FEED && got_snap); - floater->childSetEnabled("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_snap && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE); - floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE && got_snap); - floater->childSetEnabled("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL && got_snap); - floater->childSetEnabled("temp_check", is_advance && is_texture); - LLLocale locale(LLLocale::USER_LOCALE); std::string bytes_string; - LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); + if (got_bytes) + { + LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); + } + else + { + bytes_string = floater->getString("unknown"); + } S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); floater->childSetLabelArg("texture", "[AMOUNT]", llformat("%d",upload_cost)); floater->childSetLabelArg("upload_btn", "[AMOUNT]", llformat("%d",upload_cost)); - floater->childSetTextArg("file_size_label", "[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); + floater->childSetTextArg("file_size_label", "[SIZE]", bytes_string); floater->childSetColor("file_size_label", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_bytes && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : gColors.getColor( "LabelTextColor" )); - switch(shot_type) - { - case LLSnapshotLivePreview::SNAPSHOT_FEED: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - floater->childSetValue("layer_types", "colors"); - if(is_advance) - { - setResolution(floater, "feed_size_combo"); - } - break; - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - floater->childSetValue("layer_types", "colors"); - if(is_advance) - { - setResolution(floater, "postcard_size_combo"); - } - break; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - floater->childSetValue("layer_types", "colors"); - if(is_advance) - { - setResolution(floater, "texture_size_combo"); - } - break; - case LLSnapshotLivePreview::SNAPSHOT_LOCAL: - if(is_advance) - { - setResolution(floater, "local_size_combo"); - } - break; - default: - break; - } - - updateResolutionTextEntry(floater); - if (previewp) { previewp->setSnapshotType(shot_type); previewp->setSnapshotFormat(shot_format); - previewp->setSnapshotBufferType(layer_type); + } + + bool up_to_date = previewp && previewp->getSnapshotUpToDate(); + bool can_upload = up_to_date && !previewp->isUsedBy(shot_type); + floater->childSetEnabled("feed_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_FEED && can_upload); + floater->childSetEnabled("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && can_upload && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE); + floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE && can_upload); + floater->childSetEnabled("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL && can_upload); + floater->childSetEnabled("temp_check", is_advance && is_texture); + + if (previewp) + { + previewp->showFreezeFrameSnapshot(up_to_date); } } @@ -1399,15 +1495,22 @@ void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* float LLSpinCtrl* width_spinner = floater->getChild("snapshot_width"); LLSpinCtrl* height_spinner = floater->getChild("snapshot_height"); - if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (gSavedSettings.getS32("LastSnapshotType") == LLSnapshotLivePreview::SNAPSHOT_TEXTURE || + gSavedSettings.getBOOL("RenderUIInSnapshot") || + gSavedSettings.getBOOL("RenderHUDInSnapshot")) { + // Disable without making label gray. width_spinner->setAllowEdit(FALSE); + width_spinner->setIncrement(0); height_spinner->setAllowEdit(FALSE); + height_spinner->setIncrement(0); } else { width_spinner->setAllowEdit(TRUE); + width_spinner->setIncrement(32); height_spinner->setAllowEdit(TRUE); + height_spinner->setIncrement(32); } } @@ -1431,6 +1534,61 @@ void LLFloaterSnapshot::Impl::onClickDiscard(void* data) } } +// static +void LLFloaterSnapshot::Impl::onCommitFeedResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotFeedLastResolution", combobox->getCurrentIndex()); + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(view); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitPostcardResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotPostcardLastResolution", combobox->getCurrentIndex()); + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(view); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitTextureResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotTextureLastResolution", combobox->getCurrentIndex()); + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(view); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitLocalResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotLocalLastResolution", combobox->getCurrentIndex()); + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(view); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL); + } + updateResolution(ctrl, data); +} // static void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data) @@ -1450,7 +1608,11 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data) if (previewp) { - if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) + if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_FEED) + { + previewp->saveFeed(); + } + else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) { LLFloaterPostcard* floater = previewp->savePostcard(); // if still in snapshot mode, put postcard floater in snapshot floaterview @@ -1609,9 +1771,10 @@ void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize())) { resetSnapshotSizeOnUI(view, w, h) ; + previewp->setSize(w, h) ; + updateControls(view); } - previewp->setSize(w, h) ; previewp->updateSnapshot(FALSE, TRUE); checkAutoSnapshot(previewp, TRUE); } @@ -1653,19 +1816,11 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde { LLSnapshotLivePreview *previewp = getPreviewView(view) ; - // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here -#if 0 - if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view)) - { - previewp->mKeepAspectRatio = FALSE ; - return ; - } -#endif - if(0 == index) //current window size { sAspectRatioCheckOff = TRUE ; view->childSetEnabled("keep_aspect_check", FALSE) ; + view->childSetValue("keep_aspect_check", TRUE); if(previewp) { @@ -1677,11 +1832,13 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde sAspectRatioCheckOff = FALSE ; //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType")) { + bool custom_keep_aspect_ratio = gSavedSettings.getBOOL("KeepAspectForSnapshot"); view->childSetEnabled("keep_aspect_check", TRUE) ; + view->childSetValue("keep_aspect_check", custom_keep_aspect_ratio); if(previewp) { - previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; + previewp->mKeepAspectRatio = custom_keep_aspect_ratio; } } } @@ -1689,6 +1846,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde { sAspectRatioCheckOff = TRUE ; view->childSetEnabled("keep_aspect_check", FALSE) ; + view->childSetValue("keep_aspect_check", FALSE); if(previewp) { @@ -1721,7 +1879,7 @@ static std::string lastSnapshotHeightName() } // static -void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update) +void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool update_controls) { LLComboBox* combobox = (LLComboBox*)ctrl; LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; @@ -1731,11 +1889,91 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL return; } - // save off all selected resolution values - gSavedSettings.setS32("SnapshotFeedLastResolution", view->getChild("feed_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotPostcardLastResolution", view->getChild("postcard_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotTextureLastResolution", view->getChild("texture_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotLocalLastResolution", view->getChild("local_size_combo")->getCurrentIndex()); + S32 used_w = 0; + S32 used_h = 0; + LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType"); + + bool up_to_date_now = false; + bool up_to_date_after_toggling = false; + if (previewp && previewp->isUsed() && !previewp->isOverriddenBy(shot_type)) + { + up_to_date_now = previewp->getSnapshotUpToDateExceptForSize(); + previewp->mKeepAspectRatio = !previewp->mKeepAspectRatio; + up_to_date_after_toggling = previewp->getSnapshotUpToDateExceptForSize(); + previewp->mKeepAspectRatio = !previewp->mKeepAspectRatio; + } + if (up_to_date_now || up_to_date_after_toggling) + { + // need_keep_aspect is set when mKeepAspectRatio makes a difference. + bool need_keep_aspect = up_to_date_now != up_to_date_after_toggling; + + // Force the size, and possibly mKeepAspectRatio, to be the one of the existing snapshot. + previewp->getUsedSize(used_w, used_h); + LLComboBox* combo_box = NULL; + switch(shot_type) + { + case LLSnapshotLivePreview::SNAPSHOT_FEED: + combo_box = view->getChild("feed_size_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: + combo_box = view->getChild("postcard_size_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: + combo_box = view->getChild("texture_size_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_LOCAL: + combo_box = view->getChild("local_size_combo"); + break; + } + S32 index = 0; + bool keep_aspect = true; + bool needed_keep_aspect = up_to_date_now ? previewp->mKeepAspectRatio : !previewp->mKeepAspectRatio; // Only valid if need_keep_aspect is true. + S32 const custom = combo_box->getItemCount() - 1; + while (index < custom) + { + if (!need_keep_aspect || keep_aspect == needed_keep_aspect) + { + combo_box->setCurrentByIndex(index); + std::string sdstring = combobox->getSelectedValue(); + LLSD sdres; + std::stringstream sstream(sdstring); + LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); + S32 width = sdres[0]; + S32 height = sdres[1]; + if (width == 0 || height == 0) + { + width = gViewerWindow->getWindowDisplayWidth(); + height = gViewerWindow->getWindowDisplayHeight(); + } + if (width == used_w && height == used_h) + { + Dout(dc::notice, "Selected entry " << index << " with size " << width << "x" << height); + break; + } + } + ++index; + keep_aspect = false; + } + if (index == custom) + { + combo_box->setCurrentByIndex(index); + Dout(dc::notice, "Selected entry Custom"); + if (need_keep_aspect) + { + // Change mKeepAspectRatio to needed_keep_aspect. + gSavedSettings.setBOOL("KeepAspectForSnapshot", needed_keep_aspect); + checkAspectRatio(view, -1); // -1 means custom. + } + } + } + else + { + view->getChild("feed_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastResolution")); + view->getChild("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); + view->getChild("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); + view->getChild("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); + } std::string sdstring = combobox->getSelectedValue(); LLSD sdres; @@ -1745,12 +1983,10 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL S32 width = sdres[0]; S32 height = sdres[1]; - LLSnapshotLivePreview* previewp = getPreviewView(view); if (previewp && combobox->getCurrentIndex() >= 0) { S32 original_width = 0 , original_height = 0 ; previewp->getSize(original_width, original_height) ; - if (width == 0 || height == 0 || gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) { // take resolution from current window size @@ -1758,8 +1994,15 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL } else if (width == -1 || height == -1) { - // load last custom value - previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName())); + if (previewp->isUsed()) + { + previewp->setSize(used_w, used_h); + } + else + { + // load last custom value + previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName())); + } } else { @@ -1789,7 +2032,8 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL // hide old preview as the aspect ratio could be wrong checkAutoSnapshot(previewp, FALSE); getPreviewView(view)->updateSnapshot(FALSE, TRUE); - if(do_update) + + if (update_controls) { updateControls(view); } @@ -1800,18 +2044,12 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL // static void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) { - LLComboBox* combobox = (LLComboBox*)ctrl; - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) { - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp) - { - previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex()); - } - checkAutoSnapshot(previewp, TRUE); + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotLayerType", combobox->getCurrentIndex()); + updateControls(view); } } @@ -1822,7 +2060,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) if (view) { gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); updateControls(view); } } @@ -1835,7 +2072,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) if (view) { gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); updateControls(view); } } @@ -2107,10 +2343,10 @@ BOOL LLFloaterSnapshot::postBuild() childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); childSetCommitCallback("temp_check", Impl::onClickTemporaryImage, this); - childSetCommitCallback("feed_size_combo", Impl::onCommitResolution, this); - childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this); - childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this); - childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this); + childSetCommitCallback("feed_size_combo", Impl::onCommitFeedResolution, this); + childSetCommitCallback("postcard_size_combo", Impl::onCommitPostcardResolution, this); + childSetCommitCallback("texture_size_combo", Impl::onCommitTextureResolution, this); + childSetCommitCallback("local_size_combo", Impl::onCommitLocalResolution, this); // create preview window LLRect full_screen_rect = sInstance->getRootView()->getRect(); @@ -2188,14 +2424,6 @@ void LLFloaterSnapshot::show(void*) sInstance->impl.updateLayout(sInstance); } - else // just refresh the snapshot in the existing floater instance (DEV-12255) - { - LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance); - if(preview) - { - preview->updateSnapshot(TRUE); - } - } sInstance->open(); /* Flawfinder: ignore */ sInstance->focusFirstItem(FALSE); @@ -2227,6 +2455,28 @@ void LLFloaterSnapshot::update() } } +BOOL LLFloaterSnapshot::handleKeyHere(KEY key, MASK mask) +{ + static const LLCachedControl freeze_time("FreezeTime",false); + if (freeze_time && key == KEY_ESCAPE && mask == MASK_NONE) + { + // Ignore trying to defocus the snapshot floater in Freeze Time mode. + // However, if we're showing the fullscreen frozen preview, drop out of it; + // otherwise, reset the cam. + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(this); + if (previewp && previewp->getShowFreezeFrameSnapshot()) + { + previewp->showFreezeFrameSnapshot(false); + } + else + { + gAgentCamera.resetCamera(); // AIFIXME: This doesn't work! It should reset the camera view to behind the avatar again. + } + return TRUE; + } + return LLFloater::handleKeyHere(key, mask); +} + ///---------------------------------------------------------------------------- /// Class LLSnapshotFloaterView diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 8fb51c945..60ecf5483 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -57,6 +57,7 @@ public: /*virtual*/ void draw(); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void onOpen(); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); static void show(void*); static void hide(void*); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1c4bdfcff..bbfbf83dc 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4286,24 +4286,24 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p } // Saves the image from the screen to the specified filename and path. -BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, - BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size, F32 supersample) +S32 LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, + BOOL keep_window_aspect, BOOL /*is_texture*/, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size, F32 supersample) { if (!raw) { - return FALSE; + return 0; } //check if there is enough memory for the snapshot image if(LLPipeline::sMemAllocationThrottled) { - return FALSE ; //snapshot taking is disabled due to memory restriction. + return 0; //snapshot taking is disabled due to memory restriction. } if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K { if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) { llwarns << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << llendl ; - return FALSE ; //there is no enough memory for taking this snapshot. + return 0; //there is no enough memory for taking this snapshot. } } @@ -4331,17 +4331,15 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // Copy screen to a buffer // crop sides or top and bottom, if taking a snapshot of different aspect ratio // from window - LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); + LLRect const window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); + + S32 const window_width = window_rect.getWidth(); + S32 const window_height = window_rect.getHeight(); - S32 snapshot_width = window_rect.getWidth(); - S32 snapshot_height = window_rect.getHeight(); // SNAPSHOT - S32 window_width = snapshot_width; - S32 window_height = snapshot_height; - - + S32 snapshot_width = window_width; + S32 snapshot_height = window_height; F32 scale_factor = 1.0f ; - bool is_tiling = false; //fbo method no longer supported. Good riddance @@ -4409,6 +4407,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei snapshot_width = (S32)(ratio * image_width) ; snapshot_height = (S32)(ratio * image_height) ; scale_factor = llmax(1.0f, 1.0f / ratio) ; + Dout(dc::warning, "USING TILING FOR SNAPSHOT!"); is_tiling = true; } } @@ -4420,10 +4419,11 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ; S32 image_buffer_y = llfloor(snapshot_height*scale_factor) ; + S32 max_image_buffer = llmax(image_buffer_x, image_buffer_y); #if 1//SHY_MOD // screenshot improvement if(internal_scale <= 1.f) //If supersampling... Don't care about max_size. #endif //shy_mod - if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow + if(max_image_buffer > max_size) //boundary check to avoid memory overflow { scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; image_buffer_x = llfloor(snapshot_width*scale_factor) ; @@ -4435,11 +4435,11 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei } else { - return FALSE ; + return 0; } if(raw->isBufferInvalid()) { - return FALSE ; + return 0; } BOOL high_res = scale_factor > 1.f; @@ -4591,11 +4591,11 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei #if 1//SHY_MOD // screenshot improvement if(raw->isBufferInvalid()) //Just checking! - return FALSE; + return 0; if(internal_scale != 1.f) //Scale down our render to the desired dimensions. raw->scale( image_width/internal_scale, image_height/internal_scale ); if(raw->isBufferInvalid()) //Just checking! - return FALSE; + return 0; #endif //shy_mod setCursor(UI_CURSOR_ARROW); @@ -4615,7 +4615,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei send_agent_resume(); } - return ret; + return ret ? max_image_buffer : 0; } void LLViewerWindow::destroyWindow() diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 30848b386..f3190b197 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -308,10 +308,11 @@ public: enum ESnapshotType { SNAPSHOT_TYPE_COLOR, - SNAPSHOT_TYPE_DEPTH, + SNAPSHOT_TYPE_DEPTH }; BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR); - BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, + // Returns the largest dimension (x or y) of the buffer (which is never larger than max_size), or 0 on failure. + S32 rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE, F32 supersample = 1.f ); BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 19bd366b4..424bdf23f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4099,6 +4099,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLMemType mt(LLMemType::MTYPE_AVATAR); + // Frozen! + if (areAnimationsPaused()) + { + updateMotions(LLCharacter::NORMAL_UPDATE); // This is necessary to get unpaused again. + return FALSE; + } + // clear debug text mDebugText.clear(); if (LLVOAvatar::sShowAnimationDebug) diff --git a/indra/newview/skins/default/xui/en-us/floater_snapshot.xml b/indra/newview/skins/default/xui/en-us/floater_snapshot.xml index ad2387c26..7998d62aa 100644 --- a/indra/newview/skins/default/xui/en-us/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en-us/floater_snapshot.xml @@ -17,10 +17,10 @@ Send via email - Save to your inventory ([UPLOADFEE]) + Save to my inventory ([UPLOADFEE]) - Save to your hard drive + Save to my hard drive