1.1 --- a/MiniDisplay/FutabaVfd.cpp Thu May 29 19:46:57 2014 +0200
1.2 +++ b/MiniDisplay/FutabaVfd.cpp Thu May 29 21:42:07 2014 +0200
1.3 @@ -73,7 +73,13 @@
1.4
1.5 GP1212A01A::GP1212A01A():
1.6 iDisplayPositionX(0),iDisplayPositionY(0),
1.7 - iOffScreenMode(true),iFrameBuffer(NULL),iRequest(ERequestNone),iPowerOn(false)
1.8 + iOffScreenMode(true),
1.9 + iFrameAlpha(NULL),
1.10 + iFrameBeta(NULL),
1.11 + iCurrentFrame(NULL),
1.12 + iNextFrame(NULL),
1.13 + iNeedFullFrameUpdate(true),
1.14 + iRequest(ERequestNone),iPowerOn(false)
1.15 {
1.16 //ResetBuffers();
1.17 }
1.18 @@ -82,8 +88,16 @@
1.19 */
1.20 GP1212A01A::~GP1212A01A()
1.21 {
1.22 - delete iFrameBuffer;
1.23 - iFrameBuffer=NULL;
1.24 + delete iFrameAlpha;
1.25 + iFrameAlpha=NULL;
1.26 + //
1.27 + delete iFrameBeta;
1.28 + iFrameBeta=NULL;
1.29 + //
1.30 + iNextFrame=NULL;
1.31 + iCurrentFrame=NULL;
1.32 + //
1.33 + iNeedFullFrameUpdate=true;
1.34 }
1.35
1.36 /**
1.37 @@ -93,9 +107,20 @@
1.38 int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
1.39 if (success)
1.40 {
1.41 - delete iFrameBuffer;
1.42 - iFrameBuffer = NULL;
1.43 - iFrameBuffer=new BitArray(KGP12xFrameBufferPixelCount);
1.44 + //Allocate both frames
1.45 + delete iFrameAlpha;
1.46 + iFrameAlpha=NULL;
1.47 + iFrameAlpha=new BitArray(KGP12xFrameBufferPixelCount);
1.48 + //
1.49 + delete iFrameBeta;
1.50 + iFrameBeta=NULL;
1.51 + iFrameBeta=new BitArray(KGP12xFrameBufferPixelCount);
1.52 + //
1.53 + iCurrentFrame=iFrameAlpha;
1.54 + iNextFrame=iFrameBeta;
1.55 + //To make sure it is synced properly
1.56 + iNeedFullFrameUpdate=true;
1.57 + //
1.58 SetNonBlocking(1);
1.59 //Since we can't get our display position we force it to our default
1.60 //This makes sure frames are in sync from the start
1.61 @@ -112,17 +137,17 @@
1.62 //
1.63 //int byteOffset=(aX*HeightInPixels()+aY)/8;
1.64 //int bitOffset=(aX*HeightInPixels()+aY)%8;
1.65 - //iFrameBuffer[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset );
1.66 + //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset );
1.67
1.68 if (iOffScreenMode)
1.69 {
1.70 if (aOn)
1.71 {
1.72 - iFrameBuffer->SetBit(aX*HeightInPixels()+aY);
1.73 + iNextFrame->SetBit(aX*HeightInPixels()+aY);
1.74 }
1.75 else
1.76 {
1.77 - iFrameBuffer->ClearBit(aX*HeightInPixels()+aY);
1.78 + iNextFrame->ClearBit(aX*HeightInPixels()+aY);
1.79 }
1.80 }
1.81 else
1.82 @@ -141,7 +166,7 @@
1.83 {
1.84 for (int j=0;j<aSrcHeight;j++)
1.85 {
1.86 - iFrameBuffer->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]);
1.87 + iNextFrame->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]);
1.88 }
1.89 }
1.90 }
1.91 @@ -161,7 +186,7 @@
1.92
1.93 if (iOffScreenMode)
1.94 {
1.95 - memset(iFrameBuffer->Ptr(),aPattern,FrameBufferSizeInBytes());
1.96 + memset(iNextFrame->Ptr(),aPattern,FrameBufferSizeInBytes());
1.97 }
1.98 else
1.99 {
1.100 @@ -259,10 +284,10 @@
1.101 */
1.102 void GP1212A01A::Clear()
1.103 {
1.104 - //memset(iFrameBuffer->Ptr(),0x00,FrameBufferSizeInBytes());
1.105 + //memset(iNextFrame->Ptr(),0x00,FrameBufferSizeInBytes());
1.106 if (iOffScreenMode)
1.107 {
1.108 - iFrameBuffer->ClearAll();
1.109 + iNextFrame->ClearAll();
1.110 }
1.111 else
1.112 {
1.113 @@ -338,16 +363,70 @@
1.114 if (OffScreenMode())
1.115 {
1.116 //Send host back buffer to device back buffer
1.117 - SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameBuffer->Ptr());
1.118 + if (iNeedFullFrameUpdate)
1.119 + {
1.120 + //TODO: enable this once SendModifiedPixelBlocks works
1.121 + //iNeedFullFrameUpdate=false;
1.122 + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iNextFrame->Ptr());
1.123 + }
1.124 + else
1.125 + {
1.126 + SendModifiedPixelBlocks();
1.127 + }
1.128 //Swap device front and back buffer
1.129 SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.130 //Swap host buffers
1.131 - //unsigned char* backBuffer=iBackBuffer;
1.132 - //iBackBuffer = iFrontBuffer;
1.133 - //iFrontBuffer = backBuffer;
1.134 + BitArray* nextFrame=iCurrentFrame;
1.135 + iCurrentFrame = iNextFrame;
1.136 + iNextFrame = nextFrame;
1.137 }
1.138 }
1.139
1.140 +
1.141 +/**
1.142 + * @brief GP1212A01A::SendModifiedPixelBlocks
1.143 + * Compare our back and front buffer and send to the device only the modified pixels.
1.144 + * TODO: Get this working at some point.
1.145 + */
1.146 +void GP1212A01A::SendModifiedPixelBlocks()
1.147 + {
1.148 + //The largest pixel block we can sanely send with one report is 16*16
1.149 + //const int KBlocksPerRow = WidthInPixels()/16; //16
1.150 + //const int KBlocksPerColumn = HeightInPixels()/16; //4
1.151 +
1.152 + int w=WidthInPixels();
1.153 + int h=HeightInPixels();
1.154 +
1.155 + BitArray block(16*16);
1.156 + //TODO: optimize with memcmp and 16 inc
1.157 + for (int i=0;i<w;i+=16)
1.158 + {
1.159 + for (int j=0;j<h;j+=16)
1.160 + {
1.161 + //aX*HeightInPixels()+aY
1.162 + int offset=(i*w/8)+(j/8);
1.163 + if (memcmp(iNextFrame->Ptr()+offset,iCurrentFrame->Ptr()+offset,32 /*(16*16/8)*/))
1.164 + {
1.165 + //We need to update that block
1.166 +
1.167 + for (int x=i;x<i+16;x++)
1.168 + {
1.169 + for (int y=i;y<j+16;y++)
1.170 + {
1.171 + block.SetBitValue((x-i)*h+(y-j),(*iNextFrame)[x*h+y]);
1.172 + }
1.173 + }
1.174 + SetPixelBlock(i,j,15,32,block.Ptr());
1.175 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.176 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.177 +
1.178 + //SetPixelBlock(i,j,15,32,iNextFrame->Ptr()+offset);
1.179 + }
1.180 + }
1.181 + }
1.182 +
1.183 + }
1.184 +
1.185 /**
1.186 Translate the given pixel coordinate according to our off screen mode.
1.187 */
1.188 @@ -365,8 +444,8 @@
1.189 */
1.190 void GP1212A01A::ResetBuffers()
1.191 {
1.192 - //iFrameBuffer->ClearAll();
1.193 - //memset(iFrameBuffer,0x00,sizeof(iFrameBuffer));
1.194 + //iNextFrame->ClearAll();
1.195 + //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha));
1.196 //memset(iFrameBeta,0x00,sizeof(iFrameBeta));
1.197 }
1.198
2.1 --- a/MiniDisplay/FutabaVfd.h Thu May 29 19:46:57 2014 +0200
2.2 +++ b/MiniDisplay/FutabaVfd.h Thu May 29 21:42:07 2014 +0200
2.3 @@ -166,7 +166,7 @@
2.4 Request AttemptRequestCompletion();
2.5 FutabaVfdReport& InputReport() {return iInputReport;}
2.6 bool PowerOn(){return iPowerOn;}
2.7 -
2.8 +
2.9 private:
2.10 enum DW
2.11 {
2.12 @@ -179,6 +179,7 @@
2.13 void SendClearCommand();
2.14 void OffScreenTranslation(unsigned char& aX, unsigned char& aY);
2.15 void ResetBuffers();
2.16 + void SendModifiedPixelBlocks();
2.17
2.18 private:
2.19 unsigned char iDisplayPositionX;
2.20 @@ -190,7 +191,13 @@
2.21 //FutabaVfdReport iReport;
2.22 ///
2.23 //unsigned char iFrameBuffer[256*64];
2.24 - BitArray* iFrameBuffer;
2.25 + BitArray* iNextFrame;
2.26 + BitArray* iCurrentFrame;
2.27 + //
2.28 + BitArray* iFrameAlpha;
2.29 + BitArray* iFrameBeta;
2.30 + //
2.31 + bool iNeedFullFrameUpdate;
2.32 //unsigned char iFrameBeta[256*64];
2.33 //unsigned char *iFrontBuffer;
2.34 //unsigned char *iBackBuffer;