Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨CGS Update part 2 (Remastered) #3087

Merged
merged 12 commits into from
Sep 25, 2024
3 changes: 3 additions & 0 deletions Tests/Kernels/GraphicTest/Kernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ private void DoTest(Canvas aCanvas)
aCanvas.DrawImage(bitmap, 10, 10);
aCanvas.DrawImage(letter, 50, 10);

Bitmap GetImageTest = aCanvas.GetImage(50, 10, (int)letter.Width, (int)letter.Height);
Assert.AreEqual(GetImageTest.RawData, letter.RawData, "GetImage returns correct values");

/* Drawing BitmapHeaderV5 image */
Bitmap v5header = new Bitmap(Convert.FromBase64String(parrot));
aCanvas.DrawImage(v5header,0,0);
Expand Down
20 changes: 20 additions & 0 deletions source/Cosmos.Core/ManagedMemoryBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,26 @@ public unsafe void Copy(MemoryBlock block)
MemoryOperations.Copy(xDest, aDataPtr, (int)block.Size);
}

/// <summary>
/// Copies data from the memory block to the specified array.
/// </summary>
/// <param name="aStart">The start index in the memory block from which to begin copying.</param>
/// <param name="aData">The array into which data will be copied.</param>
/// <param name="aIndex">The starting index in the array where data will be copied.</param>
/// <param name="aCount">The number of elements to copy.</param>
public unsafe void Get(int aStart, int[] aData, int aIndex, int aCount)
{
int* xSrc;
fixed (byte* aArrayPtr = memory)
{
xSrc = (int*)aArrayPtr + aStart;
}
fixed (int* aDataPtr = aData)
{
MemoryOperations.Copy(aDataPtr + aIndex, xSrc, aCount);
}
}

/// <summary>
/// Write 8-bit to the memory block.
/// </summary>
Expand Down
32 changes: 32 additions & 0 deletions source/Cosmos.Core/MemoryBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,38 @@ public unsafe void Copy(ManagedMemoryBlock block)
MemoryOperations.Copy(xDest, aDataPtr, (int)block.Size);
}

/// <summary>
/// Copies data from the memory block to the specified array.
/// </summary>
/// <param name="aByteOffset">The byte offset in the memory block from which to start copying.</param>
/// <param name="aData">The array into which data will be copied.</param>
/// <param name="aIndex">The starting index in the array where data will be copied.</param>
/// <param name="aCount">The number of elements to copy.</param>
public unsafe void Get(int aByteOffset, int[] aData, int aIndex, int aCount)
{
int* xSource = (int*)(Base + aByteOffset);
fixed (int* aDataPtr = aData)
{
MemoryOperations.Copy(aDataPtr + aIndex, xSource, aCount);
}
}

/// <summary>
/// Copies a specified number of bytes from the memory block into an array.
/// </summary>
/// <param name="aByteOffset">The byte offset in the memory block from where the copy starts.</param>
/// <param name="aData">The array where the data will be copied to.</param>
/// <param name="aIndex">The starting index in the destination array.</param>
/// <param name="aCount">The number of bytes to copy.</param>
public unsafe void Get(int aByteOffset, byte[] aData, int aIndex, int aCount)
{
byte* xSource = (byte*)(Base + aByteOffset);
fixed (byte* aDataPtr = aData)
{
MemoryOperations.Copy(aDataPtr + aIndex, xSource, aCount);
}
}

/// <summary>
/// Move bytes array down the memory block.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ public uint GetVRAM(uint index)
return (uint)pixel;
}

/// <summary>
/// Get VRAM data.
/// </summary>
/// <param name="aStart">Start position in VRAM.</param>
/// <param name="aData">Array to copy data into.</param>
/// <param name="aIndex">Starting index in the array to begin copying data.</param>
/// <param name="aCount">Number of elements to copy.</param>
public void GetVRAM(int aStart, int[] aData, int aIndex, int aCount)
{
lastbuffer.Get(aStart, aData, aIndex, aCount);
}

/// <summary>
/// Clear VRAM.
/// </summary>
Expand Down
162 changes: 128 additions & 34 deletions source/Cosmos.System2/Graphics/Canvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ public virtual void Clear(Color color)
/// <param name="y">The Y coordinate.</param>
public abstract void DrawPoint(Color color, int x, int y);

/// <summary>
/// Sets the pixel at the given coordinates to the specified <paramref name="color"/>, without unnecessary color operations.
/// </summary>
/// <param name="color">The color to draw with (raw argb).</param>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
public abstract void DrawPoint(uint color, int x, int y);

/// <summary>
/// Sets the pixel at the given coordinates to the specified <paramref name="color"/>. without ToArgb()
/// </summary>
/// <param name="color">The color to draw with (raw argb).</param>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
public abstract void DrawPoint(int color, int x, int y);

/// <summary>
/// The name of the Canvas implementation.
/// </summary>
Expand All @@ -117,11 +133,14 @@ public virtual void Clear(Color color)
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
public abstract Color GetPointColor(int x, int y);

/// <summary>
/// Gets the index of the pixel at the given coordinates.
/// Gets the color of the pixel at the given coordinates in ARGB.
/// </summary>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
public abstract int GetRawPointColor(int x, int y);

internal int GetPointOffset(int x, int y)
{
return (x * Stride) + (y * Pitch);
Expand All @@ -147,6 +166,47 @@ public virtual void DrawArray(Color[] colors, int x, int y, int width, int heigh
}
}

/// <summary>
/// Draws an array of pixels to the canvas, starting at the given coordinates,
/// using the given width.
/// </summary>
/// <param name="colors">The pixels to draw.</param>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
/// <param name="width">The width of the drawn bitmap.</param>
/// <param name="height">The height of the drawn bitmap.</param>
public virtual void DrawArray(int[] colors, int x, int y, int width, int height)
{
for (int X = 0; X < width; X++)
{
for (int Y = 0; Y < height; Y++)
{
DrawPoint(colors[Y * width + X], x + X, y + Y);
}
}
}

/// <summary>
/// Draws an array of pixels to the canvas, starting at the given coordinates,
/// using the given width.
/// </summary>
/// <param name="colors">The pixels to draw.</param>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
/// <param name="width">The width of the drawn bitmap.</param>
/// <param name="height">The height of the drawn bitmap.</param>
/// <param name="startIndex">int[] colors tarting position</param>
public virtual void DrawArray(int[] colors, int x, int y, int width, int height, int startIndex)
{
for (int X = 0; X < width; X++)
{
for (int Y = 0; Y < height; Y++)
{
DrawPoint(colors[Y * width + X + startIndex], x + X, y + Y);
}
}
}

/// <summary>
/// Draws a horizontal line.
/// </summary>
Expand Down Expand Up @@ -317,6 +377,7 @@ public virtual void DrawCircle(Color color, int xCenter, int yCenter, int radius
/// <param name="x0">The X center coordinate.</param>
/// <param name="y0">The Y center coordinate.</param>
/// <param name="radius">The radius of the circle to draw.</param>
/// <param name="preventOffBoundPixels">Prevents drawing outside the bounds of the canvas.</param>
public virtual void DrawFilledCircle(Color color, int x0, int y0, int radius)
{
int x = radius;
Expand Down Expand Up @@ -485,40 +546,17 @@ public virtual void DrawSquare(Color color, int x, int y, int size)
/// <param name="height">The height of the rectangle.</param>
public virtual void DrawRectangle(Color color, int x, int y, int width, int height)
{
/*
* we must draw four lines connecting any vertex of our rectangle to do this we first obtain the position of these
* vertex (we call these vertexes A, B, C, D as for geometric convention)
*/

/* The check of the validity of x and y are done in DrawLine() */

/* The vertex A is where x,y are */
int xa = x;
int ya = y;

/* The vertex B has the same y coordinate of A but x is moved of width pixels */
int xb = x + width;
int yb = y;
// Draw top edge from (x, y) to (x + width, y)
DrawLine(color, x, y, x + width, y);

/* The vertex C has the same x coordiate of A but this time is y that is moved of height pixels */
int xc = x;
int yc = y + height;
// Draw left edge from (x, y) to (x, y + height)
DrawLine(color, x, y, x, y + height);

/* The Vertex D has x moved of width pixels and y moved of height pixels */
int xd = x + width;
int yd = y + height;
// Draw bottom edge from (x, y + height) to (x + width, y + height)
DrawLine(color, x, y + height, x + width, y + height);

/* Draw a line betwen A and B */
DrawLine(color, xa, ya, xb, yb);

/* Draw a line between A and C */
DrawLine(color, xa, ya, xc, yc);

/* Draw a line between B and D */
DrawLine(color, xb, yb, xd, yd);

/* Draw a line between C and D */
DrawLine(color, xc, yc, xd, yd);
// Draw right edge from (x + width, y) to (x + width, y + height)
DrawLine(color, x + width, y, x + width, y + height);
}

/// <summary>
Expand Down Expand Up @@ -569,6 +607,7 @@ public virtual void DrawTriangle(Color color, int v1x, int v1y, int v2x, int v2y
/// <param name="image">The image to draw.</param>
/// <param name="x">The origin X coordinate.</param>
/// <param name="y">The origin Y coordinate.</param>
/// <param name="preventOffBoundPixels">Prevents drawing outside the bounds of the canvas.</param>
public virtual void DrawImage(Image image, int x, int y, bool preventOffBoundPixels = true)
{
Color color;
Expand Down Expand Up @@ -598,6 +637,35 @@ public virtual void DrawImage(Image image, int x, int y, bool preventOffBoundPix
}
}

/// <summary>
/// Creates a bitmap by copying a portion of your canvas from the specified coordinates and dimensions.
/// </summary>
/// <param name="x">The starting X coordinate of the region to copy.</param>
/// <param name="y">The starting Y coordinate of the region to copy.</param>
/// <param name="width">The width of the region to copy.</param>
/// <param name="height">The height of the region to copy.</param>
/// <returns>A new <see cref="Bitmap"/> containing the copied region.</returns>
public virtual Bitmap GetImage(int x, int y, int width, int height)
{
Bitmap bitmap = new Bitmap((uint)x, (uint)y, ColorDepth.ColorDepth32);

for (int posy = y, desty = 0; posy < y + y; posy++, desty++)
{
for (int posx = x, destx = 0; posx < x + x; posx++, destx++)
{
bitmap.RawData[desty * x + destx] = GetRawPointColor(posx, posy);
}
}
return bitmap;
}

/// <summary>
/// Scales an image to the specified new width and height.
/// </summary>
/// <param name="image">The image to be scaled.</param>
/// <param name="newWidth">The width of the scaled image.</param>
/// <param name="newHeight">The height of the scaled image.</param>
/// <returns>An array of integers representing the scaled image's pixel data. (Raw bitmap data)</returns>
static int[] ScaleImage(Image image, int newWidth, int newHeight)
{
int[] pixels = image.RawData;
Expand All @@ -607,7 +675,6 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight)
int xRatio = (int)((w1 << 16) / newWidth) + 1;
int yRatio = (int)((h1 << 16) / newHeight) + 1;
int x2, y2;

for (int i = 0; i < newHeight; i++)
{
for (int j = 0; j < newWidth; j++)
Expand All @@ -617,7 +684,6 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight)
temp[(i * newWidth) + j] = pixels[(y2 * w1) + x2];
}
}

return temp;
}

Expand All @@ -629,6 +695,7 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight)
/// <param name="y">The Y coordinate.</param>
/// <param name="w">The desired width to scale the image to before drawing.</param>
/// <param name="h">The desired height to scale the image to before drawing</param>
/// <param name="preventOffBoundPixels">Prevents drawing outside the bounds of the canvas.</param>
public virtual void DrawImage(Image image, int x, int y, int w, int h, bool preventOffBoundPixels = true)
{
Color color;
Expand Down Expand Up @@ -660,12 +727,39 @@ public virtual void DrawImage(Image image, int x, int y, int w, int h, bool prev
}
}

/// <summary>
/// Draws the given image at the specified coordinates, cropping the image to fit within the maximum width and height.
/// </summary>
/// <param name="image">The image to draw.</param>
/// <param name="x">The X coordinate where the image will be drawn.</param>
/// <param name="y">The Y coordinate where the image will be drawn.</param>
/// <param name="maxWidth">The maximum width to display the image. If the image exceeds this width, it will be cropped.</param>
/// <param name="maxHeight">The maximum height to display the image. If the image exceeds this height, it will be cropped.</param>
/// <param name="preventOffBoundPixels">Prevents drawing outside the bounds of the canvas.</param>
public virtual void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight, bool preventOffBoundPixels = true)
{
Color color;
int width = Math.Min((int)image.Width, maxWidth);
int height = Math.Min((int)image.Height, maxHeight);
int[] pixels = image.RawData;

for (int xi = 0; xi < width; xi++)
{
for (int yi = 0; yi < height; yi++)
{
color = Color.FromArgb(pixels[xi + (yi * image.Width)]);
DrawPoint(color, x + xi, y + yi);
}
}
}

/// <summary>
/// Draws an image with alpha blending.
/// </summary>
/// <param name="image">The image to draw.</param>
/// <param name="x">The X coordinate.</param>
/// <param name="y">The Y coordinate.</param>
/// <param name="preventOffBoundPixels">Prevents drawing outside the bounds of the canvas.</param>
public void DrawImageAlpha(Image image, int x, int y, bool preventOffBoundPixels = true)
{
Color color;
Expand Down
2 changes: 1 addition & 1 deletion source/Cosmos.System2/Graphics/FullScreenCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private enum VideoDriver
VGADriver
}

static Canvas videoDriver = null;
public static Canvas videoDriver = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this to be public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you can directly access framebuffer and many driver stuff

  • CopyVRAM
  • GetVRAM
  • SetVRAM
  • ClearVRAM
  • Fill

Also i think that people should have direct access to grapic driver, only positives

static readonly PCIDevice svgaIIDevice = PCI.GetDevice(VendorID.VMWare, DeviceID.SVGAIIAdapter);

/// <summary>
Expand Down
Loading
Loading