aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloatersnapshot.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-09-06 18:24:57 -0500
committerJacek Antonelli2008-09-06 18:25:07 -0500
commit798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch)
tree1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llfloatersnapshot.cpp
parentSecond Life viewer sources 1.20.15 (diff)
downloadmeta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz
Second Life viewer sources 1.21.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloatersnapshot.cpp636
1 files changed, 352 insertions, 284 deletions
diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp
index 291c437..954bf9f 100644
--- a/linden/indra/newview/llfloatersnapshot.cpp
+++ b/linden/indra/newview/llfloatersnapshot.cpp
@@ -68,6 +68,8 @@
68#include "llgl.h" 68#include "llgl.h"
69#include "llglheaders.h" 69#include "llglheaders.h"
70#include "llimagejpeg.h" 70#include "llimagejpeg.h"
71#include "llimagepng.h"
72#include "llimagebmp.h"
71#include "llimagej2c.h" 73#include "llimagej2c.h"
72#include "llvfile.h" 74#include "llvfile.h"
73#include "llvfs.h" 75#include "llvfs.h"
@@ -83,7 +85,7 @@ LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
83 85
84LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL; 86LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL;
85 87
86const F32 SNAPSHOT_TIME_DELAY = 1.f; 88const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
87 89
88F32 SHINE_TIME = 0.5f; 90F32 SHINE_TIME = 0.5f;
89F32 SHINE_WIDTH = 0.6f; 91F32 SHINE_WIDTH = 0.6f;
@@ -93,6 +95,7 @@ S32 BORDER_WIDTH = 6;
93 95
94const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte 96const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
95const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 97const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
98
96///---------------------------------------------------------------------------- 99///----------------------------------------------------------------------------
97/// Class LLSnapshotLivePreview 100/// Class LLSnapshotLivePreview
98///---------------------------------------------------------------------------- 101///----------------------------------------------------------------------------
@@ -103,9 +106,10 @@ public:
103 { 106 {
104 SNAPSHOT_POSTCARD, 107 SNAPSHOT_POSTCARD,
105 SNAPSHOT_TEXTURE, 108 SNAPSHOT_TEXTURE,
106 SNAPSHOT_BITMAP 109 SNAPSHOT_LOCAL
107 }; 110 };
108 111
112
109 LLSnapshotLivePreview(const LLRect& rect); 113 LLSnapshotLivePreview(const LLRect& rect);
110 ~LLSnapshotLivePreview(); 114 ~LLSnapshotLivePreview();
111 115
@@ -119,6 +123,7 @@ public:
119 S32 getMaxImageSize() {return mMaxImageSize ;} 123 S32 getMaxImageSize() {return mMaxImageSize ;}
120 124
121 ESnapshotType getSnapshotType() const { return mSnapshotType; } 125 ESnapshotType getSnapshotType() const { return mSnapshotType; }
126 LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
122 BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } 127 BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
123 BOOL isSnapshotActive() { return mSnapshotActive; } 128 BOOL isSnapshotActive() { return mSnapshotActive; }
124 LLImageGL* getThumbnailImage() const { return mThumbnailImage ; } 129 LLImageGL* getThumbnailImage() const { return mThumbnailImage ; }
@@ -133,9 +138,10 @@ public:
133 BOOL isImageScaled(); 138 BOOL isImageScaled();
134 139
135 void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } 140 void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
141 void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
136 void setSnapshotQuality(S32 quality); 142 void setSnapshotQuality(S32 quality);
137 void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } 143 void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
138 void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE); 144 void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
139 LLFloaterPostcard* savePostcard(); 145 LLFloaterPostcard* savePostcard();
140 void saveTexture(); 146 void saveTexture();
141 BOOL saveLocal(); 147 BOOL saveLocal();
@@ -147,7 +153,7 @@ public:
147 153
148 static void onIdle( void* snapshot_preview ); 154 static void onIdle( void* snapshot_preview );
149 155
150protected: 156private:
151 LLColor4 mColor; 157 LLColor4 mColor;
152 LLPointer<LLImageGL> mViewerImage[2]; //used to represent the scene when the frame is frozen. 158 LLPointer<LLImageGL> mViewerImage[2]; //used to represent the scene when the frame is frozen.
153 LLRect mImageRect[2]; 159 LLRect mImageRect[2];
@@ -165,9 +171,9 @@ protected:
165 BOOL mThumbnailUpToDate ; 171 BOOL mThumbnailUpToDate ;
166 172
167 S32 mCurImageIndex; 173 S32 mCurImageIndex;
168 LLPointer<LLImageRaw> mRawImage; 174 LLPointer<LLImageRaw> mPreviewImage;
169 LLPointer<LLImageRaw> mRawImageEncoded; 175 LLPointer<LLImageRaw> mPreviewImageEncoded;
170 LLPointer<LLImageJPEG> mJPEGImage; 176 LLPointer<LLImageFormatted> mFormattedImage;
171 LLFrameTimer mSnapshotDelayTimer; 177 LLFrameTimer mSnapshotDelayTimer;
172 S32 mShineCountdown; 178 S32 mShineCountdown;
173 LLFrameTimer mShineAnimTimer; 179 LLFrameTimer mShineAnimTimer;
@@ -177,6 +183,7 @@ protected:
177 S32 mSnapshotQuality; 183 S32 mSnapshotQuality;
178 S32 mDataSize; 184 S32 mDataSize;
179 ESnapshotType mSnapshotType; 185 ESnapshotType mSnapshotType;
186 LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat;
180 BOOL mSnapshotUpToDate; 187 BOOL mSnapshotUpToDate;
181 LLFrameTimer mFallAnimTimer; 188 LLFrameTimer mFallAnimTimer;
182 LLVector3 mCameraPos; 189 LLVector3 mCameraPos;
@@ -191,25 +198,27 @@ public:
191 198
192std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList; 199std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
193LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : 200LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
194 LLView("snapshot_live_preview", rect, FALSE), 201 LLView(std::string("snapshot_live_preview"), rect, FALSE),
195 mColor(1.f, 0.f, 0.f, 0.5f), 202 mColor(1.f, 0.f, 0.f, 0.5f),
196 mCurImageIndex(0), 203 mCurImageIndex(0),
197 mRawImage(NULL), 204 mPreviewImage(NULL),
198 mThumbnailImage(NULL) , 205 mThumbnailImage(NULL) ,
199 mRawImageEncoded(NULL), 206 mPreviewImageEncoded(NULL),
200 mJPEGImage(NULL), 207 mFormattedImage(NULL),
201 mShineCountdown(0), 208 mShineCountdown(0),
202 mFlashAlpha(0.f), 209 mFlashAlpha(0.f),
203 mNeedsFlash(TRUE), 210 mNeedsFlash(TRUE),
204 mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")), 211 mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
205 mDataSize(0), 212 mDataSize(0),
206 mSnapshotType(SNAPSHOT_POSTCARD), 213 mSnapshotType(SNAPSHOT_POSTCARD),
214 mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
207 mSnapshotUpToDate(FALSE), 215 mSnapshotUpToDate(FALSE),
208 mCameraPos(LLViewerCamera::getInstance()->getOrigin()), 216 mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
209 mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), 217 mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
210 mSnapshotActive(FALSE), 218 mSnapshotActive(FALSE),
211 mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR) 219 mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR)
212{ 220{
221 setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
213 mSnapshotDelayTimer.setTimerExpirySec(0.0f); 222 mSnapshotDelayTimer.setTimerExpirySec(0.0f);
214 mSnapshotDelayTimer.start(); 223 mSnapshotDelayTimer.start();
215// gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); 224// gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
@@ -231,9 +240,9 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
231LLSnapshotLivePreview::~LLSnapshotLivePreview() 240LLSnapshotLivePreview::~LLSnapshotLivePreview()
232{ 241{
233 // delete images 242 // delete images
234 mRawImage = NULL; 243 mPreviewImage = NULL;
235 mRawImageEncoded = NULL; 244 mPreviewImageEncoded = NULL;
236 mJPEGImage = NULL; 245 mFormattedImage = NULL;
237 246
238// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); 247// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
239 sList.erase(this); 248 sList.erase(this);
@@ -291,7 +300,7 @@ BOOL LLSnapshotLivePreview::isImageScaled()
291 return mImageScaled[mCurImageIndex]; 300 return mImageScaled[mCurImageIndex];
292} 301}
293 302
294void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail) 303void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)
295{ 304{
296 if (mSnapshotUpToDate) 305 if (mSnapshotUpToDate)
297 { 306 {
@@ -331,7 +340,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
331 if (new_snapshot) 340 if (new_snapshot)
332 { 341 {
333 mSnapshotDelayTimer.start(); 342 mSnapshotDelayTimer.start();
334 mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY); 343 mSnapshotDelayTimer.setTimerExpirySec(delay);
335 } 344 }
336 else if(new_thumbnail) 345 else if(new_thumbnail)
337 { 346 {
@@ -345,6 +354,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
345 354
346void LLSnapshotLivePreview::setSnapshotQuality(S32 quality) 355void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
347{ 356{
357 llclamp(quality, 0, 100);
348 if (quality != mSnapshotQuality) 358 if (quality != mSnapshotQuality)
349 { 359 {
350 mSnapshotQuality = quality; 360 mSnapshotQuality = quality;
@@ -395,7 +405,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
395void LLSnapshotLivePreview::draw() 405void LLSnapshotLivePreview::draw()
396{ 406{
397 if (mViewerImage[mCurImageIndex].notNull() && 407 if (mViewerImage[mCurImageIndex].notNull() &&
398 mRawImageEncoded.notNull() && 408 mPreviewImageEncoded.notNull() &&
399 mSnapshotUpToDate) 409 mSnapshotUpToDate)
400 { 410 {
401 LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); 411 LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
@@ -684,8 +694,8 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
684 694
685 LLPointer<LLImageRaw> raw = NULL ; 695 LLPointer<LLImageRaw> raw = NULL ;
686 S32 w , h ; 696 S32 w , h ;
687 w = get_nearest_power_two(mThumbnailWidth, 512) * 2 ; 697 w = get_lower_power_two(mThumbnailWidth, 512) * 2 ;
688 h = get_nearest_power_two(mThumbnailHeight, 512) * 2 ; 698 h = get_lower_power_two(mThumbnailHeight, 512) * 2 ;
689 699
690 { 700 {
691 raw = new LLImageRaw ; 701 raw = new LLImageRaw ;
@@ -722,124 +732,145 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
722 previewp->mCameraPos = new_camera_pos; 732 previewp->mCameraPos = new_camera_pos;
723 previewp->mCameraRot = new_camera_rot; 733 previewp->mCameraRot = new_camera_rot;
724 // request a new snapshot whenever the camera moves, with a time delay 734 // request a new snapshot whenever the camera moves, with a time delay
725 previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); 735 BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
736 previewp->updateSnapshot(autosnap, FALSE, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
737 }
738
739 // see if it's time yet to snap the shot and bomb out otherwise.
740 previewp->mSnapshotActive =
741 (previewp->mSnapshotDelayTimer.getStarted() && previewp->mSnapshotDelayTimer.hasExpired())
742 && !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
743 if ( ! previewp->mSnapshotActive)
744 {
745 return;
726 } 746 }
727 747
728 previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() && 748 // time to produce a snapshot
729 previewp->mSnapshotDelayTimer.hasExpired());
730 749
731 // don't take snapshots while ALT-zoom active 750 if (!previewp->mPreviewImage)
732 if (LLToolCamera::getInstance()->hasMouseCapture())
733 { 751 {
734 previewp->mSnapshotActive = FALSE; 752 previewp->mPreviewImage = new LLImageRaw;
735 } 753 }
736 754
737 if (previewp->mSnapshotActive) 755 if (!previewp->mPreviewImageEncoded)
738 { 756 {
739 if (!previewp->mRawImage) 757 previewp->mPreviewImageEncoded = new LLImageRaw;
740 { 758 }
741 previewp->mRawImage = new LLImageRaw;
742 }
743 759
744 if (!previewp->mRawImageEncoded) 760 previewp->setVisible(FALSE);
761 previewp->setEnabled(FALSE);
762
763 previewp->getWindow()->incBusyCount();
764 previewp->mImageScaled[previewp->mCurImageIndex] = FALSE;
765
766 // grab the raw image and encode it into desired format
767 if(gViewerWindow->rawSnapshot(
768 previewp->mPreviewImage,
769 previewp->mWidth[previewp->mCurImageIndex],
770 previewp->mHeight[previewp->mCurImageIndex],
771 previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
772 previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
773 gSavedSettings.getBOOL("RenderUIInSnapshot"),
774 FALSE,
775 previewp->mSnapshotBufferType,
776 previewp->getMaxImageSize()))
777 {
778 previewp->mPreviewImageEncoded->resize(
779 previewp->mPreviewImage->getWidth(),
780 previewp->mPreviewImage->getHeight(),
781 previewp->mPreviewImage->getComponents());
782
783 if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
745 { 784 {
746 previewp->mRawImageEncoded = new LLImageRaw; 785 LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
747 } 786 LLPointer<LLImageRaw> scaled = new LLImageRaw(
748 787 previewp->mPreviewImage->getData(),
749 previewp->setVisible(FALSE); 788 previewp->mPreviewImage->getWidth(),
750 previewp->setEnabled(FALSE); 789 previewp->mPreviewImage->getHeight(),
790 previewp->mPreviewImage->getComponents());
751 791
752 previewp->getWindow()->incBusyCount(); 792 scaled->biasedScaleToPowerOfTwo(512);
753 previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; 793 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
754 794 if (formatted->encode(scaled, 0.f))
755 // do update 795 {
756 if(gViewerWindow->rawSnapshot(previewp->mRawImage, 796 previewp->mDataSize = formatted->getDataSize();
757 previewp->mWidth[previewp->mCurImageIndex], 797 formatted->decode(previewp->mPreviewImageEncoded, 0);
758 previewp->mHeight[previewp->mCurImageIndex], 798 }
759 previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), 799 }
760 previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, 800 else
761 gSavedSettings.getBOOL("RenderUIInSnapshot"),
762 FALSE,
763 previewp->mSnapshotBufferType,
764 previewp->getMaxImageSize()))
765 { 801 {
766 previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents()); 802 // delete any existing image
767 803 previewp->mFormattedImage = NULL;
768 if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD) 804 // now create the new one of the appropriate format.
805 // note: postcards hardcoded to use jpeg always.
806 LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotType() == SNAPSHOT_POSTCARD
807 ? LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG : previewp->getSnapshotFormat();
808 switch(format)
769 { 809 {
770 // *FIX: just resize and reuse existing jpeg? 810 case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
771 previewp->mJPEGImage = NULL; // deletes image 811 previewp->mFormattedImage = new LLImagePNG();
772 previewp->mJPEGImage = new LLImageJPEG(); 812 break;
773 previewp->mJPEGImage->setEncodeQuality(llclamp(previewp->mSnapshotQuality, 0, 100)); 813 case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
774 if (previewp->mJPEGImage->encode(previewp->mRawImage, 0.0f)) 814 previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality);
815 break;
816 case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
817 previewp->mFormattedImage = new LLImageBMP();
818 break;
819 }
820 if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
821 {
822 // special case BMP to copy instead of decode otherwise decode will crash.
823 if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
824 {
825 previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
826 }
827 else
775 { 828 {
776 previewp->mDataSize = previewp->mJPEGImage->getDataSize(); 829 previewp->mDataSize = previewp->mFormattedImage->getDataSize();
777 previewp->mJPEGImage->decode(previewp->mRawImageEncoded, 0.0f); 830 previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
778 } 831 }
779 } 832 }
780 else if (previewp->getSnapshotType() == SNAPSHOT_TEXTURE) 833 }
834
835 LLPointer<LLImageRaw> scaled = new LLImageRaw(
836 previewp->mPreviewImageEncoded->getData(),
837 previewp->mPreviewImageEncoded->getWidth(),
838 previewp->mPreviewImageEncoded->getHeight(),
839 previewp->mPreviewImageEncoded->getComponents());
840
841 if(!scaled->isBufferInvalid())
842 {
843 // leave original image dimensions, just scale up texture buffer
844 if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
781 { 845 {
782 LLPointer<LLImageJ2C> formatted = new LLImageJ2C; 846 // go ahead and shrink image to appropriate power of 2 for display
783 LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImage->getData(), 847 scaled->biasedScaleToPowerOfTwo(1024);
784 previewp->mRawImage->getWidth(),
785 previewp->mRawImage->getHeight(),
786 previewp->mRawImage->getComponents());
787
788 scaled->biasedScaleToPowerOfTwo(512);
789 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; 848 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
790 if (formatted->encode(scaled, 0.0f))
791 {
792 previewp->mDataSize = formatted->getDataSize();
793 formatted->decode(previewp->mRawImageEncoded, 0.0f);
794 }
795 } 849 }
796 else 850 else
797 { 851 {
798 previewp->mRawImageEncoded->copy(previewp->mRawImage); 852 // expand image but keep original image data intact
799 previewp->mDataSize = previewp->mRawImage->getDataSize(); 853 scaled->expandToPowerOfTwo(1024, FALSE);
800 } 854 }
801 855
802 // 856 previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
803 //the mViewerImage is used to represent the scene when the frame is frozen. 857 previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
804 // 858 LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
805 LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImageEncoded->getData(), 859 previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
806 previewp->mRawImageEncoded->getWidth(),
807 previewp->mRawImageEncoded->getHeight(),
808 previewp->mRawImageEncoded->getComponents());
809
810 if(!scaled->isBufferInvalid())
811 {
812 // leave original image dimensions, just scale up texture buffer
813 if (previewp->mRawImageEncoded->getWidth() > 1024 || previewp->mRawImageEncoded->getHeight() > 1024)
814 {
815 // go ahead and shrink image to appropriate power of 2 for display
816 scaled->biasedScaleToPowerOfTwo(1024);
817 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
818 }
819 else
820 {
821 // expand image but keep original image data intact
822 scaled->expandToPowerOfTwo(1024, FALSE);
823 }
824
825 previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
826 previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
827 LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
828 previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
829 860
830 previewp->mSnapshotUpToDate = TRUE; 861 previewp->mSnapshotUpToDate = TRUE;
831 previewp->generateThumbnailImage(TRUE) ; 862 previewp->generateThumbnailImage(TRUE) ;
832 863
833 previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); 864 previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
834 previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame 865 previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
835 }
836 } 866 }
837 previewp->getWindow()->decBusyCount();
838 // only show fullscreen preview when in freeze frame mode
839 previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
840 previewp->mSnapshotDelayTimer.stop();
841 previewp->mSnapshotActive = FALSE;
842 } 867 }
868 previewp->getWindow()->decBusyCount();
869 // only show fullscreen preview when in freeze frame mode
870 previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
871 previewp->mSnapshotDelayTimer.stop();
872 previewp->mSnapshotActive = FALSE;
873
843 if(!previewp->getThumbnailUpToDate()) 874 if(!previewp->getThumbnailUpToDate())
844 { 875 {
845 previewp->generateThumbnailImage() ; 876 previewp->generateThumbnailImage() ;
@@ -868,11 +899,16 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard()
868 image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight())); 899 image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight()));
869 } 900 }
870 901
871 902 LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
872 LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(mJPEGImage, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal); 903 if(!jpg)
904 {
905 llwarns << "Formatted image not a JPEG" << llendl;
906 return NULL;
907 }
908 LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);
873 // relinquish lifetime of viewerimage and jpeg image to postcard floater 909 // relinquish lifetime of viewerimage and jpeg image to postcard floater
874 mViewerImage[mCurImageIndex] = NULL; 910 mViewerImage[mCurImageIndex] = NULL;
875 mJPEGImage = NULL; 911 mFormattedImage = NULL;
876 912
877 return floater; 913 return floater;
878} 914}
@@ -885,10 +921,10 @@ void LLSnapshotLivePreview::saveTexture()
885 LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); 921 LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
886 922
887 LLPointer<LLImageJ2C> formatted = new LLImageJ2C; 923 LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
888 LLPointer<LLImageRaw> scaled = new LLImageRaw(mRawImage->getData(), 924 LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
889 mRawImage->getWidth(), 925 mPreviewImage->getWidth(),
890 mRawImage->getHeight(), 926 mPreviewImage->getHeight(),
891 mRawImage->getComponents()); 927 mPreviewImage->getComponents());
892 928
893 scaled->biasedScaleToPowerOfTwo(512); 929 scaled->biasedScaleToPowerOfTwo(512);
894 930
@@ -921,7 +957,7 @@ void LLSnapshotLivePreview::saveTexture()
921 957
922BOOL LLSnapshotLivePreview::saveLocal() 958BOOL LLSnapshotLivePreview::saveLocal()
923{ 959{
924 BOOL success = gViewerWindow->saveImageNumbered(mRawImage); 960 BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
925 if(success) 961 if(success)
926 { 962 {
927 gViewerWindow->playSnapshotAnimAndSound(); 963 gViewerWindow->playSnapshotAnimAndSound();
@@ -949,6 +985,7 @@ public:
949 } 985 }
950 static void onClickDiscard(void* data); 986 static void onClickDiscard(void* data);
951 static void onClickKeep(void* data); 987 static void onClickKeep(void* data);
988 static void onCommitSave(LLUICtrl* ctrl, void* data);
952 static void onClickNewSnapshot(void* data); 989 static void onClickNewSnapshot(void* data);
953 static void onClickAutoSnap(LLUICtrl *ctrl, void* data); 990 static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
954 //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); 991 //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
@@ -963,6 +1000,7 @@ public:
963 static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); 1000 static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
964 static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); 1001 static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
965 static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); 1002 static void onCommitSnapshotType(LLUICtrl* ctrl, void* data);
1003 static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data);
966 static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); 1004 static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);
967 static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ; 1005 static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;
968 static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); 1006 static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
@@ -971,12 +1009,14 @@ public:
971 static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); 1009 static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);
972 static void updateControls(LLFloaterSnapshot* floater); 1010 static void updateControls(LLFloaterSnapshot* floater);
973 static void updateLayout(LLFloaterSnapshot* floater); 1011 static void updateLayout(LLFloaterSnapshot* floater);
1012 static void updateResolutionTextEntry(LLFloaterSnapshot* floater);
974 1013
975 static LLHandle<LLView> sPreviewHandle; 1014 static LLHandle<LLView> sPreviewHandle;
976 static BOOL sAspectRatioCheckOff ; 1015 static BOOL sAspectRatioCheckOff ;
977 1016
978private: 1017private:
979 static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); 1018 static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater);
1019 static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater);
980 static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); 1020 static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);
981 static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); 1021 static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);
982 static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); 1022 static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
@@ -993,6 +1033,7 @@ LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;
993 1033
994//static 1034//static
995BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ; 1035BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ;
1036
996// static 1037// static
997LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) 1038LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
998{ 1039{
@@ -1011,10 +1052,28 @@ LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFlo
1011 else if (id == "texture") 1052 else if (id == "texture")
1012 index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE; 1053 index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
1013 else if (id == "local") 1054 else if (id == "local")
1014 index = LLSnapshotLivePreview::SNAPSHOT_BITMAP; 1055 index = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
1056 return index;
1057}
1058
1059
1060// static
1061LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFloaterSnapshot* floater)
1062{
1063 ESnapshotFormat index = SNAPSHOT_FORMAT_PNG;
1064 LLSD value = floater->childGetValue("local_format_combo");
1065 const std::string id = value.asString();
1066 if (id == "PNG")
1067 index = SNAPSHOT_FORMAT_PNG;
1068 else if (id == "JPEG")
1069 index = SNAPSHOT_FORMAT_JPEG;
1070 else if (id == "BMP")
1071 index = SNAPSHOT_FORMAT_BMP;
1015 return index; 1072 return index;
1016} 1073}
1017 1074
1075
1076
1018// static 1077// static
1019LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) 1078LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)
1020{ 1079{
@@ -1132,10 +1191,10 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
1132// static 1191// static
1133void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) 1192void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
1134{ 1193{
1135 BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot") ;
1136 LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio"); 1194 LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio");
1137 snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType")); 1195 snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType"));
1138 LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); 1196 LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater);
1197 ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater); LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
1139 LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); 1198 LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
1140 1199
1141 floater->childSetVisible("postcard_size_combo", FALSE); 1200 floater->childSetVisible("postcard_size_combo", FALSE);
@@ -1149,114 +1208,102 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
1149 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); 1208 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
1150 combo = floater->getChild<LLComboBox>("local_size_combo"); 1209 combo = floater->getChild<LLComboBox>("local_size_combo");
1151 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); 1210 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
1152 1211 combo = floater->getChild<LLComboBox>("local_format_combo");
1153 floater->childSetVisible("upload_btn", FALSE); 1212 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
1154 floater->childSetVisible("send_btn", FALSE); 1213
1155 floater->childSetVisible("save_btn", FALSE); 1214 floater->childSetVisible("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE);
1156 floater->childSetEnabled("keep_aspect_check", FALSE) ; 1215 floater->childSetVisible("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
1216 floater->childSetVisible("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
1217 floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff);
1218 floater->childSetEnabled("layer_types", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
1219
1220 BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot");
1221 BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL;
1222 BOOL show_slider =
1223 shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
1224 || (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
1225
1226 floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode
1227 floater->childSetVisible("less_btn", is_advance);
1228 floater->childSetVisible("type_label2", is_advance);
1229 floater->childSetVisible("format_label", is_advance && is_local);
1230 floater->childSetVisible("local_format_combo", is_advance && is_local);
1231 floater->childSetVisible("layer_types", is_advance);
1232 floater->childSetVisible("layer_type_label", is_advance);
1233 floater->childSetVisible("snapshot_width", is_advance);
1234 floater->childSetVisible("snapshot_height", is_advance);
1235 floater->childSetVisible("keep_aspect_check", is_advance);
1236 floater->childSetVisible("ui_check", is_advance);
1237 floater->childSetVisible("hud_check", is_advance);
1238 floater->childSetVisible("keep_open_check", is_advance);
1239 floater->childSetVisible("freeze_frame_check", is_advance);
1240 floater->childSetVisible("auto_snapshot_check", is_advance);
1241 floater->childSetVisible("image_quality_slider", is_advance && show_slider);
1157 1242
1158 switch(shot_type) 1243 switch(shot_type)
1159 { 1244 {
1160 case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: 1245 case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
1161 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; 1246 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
1162 floater->childSetValue("layer_types", "colors"); 1247 floater->childSetValue("layer_types", "colors");
1163 floater->childSetEnabled("layer_types", FALSE);
1164
1165 if(is_advance) 1248 if(is_advance)
1166 { 1249 {
1167 floater->childSetEnabled("image_quality_slider", TRUE);
1168 setResolution(floater, "postcard_size_combo"); 1250 setResolution(floater, "postcard_size_combo");
1169
1170 if(!sAspectRatioCheckOff)
1171 {
1172 floater->childSetEnabled("keep_aspect_check", TRUE) ;
1173 }
1174 } 1251 }
1175
1176 floater->childSetVisible("send_btn", TRUE);
1177 break; 1252 break;
1178 case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: 1253 case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
1179 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; 1254 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
1180 floater->childSetValue("layer_types", "colors"); 1255 floater->childSetValue("layer_types", "colors");
1181 floater->childSetEnabled("layer_types", FALSE);
1182 floater->childSetEnabled("image_quality_slider", FALSE);
1183
1184 if(is_advance) 1256 if(is_advance)
1185 { 1257 {
1186 setResolution(floater, "texture_size_combo"); 1258 setResolution(floater, "texture_size_combo");
1187 } 1259 }
1188
1189 floater->childSetVisible("upload_btn", TRUE);
1190 break; 1260 break;
1191 case LLSnapshotLivePreview::SNAPSHOT_BITMAP: 1261 case LLSnapshotLivePreview::SNAPSHOT_LOCAL:
1192 floater->childSetEnabled("layer_types", TRUE);
1193 floater->childSetEnabled("image_quality_slider", FALSE);
1194
1195 if(is_advance) 1262 if(is_advance)
1196 { 1263 {
1197 setResolution(floater, "local_size_combo"); 1264 setResolution(floater, "local_size_combo");
1198
1199 if(!sAspectRatioCheckOff)
1200 {
1201 floater->childSetEnabled("keep_aspect_check", TRUE) ;
1202 }
1203 } 1265 }
1204
1205 floater->childSetVisible("save_btn", TRUE);
1206 break; 1266 break;
1207 default: 1267 default:
1208 break; 1268 break;
1209 } 1269 }
1210 1270
1211 if(is_advance) 1271 updateResolutionTextEntry(floater);
1212 {
1213 floater->childSetVisible("type_label2", TRUE) ;
1214 floater->childSetVisible("layer_types", TRUE) ;
1215 floater->childSetVisible("layer_type_label", TRUE) ;
1216 floater->childSetVisible("snapshot_width", TRUE) ;
1217 floater->childSetVisible("snapshot_height", TRUE) ;
1218 floater->childSetVisible("keep_aspect_check", TRUE) ;
1219 floater->childSetVisible("ui_check", TRUE) ;
1220 floater->childSetVisible("hud_check", TRUE) ;
1221 floater->childSetVisible("keep_open_check", TRUE) ;
1222 floater->childSetVisible("freeze_frame_check", TRUE) ;
1223 floater->childSetVisible("auto_snapshot_check", TRUE) ;
1224 floater->childSetVisible("image_quality_slider", TRUE);
1225 floater->childSetVisible("more_btn", FALSE);
1226 floater->childSetVisible("less_btn", TRUE);
1227 }
1228 else
1229 {
1230 floater->childSetVisible("type_label2", FALSE) ;
1231 floater->childSetVisible("layer_types", FALSE) ;
1232 floater->childSetVisible("layer_type_label", FALSE) ;
1233 floater->childSetVisible("snapshot_width", FALSE) ;
1234 floater->childSetVisible("snapshot_height", FALSE) ;
1235 floater->childSetVisible("keep_aspect_check", FALSE) ;
1236 floater->childSetVisible("ui_check", FALSE) ;
1237 floater->childSetVisible("hud_check", FALSE) ;
1238 floater->childSetVisible("keep_open_check", FALSE) ;
1239 floater->childSetVisible("freeze_frame_check", FALSE) ;
1240 floater->childSetVisible("auto_snapshot_check", FALSE) ;
1241 floater->childSetVisible("image_quality_slider", FALSE);
1242 floater->childSetVisible("more_btn", TRUE);
1243 floater->childSetVisible("less_btn", FALSE);
1244 }
1245 1272
1246 LLSnapshotLivePreview* previewp = getPreviewView(floater); 1273 LLSnapshotLivePreview* previewp = getPreviewView(floater);
1247 if (previewp) 1274 if (previewp)
1248 { 1275 {
1249 previewp->setSnapshotType(shot_type); 1276 previewp->setSnapshotType(shot_type);
1277 previewp->setSnapshotFormat(shot_format);
1250 previewp->setSnapshotBufferType(layer_type); 1278 previewp->setSnapshotBufferType(layer_type);
1251 } 1279 }
1252} 1280}
1253 1281
1254// static 1282// static
1283void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* floater)
1284{
1285 LLSpinCtrl* width_spinner = floater->getChild<LLSpinCtrl>("snapshot_width");
1286 LLSpinCtrl* height_spinner = floater->getChild<LLSpinCtrl>("snapshot_height");
1287
1288 if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
1289 {
1290 width_spinner->setAllowEdit(FALSE);
1291 height_spinner->setAllowEdit(FALSE);
1292 }
1293 else
1294 {
1295 width_spinner->setAllowEdit(TRUE);
1296 height_spinner->setAllowEdit(TRUE);
1297 }
1298}
1299
1300// static
1255void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail) 1301void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
1256{ 1302{
1257 if (previewp) 1303 if (previewp)
1258 { 1304 {
1259 previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"), update_thumbnail); 1305 BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
1306 previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
1260 } 1307 }
1261} 1308}
1262 1309
@@ -1270,6 +1317,17 @@ void LLFloaterSnapshot::Impl::onClickDiscard(void* data)
1270 } 1317 }
1271} 1318}
1272 1319
1320
1321// static
1322void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data)
1323{
1324 if (ctrl->getValue().asString() == "save as")
1325 {
1326 gViewerWindow->resetSnapshotLoc();
1327 }
1328 onClickKeep(data);
1329}
1330
1273// static 1331// static
1274void LLFloaterSnapshot::Impl::onClickKeep(void* data) 1332void LLFloaterSnapshot::Impl::onClickKeep(void* data)
1275{ 1333{
@@ -1283,7 +1341,7 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)
1283 LLFloaterPostcard* floater = previewp->savePostcard(); 1341 LLFloaterPostcard* floater = previewp->savePostcard();
1284 // if still in snapshot mode, put postcard floater in snapshot floaterview 1342 // if still in snapshot mode, put postcard floater in snapshot floaterview
1285 // and link it to snapshot floater 1343 // and link it to snapshot floater
1286 if (!gSavedSettings.getBOOL("CloseSnapshotOnKeep")) 1344 if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
1287 { 1345 {
1288 gFloaterView->removeChild(floater); 1346 gFloaterView->removeChild(floater);
1289 gSnapshotFloaterView->addChild(floater); 1347 gSnapshotFloaterView->addChild(floater);
@@ -1463,13 +1521,16 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
1463void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index) 1521void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index)
1464{ 1522{
1465 LLSnapshotLivePreview *previewp = getPreviewView(view) ; 1523 LLSnapshotLivePreview *previewp = getPreviewView(view) ;
1466
1467 //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view))
1468 //{
1469 // previewp->mKeepAspectRatio = FALSE ;
1470 // return ;
1471 //}
1472 1524
1525 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
1526#if 0
1527 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view))
1528 {
1529 previewp->mKeepAspectRatio = FALSE ;
1530 return ;
1531 }
1532#endif
1533
1473 if(!index) //current window size 1534 if(!index) //current window size
1474 { 1535 {
1475 sAspectRatioCheckOff = TRUE ; 1536 sAspectRatioCheckOff = TRUE ;
@@ -1599,6 +1660,22 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)
1599 } 1660 }
1600} 1661}
1601 1662
1663
1664//static
1665void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data)
1666{
1667 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
1668 if (view)
1669 {
1670 gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view));
1671 getPreviewView(view)->updateSnapshot(TRUE);
1672 updateControls(view);
1673 }
1674}
1675
1676
1677
1678
1602// static 1679// static
1603void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) 1680void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
1604{ 1681{
@@ -1620,22 +1697,36 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3
1620 S32 h = height ; 1697 S32 h = height ;
1621 1698
1622 //if texture, ignore aspect ratio setting, round image size to power of 2. 1699 //if texture, ignore aspect ratio setting, round image size to power of 2.
1623 //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) 1700#if 0 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
1624 //{ 1701 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
1625 // if(width > max_value) 1702 {
1626 // { 1703 if(width > max_value)
1627 // width = max_value ; 1704 {
1628 // } 1705 width = max_value ;
1629 // if(height > max_value) 1706 }
1630 // { 1707 if(height > max_value)
1631 // height = max_value ; 1708 {
1632 // } 1709 height = max_value ;
1633 1710 }
1634 // //round to nearest power of 2 1711
1635 // width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ; 1712 //round to nearest power of 2 based on the direction of movement
1636 // height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ; 1713 // i.e. higher power of two if increasing texture resolution
1637 //} 1714 if(gSavedSettings.getS32("LastSnapshotWidth") < width ||
1638 //else 1715 gSavedSettings.getS32("LastSnapshotHeight") < height)
1716 {
1717 // Up arrow pressed
1718 width = get_next_power_two(width, MAX_TEXTURE_SIZE) ;
1719 height = get_next_power_two(height, MAX_TEXTURE_SIZE) ;
1720 }
1721 else
1722 {
1723 // Down or no change
1724 width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ;
1725 height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ;
1726 }
1727 }
1728 else
1729#endif
1639 if(previewp && previewp->mKeepAspectRatio) 1730 if(previewp && previewp->mKeepAspectRatio)
1640 { 1731 {
1641 if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1) 1732 if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1)
@@ -1706,9 +1797,6 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
1706 S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal()); 1797 S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
1707 S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal()); 1798 S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
1708 1799
1709 gSavedSettings.setS32("LastSnapshotWidth", w);
1710 gSavedSettings.setS32("LastSnapshotHeight", h);
1711
1712 LLSnapshotLivePreview* previewp = getPreviewView(view); 1800 LLSnapshotLivePreview* previewp = getPreviewView(view);
1713 if (previewp) 1801 if (previewp)
1714 { 1802 {
@@ -1719,28 +1807,32 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
1719 { 1807 {
1720 BOOL update_ = FALSE ; 1808 BOOL update_ = FALSE ;
1721 //if to upload a snapshot, process spinner input in a special way. 1809 //if to upload a snapshot, process spinner input in a special way.
1722 //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) 1810#if 0 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
1723 //{ 1811 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
1724 // S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ; 1812 {
1725 // S32 dw = w - curw ; 1813 S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ;
1726 // S32 dh = h - curh ; 1814 S32 dw = w - curw ;
1727 // dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ; 1815 S32 dh = h - curh ;
1728 // dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ; 1816 dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ;
1729 1817 dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ;
1730 // if(dw) 1818
1731 // { 1819 if(dw)
1732 // w = (dw > 0) ? curw << dw : curw >> -dw ; 1820 {
1733 // update_ = TRUE ; 1821 w = (dw > 0) ? curw << dw : curw >> -dw ;
1734 // } 1822 update_ = TRUE ;
1735 // if(dh) 1823 }
1736 // { 1824 if(dh)
1737 // h = (dh > 0) ? curh << dh : curh >> -dh ; 1825 {
1738 // update_ = TRUE ; 1826 h = (dh > 0) ? curh << dh : curh >> -dh ;
1739 // } 1827 update_ = TRUE ;
1740 //} 1828 }
1741 1829 }
1830#endif
1742 previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ; 1831 previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ;
1743 if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) || update_) 1832
1833 // Check image size changes the value of height and width
1834 if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize())
1835 || update_)
1744 { 1836 {
1745 resetSnapshotSizeOnUI(view, w, h) ; 1837 resetSnapshotSizeOnUI(view, w, h) ;
1746 } 1838 }
@@ -1752,6 +1844,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
1752 comboSetCustom(view, "local_size_combo"); 1844 comboSetCustom(view, "local_size_combo");
1753 } 1845 }
1754 } 1846 }
1847
1848 gSavedSettings.setS32("LastSnapshotWidth", w);
1849 gSavedSettings.setS32("LastSnapshotHeight", h);
1850
1755 } 1851 }
1756} 1852}
1757 1853
@@ -1761,7 +1857,7 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
1761 1857
1762// Default constructor 1858// Default constructor
1763LLFloaterSnapshot::LLFloaterSnapshot() 1859LLFloaterSnapshot::LLFloaterSnapshot()
1764 : LLFloater("Snapshot Floater"), 1860 : LLFloater(std::string("Snapshot Floater")),
1765 impl (*(new Impl)) 1861 impl (*(new Impl))
1766{ 1862{
1767} 1863}
@@ -1790,6 +1886,7 @@ LLFloaterSnapshot::~LLFloaterSnapshot()
1790BOOL LLFloaterSnapshot::postBuild() 1886BOOL LLFloaterSnapshot::postBuild()
1791{ 1887{
1792 childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this); 1888 childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this);
1889 childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this);
1793 1890
1794 childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); 1891 childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
1795 1892
@@ -1803,7 +1900,7 @@ BOOL LLFloaterSnapshot::postBuild()
1803 1900
1804 childSetAction("upload_btn", Impl::onClickKeep, this); 1901 childSetAction("upload_btn", Impl::onClickKeep, this);
1805 childSetAction("send_btn", Impl::onClickKeep, this); 1902 childSetAction("send_btn", Impl::onClickKeep, this);
1806 childSetAction("save_btn", Impl::onClickKeep, this); 1903 childSetCommitCallback("save_btn", Impl::onCommitSave, this);
1807 childSetAction("discard_btn", Impl::onClickDiscard, this); 1904 childSetAction("discard_btn", Impl::onClickDiscard, this);
1808 1905
1809 childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this); 1906 childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this);
@@ -1850,7 +1947,7 @@ BOOL LLFloaterSnapshot::postBuild()
1850 1947
1851 impl.updateControls(this); 1948 impl.updateControls(this);
1852 1949
1853 return TRUE; 1950 return TRUE;
1854} 1951}
1855 1952
1856void LLFloaterSnapshot::draw() 1953void LLFloaterSnapshot::draw()
@@ -1869,7 +1966,7 @@ void LLFloaterSnapshot::draw()
1869 { 1966 {
1870 LLLocale locale(LLLocale::USER_LOCALE); 1967 LLLocale locale(LLLocale::USER_LOCALE);
1871 1968
1872 LLString bytes_string; 1969 std::string bytes_string;
1873 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && 1970 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD &&
1874 previewp->getDataSize() > MAX_POSTCARD_DATASIZE) 1971 previewp->getDataSize() > MAX_POSTCARD_DATASIZE)
1875 { 1972 {
@@ -1884,7 +1981,7 @@ void LLFloaterSnapshot::draw()
1884 1981
1885 if (previewp->getSnapshotUpToDate()) 1982 if (previewp->getSnapshotUpToDate())
1886 { 1983 {
1887 LLString bytes_string; 1984 std::string bytes_string;
1888 LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); 1985 LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
1889 childSetTextArg("file_size_label", "[SIZE]", bytes_string); 1986 childSetTextArg("file_size_label", "[SIZE]", bytes_string);
1890 } 1987 }
@@ -1899,7 +1996,7 @@ void LLFloaterSnapshot::draw()
1899 } 1996 }
1900 else 1997 else
1901 { 1998 {
1902 childSetTextArg("file_size_label", "[SIZE]", LLString("???")); 1999 childSetTextArg("file_size_label", "[SIZE]", std::string("???"));
1903 childSetEnabled("upload_btn", FALSE); 2000 childSetEnabled("upload_btn", FALSE);
1904 childSetEnabled("send_btn", FALSE); 2001 childSetEnabled("send_btn", FALSE);
1905 childSetEnabled("save_btn", FALSE); 2002 childSetEnabled("save_btn", FALSE);
@@ -1907,50 +2004,11 @@ void LLFloaterSnapshot::draw()
1907 2004
1908 BOOL ui_in_snapshot = gSavedSettings.getBOOL("RenderUIInSnapshot"); 2005 BOOL ui_in_snapshot = gSavedSettings.getBOOL("RenderUIInSnapshot");
1909 childSetValue("ui_check", ui_in_snapshot); 2006 childSetValue("ui_check", ui_in_snapshot);
1910 childSetToolTip("ui_check", "If selected shows the UI in the snapshot"); 2007 childSetToolTip("ui_check", std::string("If selected shows the UI in the snapshot"));
1911 } 2008 }
1912 2009
1913 LLFloater::draw(); 2010 LLFloater::draw();
1914 2011
1915 // draw snapshot thumbnail if not in fullscreen preview mode
1916 /*if (previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate())
1917 {
1918 F32 aspect = previewp->getImageAspect();
1919 // UI size for thumbnail
1920 S32 max_width = getRect().getWidth() - 20;
1921 S32 max_height = 90;
1922
1923 S32 img_render_width = 0;
1924 S32 img_render_height = 0;
1925 if (aspect > max_width / max_height)
1926 {
1927 // image too wide, shrink to width
1928 img_render_width = max_width;
1929 img_render_height = llround((F32)max_width / aspect);
1930 }
1931 else
1932 {
1933 // image too tall, shrink to height
1934 img_render_height = max_height;
1935 img_render_width = llround((F32)max_height * aspect);
1936 }
1937 S32 image_width, image_height;
1938 previewp->getSize(image_width, image_height);
1939 glMatrixMode(GL_TEXTURE);
1940 glPushMatrix();
1941 {
1942 // handle case where image is only a portion of image buffer
1943 if (!previewp->isImageScaled())
1944 {
1945 glScalef(llmin(1.f, (F32)image_width / (F32)previewp->getCurrentImage()->getWidth()), llmin(1.f, (F32)image_height / (F32)previewp->getCurrentImage()->getHeight()), 1.f);
1946 }
1947 glMatrixMode(GL_MODELVIEW);
1948 gl_draw_scaled_image((getRect().getWidth() - img_render_width) / 2, getRect().getHeight() - 205 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white);
1949 }
1950 glMatrixMode(GL_TEXTURE);
1951 glPopMatrix();
1952 glMatrixMode(GL_MODELVIEW);
1953 }*/
1954 if (previewp) 2012 if (previewp)
1955 { 2013 {
1956 if(previewp->getThumbnailImage()) 2014 if(previewp->getThumbnailImage())
@@ -1980,7 +2038,6 @@ void LLFloaterSnapshot::show(void*)
1980 if (!sInstance) 2038 if (!sInstance)
1981 { 2039 {
1982 sInstance = new LLFloaterSnapshot(); 2040 sInstance = new LLFloaterSnapshot();
1983
1984 LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); 2041 LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE);
1985 //move snapshot floater to special purpose snapshotfloaterview 2042 //move snapshot floater to special purpose snapshotfloaterview
1986 gFloaterView->removeChild(sInstance); 2043 gFloaterView->removeChild(sInstance);
@@ -1988,6 +2045,14 @@ void LLFloaterSnapshot::show(void*)
1988 2045
1989 sInstance->impl.updateLayout(sInstance); 2046 sInstance->impl.updateLayout(sInstance);
1990 } 2047 }
2048 else // just refresh the snapshot in the existing floater instance (DEV-12255)
2049 {
2050 LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance);
2051 if(preview)
2052 {
2053 preview->updateSnapshot(TRUE);
2054 }
2055 }
1991 2056
1992 sInstance->open(); /* Flawfinder: ignore */ 2057 sInstance->open(); /* Flawfinder: ignore */
1993 sInstance->focusFirstItem(FALSE); 2058 sInstance->focusFirstItem(FALSE);
@@ -2013,9 +2078,12 @@ void LLFloaterSnapshot::update()
2013 } 2078 }
2014} 2079}
2015 2080
2016//============================================================================
2017 2081
2018LLSnapshotFloaterView::LLSnapshotFloaterView( const LLString& name, const LLRect& rect ) : LLFloaterView(name, rect) 2082///----------------------------------------------------------------------------
2083/// Class LLSnapshotFloaterView
2084///----------------------------------------------------------------------------
2085
2086LLSnapshotFloaterView::LLSnapshotFloaterView( const std::string& name, const LLRect& rect ) : LLFloaterView(name, rect)
2019{ 2087{
2020 setMouseOpaque(TRUE); 2088 setMouseOpaque(TRUE);
2021 setEnabled(FALSE); 2089 setEnabled(FALSE);