New modular driver set for video
Started outlining how the modular driver set will look for video drawing routines. Currently supports Drawing pixels to the screen & Flushing backbuffer -> frontbuffer. Still very much test code, tracer is used everywhere for debugging, NOT DEVELOP READY. Many more draw routines need implementing - such as, but not limited to; drawRect, drawBitmap, drawLine, drawCurve, drawCircle. TODO: Implement the aforementioned routines in all VESA modes + WindowManager.
This commit is contained in:
		| @@ -13,19 +13,19 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->VESA - Provides an interface the VESA drivers. | 	Driver->Video->VESA - VESA Display Driver. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| unit VESA; | unit vesa; | ||||||
|  |  | ||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     Video, multiboot; |     videotypes, tracer, multiboot, lmemorymanager; | ||||||
|  |  | ||||||
| procedure init(); |  | ||||||
|  |  | ||||||
|  | //Init the driver, and register with the video interface in a state ready for execution. | ||||||
|  | procedure init(Register : FRegisterDriver); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
| @@ -38,51 +38,50 @@ var | |||||||
|     Block : uint32; |     Block : uint32; | ||||||
|  |  | ||||||
| begin | begin | ||||||
|     tracer.push_trace('vesa.allocateFrameBuffer.enter'); |     tracer.push_trace('VESA.allocateFrameBuffer.enter'); | ||||||
|     LowerAddress:= ((Address) SHR 22)-1; |     LowerAddress:= ((Address) SHR 22)-1; | ||||||
|     UpperAddress:= ((Address + (Width * Height)) SHR 22)+1; |     UpperAddress:= ((Address + (Width * Height)) SHR 22)+1; | ||||||
|     For Block:=LowerAddress to UpperAddress do begin |     For Block:=LowerAddress to UpperAddress do begin | ||||||
|         kpalloc(Block SHL 22); |         kpalloc(Block SHL 22); | ||||||
|     end; |     end; | ||||||
|     tracer.push_trace('vesa.allocateFrameBuffer.enter'); |     tracer.push_trace('VESA.allocateFrameBuffer.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure initVESAFrameBuffer(VideoBuffer : PVideoBuffer; Location : uint64; Width : uint32; Height : uint32; BitsPerPixel : uint8); | procedure initVESAFrameBuffer(VideoBuffer : PVideoBuffer; Location : uint64; Width : uint32; Height : uint32; BitsPerPixel : uint8); | ||||||
| begin | begin | ||||||
|     if not(VideoBuffer^.MMIOBuffer.Initialized) then begin |     tracer.push_trace('VESA.initVESAFrameBuffer.enter'); | ||||||
|         VideoBuffer^.MMIOBuffer.Location:= Location; |     if not(VideoBuffer^.Initialized) then begin | ||||||
|         VideoBuffer^.MMIOBuffer.BitsPerPixel:= BitsPerPixel; |         VideoBuffer^.Location:= Location; | ||||||
|         VideoBuffer^.MMIOBuffer.Width:= Width; |         VideoBuffer^.BitsPerPixel:= BitsPerPixel; | ||||||
|         VideoBuffer^.MMIOBuffer.Height:= Height; |         VideoBuffer^.Width:= Width; | ||||||
|         allocateVESAFrameBuffer(VideoBuffer^.MMIOBuffer.Location, VideoBuffer^.MMIOBuffer.Width, VideoBuffer^.MMIOBuffer.Height); |         VideoBuffer^.Height:= Height; | ||||||
|         VideoBuffer^.DefaultBuffer:= VideoBuffer^.MMIOBuffer.Location; |         allocateVESAFrameBuffer(VideoBuffer^.Location, VideoBuffer^.Width, VideoBuffer^.Height); | ||||||
|         VideoBuffer^.MMIOBuffer.Initialized:= True; |         if VideoBuffer^.Location <> 0 then | ||||||
|  |             VideoBuffer^.Initialized:= True; | ||||||
|     end; |     end; | ||||||
|  |     tracer.push_trace('VESA.initVESAFrameBuffer.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure Flush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); | function enable(VideoInterface : PVideoInterface) : boolean; | ||||||
| var |  | ||||||
|     x,y : uint32; |  | ||||||
|     Back,Front : PuInt64; |  | ||||||
|  |  | ||||||
| begin | begin | ||||||
|     if not(BackBuffer^.Initialized) then exit; |     tracer.push_trace('VESA.enable.enter'); | ||||||
|     Back:= PUint64(BackBuffer^.Location); |     initVESAFrameBuffer(@VideoInterface^.FrontBuffer, multiboot.multibootinfo^.framebuffer_addr, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp); | ||||||
|     Front:= PuInt64(FrontBuffer^.Location); |     case (VideoInterface^.FrontBuffer.BitsPerPixel) of | ||||||
|     for x:=0 to (VideoDriver.MMIOBuffer.Width-1) div 2 do begin |         08:VESA8.init(@VideoInterface^.DrawRoutines); | ||||||
|         for y:=0 to (VideoDriver.MMIOBuffer.Height-1) div 2 do begin |         16:VESA16.init(@VideoInterface^.DrawRoutines); | ||||||
|             Front[(Y * VideoDriver.MMIOBuffer.Width)+X]:= Back[(Y * VideoDriver.MMIOBuffer.Width)+X]; |         24:VESA24.init(@VideoInterface^.DrawRoutines); | ||||||
|         end; |         32:VESA32.init(@VideoInterface^.DrawRoutines); | ||||||
|     end; |     end; | ||||||
|  |     enable:= VideoInterface^.FrontBuffer.Initialized;   | ||||||
|  |     tracer.push_trace('VESA.enable.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(Register : FRegisterDriver); | ||||||
| begin | begin | ||||||
|     initVESAFrameBuffer(@VideoDriver, multiboot.multibootinfo^.framebuffer_addr, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);  |     tracer.push_trace('VESA.init.enter'); | ||||||
|     VESA8.init(); |     if Register <> nil then | ||||||
|     VESA16.init(); |         Register('VESA', @enable);    | ||||||
|     VESA24.init(); |     tracer.push_trace('VESA.init.exit'); | ||||||
|     VESA32.init(); |  | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
| @@ -13,18 +13,19 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->VESA16 - Implementation of VESA 16bpp draw routines. | 	Driver->Video->VESA16 - Implementation of VESA 16bpp draw routines for the VESA Driver. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| unit VESA16; | unit vesa16; | ||||||
|  |  | ||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     Video, VESA; |     videotypes, vesa, tracer, color; | ||||||
|  |  | ||||||
| procedure init(); | //Init the draw routines by providing what we support through the DrawRoutines struct. | ||||||
|  | procedure init(DrawRoutines : PDrawRoutines); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
| @@ -33,9 +34,10 @@ begin | |||||||
|  |  | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(DrawRoutines : PDrawRoutines); | ||||||
| begin | begin | ||||||
|      |     tracer.push_trace('vesa16.init.enter');    | ||||||
|  |     tracer.push_trace('vesa16.init.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
| @@ -13,18 +13,19 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->VESA24 - Implementation of VESA 24bpp draw routines. | 	Driver->Video->VESA24 - Implementation of VESA 24bpp draw routines for the VESA Driver. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| unit VESA24; | unit vesa24; | ||||||
|  |  | ||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     Video, VESA; |     videotypes, vesa, tracer, color; | ||||||
|  |  | ||||||
| procedure init(); | //Init the draw routines by providing what we support through the DrawRoutines struct. | ||||||
|  | procedure init(DrawRoutines : PDrawRoutines); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
| @@ -33,9 +34,10 @@ begin | |||||||
|  |  | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(DrawRoutines : PDrawRoutines); | ||||||
| begin | begin | ||||||
|      | 	tracer.push_trace('vesa24.init.enter'); | ||||||
|  | 	tracer.push_trace('vesa24.init.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
| @@ -13,18 +13,19 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->VESA32 - Implementation of VESA 32bpp draw routines. | 	Driver->Video->VESA32 - Implementation of VESA 32bpp draw routines for the VESA Driver. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| unit VESA32; | unit vesa32; | ||||||
|  |  | ||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     Video, VESA; |     videotypes, vesa, tracer, color; | ||||||
|  |  | ||||||
| procedure init(); | //Init the draw routines by providing what we support through the DrawRoutines struct. | ||||||
|  | procedure init(DrawRoutines : PDrawRoutines); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
| @@ -34,14 +35,18 @@ var | |||||||
|     LocationIndex : Uint32; |     LocationIndex : Uint32; | ||||||
|  |  | ||||||
| begin | begin | ||||||
|  |     tracer.push_trace('vesa32.DrawPixel.enter'); | ||||||
|     Location:= Puint32(Buffer^.Location); |     Location:= Puint32(Buffer^.Location); | ||||||
|     LocationIndex:= (Y * Buffer^.Width) + X; |     LocationIndex:= (Y * Buffer^.Width) + X; | ||||||
|     Location[LocationIndex]:= uint32(Pixel); |     Location[LocationIndex]:= uint32(Pixel); | ||||||
|  |     tracer.push_trace('vesa32.DrawPixel.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(DrawRoutines : PDrawRoutines); | ||||||
| begin | begin | ||||||
|      |     tracer.push_trace('vesa32.init.enter'); | ||||||
|  |     DrawRoutines^.DrawPixel:= @DrawPixel; | ||||||
|  |     tracer.push_trace('vesa32.init.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
| @@ -13,18 +13,19 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->VESA8 - Implementation of VESA 8bpp draw routines. | 	Driver->Video->VESA8 - Implementation of VESA 8bpp draw routines for the VESA Driver. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| unit VESA8; | unit vesa8; | ||||||
|  |  | ||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     Video, VESA; |     videotypes, vesa, tracer, color; | ||||||
|  |  | ||||||
| procedure init(); | //Init the draw routines by providing what we support through the DrawRoutines struct. | ||||||
|  | procedure init(DrawRoutines : PDrawRoutines); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
| @@ -33,9 +34,10 @@ begin | |||||||
|  |  | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(DrawRoutines : PDrawRoutines); | ||||||
| begin | begin | ||||||
|      |     tracer.push_trace('vesa8.init.enter');    | ||||||
|  |     tracer.push_trace('vesa8.init.exit');   | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
							
								
								
									
										94
									
								
								src/driver/video/doublebuffer.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/driver/video/doublebuffer.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | //  Copyright 2021 Kieron Morris | ||||||
|  | // | ||||||
|  | //  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | //  you may not use this file except in compliance with the License. | ||||||
|  | //  You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //  http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | //  Unless required by applicable law or agreed to in writing, software | ||||||
|  | //  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | //  See the License for the specific language governing permissions and | ||||||
|  | //  limitations under the License. | ||||||
|  |  | ||||||
|  | {  | ||||||
|  | 	Driver->Video->Doublebuffer - Implements a very basic double buffer, tested with VESA drivers. | ||||||
|  | 	 | ||||||
|  | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
|  | } | ||||||
|  | unit doublebuffer; | ||||||
|  |  | ||||||
|  | interface | ||||||
|  |  | ||||||
|  | uses | ||||||
|  |     lmemorymanager, tracer, videotypes; | ||||||
|  |  | ||||||
|  | //Init the driver, and register with the video interface in a state ready for execution. | ||||||
|  | procedure init(Register : FRegisterDriver); | ||||||
|  |  | ||||||
|  | implementation | ||||||
|  |  | ||||||
|  | function allocateBackBuffer(Width : uint32; Height : uint32; BitsPerPixel : uint8) : uint64; | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('doublebuffer.allocateBackBuffer.enter'); | ||||||
|  |     //This doesn't currently work... Needs a rework of lmemorymanager | ||||||
|  |     allocateBackBuffer:= uint64(klalloc((Width * Height) * BitsPerPixel)); | ||||||
|  |     tracer.push_trace('doublebuffer.allocateBackBuffer.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | procedure initBackBuffer(VInterface : PVideoInterface; Width : uint32; Height : uint32; BitsPerPixel : uint8); | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('doublebuffer.initBackBuffer.enter'); | ||||||
|  |     if not(VInterface^.BackBuffer.Initialized) then begin | ||||||
|  |         VInterface^.BackBuffer.Location:= allocateBackBuffer(Width, Height, BitsPerPixel); | ||||||
|  |         if (VInterface^.BackBuffer.Location <> 0) then begin | ||||||
|  |             VInterface^.BackBuffer.Width:= Width; | ||||||
|  |             VInterface^.BackBuffer.Height:= Height; | ||||||
|  |             VInterface^.BackBuffer.BitsPerPixel:= BitsPerPixel; | ||||||
|  |             VInterface^.BackBuffer.Initialized:= True; | ||||||
|  |         end; | ||||||
|  |     end; | ||||||
|  |     tracer.push_trace('doublebuffer.initBackBuffer.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | procedure Flush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); | ||||||
|  | var | ||||||
|  |     X,Y : uint32; | ||||||
|  |     Back,Front : PuInt64; | ||||||
|  |  | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('doublebuffer.Flush.enter'); | ||||||
|  |     if not(BackBuffer^.Initialized) then exit; | ||||||
|  |     if ((FrontBuffer^.Width > BackBuffer^.Width) or (FrontBuffer^.Height > BackBuffer^.Height)) then exit; | ||||||
|  |     Back:= PUint64(BackBuffer^.Location); | ||||||
|  |     Front:= PuInt64(FrontBuffer^.Location); | ||||||
|  |     for X:=0 to (BackBuffer^.Width-1) div 2 do begin | ||||||
|  |         for Y:=0 to (BackBuffer^.Height-1) div 2 do begin | ||||||
|  |             Front[(Y * BackBuffer^.Width) + X]:= Back[(Y * BackBuffer^.Width) + X]; | ||||||
|  |         end; | ||||||
|  |     end; | ||||||
|  |     tracer.push_trace('doublebuffer.Flush.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function enable(VideoInterface : PVideoInterface) : boolean; | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('doublebuffer.enable.enter'); | ||||||
|  |     enable:= false; | ||||||
|  |     initBackBuffer(VideoInterface, VideoInterface^.FrontBuffer.Width, VideoInterface^.FrontBuffer.Height, VideoInterface^.FrontBuffer.BitsPerPixel); | ||||||
|  |     if VideoInterface^.BackBuffer.Initialized then begin | ||||||
|  |         VideoInterface^.DefaultBuffer:= @VideoInterface^.BackBuffer; | ||||||
|  |         VideoInterface^.DrawRoutines.Flush:= @Flush; | ||||||
|  |         enable:= true; | ||||||
|  |     end; | ||||||
|  |     tracer.push_trace('doublebuffer.enable.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | procedure init(Register : FRegisterDriver); | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('doublebuffer.init.enter'); | ||||||
|  |     Register('BASIC_DOUBLE_BUFFER', @enable); | ||||||
|  |     tracer.push_trace('doublebuffer.init.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | end. | ||||||
| @@ -13,7 +13,7 @@ | |||||||
| //  limitations under the License. | //  limitations under the License. | ||||||
|  |  | ||||||
| {  | {  | ||||||
| 	Driver->Video->Video - Provides abstract rasterization/drawing functions. | 	Driver->Video->Video - Provides an abstract rasterization/drawing interface. | ||||||
| 	 | 	 | ||||||
| 	@author(Kieron Morris <kjm@kieronmorris.me>) | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
| } | } | ||||||
| @@ -22,83 +22,37 @@ unit video; | |||||||
| interface | interface | ||||||
|  |  | ||||||
| uses | uses | ||||||
|     lmemorymanager, tracer, color, rand; |     lmemorymanager, tracer, color, videotypes, hashmap; | ||||||
|  |  | ||||||
| procedure init(); | procedure init(); | ||||||
| procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); | procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); | ||||||
| procedure Flush(); | procedure Flush(); | ||||||
|  | function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean; | ||||||
| type | function enable(DriverIdentifier : pchar) : boolean; | ||||||
|     //Arbitrary pointer to a video buffer in memory | function frontBufferWidth : uint32; | ||||||
|     VideoBuffer = uint64; | function frontBufferHeight : uint32; | ||||||
|  | function frontBufferBpp : uint8; | ||||||
|     //Struct representing a Memory Mapped Video Buffer | function backBufferWidth : uint32; | ||||||
|     TVideoBuffer = record | function backBufferHeight : uint32; | ||||||
|         //Has this buffer been initialized? Has it been paged/created in memory? | function backBufferBpp : uint8; | ||||||
|         Initialized     : Boolean; |  | ||||||
|         //Location of the video buffer in memory as a QWORD. |  | ||||||
|         Location        : VideoBuffer; |  | ||||||
|         //How many bits per pixel? |  | ||||||
|         BitsPerPixel    : uint8; |  | ||||||
|         //Width of the buffer. |  | ||||||
|         Width           : uint32; |  | ||||||
|         //Height of the buffer. |  | ||||||
|         Height          : uint32; |  | ||||||
|     end; |  | ||||||
|     //Pointer to a video buffer |  | ||||||
|     PVideoBuffer = ^TVideoBuffer; |  | ||||||
|  |  | ||||||
|     //Routines for drawing to the screen |  | ||||||
|     TDrawRoutines = record |  | ||||||
|         DrawPixel : FDrawPixel; |  | ||||||
|         Flush     : FFlush; |  | ||||||
|     end; |  | ||||||
|     //Pointer to drawing routines |  | ||||||
|     PDrawRoutines = ^TDrawRoutines; |  | ||||||
|  |  | ||||||
|     //Struct representing the whole video driver. |  | ||||||
|     TVideoDriver = record |  | ||||||
|         //Default buffer to be used when rendering, front buffer for no double buffering, back buffer otherwise. |  | ||||||
|         DefaultBuffer   : PVideoBuffer; |  | ||||||
|         //Memory Mapped IO Buffer for raw rasterization. |  | ||||||
|         MMIOBuffer      : TVideoBuffer; |  | ||||||
|         //Back buffer used for double buffering, this is flushed to MMIOBuffer with flush(); |  | ||||||
|         BackBuffer      : TVideoBuffer; |  | ||||||
|         //Drawing Routines |  | ||||||
|         DrawRoutines    : TDrawRoutines; |  | ||||||
|     end; |  | ||||||
|     //Pointer to a video driver struct. |  | ||||||
|     PVideoDriver = ^TVideoDriver; |  | ||||||
|  |  | ||||||
|     //Draw a pixel to screenspace |  | ||||||
|     FDrawPixel = procedure(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); |  | ||||||
|     //Flush backbuffer to MMIO Buffer |  | ||||||
|     FFlush     = procedure(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); |  | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
|  | Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('video.dummyFDrawPixel.enter'); | ||||||
|  |     //Do nothing | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | Procedure dummyFFlush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('video.dummyFFlush.enter'); | ||||||
|  |     //Do nothing | ||||||
|  | end; | ||||||
|  |  | ||||||
| var | var | ||||||
|     VideoDriver : TVideoDriver; |     VideoInterface : TVideoInterface; | ||||||
|  |     DriverMap      : PHashMap; | ||||||
| function allocateBackBuffer(Width : uint32; Height : uint32; BitsPerPixel : uint8) : uint64; |  | ||||||
| begin |  | ||||||
|     Outputln('VIDEO','Start Kalloc Backbuffer'); |  | ||||||
|     //This doesn't currently work... Needs a rework of lmemorymanager |  | ||||||
|     allocateBackBuffer:= uint64(klalloc((Width * Height) * BitsPerPixel)); |  | ||||||
|     Outputln('VIDEO','End Kalloc Backbuffer'); |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| procedure initBackBuffer(DriverInfo : PVideoDriver; Width : uint32; Height : uint32; BitsPerPixel : uint8); |  | ||||||
| begin |  | ||||||
|     if not(DriverInfo^.BackBuffer.Initialized) then begin |  | ||||||
|         DriverInfo^.BackBuffer.Width:= Width; |  | ||||||
|         DriverInfo^.BackBuffer.Height:= Height; |  | ||||||
|         DriverInfo^.BackBuffer.BitsPerPixel:= BitsPerPixel; |  | ||||||
|         DriverInfo^.BackBuffer.Location:= allocateBackBuffer(DriverInfo^.BackBuffer.Width, DriverInfo^.BackBuffer.Height, DriverInfo^.BackBuffer.BitsPerPixel); |  | ||||||
|         DriverInfo^.DefaultBuffer:= DriverInfo^.BackBuffer.Location; |  | ||||||
|         DriverInfo^.BackBuffer.Initialized:= True; |  | ||||||
|     end; |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| procedure init(); | procedure init(); | ||||||
| var | var | ||||||
| @@ -107,23 +61,86 @@ var | |||||||
|  |  | ||||||
| begin | begin | ||||||
|     tracer.push_trace('video.init.enter'); |     tracer.push_trace('video.init.enter'); | ||||||
|      |     VideoInterface.FrontBuffer.Initialized:= false; | ||||||
|     console.Outputln('VIDEO', 'Init VideoDriver MMIOBuffer'); |     VideoInterface.BackBuffer.Initialized:= false; | ||||||
|         |     VideoInterface.DefaultBuffer:= @VideoInterface.FrontBuffer; | ||||||
|     console.Outputln('VIDEO', 'Init VideoDriver Backbuffer'); |     VideoInterface.DrawRoutines.DrawPixel:= @dummyFDrawPixel; | ||||||
|     //initBackBuffer(@VideoDriver, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp); |     VideoInterface.DrawRoutines.Flush:= @dummyFFlush; | ||||||
|  |     DriverMap:= hashmap.new; | ||||||
|     tracer.push_trace('video.init.exit'); |     tracer.push_trace('video.init.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
|  | function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean; | ||||||
|  | var | ||||||
|  |     Value : Void; | ||||||
|  |  | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('video.register.enter'); | ||||||
|  |     register:= false; | ||||||
|  |     Value:= Hashmap.get(DriverMap, DriverIdentifier); | ||||||
|  |     if (Value = nil) then begin | ||||||
|  |         Hashmap.add(DriverMap, DriverIdentifier, void(EnableCallback)); | ||||||
|  |         register:= true; | ||||||
|  |     end; | ||||||
|  |     tracer.push_trace('video.register.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function enable(DriverIdentifier : pchar) : boolean; | ||||||
|  | var | ||||||
|  |     Value : Void; | ||||||
|  |  | ||||||
|  | begin | ||||||
|  |     tracer.push_trace('video.enable.enter'); | ||||||
|  |     enable:= false; | ||||||
|  |     Value:= Hashmap.get(DriverMap, DriverIdentifier); | ||||||
|  |     if (Value <> nil) then begin | ||||||
|  |         enable:= FEnableDriver(Value)(@VideoInterface); | ||||||
|  |     end; | ||||||
|  |     tracer.push_trace('video.enable.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
| procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); | procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); | ||||||
| begin | begin | ||||||
|  |     tracer.push_trace('video.DrawPixel.enter'); | ||||||
|  |     VideoInterface.DrawRoutines.DrawPixel(VideoInterface.DefaultBuffer, X, Y, Pixel); | ||||||
|  |     tracer.push_trace('video.DrawPixel.exit'); | ||||||
| end; | end; | ||||||
|  |  | ||||||
| procedure Flush(); | procedure Flush(); | ||||||
| begin | begin | ||||||
|  |     tracer.push_trace('video.Flush.enter'); | ||||||
|  |     VideoInterface.DrawRoutines.Flush(@VideoInterface.FrontBuffer, @VideoInterface.BackBuffer); | ||||||
|  |     tracer.push_trace('video.Flush.exit'); | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function frontBufferWidth : uint32; | ||||||
|  | begin | ||||||
|  |     frontBufferWidth:= VideoInterface.FrontBuffer.Width; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function frontBufferHeight : uint32; | ||||||
|  | begin | ||||||
|  |     frontBufferHeight:= VideoInterface.FrontBuffer.Height; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function frontBufferBpp : uint8; | ||||||
|  | begin | ||||||
|  |     frontBufferBpp:= VideoInterface.FrontBuffer.BitsPerPixel; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function backBufferWidth : uint32; | ||||||
|  | begin | ||||||
|  |     backBufferWidth:= VideoInterface.BackBuffer.Width; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function backBufferHeight : uint32; | ||||||
|  | begin | ||||||
|  |     backBufferHeight:= VideoInterface.BackBuffer.Height; | ||||||
|  | end; | ||||||
|  |  | ||||||
|  | function backBufferBpp : uint8; | ||||||
|  | begin | ||||||
|  |     backBufferBpp:= VideoInterface.BackBuffer.BitsPerPixel; | ||||||
| end; | end; | ||||||
|  |  | ||||||
| end. | end. | ||||||
							
								
								
									
										83
									
								
								src/driver/video/videotypes.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/driver/video/videotypes.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | //  Copyright 2021 Kieron Morris | ||||||
|  | // | ||||||
|  | //  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | //  you may not use this file except in compliance with the License. | ||||||
|  | //  You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //  http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | //  Unless required by applicable law or agreed to in writing, software | ||||||
|  | //  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | //  See the License for the specific language governing permissions and | ||||||
|  | //  limitations under the License. | ||||||
|  |  | ||||||
|  | {  | ||||||
|  | 	Driver->Video->Videotypes - Provides types relating to the video framework & driver interface. | ||||||
|  | 	 | ||||||
|  | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
|  | } | ||||||
|  | unit videotypes; | ||||||
|  |  | ||||||
|  | interface | ||||||
|  |  | ||||||
|  | uses | ||||||
|  |     color; | ||||||
|  |  | ||||||
|  | type | ||||||
|  |     //Arbitrary pointer to a video buffer in memory | ||||||
|  |     VideoBuffer = uint32; | ||||||
|  |  | ||||||
|  |     //Struct representing a Memory Mapped Video Buffer | ||||||
|  |     TVideoBuffer = record | ||||||
|  |         //Has this buffer been initialized? Has it been paged/created in memory? | ||||||
|  |         Initialized     : Boolean; | ||||||
|  |         //Location of the video buffer in memory as a QWORD. | ||||||
|  |         Location        : VideoBuffer; | ||||||
|  |         //How many bits per pixel? | ||||||
|  |         BitsPerPixel    : uint8; | ||||||
|  |         //Width of the buffer. | ||||||
|  |         Width           : uint32; | ||||||
|  |         //Height of the buffer. | ||||||
|  |         Height          : uint32; | ||||||
|  |     end; | ||||||
|  |     //Pointer to a video buffer | ||||||
|  |     PVideoBuffer = ^TVideoBuffer; | ||||||
|  |  | ||||||
|  |     //(Abstract) Draw a pixel to screenspace | ||||||
|  |     FDrawPixel = procedure(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); | ||||||
|  |     //(Abstract) Flush backbuffer to MMIO Buffer | ||||||
|  |     FFlush     = procedure(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); | ||||||
|  |  | ||||||
|  |     //Routines for drawing to the screen | ||||||
|  |     TDrawRoutines = record | ||||||
|  |         DrawPixel : FDrawPixel; | ||||||
|  |         Flush     : FFlush; | ||||||
|  |     end; | ||||||
|  |     //Pointer to drawing routines | ||||||
|  |     PDrawRoutines = ^TDrawRoutines; | ||||||
|  |  | ||||||
|  |     //Struct representing the whole video driver. | ||||||
|  |     TVideoInterface = record | ||||||
|  |         //Default buffer to be used when rendering, front buffer for no double buffering, back buffer otherwise. | ||||||
|  |         DefaultBuffer   : PVideoBuffer; | ||||||
|  |         //Memory Mapped IO Buffer for raw rasterization. | ||||||
|  |         FrontBuffer     : TVideoBuffer; | ||||||
|  |         //Back buffer used for double buffering, this is flushed to FrontBuffer with flush(); | ||||||
|  |         BackBuffer      : TVideoBuffer; | ||||||
|  |         //Drawing Routines | ||||||
|  |         DrawRoutines    : TDrawRoutines; | ||||||
|  |     end; | ||||||
|  |     //Pointer to a video interface struct. | ||||||
|  |     PVideoInterface = ^TVideoInterface; | ||||||
|  |  | ||||||
|  |     //(Abstract) Enable method for a driver, called from video to enable driver. | ||||||
|  |     FEnableDriver = function(VideoInterface : PVideoInterface) : boolean; | ||||||
|  |     //(Abstract) Register driver, called from a driver to register with the video interface. | ||||||
|  |     FRegisterDriver = function(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean; | ||||||
|  |     //(Abstract) Init driver, called from _somewhere_ to start the driver and register it with the video interface. | ||||||
|  |     FInitDriver = procedure(Register : FRegisterDriver); | ||||||
|  |  | ||||||
|  | implementation | ||||||
|  |  | ||||||
|  | end. | ||||||
| @@ -1,3 +1,22 @@ | |||||||
|  | //  Copyright 2021 Kieron Morris | ||||||
|  | // | ||||||
|  | //  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | //  you may not use this file except in compliance with the License. | ||||||
|  | //  You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //  http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | //  Unless required by applicable law or agreed to in writing, software | ||||||
|  | //  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | //  See the License for the specific language governing permissions and | ||||||
|  | //  limitations under the License. | ||||||
|  |  | ||||||
|  | {  | ||||||
|  | 	Include->Color - Provides types relating to color/graphics. | ||||||
|  | 	 | ||||||
|  | 	@author(Kieron Morris <kjm@kieronmorris.me>) | ||||||
|  | } | ||||||
| unit color; | unit color; | ||||||
|  |  | ||||||
| interface | interface | ||||||
| @@ -31,6 +50,9 @@ type | |||||||
| const | const | ||||||
|     black : TRGB32 = (B: 000; G: 000; R: 000; A: 000); |     black : TRGB32 = (B: 000; G: 000; R: 000; A: 000); | ||||||
|     white : TRGB32 = (B: 255; G: 255; R: 255; A: 000); |     white : TRGB32 = (B: 255; G: 255; R: 255; A: 000); | ||||||
|  |     red   : TRGB32 = (B: 000; G: 000; R: 255; A: 000); | ||||||
|  |     green : TRGB32 = (B: 000; G: 255; R: 000; A: 000); | ||||||
|  |     blue  : TRGB32 = (B: 255; G: 000; R: 000; A: 000); | ||||||
|  |  | ||||||
| implementation | implementation | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,8 @@ uses | |||||||
|      base64, |      base64, | ||||||
|      rand, |      rand, | ||||||
|      terminal, |      terminal, | ||||||
|      hashmap, vfs, video; |      hashmap, vfs,  | ||||||
|  |      video, vesa, doublebuffer, color; | ||||||
|   |   | ||||||
| procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; | procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; | ||||||
|   |   | ||||||
| @@ -124,6 +125,8 @@ var | |||||||
|  |  | ||||||
|    HM              : PHashMap; |    HM              : PHashMap; | ||||||
|  |  | ||||||
|  |    colour          : TRGB32; | ||||||
|  |     | ||||||
| begin | begin | ||||||
|      { Init the base system unit } |      { Init the base system unit } | ||||||
|      System.init(); |      System.init(); | ||||||
| @@ -204,6 +207,27 @@ begin | |||||||
|      tracer.init(); |      tracer.init(); | ||||||
|  |  | ||||||
|      video.init(); |      video.init(); | ||||||
|  |      vesa.init(@video.register); | ||||||
|  |      doublebuffer.init(@video.register); | ||||||
|  |      video.enable('VESA'); | ||||||
|  |      video.enable('BASIC_DOUBLE_BUFFER'); | ||||||
|  |      colour:= color.red; | ||||||
|  |      while true do begin | ||||||
|  |         for i:=0 to video.frontBufferWidth-1 do begin | ||||||
|  |             for z:=0 to video.frontBufferHeight-1 do begin | ||||||
|  |                 video.DrawPixel(i, z, colour); | ||||||
|  |             end; | ||||||
|  |         end; | ||||||
|  |          | ||||||
|  |         if uint32(colour) = uint32(color.red) then | ||||||
|  |             colour:= color.green | ||||||
|  |         else if uint32(colour) = uint32(color.green) then | ||||||
|  |             colour:= color.blue | ||||||
|  |         else if uint32(colour) = uint32(color.blue) then | ||||||
|  |             colour:= color.red; | ||||||
|  |  | ||||||
|  |         video.Flush(); | ||||||
|  |      end; | ||||||
|  |  | ||||||
|      { VFS Init } |      { VFS Init } | ||||||
|      vfs.init(); |      vfs.init(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user