Added basic 2D video accelleration
authorJohn Hodge <[email protected]>
Sat, 24 Apr 2010 15:38:02 +0000 (23:38 +0800)
committerJohn Hodge <[email protected]>
Sat, 24 Apr 2010 15:38:02 +0000 (23:38 +0800)
Kernel/Makefile.BuildNum
Kernel/drv/vterm.c
Kernel/drvutil.c
Kernel/include/tpl_drv_video.h
Modules/Display/VESA/main.c
Usermode/Applications/axwin2_src/WM/interface.c

index 0deb19f..0c5bde4 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 2057
+BUILD_NUM = 2070
index 8255f6c..ab1e97d 100644 (file)
@@ -77,6 +77,7 @@ void  VT_KBCallBack(Uint32 Codepoint);
 void   VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count);
  int   VT_int_ParseEscape(tVTerm *Term, char *Buffer);
 void   VT_int_PutChar(tVTerm *Term, Uint32 Ch);
+void   VT_int_ScrollFramebuffer( tVTerm *Term );
 void   VT_int_UpdateScreen( tVTerm *Term, int UpdateAll );
 void   VT_int_ChangeMode(tVTerm *Term, int NewMode);
 
@@ -920,13 +921,13 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                Term->WritePos ++;
                break;
        }
-               
        
        // Move Screen
        if(Term->WritePos >= Term->Width*Term->Height*VT_SCROLLBACK)
        {
                 int    base, i;
                Term->WritePos -= Term->Width;
+               VT_int_UpdateScreen( Term, 0 );
                
                // Update view position
                base = Term->Width*Term->Height*(VT_SCROLLBACK-1);
@@ -951,18 +952,58 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                }
                
                //LOG("Scrolled buffer");
-               VT_int_UpdateScreen( Term, 1 );
+               VT_int_ScrollFramebuffer( Term );
+               VT_int_UpdateScreen( Term, 0 );
        }
-       else if(Term->WritePos >= Term->Width*Term->Height+Term->ViewPos)
+       else if(Term->WritePos >= Term->ViewPos + Term->Width*Term->Height)
        {
-               Term->ViewPos += Term->Width;
                //LOG("Scrolled screen");
-               VT_int_UpdateScreen( Term, 1 );
+               Term->WritePos -= Term->Width;
+               VT_int_UpdateScreen( Term, 0 );
+               Term->WritePos += Term->Width;
+               
+               Term->ViewPos += Term->Width;
+               VT_int_ScrollFramebuffer( Term );
+               VT_int_UpdateScreen( Term, 0 );
        }
        
        //LEAVE('-');
 }
 
+/**
+ * \fn void VT_int_ScrollFramebuffer( tVTerm *Term )
+ * \note Scrolls the framebuffer by 1 text line
+ */
+void VT_int_ScrollFramebuffer( tVTerm *Term )
+{
+        int    tmp;
+       struct {
+               Uint8   Op;
+               Uint16  DstX, DstY;
+               Uint16  SrcX, SrcY;
+               Uint16  W, H;
+       } PACKED        buf;
+       // Only update if this is the current terminal
+       if( Term != gpVT_CurTerm )      return;
+       
+       // This should only be called in text mode
+       
+       tmp = VIDEO_BUFFMT_2DSTREAM;
+       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
+       
+       buf.Op = VIDEO_2DOP_BLIT;
+       buf.DstX = 0;   buf.DstY = 0;
+       buf.SrcX = 0;   buf.SrcY = giVT_CharHeight;
+       buf.W = Term->Width * giVT_CharWidth;
+       buf.H = (Term->Height-1) * giVT_CharHeight;
+       
+       VFS_WriteAt(giVT_OutputDevHandle, 0, 1+12, &buf);
+       
+       // Restore old mode
+       tmp = VIDEO_BUFFMT_TEXT;
+       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
+}
+
 /**
  * \fn void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
  * \brief Updates the video framebuffer
index 12f21cd..99d02f6 100644 (file)
@@ -5,8 +5,82 @@
 #define DEBUG  0
 #include <acess.h>
 #include <tpl_drv_disk.h>
+#include <tpl_drv_video.h>
 
 // === CODE ===
+// --- Video Driver Helpers ---
+Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
+       tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
+{
+       Uint8   *stream = Buffer;
+        int    rem = Length;
+        int    op;
+       while( rem )
+       {
+               rem --;
+               op = *stream++;
+               
+               if(op > NUM_VIDEO_2DOPS) {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Unknown"
+                               " operation %i", op);
+               }
+               
+               if(op*4 > SizeofHandlers) {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver does"
+                               " not support op %i", op);
+                       return Length-rem;
+               }
+               
+               switch(op)
+               {
+               case VIDEO_2DOP_NOP:    break;
+               
+               case VIDEO_2DOP_FILL:
+                       if(rem < 12)    return Length-rem;
+                       
+                       if(!Handlers->Fill) {
+                               Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
+                                       " does not support VIDEO_2DOP_FILL");
+                               return Length-rem;
+                       }
+                       
+                       Handlers->Fill(
+                               Ent,
+                               *(Uint16*)(&stream[0]), *(Uint16*)(&stream[2]),
+                               *(Uint16*)(&stream[4]), *(Uint16*)(&stream[6]),
+                               *(Uint32*)(&stream[8])
+                               );
+                       
+                       rem -= 12;
+                       stream += 12;
+                       break;
+               
+               case VIDEO_2DOP_BLIT:
+                       if(rem < 12)    return Length-rem;
+                       
+                       if(!Handlers->Blit) {
+                               Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
+                                       " does not support VIDEO_2DOP_BLIT");
+                               return Length-rem;
+                       }
+                       
+                       Handlers->Blit(
+                               Ent,
+                               *(Uint16*)(&stream[0]), *(Uint16*)(&stream[2]),
+                               *(Uint16*)(&stream[4]), *(Uint16*)(&stream[6]),
+                               *(Uint16*)(&stream[8]), *(Uint16*)(&stream[10])
+                               );
+                       
+                       rem -= 12;
+                       stream += 12;
+                       break;
+               
+               }
+       }
+       return 0;
+}
+
+// --- Disk Driver Helpers ---
 Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
        tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
 {
index ce575bb..89bdbfd 100644 (file)
@@ -159,6 +159,38 @@ enum eTplVideo_BufFormats
        VIDEO_BUFFMT_3DSTREAM\r
 };\r
 \r
+/**\r
+ * \brief \r
+ */\r
+enum eTplVideo_2DCommands\r
+{\r
+       /**\r
+        * \brief No Operation\r
+        */\r
+       VIDEO_2DOP_NOP,\r
+       /**\r
+        * \brief Fill a region\r
+        * \param X     Uint16 - Leftmost pixels of the region\r
+        * \param Y     Uint16 - Topmost pixels of the region\r
+        * \param W     Uint16 - Width of the region\r
+        * \param H     Uint16 - Height of the region\r
+        * \param Colour        Uint32 - Value to fill with\r
+        */\r
+       VIDEO_2DOP_FILL,\r
+       /**\r
+        * \brief Copy a region from one part of the framebuffer to another\r
+        * \param DestX Uint16 - Leftmost pixels of the destination\r
+        * \param DestY Uint16 - Topmost pixels of the destination\r
+        * \param SrcX  Uint16 - Leftmost pixels of the source\r
+        * \param SrcY  Uint16 - Topmost pixels of the source\r
+        * \param Width Uint16 - Width of the region\r
+        * \param Height        Uint16 - Height of the region\r
+        */\r
+       VIDEO_2DOP_BLIT,\r
+\r
+       NUM_VIDEO_2DOPS\r
+};\r
+\r
 /**\r
  * \brief Describes a position in the video framebuffer\r
  */\r
@@ -221,4 +253,20 @@ extern void        VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC
  */\r
 extern Uint32  VT_Colour12to24(Uint16 Col12);\r
 \r
+/**\r
+ * \r
+ */\r
+typedef struct sDrvUtil_Video_2DHandlers\r
+{\r
+       void    *Nop;\r
+       void    (*Fill)(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
+       void    (*Blit)(void *Ent, Uint16 DestX, Uint16 DestY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
+}      tDrvUtil_Video_2DHandlers;\r
+\r
+/**\r
+ * \brief \r
+ */\r
+extern Uint64  DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,\r
+       tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);\r
+\r
 #endif\r
index 85bcb3b..a4f346f 100644 (file)
@@ -25,6 +25,9 @@ Uint64        Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   Vesa_Int_SetMode(int Mode);\r
  int   Vesa_Int_FindMode(tVideo_IOCtl_Mode *data);\r
  int   Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data);\r
+// --- 2D Acceleration Functions --\r
+void   Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
+void   Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
 \r
 // === GLOBALS ===\r
 MODULE_DEFINE(0, VERSION, Vesa, Vesa_Install, NULL, "PCI", "VM8086", NULL);\r
@@ -45,6 +48,11 @@ char *gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER;
 tVesa_Mode     *gVesa_Modes;\r
  int   giVesaModeCount = 0;\r
  int   giVesaPageCount = 0;\r
+tDrvUtil_Video_2DHandlers      gVesa_2DFunctions = {\r
+       NULL,\r
+       Vesa_2D_Fill,\r
+       Vesa_2D_Blit\r
+};\r
 \r
 //CODE\r
 int Vesa_Install(char **Arguments)\r
@@ -291,6 +299,14 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                LOG("BGA Framebuffer updated");\r
                }\r
                break;\r
+       \r
+       case VIDEO_BUFFMT_2DSTREAM:\r
+               Length = DrvUtil_Video_2DStream(\r
+                       NULL,   // Single framebuffer, so Ent is unused\r
+                       Buffer, Length, &gVesa_2DFunctions, sizeof(gVesa_2DFunctions)\r
+                       );\r
+               break;\r
+       \r
        default:\r
                LEAVE('i', -1);\r
                return -1;\r
@@ -429,3 +445,58 @@ int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data)
        data->bpp = gVesa_Modes[data->id].bpp;\r
        return 1;\r
 }\r
+\r
+// ------------------------\r
+// --- 2D Accelleration ---\r
+// ------------------------\r
+void Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)\r
+{\r
+        int    scrnwidth = gVesa_Modes[giVesaCurrentMode].width;\r
+       Uint32  *buf = (Uint32*)gpVesa_Framebuffer + Y*scrnwidth + X;\r
+       while( H -- ) {\r
+               memsetd(buf, Colour, W);\r
+               buf += scrnwidth;\r
+       }\r
+}\r
+\r
+void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)\r
+{\r
+        int    scrnwidth = gVesa_Modes[giVesaCurrentMode].width;\r
+        int    dst = DstY*scrnwidth + DstX;\r
+        int    src = SrcY*scrnwidth + SrcX;\r
+        int    tmp;\r
+       \r
+       //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",\r
+       //      Ent, DstX, DstY, SrcX, SrcY, W, H);\r
+       \r
+       if(SrcX + W > scrnwidth)\r
+               W = scrnwidth - SrcX;\r
+       if(DstX + W > scrnwidth)\r
+               W = scrnwidth - DstX;\r
+       if(SrcY + H > gVesa_Modes[giVesaCurrentMode].height)\r
+               H = gVesa_Modes[giVesaCurrentMode].height - SrcY;\r
+       if(DstY + H > gVesa_Modes[giVesaCurrentMode].height)\r
+               H = gVesa_Modes[giVesaCurrentMode].height - DstY;\r
+       \r
+       if( dst > src ) {\r
+               // Reverse copy\r
+               dst += H*scrnwidth;\r
+               src += H*scrnwidth;\r
+               while( H -- ) {\r
+                       dst -= scrnwidth;\r
+                       src -= scrnwidth;\r
+                       tmp = W;\r
+                       for( tmp = W; tmp --; ) {\r
+                               *((Uint32*)gpVesa_Framebuffer + dst + tmp) = *((Uint32*)gpVesa_Framebuffer + src + tmp);\r
+                       }\r
+               }\r
+       }\r
+       else {\r
+               // Normal copy is OK\r
+               while( H -- ) {\r
+                       memcpyd((Uint32*)gpVesa_Framebuffer + dst, (Uint32*)gpVesa_Framebuffer + src, W);\r
+                       dst += scrnwidth;\r
+                       src += scrnwidth;\r
+               }\r
+       }\r
+}\r
index 36e0124..4d22b50 100644 (file)
@@ -4,12 +4,17 @@
  */
 #include "common.h"
 
+// === GLOBALS ==
+ int   giInterface_Width = 0;
+
 // === CODE ===
 void Interface_Render(void)
 {
+       giInterface_Width = giScreenWidth/16;
+       
        Video_FillRect(
                0, 0,
-               giScreenWidth/16, giScreenHeight,
+               giInterface_Width, giScreenHeight,
                0xDDDDDD);
        
        Video_Update();

UCC git Repository :: git.ucc.asn.au