/* Copyright (c) Cloud Software Group, Inc. * * 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 XenAdmin.Core; using XenAPI; namespace XenAdmin.Controls.GPU { public partial class GpuShinyBar : ShinyBar { public GpuShinyBar() { InitializeComponent(); } public PGPU PGPU { get; private set; } private List vGPUs; private Dictionary vms; private long capacity; private long maxCapacity; public void Initialize(PGPU pGPU) { this.PGPU = pGPU; vGPUs = pGPU.Connection.ResolveAll(pGPU.resident_VGPUs); vms = new Dictionary(); foreach (VGPU vgpu in vGPUs) vms[vgpu] = vgpu.Connection.Resolve(vgpu.VM); maxCapacity = 1; if (!Helpers.FeatureForbidden(pGPU, Host.RestrictVgpu) && pGPU.HasVGpu() && pGPU.supported_VGPU_max_capacities != null) { foreach (var n in pGPU.supported_VGPU_max_capacities.Values) { if (n > maxCapacity) maxCapacity = n; } } capacity = vGPUs.Count > 0 && pGPU.supported_VGPU_max_capacities.ContainsKey(vGPUs[0].type) ? pGPU.supported_VGPU_max_capacities[vGPUs[0].type] : maxCapacity; } protected override void OnPaint(PaintEventArgs e) { if (PGPU == null || vGPUs == null) return; Graphics g = e.Graphics; Rectangle barArea = barRect; // Grid if (maxCapacity > 1) 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 : maxCapacity); 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 : "", GpuShinyBar_VMs[i++ % 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, ShinyBar_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 : maxCapacity); // Draw the grid using (Pen pen = new Pen(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, ShinyBar_Text, HorizontalAlignment.Center, caption); left += width; } protected override int barHeight => 40; protected override Rectangle barRect => new Rectangle(10, 20, this.Width - 25, barHeight); } }