xenadmin/XenAdmin/Controls/GPU/GpuShinyBar.cs
Konstantina Chremmou 7e8350d182 CA-123181: Add check to avoid exception thrown on GPU tab when NVIDIA host drivers were removed while vGPUs were in use
# HG changeset patch
# User Mihaela Stoica <Mihaela.Stoica@citrix.com>
# Date 1386260329 0
#      Thu Dec 05 16:18:49 2013 +0000
# Node ID 57df60d36fe5dd6a51ffa9a047a992460e0d3982
# Parent  cc6b94ee85c5927cb0dcc83268d3e066823071df

Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
2013-12-11 10:50:09 +00:00

163 lines
5.6 KiB
C#

/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using XenAdmin.Controls.Ballooning;
using XenAPI;
namespace XenAdmin.Controls.GPU
{
public partial class GpuShinyBar : ShinyBar
{
public GpuShinyBar()
{
InitializeComponent();
}
public PGPU PGPU { get; private set; }
private List<VGPU> vGPUs;
private Dictionary<VGPU, VM> vms;
private long capacity;
public void Initialize(PGPU pGPU)
{
this.PGPU = pGPU;
vGPUs = pGPU.Connection.ResolveAll(pGPU.resident_VGPUs);
vms = new Dictionary<VGPU, VM>();
foreach (VGPU vgpu in vGPUs)
vms[vgpu] = vgpu.Connection.Resolve(vgpu.VM);
capacity = vGPUs.Count > 0 && pGPU.supported_VGPU_max_capacities.ContainsKey(vGPUs[0].type)
? pGPU.supported_VGPU_max_capacities[vGPUs[0].type] : 8;
}
protected override void OnPaint(PaintEventArgs e)
{
if (PGPU == null || vGPUs == null)
return;
Graphics g = e.Graphics;
Rectangle barArea = barRect;
// Grid
DrawGrid(g, barArea, barArea.Width);
double left = barArea.Left;
// A bar for each vGPU
int i = 0;
vGPUs.Sort();
long segmentLength = barArea.Width / (capacity > 0 ? capacity : 8);
foreach (VGPU vgpu in vGPUs)
{
VM vm = vms[vgpu];
if (vm != null)
{
var vGpuType = PGPU.Connection.Resolve(vgpu.type);
DrawSegment(g, segmentLength, vm.Name, vGpuType != null ? vGpuType.model_name : "",
GpuShinyBarColors.GpuShinyBar_VMs[i++ % GpuShinyBarColors.GpuShinyBar_VMs.Length],
ref left);
}
}
// One final bar for free space
Rectangle rectFree = new Rectangle((int)left, barArea.Top, barArea.Right - (int)left, barArea.Height);
DrawToTarget(g, barArea, rectFree, GpuShinyBarColors.GpuShinyBar_Unused);
}
private void DrawGrid(Graphics g, Rectangle barArea, long max)
{
const int line_height = 12;
int line_bottom = barArea.Top + barArea.Height / 2;
int line_top = barArea.Top - line_height;
long incr = max / (capacity > 0 ? capacity : 8);
// Draw the grid
using (Pen pen = new Pen(GpuShinyBarColors.Grid))
{
for (long x = 0; x <= max; x += incr)
{
// Tick
int pos = barArea.Left + (int)((double)x);
g.DrawLine(pen, pos, line_top, pos, line_bottom);
}
}
}
private void DrawSegment(Graphics g, long width, string name, string description, Color color, ref double left)
{
if (width < 0)
return;
var rect = new Rectangle((int)left, barRect.Top,
(int)(left + width) - (int)left, // this is not necessarily the same as (int)width, which can leave a 1 pixel gap
barRect.Height);
var caption = name + "\n" + description;
DrawToTarget(g, barRect, rect, color, caption, GpuShinyBarColors.GpuShinyBar_Text, HorizontalAlignment.Center, caption);
left += width;
}
protected override int barHeight
{
get
{
return 40;
}
}
protected override Rectangle barRect
{
get
{
return new Rectangle(10, 20, this.Width - 25, barHeight);
}
}
}
public static class GpuShinyBarColors
{
public static Color[] GpuShinyBar_VMs = { Color.FromArgb(83, 39, 139), Color.FromArgb(157, 115, 215) };
public static Color GpuShinyBar_Unused = Color.Black;
public static Color GpuShinyBar_Text = Color.White;
public static Color Grid = Color.DarkGray;
}
}