diff options
Diffstat (limited to 'indra/newview/llviewerwindow.cpp')
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 470 |
1 files changed, 282 insertions, 188 deletions
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2981dc8c82..3a63fdfbd7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2,25 +2,31 @@ * @file llviewerwindow.cpp * @brief Implementation of the LLViewerWindow class. * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -1112,7 +1118,28 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) mActive = TRUE; send_agent_resume(); gAgent.clearAFK(); - + if (mWindow->getFullscreen() && !mIgnoreActivate) + { + if (!LLApp::isExiting() ) + { + if (LLStartUp::getStartupState() >= STATE_STARTED) + { + // if we're in world, show a progress bar to hide reloading of textures + llinfos << "Restoring GL during activate" << llendl; + restoreGL(LLTrans::getString("ProgressRestoring")); + } + else + { + // otherwise restore immediately + restoreGL(); + } + } + else + { + llwarns << "Activating while quitting" << llendl; + } + } + // Unmute audio audio_update_volume(); } @@ -1132,7 +1159,12 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) } send_agent_pause(); - + + if (mWindow->getFullscreen() && !mIgnoreActivate) + { + llinfos << "Stopping GL during deactivation" << llendl; + stopGL(); + } // Mute audio audio_update_volume(); } @@ -1299,10 +1331,12 @@ LLViewerWindow::LLViewerWindow( const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, - BOOL fullscreen, BOOL ignore_pixel_depth) // fullscreen is no longer used + BOOL fullscreen, BOOL ignore_pixel_depth) : mWindow(NULL), mActive(TRUE), + mWantFullscreen(fullscreen), + mShowFullscreenProgress(FALSE), mWindowRectRaw(0, height, width, 0), mWindowRectScaled(0, height, width, 0), mWorldViewRectRaw(0, height, width, 0), @@ -1317,6 +1351,7 @@ LLViewerWindow::LLViewerWindow( mIgnoreActivate( FALSE ), mResDirty(false), mStatesDirty(false), + mIsFullscreenChecked(false), mCurrResolutionIndex(0), mViewerWindowListener(new LLViewerWindowListener(this)), mProgressView(NULL) @@ -1342,7 +1377,7 @@ LLViewerWindow::LLViewerWindow( gSavedSettings.getBOOL("DisableVerticalSync"), !gNoRender, ignore_pixel_depth, - gSavedSettings.getU32("RenderFSAASamples")); + 0); //gSavedSettings.getU32("RenderFSAASamples")); if (!LLAppViewer::instance()->restoreErrorTrap()) { @@ -1556,9 +1591,6 @@ void LLViewerWindow::initBase() gDebugView->init(); gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view"); - // Initialize busy response message when logged in - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse)); - // Add the progress bar view (startup view), which overrides everything mProgressView = getRootView()->getChild<LLProgressView>("progress_view"); setShowProgress(FALSE); @@ -1876,17 +1908,24 @@ void LLViewerWindow::reshape(S32 width, S32 height) sendShapeToSim(); - // store new settings for the mode we are in, regardless - // Only save size if not maximized - BOOL maximized = mWindow->getMaximized(); - gSavedSettings.setBOOL("WindowMaximized", maximized); - LLCoordScreen window_size; - if (!maximized - && mWindow->getSize(&window_size)) + // store the mode the user wants (even if not there yet) + gSavedSettings.setBOOL("FullScreen", mWantFullscreen); + + // store new settings for the mode we are in, regardless + if (!mWindow->getFullscreen()) { - gSavedSettings.setS32("WindowWidth", window_size.mX); - gSavedSettings.setS32("WindowHeight", window_size.mY); + // Only save size if not maximized + BOOL maximized = mWindow->getMaximized(); + gSavedSettings.setBOOL("WindowMaximized", maximized); + + LLCoordScreen window_size; + if (!maximized + && mWindow->getSize(&window_size)) + { + gSavedSettings.setS32("WindowWidth", window_size.mX); + gSavedSettings.setS32("WindowHeight", window_size.mY); + } } LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); @@ -2323,9 +2362,7 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) // Zoom the camera in and out behavior - if(top_ctrl == 0 - && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) - && gAgentCamera.isInitialized()) + if(top_ctrl == 0 && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) ) gAgentCamera.handleScrollWheel(clicks); return; @@ -2422,7 +2459,7 @@ void LLViewerWindow::updateUI() LLLayoutStack::updateClass(); // use full window for world view when not rendering UI - bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); + bool world_view_uses_full_window = !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); updateWorldViewRect(world_view_uses_full_window); LLView::sMouseHandlerMessage.clear(); @@ -3766,7 +3803,18 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) BORDERHEIGHT = size.mY- y; LLCoordScreen new_size(new_width + BORDERWIDTH, new_height + BORDERHEIGHT); - gViewerWindow->mWindow->setSize(new_size); + BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync"); + if (gViewerWindow->mWindow->getFullscreen()) + { + gViewerWindow->changeDisplaySettings(FALSE, + new_size, + disable_sync, + TRUE); + } + else + { + gViewerWindow->mWindow->setSize(new_size); + } } } @@ -3812,140 +3860,6 @@ void LLViewerWindow::playSnapshotAnimAndSound() BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) { return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); - - // *TODO below code was broken in deferred pipeline - /* - if ((!raw) || preview_width < 10 || preview_height < 10) - { - return FALSE; - } - - if(gResizeScreenTexture) //the window is resizing - { - return FALSE ; - } - - setCursor(UI_CURSOR_WAIT); - - // Hide all the UI widgets first and draw a frame - BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); - - if ( prev_draw_ui != show_ui) - { - LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); - } - - BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = FALSE; - } - - S32 render_name = gSavedSettings.getS32("RenderName"); - gSavedSettings.setS32("RenderName", 0); - LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame - - S32 w = preview_width ; - S32 h = preview_height ; - LLVector2 display_scale = mDisplayScale ; - mDisplayScale.setVec((F32)w / mWindowRectRaw.getWidth(), (F32)h / mWindowRectRaw.getHeight()) ; - LLRect window_rect = mWindowRectRaw; - mWindowRectRaw.set(0, h, w, 0); - - gDisplaySwapBuffers = FALSE; - gDepthDirty = TRUE; - glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - setup3DRender(); - - LLFontGL::setFontDisplay(FALSE) ; - LLHUDText::setDisplayText(FALSE) ; - if (type == SNAPSHOT_TYPE_OBJECT_ID) - { - gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE); - } - else - { - display(do_rebuild, 1.0f, 0, TRUE); - render_ui(); - } - - S32 glformat, gltype, glpixel_length ; - if(SNAPSHOT_TYPE_DEPTH == type) - { - glpixel_length = 4 ; - glformat = GL_DEPTH_COMPONENT ; - gltype = GL_FLOAT ; - } - else - { - glpixel_length = 3 ; - glformat = GL_RGB ; - gltype = GL_UNSIGNED_BYTE ; - } - - raw->resize(w, h, glpixel_length); - glReadPixels(0, 0, w, h, glformat, gltype, raw->getData()); - - if(SNAPSHOT_TYPE_DEPTH == type) - { - LLViewerCamera* camerap = LLViewerCamera::getInstance(); - F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); - F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); - - //calculate the depth - for (S32 y = 0 ; y < h ; y++) - { - for(S32 x = 0 ; x < w ; x++) - { - S32 i = (w * y + x) << 2 ; - - F32 depth_float_i = *(F32*)(raw->getData() + i); - - F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2)); - U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar()); - *(raw->getData() + i + 0) = depth_byte; - *(raw->getData() + i + 1) = depth_byte; - *(raw->getData() + i + 2) = depth_byte; - *(raw->getData() + i + 3) = 255; - } - } - } - - LLFontGL::setFontDisplay(TRUE) ; - LLHUDText::setDisplayText(TRUE) ; - mDisplayScale.setVec(display_scale) ; - mWindowRectRaw = window_rect; - setup3DRender(); - gDisplaySwapBuffers = FALSE; - gDepthDirty = TRUE; - - // POST SNAPSHOT - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); - } - - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = TRUE; - } - - setCursor(UI_CURSOR_ARROW); - - if (do_rebuild) - { - // If we had to do a rebuild, that means that the lists of drawables to be rendered - // was empty before we started. - // Need to reset these, otherwise we call state sort on it again when render gets called the next time - // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of - // objects on them. - gPipeline.resetDrawOrders(); - } - - gSavedSettings.setS32("RenderName", render_name); - - return TRUE;*/ } // Saves the image from the screen to the specified filename and path. @@ -4518,7 +4432,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gResizeScreenTexture = TRUE; - if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) + if (gAgentCamera.cameraCustomizeAvatar()) { LLVisualParamHint::requestHintUpdates(); } @@ -4552,12 +4466,51 @@ void LLViewerWindow::initFonts(F32 zoom_factor) LLFontGL::loadDefaultFonts(); } +void LLViewerWindow::toggleFullscreen(BOOL show_progress) +{ + if (mWindow) + { + mWantFullscreen = mWindow->getFullscreen() ? FALSE : TRUE; + mIsFullscreenChecked = mWindow->getFullscreen() ? FALSE : TRUE; + mShowFullscreenProgress = show_progress; + } +} + +void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height) const +{ + fullscreen = mWantFullscreen; + + if (mWindow + && mWindow->getFullscreen() == mWantFullscreen) + { + width = getWindowWidthRaw(); + height = getWindowHeightRaw(); + } + else if (mWantFullscreen) + { + width = gSavedSettings.getS32("FullScreenWidth"); + height = gSavedSettings.getS32("FullScreenHeight"); + } + else + { + width = gSavedSettings.getS32("WindowWidth"); + height = gSavedSettings.getS32("WindowHeight"); + } +} + void LLViewerWindow::requestResolutionUpdate() { mResDirty = true; } -void LLViewerWindow::checkSettings() +void LLViewerWindow::requestResolutionUpdate(bool fullscreen_checked) +{ + mResDirty = true; + mWantFullscreen = fullscreen_checked; + mIsFullscreenChecked = fullscreen_checked; +} + +BOOL LLViewerWindow::checkSettings() { if (mStatesDirty) { @@ -4569,9 +4522,70 @@ void LLViewerWindow::checkSettings() // We want to update the resolution AFTER the states getting refreshed not before. if (mResDirty) { + if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio")) + { + getWindow()->setNativeAspectRatio(0.f); + } + else + { + getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio")); + } + reshape(getWindowWidthRaw(), getWindowHeightRaw()); + + // force aspect ratio + if (mIsFullscreenChecked) + { + LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + } + mResDirty = false; - } + } + + BOOL is_fullscreen = mWindow->getFullscreen(); + if(mWantFullscreen) + { + LLCoordScreen screen_size; + LLCoordScreen desired_screen_size(gSavedSettings.getS32("FullScreenWidth"), + gSavedSettings.getS32("FullScreenHeight")); + getWindow()->getSize(&screen_size); + if(!is_fullscreen || + screen_size.mX != desired_screen_size.mX + || screen_size.mY != desired_screen_size.mY) + { + if (!LLStartUp::canGoFullscreen()) + { + return FALSE; + } + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + changeDisplaySettings(TRUE, + desired_screen_size, + gSavedSettings.getBOOL("DisableVerticalSync"), + mShowFullscreenProgress); + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + mStatesDirty = true; + return TRUE; + } + } + else + { + if(is_fullscreen) + { + // Changing to windowed mode. + changeDisplaySettings(FALSE, + LLCoordScreen(gSavedSettings.getS32("WindowWidth"), + gSavedSettings.getS32("WindowHeight")), + TRUE, + mShowFullscreenProgress); + mStatesDirty = true; + return TRUE; + } + } + return FALSE; } void LLViewerWindow::restartDisplay(BOOL show_progress_bar) @@ -4588,23 +4602,39 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) } } -BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) +BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) { BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); + mWantFullscreen = fullscreen; + mShowFullscreenProgress = show_progress_bar; + gSavedSettings.setBOOL("FullScreen", mWantFullscreen); //gResizeScreenTexture = TRUE; - U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); - U32 old_fsaa = mWindow->getFSAASamples(); - // if not maximized, use the request size - if (!mWindow->getMaximized()) + BOOL old_fullscreen = mWindow->getFullscreen(); + if (!old_fullscreen && fullscreen && !LLStartUp::canGoFullscreen()) { - mWindow->setSize(size); + // Not allowed to switch to fullscreen now, so exit early. + // *NOTE: This case should never be reached, but just-in-case. + return TRUE; } - if (fsaa == old_fsaa) + //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); + //U32 old_fsaa = mWindow->getFSAASamples(); + + // going from windowed to windowed + if (!old_fullscreen && !fullscreen) { - return TRUE; + // if not maximized, use the request size + if (!mWindow->getMaximized()) + { + mWindow->setSize(size); + } + + //if (fsaa == old_fsaa) + { + return TRUE; + } } // Close floaters that don't handle settings change @@ -4621,15 +4651,23 @@ BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsyn LLCoordScreen old_size; LLCoordScreen old_pos; mWindow->getSize(&old_size); + BOOL got_position = mWindow->getPosition(&old_pos); - mWindow->setFSAASamples(fsaa); + if (!old_fullscreen && fullscreen && got_position) + { + // switching from windowed to fullscreen, so save window position + gSavedSettings.setS32("WindowX", old_pos.mX); + gSavedSettings.setS32("WindowY", old_pos.mY); + } + + //mWindow->setFSAASamples(fsaa); - result_first_try = mWindow->switchContext(false, size, disable_vsync); + result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync); if (!result_first_try) { // try to switch back - mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(false, old_size, disable_vsync); + //mWindow->setFSAASamples(old_fsaa); + result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync); if (!result_second_try) { @@ -4661,9 +4699,20 @@ BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsyn } BOOL success = result_first_try || result_second_try; - if (success) { +#if LL_WINDOWS + // Only trigger a reshape after switching to fullscreen; otherwise rely on the windows callback + // (otherwise size is wrong; this is the entire window size, reshape wants the visible window size) + if (fullscreen && result_first_try) +#endif + { + reshape(size.mX, size.mY); + } + } + + if (!mWindow->getFullscreen() && success) + { // maximize window if was maximized, else reposition if (was_maximized) { @@ -4680,14 +4729,45 @@ BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsyn mIgnoreActivate = FALSE; gFocusMgr.setKeyboardFocus(keyboard_focus); + mWantFullscreen = mWindow->getFullscreen(); + mShowFullscreenProgress = FALSE; return success; } + +F32 LLViewerWindow::getDisplayAspectRatio() const +{ + if (mWindow->getFullscreen()) + { + if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio")) + { + return mWindow->getNativeAspectRatio(); + } + else + { + return gSavedSettings.getF32("FullScreenAspectRatio"); + } + } + else + { + return mWindow->getNativeAspectRatio(); + } +} + + F32 LLViewerWindow::getWorldViewAspectRatio() const { F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight(); - return world_aspect; + //F32 window_aspect = (F32)mWindowRectRaw.getWidth() / (F32)mWindowRectRaw.getHeight(); + if (mWindow->getFullscreen()) + { + return world_aspect * mWindow->getPixelAspectRatio(); + } + else + { + return world_aspect; + } } void LLViewerWindow::calcDisplayScale() @@ -4695,13 +4775,27 @@ void LLViewerWindow::calcDisplayScale() F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); LLVector2 display_scale; display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); - display_scale *= ui_scale_factor; + F32 height_normalization = gSavedSettings.getBOOL("UIAutoScale") ? ((F32)mWindowRectRaw.getHeight() / display_scale.mV[VY]) / 768.f : 1.f; + if(mWindow->getFullscreen()) + { + display_scale *= (ui_scale_factor * height_normalization); + } + else + { + display_scale *= ui_scale_factor; + } // limit minimum display scale if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE) { display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]); } + + if (mWindow->getFullscreen()) + { + display_scale.mV[0] = llround(display_scale.mV[0], 2.0f/(F32) mWindowRectRaw.getWidth()); + display_scale.mV[1] = llround(display_scale.mV[1], 2.0f/(F32) mWindowRectRaw.getHeight()); + } if (display_scale != mDisplayScale) { |