Cosmos
Cosmos copied to clipboard
[CGS] Add to the Bochs driver the support for 4, 8, 16 and 24 bit color depths
The method DrawPoint() in VBEScreen actually throws if the mode is set differently from 32, but the Bochs VGA driver support the other Color Depths. Look here as a starting point: http://wiki.osdev.org/Bochs_VBE_Extensions#Memory%20layout%20of%20video%20modes
The simple version of this modification (and the one I've tough during the development) is to continue to use the Color class that CGS uses that as the System.Drawing.Graphic accepts only RGB32 values and do the conversion in VBEScreen in the methods Clear() and DrawPoint(), this could be slow thinking to when a line or a rectangle is drawn this conversion will happen more than one time! A possible mitigation of this could be to save in some static variable the last color converted and check if it is the same Color and if so use it instead of doing the conversion again...
A more object oriented solution should be to make the Color class an abstract class (or interface better if we want one day make Color a structure again) and inherit from it the following classes (structures in future):
- Color4: only 16 colors possible, underlying type byte
- Color8: only 256 colors possible, underlying type byte
- Color16: only 65535 colors possible, underlying type ushort
- Color24: same as 32 bit colors but without alpha channel, underlying type uint
The abstract class / interface Color will be have the same API of the System.Drawing.Graphic Class (but the implementation could be simplified not having anymore to be compatible with some weird GDI+ struct layout) but as these types should be in the end used as "enhanced" integers implicit / explicit cast between them should be present.
To be decided what to do when for example a Color is requested but cannot be represented in the specified color depth we throw or try to give an approximation of the Color think for example at this:
// there is only Red in 16 bit colors? We throw or silently create Red?
Color4 color = new Color4(Color.IndianRed);
Another possibility is to retain the Color class but save inside it the ColorDepht information, so for example to get a 4 bit Color:
Color color = new Color((Color.IndianRed, ColorDepth.ColorDepth4);
if not indicated ColorDepth32 is assumed.
#601
Conversion from one bit depth to another is just a series of logical shifts and bitmasks, its not that much of an overhead and we could cache it. We could have a method ConvertToBitDepth(CurrentColorDepth)
which can be used by the Canvas
class (or whatever inherits it) to send the correct data to the driver.
On the other hand, it could be handled entirely in the HAL driver as not all implementations of 16 bit colour are the same.
Regardless of how different bit depths are supported, there should be a guarantee to that whatever colour is defined is not changed due to the bit depth. Having different behaviour for different bit depths sounds really difficult for developers to work around, and it will likely force them to only support one.
Secondly, do we need to support all these bit depths? I don't think 24 bit is actually used because its slower than 32 bit (you have to take into account the misalignment between an int[] and a 24bit number). Most new displays and GPUs don't support anything below 32bit, it doesn't really achieve much if we do implement it. I can see the merit of implementing 16bit so we can be certain that the graphics system can handle different bit depths.
Can be closed if done
Personally, I feel like this can be closed. The Bochs VBE Extensions are a VM-dependent feature, and implementing lower bit-depths seems a bit counter-productive.