void LLViewerImageList::updateImages(F32 max_time)
{
	llpushcallstacks ;
	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());

	sNumImagesStat.addValue(sNumImages);
	sNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
	sGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes));
	sGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes));
	sRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
	sFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));

	llpushcallstacks ;

	updateImagesDecodePriorities();

	llpushcallstacks ;
	F32 total_max_time = max_time;
	max_time -= updateImagesFetchTextures(max_time);

	llpushcallstacks ;
	max_time = llmax(max_time, total_max_time*.25f); // at least 25% of max_time
	max_time -= updateImagesCreateTextures(max_time);
	
	llpushcallstacks ;
	
	if (!mDirtyTextureList.empty())
	{
		LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY);
		gPipeline.dirtyPoolObjectTextures(mDirtyTextureList);
		mDirtyTextureList.clear();
	}
	llpushcallstacks ;
	bool didone = false;
	for (image_list_t::iterator iter = mCallbackList.begin();
		iter != mCallbackList.end(); )
	{
		//trigger loaded callbacks on local textures immediately
		LLViewerImage* image = *iter++;
		if (!image->mUrl.empty())
		{
			// Do stuff to handle callbacks, update priorities, etc.
			didone = image->doLoadedCallbacks();
		}
		else if (!didone)
		{
			// Do stuff to handle callbacks, update priorities, etc.
			didone = image->doLoadedCallbacks();
		}
	}
	llpushcallstacks ;
	if (!gNoRender && !gGLManager.mIsDisabled)
	{
		LLViewerMedia::updateMedia();
	}
	llpushcallstacks ;
	updateImagesUpdateStats();
	llpushcallstacks ;
}
//static
// Returns max setting for TextureMemory (in MB)
S32 LLViewerImageList::getMaxVideoRamSetting(bool get_recommended)
{
	S32 max_texmem;
	if (gGLManager.mVRAM != 0)
	{
		// Treat any card with < 32 MB (shudder) as having 32 MB
		//  - it's going to be swapping constantly regardless
		S32 max_vram = gGLManager.mVRAM;
		max_vram = llmax(max_vram, getMinVideoRamSetting());
		max_texmem = max_vram;
		if (!get_recommended)
			max_texmem *= 2;
	}
	else
	{
		if (get_recommended)
			max_texmem = 128;
		else
			max_texmem = 512;
		llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl;
	}

	S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB
	//llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl;
	if (get_recommended)
		max_texmem = llmin(max_texmem, (S32)(system_ram/2));
	else
		max_texmem = llmin(max_texmem, (S32)(system_ram));
		
	max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); 
	
	return max_texmem;
}
// Returns min setting for TextureMemory (in MB)
S32 LLViewerTextureList::getMinVideoRamSetting()
{
	S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());
	if (system_ram > 2000)
		return 128;
	else if (system_ram > 1000)
		return 64;
	else
		return MIN_VIDEO_RAM_IN_MEGA_BYTES;
}
void LLFloaterLagMeter::determineClient()
{
	F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
	bool find_cause = false;

	if (!gFocusMgr.getAppHasFocus())
	{
		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
		mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
		mClientCause->setText( LLStringUtil::null );
	}
	else if(client_frame_time >= mClientFrameTimeCritical)
	{
		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
		mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
		find_cause = true;
	}
	else if(client_frame_time >= mClientFrameTimeWarning)
	{
		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
		mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
		find_cause = true;
	}
	else
	{
		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
		mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
		mClientCause->setText( LLStringUtil::null );
	}	

	if(find_cause)
	{
		if(gSavedSettings.getF32("RenderFarClip") > 128)
		{
			mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) );
		}
		else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)
		{
			mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
		}
		else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes)
		{
			mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
		}
		else 
		{
			mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) );
		}
	}
}
// Returns min setting for TextureMemory (in MB)
S32 LLViewerImageList::getMinVideoRamSetting()
{
	S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());
	//min texture mem sets to 64M if total physical mem is more than 1.5GB
	return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ;
}
	// TODO: set available resident texture mem based on use by other subsystems
	// currently max(12MB, VRAM/4) assumed...
	
	S32 vb_mem = mem;
	S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
	mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
	
	mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
	if (mMaxResidentTexMemInMegaBytes > 640)
	{
		mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2);
	}

	//system mem
	S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB

	//minimum memory reserved for non-texture use.
	//if system_raw >= 1GB, reserve at least 512MB for non-texture use;
	//otherwise reserve half of the system_ram for non-texture use.
	S32 min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; 

	if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem)
	{
		mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ;
	}
	
	llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl;
	llinfos << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << llendl;
}
void LLGLTexMemBar::draw()
{
    S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes);
    S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes;
    S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
    S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
    F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
    F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
    F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
    S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
    S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
    F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
    F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
    U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();
    //----------------------------------------------------------------------------
    LLGLSUIDefault gls_ui;
    LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
    LLColor4 color;

    // Gray background using completely magic numbers
    gGL.color4f(0.f, 0.f, 0.f, 0.25f);
    // const LLRect & rect(getRect());
    // gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4);

    std::string text = "";
    LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
                    total_mem,
                    max_total_mem,
                    bound_mem,
                    max_bound_mem,
                    LLRenderTarget::sBytesAllocated/(1024*1024),
                    LLImageRaw::sGlobalRawMemory >> 20,
                    discard_bias,
                    cache_usage,
                    cache_max_usage);
    //, cache_entries, cache_max_entries

    // <FS:Ansariel> Texture memory bars
    //LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
    LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
            // </FS:Ansariel>
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    // <FS:Ansariel> Texture memory bars
    S32 bar_left = 0;
    S32 bar_width = 200;
    S32 bar_space = 32;
    S32 top = line_height*4 - 2 + v_offset;
    S32 bottom = top - 6;
    S32 left = bar_left;
    S32 right = left + bar_width;
    F32 bar_scale;

    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

    // GL Mem Bar

    left = bar_left;
    text = "GL";
    LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*4,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    left = bar_left+20;
    right = left + bar_width;

    gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey
    gl_rect_2d(left, top, right, bottom);

    bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
    right = left + llfloor(total_mem * bar_scale);
    right = llclamp(right, bar_left, bar_left + bar_width);

    color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
            (total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
    color[VALPHA] = .75f;
//	gGL.diffuseColor4fv(color.mV);

    gl_rect_2d(left, top, right, bottom, color); // red/yellow/green

    //
    bar_left += bar_width + bar_space;
    //top = bottom - 2; bottom = top - 6;

    // Bound Mem Bar

    left = bar_left;
    text = "Bound";
    LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*4,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);
    left = bar_left + 42;
    right = left + bar_width;

    gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
    gl_rect_2d(left, top, right, bottom);

    color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
            (bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
    color[VALPHA] = .75f;
//	gGL.diffuseColor4fv(color.mV);

    bar_scale = (F32)bar_width / (max_bound_mem * 1.5f);
    right = left + llfloor(bound_mem * bar_scale);

    gl_rect_2d(left, top, right, bottom, color);
    // </FS:Ansariel>

    U32 cache_read(0U), cache_write(0U), res_wait(0U);
    LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);

    // <FS:Ansariel> Fast cache stats
    //text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
    text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u FCread: %u",
                    // </FS:Ansariel>
                    total_texture_downloaded,
                    total_object_downloaded,
                    total_http_requests,
                    cache_read,
                    cache_write,
                    // <FS:Ansariel> Fast cache stats
                    //res_wait);
                    res_wait,
                    LLViewerTextureList::sNumFastCacheReads);
    // </FS:Ansariel>

    LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    // <FS:Ansariel> Texture memory bars
    //S32 left = 0 ;
    //----------------------------------------------------------------------------

    // <FS:Ansariel> Fast cache stats
    //text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
    text = llformat("Tex: %d Fetch: %d(%d) Pkts:%d(%d) CAC R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d FCA:%d",
                    // </FS:Ansariel>
                    gTextureList.getNumImages(),
                    LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
                    LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,
                    LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
                    LLLFSThread::sLocal->getPending(),
                    LLImageRaw::sRawImageCount,
                    LLAppViewer::getTextureFetch()->getNumHTTPRequests(),
                    LLAppViewer::getImageDecodeThread()->getPending(),
                    // <FS:Ansariel> Fast cache stats
                    //gTextureList.mCreateTextureList.size());
                    gTextureList.mCreateTextureList.size(),
                    gTextureList.mFastCacheList.size());
    // </FS:Ansariel>

    LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);


    // <FS:Ansariel> Move BW figures further to the right to prevent overlapping
    //left = 550;
    left = 575;
    F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
    // <FS:Ansariel> Speed-up
    //F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
    static LLCachedControl<F32> throttleBandwidthKBPS(gSavedSettings, "ThrottleBandwidthKBPS");
    F32 max_bandwidth = F32(throttleBandwidthKBPS);
    // </FS:Ansariel> Speed-up
    color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
    color[VALPHA] = text_color[VALPHA];
    text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
    LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
            color, LLFontGL::LEFT, LLFontGL::TOP);

    S32 dx1 = 0;
    if (LLAppViewer::getTextureFetch()->mDebugPause)
    {
        LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, v_offset + line_height,
                text_color, LLFontGL::LEFT, LLFontGL::TOP);
        dx1 += 8;
    }
    if (mTextureView->mFreezeView)
    {
        LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, v_offset + line_height,
                text_color, LLFontGL::LEFT, LLFontGL::TOP);
        dx1 += 8;
    }
    if (mTextureView->mOrderFetch)
    {
        LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, v_offset + line_height,
                text_color, LLFontGL::LEFT, LLFontGL::TOP);
    }
    else
    {
        LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, v_offset + line_height,
                text_color, LLFontGL::LEFT, LLFontGL::TOP);
    }

    LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, v_offset + line_height,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, v_offset + line_height,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);

    LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, v_offset + line_height,
            text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
void LLGLTexMemBar::draw()
{
	S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes);
 	S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes;
	S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
	S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
	//----------------------------------------------------------------------------
	LLGLSUIDefault gls_ui;
	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
	LLColor4 color;
	
	std::string text = "";

	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
											 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
					total_mem,
					max_total_mem,
					bound_mem,
					max_bound_mem,
					LLRenderTarget::sBytesAllocated/(1024*1024),
					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias,
					cache_usage, cache_max_usage);
	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
											 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
					total_texture_downloaded, total_object_downloaded, total_http_requests);
	//, cache_entries, cache_max_entries
	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
											 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	S32 left = 0 ;
	//----------------------------------------------------------------------------

	text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
					gTextureList.getNumImages(),
					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, 
					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
					LLLFSThread::sLocal->getPending(),
					LLImageRaw::sRawImageCount,
					LLAppViewer::getTextureFetch()->getNumHTTPRequests(),
					LLAppViewer::getImageDecodeThread()->getPending(), 
					gTextureList.mCreateTextureList.size());

	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);


	left = 550;
	F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
	F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
	color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
	color[VALPHA] = text_color[VALPHA];
	text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
											 color, LLFontGL::LEFT, LLFontGL::TOP);
	
	S32 dx1 = 0;
	if (LLAppViewer::getTextureFetch()->mDebugPause)
	{
		LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, v_offset + line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
		dx1 += 8;
	}
	if (mTextureView->mFreezeView)
	{
		LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, v_offset + line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
		dx1 += 8;
	}
	if (mTextureView->mOrderFetch)
	{
		LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, v_offset + line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
	}
	else
	{	
		LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, v_offset + line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
	}
	
	LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, v_offset + line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, v_offset + line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, v_offset + line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
void LLGLTexMemBar::draw()
{
	S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes);
 	S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes;
	S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes);
	S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes;
	F32 discard_bias = LLViewerImage::sDesiredDiscardBias;
	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
	
	//----------------------------------------------------------------------------
	LLGLSUIDefault gls_ui;
	F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
	
	std::string text;
	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Discard Bias: %.2f",
					total_mem,
					max_total_mem,
					bound_mem,
					max_bound_mem,
					discard_bias);

	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*3,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	//----------------------------------------------------------------------------
	S32 bar_left = 380;
	S32 bar_width = 200;
	S32 top = line_height*3 - 2;
	S32 bottom = top - 6;
	S32 left = bar_left;
	S32 right = left + bar_width;

	F32 bar_scale = (F32)bar_width / (max_bound_mem * 1.5f);
	
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	
	gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
	gl_rect_2d(left, top, right, bottom);

	
	left = bar_left;
	right = left + llfloor(bound_mem * bar_scale);
	if (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale))
	{
		gGL.color4f(0.f, 1.f, 0.f, 0.75f);
	}
	else if (bound_mem < max_bound_mem)
	{
		gGL.color4f(1.f, 1.f, 0.f, 0.75f);
	}
	else
	{
		gGL.color4f(1.f, 0.f, 0.f, 0.75f);
	}
	gl_rect_2d(left, top, right, bottom);

	bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
	
	top = bottom - 2;
	bottom = top - 6;
	left = bar_left;
	right = left + llfloor(total_mem * bar_scale);
	if (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale))
	{
		gGL.color4f(0.f, 1.f, 0.f, 0.75f);
	}
	else if (total_mem < max_total_mem)
	{
		gGL.color4f(1.f, 1.f, 0.f, 0.75f);
	}
	else
	{
		gGL.color4f(1.f, 0.f, 0.f, 0.75f);
	}
	gl_rect_2d(left, top, right, bottom);

	//----------------------------------------------------------------------------

	text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d",
					gImageList.getNumImages(),
					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, 
					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
					LLLFSThread::sLocal->getPending(),
					LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
					LLImageRaw::sRawImageCount, LLViewerImage::sRawCount, LLViewerImage::sAuxCount,
					gImageList.mCallbackList.size());

	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
	
	S32 dx1 = 0;
	if (LLAppViewer::getTextureFetch()->mDebugPause)
	{
		LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
		dx1 += 8;
	}
	if (mTextureView->mFreezeView)
	{
		LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
		dx1 += 8;
	}
	if (mTextureView->mOrderFetch)
	{
		LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
	}
	else
	{	
		LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, line_height,
										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
	}
	
	LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);

	LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, line_height,
									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
}