[WIP] [CGS] Merge pull request #767 from KingLuigi4932/patch-7

[CGS] VmWare Support
This commit is contained in:
Arawn Davies 2018-02-20 21:12:32 +00:00 committed by GitHub
commit a4e797f388
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 250 additions and 22 deletions

View file

@ -14,8 +14,8 @@ namespace Cosmos_Graphic_Subsytem
protected override void BeforeRun()
{
Console.WriteLine("Cosmos booted successfully. Let's go in Graphic Mode");
/* Get on istance of the Canvas that is all the Screen */
/* Get on instance of the Canvas that is all the Screen */
canvas = FullScreenCanvas.GetFullScreenCanvas();
/* Clear the Screen with the color 'Blue' */

View file

@ -1,4 +1,4 @@
//#define COSMOSDEBUG
//#define COSMOSDEBUG
using System;
using System.Drawing;
using System.Collections.Generic;
@ -93,6 +93,8 @@ namespace Cosmos.System.Graphics
public abstract void DrawPoint(Pen pen, int x, int y);
public abstract void DrawPoint(Pen pen, float x, float y);
public abstract Color GetPointColor(int x, int y);
public virtual void DrawArray(Color[] colors, Point point, int width, int height)
{

View file

@ -1,22 +1,37 @@
//#define COSMOSDEBUG
//#define COSMOSDEBUG
using Cosmos.System.Graphics;
using Cosmos.HAL;
namespace Cosmos.System.Graphics
{
public static class FullScreenCanvas
{
/*
* For now we hardcode that the VideoDriver is always VBE when we have more that a driver supported we need to find
* what to use when we do the 'new' (inside GetFullScreenCanvas() static methods). MyVideoDriver should be
* of type Canvas
*/
static private Canvas MyVideoDriver = null;
private enum VideoDriver
{
VMWareSVGAIIDriver,
//VGADriver,
VBEDriver
}
private static PCIDevice SVGAIIDevice = PCI.GetDevice(0x15AD, 0x0405);
private static bool SVGAIIExists = SVGAIIDevice.DeviceExists;
private static VideoDriver videoDevice;
private static Canvas MyVideoDriver;
public static Canvas GetFullScreenCanvas(Mode mode)
{
Global.mDebugger.SendInternal("GetFullScreenCanvas() with mode " + mode);
if (MyVideoDriver == null)
/* Use SVGAII When Exists in PCI */
if(SVGAIIExists)
videoDevice = VideoDriver.VMWareSVGAIIDriver;
if (videoDevice == VideoDriver.VMWareSVGAIIDriver)
return MyVideoDriver = new SVGAIIScreen(mode);
else if (videoDevice == VideoDriver.VBEDriver)
return MyVideoDriver = new VBEScreen(mode);
/* We have already got a VideoDriver istance simple change its mode */
@ -27,12 +42,9 @@ namespace Cosmos.System.Graphics
public static Canvas GetFullScreenCanvas()
{
Global.mDebugger.SendInternal($"GetFullScreenCanvas() with default mode");
if (MyVideoDriver == null)
return new VBEScreen();
/* We have already got a VideoDriver istance simple reset its mode to DefaultGraphicMode */
MyVideoDriver.Mode = MyVideoDriver.DefaultGraphicMode;
return MyVideoDriver;
return GetFullScreenCanvas(MyVideoDriver.DefaultGraphicMode);
}
}
}

View file

@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.Text;
using Cosmos.HAL.Drivers.PCI.Video;
namespace Cosmos.System.Graphics
{
public class SVGAIIScreen : Canvas
{
public VMWareSVGAII xSVGAIIDriver;
internal Debug.Kernel.Debugger mSVGAIIDebugger = new Debug.Kernel.Debugger("System", "SVGAIIScreen");
public SVGAIIScreen() : base()
{
mSVGAIIDebugger.SendInternal($"Creting new SVGAIIScreen with default mode {defaultGraphicMode}");
xSVGAIIDriver = new VMWareSVGAII();
xSVGAIIDriver.SetMode((uint)defaultGraphicMode.Columns, (uint)defaultGraphicMode.Rows, (uint)defaultGraphicMode.ColorDepth);
}
public SVGAIIScreen(Mode aMode) : base(aMode)
{
ThrowIfModeIsNotValid(aMode);
xSVGAIIDriver = new VMWareSVGAII();
xSVGAIIDriver.SetMode((uint)aMode.Columns, (uint)aMode.Rows, (uint)aMode.ColorDepth);
}
public override Mode Mode
{
get => mode;
set
{
mode = value;
SetGraphicsMode(mode);
}
}
public override void DrawPoint(Pen pen, int x, int y)
{
Color xColor = pen.Color;
mSVGAIIDebugger.SendInternal($"Drawing point to x:{x}, y:{y} with {xColor.Name} Color");
xSVGAIIDriver.SetPixel((uint)x, (uint)y, (uint)xColor.ToArgb());
mSVGAIIDebugger.SendInternal($"Done drawing point");
xSVGAIIDriver.Update(0, 0, (uint)mode.Columns, (uint)mode.Rows);
}
public override void DrawPoint(Pen pen, float x, float y)
{
throw new NotImplementedException();
}
public override void DrawFilledRectangle(Pen pen, int x_start, int y_start, int width, int height)
{
xSVGAIIDriver.Fill((uint)x_start, (uint)y_start, (uint)width, (uint)height, (uint)pen.Color.ToArgb());
}
public override List<Mode> getAvailableModes()
{
return new List<Mode>
{
/* 16-bit Depth Resolutions*/
/* SD Resolutions */
new Mode(320, 200, ColorDepth.ColorDepth16),
new Mode(320, 240, ColorDepth.ColorDepth16),
new Mode(640, 480, ColorDepth.ColorDepth16),
new Mode(720, 480, ColorDepth.ColorDepth16),
new Mode(800, 600, ColorDepth.ColorDepth16),
new Mode(1152, 768, ColorDepth.ColorDepth16),
/* Old HD-Ready Resolutions */
new Mode(1280, 720, ColorDepth.ColorDepth16),
new Mode(1280, 768, ColorDepth.ColorDepth16),
new Mode(1280, 800, ColorDepth.ColorDepth16), // WXGA
new Mode(1280, 1024, ColorDepth.ColorDepth16), // SXGA
/* Better HD-Ready Resolutions */
new Mode(1360, 768, ColorDepth.ColorDepth16),
new Mode(1366, 768, ColorDepth.ColorDepth16), // Original Laptop Resolution
new Mode(1440, 900, ColorDepth.ColorDepth16), // WXGA+
new Mode(1400, 1050, ColorDepth.ColorDepth16), // SXGA+
new Mode(1600, 1200, ColorDepth.ColorDepth16), // UXGA
new Mode(1680, 1050, ColorDepth.ColorDepth16), // WXGA++
/* HDTV Resolutions */
new Mode(1920, 1080, ColorDepth.ColorDepth16),
new Mode(1920, 1200, ColorDepth.ColorDepth16), // WUXGA
/* 2K Resolutions */
new Mode(2048, 1536, ColorDepth.ColorDepth16), // QXGA
new Mode(2560, 1080, ColorDepth.ColorDepth16), // UW-UXGA
new Mode(2560, 1600, ColorDepth.ColorDepth16), // WQXGA
new Mode(2560, 2048, ColorDepth.ColorDepth16), // QXGA+
new Mode(3200, 2048, ColorDepth.ColorDepth16), // WQXGA+
new Mode(3200, 2400, ColorDepth.ColorDepth16), // QUXGA
new Mode(3840, 2400, ColorDepth.ColorDepth16), // WQUXGA
/* 32-bit Depth Resolutions*/
/* SD Resolutions */
new Mode(320, 200, ColorDepth.ColorDepth32),
new Mode(320, 240, ColorDepth.ColorDepth32),
new Mode(640, 480, ColorDepth.ColorDepth32),
new Mode(720, 480, ColorDepth.ColorDepth32),
new Mode(800, 600, ColorDepth.ColorDepth32),
new Mode(1152, 768, ColorDepth.ColorDepth32),
/* Old HD-Ready Resolutions */
new Mode(1280, 720, ColorDepth.ColorDepth32),
new Mode(1280, 768, ColorDepth.ColorDepth32),
new Mode(1280, 800, ColorDepth.ColorDepth32), // WXGA
new Mode(1280, 1024, ColorDepth.ColorDepth32), // SXGA
/* Better HD-Ready Resolutions */
new Mode(1360, 768, ColorDepth.ColorDepth32),
new Mode(1366, 768, ColorDepth.ColorDepth32), // Original Laptop Resolution
new Mode(1440, 900, ColorDepth.ColorDepth32), // WXGA+
new Mode(1400, 1050, ColorDepth.ColorDepth32), // SXGA+
new Mode(1600, 1200, ColorDepth.ColorDepth32), // UXGA
new Mode(1680, 1050, ColorDepth.ColorDepth32), // WXGA++
/* HDTV Resolutions */
new Mode(1920, 1080, ColorDepth.ColorDepth32),
new Mode(1920, 1200, ColorDepth.ColorDepth32), // WUXGA
/* 2K Resolutions */
new Mode(2048, 1536, ColorDepth.ColorDepth32), // QXGA
new Mode(2560, 1080, ColorDepth.ColorDepth32), // UW-UXGA
new Mode(2560, 1600, ColorDepth.ColorDepth32), // WQXGA
new Mode(2560, 2048, ColorDepth.ColorDepth32), // QXGA+
new Mode(3200, 2048, ColorDepth.ColorDepth32), // WQXGA+
new Mode(3200, 2400, ColorDepth.ColorDepth32), // QUXGA
new Mode(3840, 2400, ColorDepth.ColorDepth32), // WQUXGA
};
}
protected override Mode getDefaultGraphicMode() => new Mode(1024, 768, ColorDepth.ColorDepth16);
private void SetGraphicsMode(Mode aMode)
{
ThrowIfModeIsNotValid(aMode);
var xWidth = (uint)aMode.Columns;
var xHeight = (uint)aMode.Rows;
var xColorDepth = (uint)aMode.ColorDepth;
xSVGAIIDriver.SetMode(xWidth, xHeight, xColorDepth);
}
public override void Clear(Color color)
{
xSVGAIIDriver.Fill(0, 0, (uint)mode.Columns, (uint)mode.Rows, (uint)color.ToArgb());
}
public Color GetPixel(int aX, int aY)
{
var xColorARGB = xSVGAIIDriver.GetPixel((uint)aX, (uint)aX);
var xColor = Color.FromArgb((int)xColorARGB);
return xColor;
}
public void SetCursor(bool aVisible, int aX, int aY)
{
xSVGAIIDriver.SetCursor(aVisible, (uint)aX, (uint)aY);
}
public void CreateCursor()
{
xSVGAIIDriver.DefineCursor();
}
public void CopyPixel(int aX, int aY, int aNewX, int aNewY, int aWidth = 1, int aHeight = 1)
{
xSVGAIIDriver.Copy((uint)aX, (uint)aY, (uint)aNewX, (uint)aNewY, (uint)aWidth, (uint)aHeight);
}
public void MovePixel(int aX, int aY, int aNewX, int aNewY)
{
xSVGAIIDriver.Copy((uint)aX, (uint)aY, (uint)aNewX, (uint)aNewY, 1, 1);
xSVGAIIDriver.SetPixel((uint)aX, (uint)aY, 0);
}
public override Color GetPointColor(int x, int y)
{
return Color.FromArgb((int)xSVGAIIDriver.GetPixel((uint)x, (uint)y));
}
}
}

View file

@ -1,4 +1,4 @@
//#define COSMOSDEBUG
//#define COSMOSDEBUG
using Cosmos.HAL.Drivers;
using System;
using System.Collections.Generic;
@ -6,6 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmos.System.Graphics;
using Cosmos.Common.Extensions;
namespace Cosmos.System
{
@ -26,7 +27,7 @@ namespace Cosmos.System
public VBEScreen(Mode mode) : base(mode)
{
//Global.mDebugger.SendInternal($"Creating new VBEScreen() with mode {mode}");
Global.mDebugger.SendInternal($"Creating new VBEScreen() with mode {mode.Columns}x{mode.Rows}x{(uint)mode.ColorDepth}");
ThrowIfModeIsNotValid(mode);
@ -128,9 +129,7 @@ namespace Cosmos.System
* For now we can Draw only if the ColorDepth is 32 bit, we will throw otherwise.
*
* How to support other ColorDepth? The offset calculation should be the same (and so could be done out of the switch)
* adding support ColorDepth.ColorDepth24 is easier as you need can use the version of SetVRAM() that take a byte
* and call it 3 time for the B, G and R component (the Color class has properties to do this!), the problem is
* for ColorDepth.ColorDepth16 and ColorDepth.ColorDepth8 than need a conversion from color (an ARGB32 color) to the RGB16 and RGB8
* ColorDepth.ColorDepth16 and ColorDepth.ColorDepth8 need a conversion from color (an ARGB32 color) to the RGB16 and RGB8
* how to do this conversion faster maybe using pre-computed tables? What happens if the color cannot be converted? We will throw?
*/
switch (mode.ColorDepth)
@ -148,7 +147,18 @@ namespace Cosmos.System
Global.mDebugger.SendInternal("Point drawn");
break;
case ColorDepth.ColorDepth24:
Global.mDebugger.SendInternal("Computing offset...");
pitch = (uint)mode.Columns * ColorDepthInBytes;
stride = ColorDepthInBytes;
//offset = ((uint)x * pitch) + ((uint)y * stride);
offset = ((uint)x * stride) + ((uint)y * pitch);
Global.mDebugger.SendInternal($"Drawing Point of color {color} at offset {offset}");
VBEDriver.SetVRAM(offset, (((uint)color.R * 1000 + color.G) * 1000 + color.B));
Global.mDebugger.SendInternal("Point drawn");
break;
default:
String errorMsg = "DrawPoint() with ColorDepth " + (int)Mode.ColorDepth + " not yet supported";
throw new NotImplementedException(errorMsg);
@ -184,7 +194,22 @@ namespace Cosmos.System
#endregion
#region Reading
// TODO add to Canvas GetPointColor()
public override Color GetPointColor(int x, int y)
{
uint pitch;
uint stride;
uint offset;
uint ColorDepthInBytes = (uint)mode.ColorDepth / 8;
Global.mDebugger.SendInternal("Computing offset...");
pitch = (uint)mode.Columns * ColorDepthInBytes;
stride = ColorDepthInBytes;
//offset = ((uint)x * pitch) + ((uint)y * stride);
offset = ((uint)x * stride) + ((uint)y * pitch);
Global.mDebugger.SendInternal($"Getting color from point at offset {offset}");
return Color.FromArgb(VBEDriver.GetVRAM(offset));
}
#endregion