From 4ffac619945cafc9c7da357bf56c9bc92e318b1b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 4 Mar 2010 15:30:15 -0600 Subject: Optimiziation pass. Added RenderUseStreamVBO to enable/disable usage of VBO's for streaming buffers. Faster traversal of LLCullResult members. Removal of llpushcallstacks from inner loops. Sprinkling in fast timers. --- indra/newview/lldrawpoolalpha.cpp | 168 ++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 80 deletions(-) (limited to 'indra/newview/lldrawpoolalpha.cpp') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5d1a0ee9de..75973cfa54 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -2,25 +2,31 @@ * @file lldrawpoolalpha.cpp * @brief LLDrawPoolAlpha class implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-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$ */ @@ -288,96 +294,98 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); - if (params.mFullbright) { - // Turn off lighting if it hasn't already been so. - if (light_enabled || !initialized_lighting) + if (params.mFullbright) + { + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) + { + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = fullbright_shader; + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + light_enabled = FALSE; + } + } + // Turn on lighting if it isn't already. + else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { - target_shader = fullbright_shader; + target_shader = simple_shader; } else { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gPipeline.enableLightsDynamic(); } - light_enabled = FALSE; - } - } - // Turn on lighting if it isn't already. - else if (!light_enabled || !initialized_lighting) - { - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = simple_shader; + light_enabled = TRUE; } - else - { - gPipeline.enableLightsDynamic(); - } - light_enabled = TRUE; - } - // If we need shaders, and we're not ALREADY using the proper shader, then bind it - // (this way we won't rebind shaders unnecessarily). - if(use_shaders && (current_shader != target_shader)) - { - llassert(target_shader != NULL); - if (deferred_render && current_shader != NULL) - { - gPipeline.unbindDeferredShader(*current_shader); - diffuse_channel = 0; - } - current_shader = target_shader; - if (deferred_render) + // If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + if(use_shaders && (current_shader != target_shader)) { - gPipeline.bindDeferredShader(*current_shader); - diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - else - { - current_shader->bind(); + llassert(target_shader != NULL); + if (deferred_render && current_shader != NULL) + { + gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; + } + current_shader = target_shader; + if (deferred_render) + { + gPipeline.bindDeferredShader(*current_shader); + diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + else + { + current_shader->bind(); + } } - } - else if (!use_shaders && current_shader != NULL) - { - if (deferred_render) + else if (!use_shaders && current_shader != NULL) { - gPipeline.unbindDeferredShader(*current_shader); - diffuse_channel = 0; + if (deferred_render) + { + gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; + } + LLGLSLShader::bindNoShader(); + current_shader = NULL; } - LLGLSLShader::bindNoShader(); - current_shader = NULL; - } - - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } - - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); - if(params.mTexture.notNull()) + if (params.mGroup) { - params.mTexture->addTextureStats(params.mVSize); + params.mGroup->rebuildMesh(); } - if (params.mTextureMatrix) + + + if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->activate(); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); + if(params.mTexture.notNull()) + { + params.mTexture->addTextureStats(params.mVSize); + } + if (params.mTextureMatrix) + { + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } } } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - + if (params.mTextureMatrix && params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); -- cgit v1.3 From 5461959d33f2cccfcacfe7887622d68e1c94ad12 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Mon, 8 Mar 2010 12:28:33 +0000 Subject: fixes VWR-4214 Glow effect passes through alpha textures where alpha is actually "solid" and its many many dupes. In summary this does the following: * When laying down alpha, uses the new separated color-and-alpha blend func support to suppress existing glow in proportion to the opacity of the incoming fragments * Moves glowing-alpha support from the glow pool to the alpha pool, ensures that the glow pass for a vertex buffer happens after the alpha pass for the vertex buffer so that it doesn't suppress its *own* glow. Tested with all shader modes, FBO on/off, and deferred rendering. Tested with every permutation of alpha/non-alpha/glow/non-glow/fullbright/waterglow/particle interaction I could contrive so far. :) --- indra/newview/lldrawpoolalpha.cpp | 37 ++++++++++++++++++++++++++++++++++++- indra/newview/llvovolume.cpp | 16 +++++----------- 2 files changed, 41 insertions(+), 12 deletions(-) (limited to 'indra/newview/lldrawpoolalpha.cpp') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 75973cfa54..9a778a063d 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -204,7 +204,12 @@ void LLDrawPoolAlpha::render(S32 pass) } LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderAlpha(getVertexDataMask()); + gGL.setColorMask(true, false); if (deferred_render && current_shader != NULL) { @@ -283,9 +288,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; + llassert(group); + llassert(group->mSpatialPartition); + if (group->mSpatialPartition->mRenderByGroup && - !group->isDead()) + !group->isDead()) { + bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. + // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD && + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) @@ -385,6 +399,27 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + + // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. + if (draw_glow_for_this_partition && + params.mGlowColor.mV[3] > 0) + { + // install glow-accumulating blend mode + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color + LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) + + // glow doesn't use vertex colors from the mesh data + params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR); + glColor4ubv(params.mGlowColor.mV); + + // do the actual drawing, again + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + + // restore our alpha blend mode + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + } if (params.mTextureMatrix && params.mTexture.notNull()) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 073d7c2b91..c92af140da 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3199,11 +3199,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, S32 idx = draw_vec.size()-1; - BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || - (type == LLRenderPass::PASS_INVISIBLE) || - (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE); - + (type == LLRenderPass::PASS_INVISIBLE) || + (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE); + if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { llwarns << "Non fullbright face has no normals!" << llendl; @@ -3232,12 +3231,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); - U8 glow = 0; - - if (type == LLRenderPass::PASS_GLOW) - { - glow = (U8) (facep->getTextureEntry()->getGlow() * 255); - } + U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255); if (facep->mVertexBuffer.isNull()) { @@ -3878,7 +3872,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } - if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) + if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) { registerFace(group, facep, LLRenderPass::PASS_GLOW); } -- cgit v1.3 From 6de84031ee5c786b1a773d9d35f499c7c7a5ec20 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Mon, 8 Mar 2010 14:51:27 +0000 Subject: VWR-4214 followup Make the fix work for alpha masks ('fast alpha') too - ironically this hasn't ever worked either AFAICT. --- indra/newview/lldrawpoolalpha.cpp | 26 ++++++++++++++++------- indra/newview/lldrawpoolalpha.h | 43 +++++++++++++++++++++++++-------------- 2 files changed, 47 insertions(+), 22 deletions(-) (limited to 'indra/newview/lldrawpoolalpha.cpp') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 9a778a063d..7fd7cd3910 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -60,7 +60,9 @@ static BOOL deferred_render = FALSE; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), current_shader(NULL), target_shader(NULL), - simple_shader(NULL), fullbright_shader(NULL) + simple_shader(NULL), fullbright_shader(NULL), + mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), + mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF) { } @@ -178,9 +180,16 @@ void LLDrawPoolAlpha::render(S32 pass) LLGLSPipelineAlpha gls_pipeline_alpha; + gGL.setColorMask(true, true); + if (LLPipeline::sFastAlpha && !deferred_render) { - LLGLDisable blend_disable(GL_BLEND); + mColorSFactor = LLRender::BF_ONE; // } + mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow + mAlphaSFactor = LLRender::BF_ZERO; + mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); if (mVertexShaderLevel > 0) { @@ -205,10 +214,14 @@ void LLDrawPoolAlpha::render(S32 pass) LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend + mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression + mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + renderAlpha(getVertexDataMask()); + gGL.setColorMask(true, false); if (deferred_render && current_shader != NULL) @@ -417,8 +430,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); // restore our alpha blend mode - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); } if (params.mTextureMatrix && params.mTexture.notNull()) diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 0477093afa..61f73d0b31 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -2,25 +2,31 @@ * @file lldrawpoolalpha.h * @brief LLDrawPoolAlpha class definition * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-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$ */ @@ -28,6 +34,7 @@ #define LL_LLDRAWPOOLALPHA_H #include "lldrawpool.h" +#include "llrender.h" #include "llframetimer.h" class LLFace; @@ -77,6 +84,12 @@ private: LLGLSLShader* target_shader; LLGLSLShader* simple_shader; LLGLSLShader* fullbright_shader; + + // our 'normal' alpha blend function for this pass + LLRender::eBlendFactor mColorSFactor; + LLRender::eBlendFactor mColorDFactor; + LLRender::eBlendFactor mAlphaSFactor; + LLRender::eBlendFactor mAlphaDFactor; }; class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha -- cgit v1.3 From 0655104fa2339fd0b8e5a0385e5a1d8141834a88 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Mon, 26 Apr 2010 14:42:06 +0100 Subject: EXT-7060 default auto alpha masking to ON for deferred rendering (only deferred rendering) (transplanted from 050ae2c9451a6b89374c5a10403f373e2475f23b) --- indra/newview/app_settings/settings.xml | 15 ++++++-- indra/newview/lldrawpoolalpha.cpp | 2 +- indra/newview/llface.cpp | 20 +++++++++++ indra/newview/llface.h | 40 +++++++++++++--------- indra/newview/llspatialpartition.h | 2 -- indra/newview/llviewercontrol.cpp | 3 +- indra/newview/llviewerdisplay.cpp | 3 +- indra/newview/llvovolume.cpp | 21 ++---------- indra/newview/pipeline.cpp | 3 +- indra/newview/pipeline.h | 3 +- indra/newview/skins/default/xui/en/menu_viewer.xml | 18 +++++++--- 11 files changed, 82 insertions(+), 48 deletions(-) (limited to 'indra/newview/lldrawpoolalpha.cpp') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 43e7f1c06c..5014ba3349 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6973,10 +6973,10 @@ Value 256.0 - RenderFastAlpha + RenderAutoMaskAlphaNonDeferred Comment - Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces). + Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode Persist 1 Type @@ -6984,6 +6984,17 @@ Value 0 + RenderAutoMaskAlphaDeferred + + Comment + Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode + Persist + 1 + Type + Boolean + Value + 1 + RenderFastUI Comment diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7fd7cd3910..def463cb41 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -182,7 +182,7 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.setColorMask(true, true); - if (LLPipeline::sFastAlpha && !deferred_render) + if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render) { mColorSFactor = LLRender::BF_ONE; // } mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 8d86070bdf..f6932b0e68 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -862,6 +862,26 @@ void LLFace::updateRebuildFlags() } } + +bool LLFace::canRenderAsMask() +{ + const LLTextureEntry* te = getTextureEntry(); + return ( + ( + (LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaDeferred) || + + (!LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaNonDeferred) + ) // do we want masks at all? + && + (te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha + !(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid + (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask + + getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily recalculated but expensive) + ); +} + + static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); BOOL LLFace::getGeometryVolume(const LLVolume& volume, diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 351d48a671..02cc2af433 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -2,25 +2,31 @@ * @file llface.h * @brief LLFace class definition * - * $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$ */ @@ -132,10 +138,10 @@ public: void unsetFaceColor(); // switch back to material color const LLColor4& getFaceColor() const { return mFaceColor; } const LLColor4& getRenderColor() const; - //for volumes void updateRebuildFlags(); + bool canRenderAsMask(); // logic helper BOOL getGeometryVolume(const LLVolume& volume, const S32 &f, const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, @@ -273,7 +279,7 @@ public: { bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { - return !lhs || (rhs && (lhs->mDistance > rhs->mDistance)); // farthest = first + return lhs->mDistance > rhs->mDistance; // farthest = first } }; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 2c09a25e04..19af6a0c38 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -620,8 +620,6 @@ class LLVolumeGeometryManager: public LLGeometryManager virtual void getGeometry(LLSpatialGroup* group); void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector& faces, BOOL distance_sort = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); - private: - bool canRenderAsMask(LLFace* facep); // logic helper }; //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 3fa6b0c8c2..33fb3d0f0f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -532,7 +532,8 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2)); gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 8e2e2283bf..ede5950ecc 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -596,7 +596,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLPipeline::sUseOcclusion = 3; } - LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); + LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); + LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible"); LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 49c0c4d4e0..aa22dc7f5d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2921,9 +2921,7 @@ F32 LLVOVolume::getBinRadius() { LLFace* face = mDrawable->getFace(i); if (face->getPoolType() == LLDrawPool::POOL_ALPHA && - (!LLPipeline::sFastAlpha || - face->getFaceColor().mV[3] != 1.f || - !face->getTexture()->getIsAlphaMask())) + !face->canRenderAsMask()) { alpha_wrap = TRUE; break; @@ -3296,19 +3294,6 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); -bool LLVolumeGeometryManager::canRenderAsMask(LLFace* facep) -{ - const LLTextureEntry* te = facep->getTextureEntry(); - return ( - LLPipeline::sFastAlpha && // do we want masks at all? - - (te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha - !(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid - (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask - - facep->getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily calculated but expensive) - ); -} void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { @@ -3435,7 +3420,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (type == LLDrawPool::POOL_ALPHA) { - if (canRenderAsMask(facep)) + if (facep->canRenderAsMask()) { //can be treated as alpha mask simple_faces.push_back(facep); } @@ -3784,7 +3769,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (is_alpha) { // can we safely treat this as an alpha mask? - if (canRenderAsMask(facep)) + if (facep->canRenderAsMask()) { if (te->getFullbright()) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7a9a47feab..e6b4c5f3ed 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -269,7 +269,8 @@ BOOL LLPipeline::sRenderHighlight = TRUE; BOOL LLPipeline::sForceOldBakedUpload = FALSE; S32 LLPipeline::sUseOcclusion = 0; BOOL LLPipeline::sDelayVBUpdate = TRUE; -BOOL LLPipeline::sFastAlpha = TRUE; +BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; +BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; BOOL LLPipeline::sUseTriStrips = TRUE; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 60e0b0ae8c..a096a887b0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -444,7 +444,8 @@ public: static BOOL sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write static BOOL sDelayVBUpdate; - static BOOL sFastAlpha; + static BOOL sAutoMaskAlphaDeferred; + static BOOL sAutoMaskAlphaNonDeferred; static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders static BOOL sRenderBump; static BOOL sUseTriStrips; diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 3af80f63fe..cc16194c2d 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2137,14 +2137,24 @@ parameter="RenderDebugPipeline" /> + label="Automatic Alpha Masks (deferred)" + name="Automatic Alpha Masks (deferred)"> + parameter="RenderAutoMaskAlphaDeferred" /> + parameter="RenderAutoMaskAlphaDeferred" /> + + + +