# HG changeset patch # User sl # Date 1401392527 -7200 # Node ID be04ffbb561cdefe87a2f222ca92df5b4d32cae3 # Parent 79801cc3bc947f04705a594970aefc780d26a2cd Trying to optimize our swap buffer implementation by sending only the pixel block which ave changed. No joy so far. diff -r 79801cc3bc94 -r be04ffbb561c MiniDisplay/FutabaVfd.cpp --- a/MiniDisplay/FutabaVfd.cpp Thu May 29 19:46:57 2014 +0200 +++ b/MiniDisplay/FutabaVfd.cpp Thu May 29 21:42:07 2014 +0200 @@ -73,7 +73,13 @@ GP1212A01A::GP1212A01A(): iDisplayPositionX(0),iDisplayPositionY(0), - iOffScreenMode(true),iFrameBuffer(NULL),iRequest(ERequestNone),iPowerOn(false) + iOffScreenMode(true), + iFrameAlpha(NULL), + iFrameBeta(NULL), + iCurrentFrame(NULL), + iNextFrame(NULL), + iNeedFullFrameUpdate(true), + iRequest(ERequestNone),iPowerOn(false) { //ResetBuffers(); } @@ -82,8 +88,16 @@ */ GP1212A01A::~GP1212A01A() { - delete iFrameBuffer; - iFrameBuffer=NULL; + delete iFrameAlpha; + iFrameAlpha=NULL; + // + delete iFrameBeta; + iFrameBeta=NULL; + // + iNextFrame=NULL; + iCurrentFrame=NULL; + // + iNeedFullFrameUpdate=true; } /** @@ -93,9 +107,20 @@ int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL); if (success) { - delete iFrameBuffer; - iFrameBuffer = NULL; - iFrameBuffer=new BitArray(KGP12xFrameBufferPixelCount); + //Allocate both frames + delete iFrameAlpha; + iFrameAlpha=NULL; + iFrameAlpha=new BitArray(KGP12xFrameBufferPixelCount); + // + delete iFrameBeta; + iFrameBeta=NULL; + iFrameBeta=new BitArray(KGP12xFrameBufferPixelCount); + // + iCurrentFrame=iFrameAlpha; + iNextFrame=iFrameBeta; + //To make sure it is synced properly + iNeedFullFrameUpdate=true; + // SetNonBlocking(1); //Since we can't get our display position we force it to our default //This makes sure frames are in sync from the start @@ -112,17 +137,17 @@ // //int byteOffset=(aX*HeightInPixels()+aY)/8; //int bitOffset=(aX*HeightInPixels()+aY)%8; - //iFrameBuffer[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset ); + //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset ); if (iOffScreenMode) { if (aOn) { - iFrameBuffer->SetBit(aX*HeightInPixels()+aY); + iNextFrame->SetBit(aX*HeightInPixels()+aY); } else { - iFrameBuffer->ClearBit(aX*HeightInPixels()+aY); + iNextFrame->ClearBit(aX*HeightInPixels()+aY); } } else @@ -141,7 +166,7 @@ { for (int j=0;jSetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]); + iNextFrame->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]); } } } @@ -161,7 +186,7 @@ if (iOffScreenMode) { - memset(iFrameBuffer->Ptr(),aPattern,FrameBufferSizeInBytes()); + memset(iNextFrame->Ptr(),aPattern,FrameBufferSizeInBytes()); } else { @@ -259,10 +284,10 @@ */ void GP1212A01A::Clear() { - //memset(iFrameBuffer->Ptr(),0x00,FrameBufferSizeInBytes()); + //memset(iNextFrame->Ptr(),0x00,FrameBufferSizeInBytes()); if (iOffScreenMode) { - iFrameBuffer->ClearAll(); + iNextFrame->ClearAll(); } else { @@ -338,16 +363,70 @@ if (OffScreenMode()) { //Send host back buffer to device back buffer - SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameBuffer->Ptr()); + if (iNeedFullFrameUpdate) + { + //TODO: enable this once SendModifiedPixelBlocks works + //iNeedFullFrameUpdate=false; + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iNextFrame->Ptr()); + } + else + { + SendModifiedPixelBlocks(); + } //Swap device front and back buffer SetDisplayPosition(iDisplayPositionX,OffScreenY()); //Swap host buffers - //unsigned char* backBuffer=iBackBuffer; - //iBackBuffer = iFrontBuffer; - //iFrontBuffer = backBuffer; + BitArray* nextFrame=iCurrentFrame; + iCurrentFrame = iNextFrame; + iNextFrame = nextFrame; } } + +/** + * @brief GP1212A01A::SendModifiedPixelBlocks + * Compare our back and front buffer and send to the device only the modified pixels. + * TODO: Get this working at some point. + */ +void GP1212A01A::SendModifiedPixelBlocks() + { + //The largest pixel block we can sanely send with one report is 16*16 + //const int KBlocksPerRow = WidthInPixels()/16; //16 + //const int KBlocksPerColumn = HeightInPixels()/16; //4 + + int w=WidthInPixels(); + int h=HeightInPixels(); + + BitArray block(16*16); + //TODO: optimize with memcmp and 16 inc + for (int i=0;iPtr()+offset,iCurrentFrame->Ptr()+offset,32 /*(16*16/8)*/)) + { + //We need to update that block + + for (int x=i;xPtr()+offset); + } + } + } + + } + /** Translate the given pixel coordinate according to our off screen mode. */ @@ -365,8 +444,8 @@ */ void GP1212A01A::ResetBuffers() { - //iFrameBuffer->ClearAll(); - //memset(iFrameBuffer,0x00,sizeof(iFrameBuffer)); + //iNextFrame->ClearAll(); + //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha)); //memset(iFrameBeta,0x00,sizeof(iFrameBeta)); } diff -r 79801cc3bc94 -r be04ffbb561c MiniDisplay/FutabaVfd.h --- a/MiniDisplay/FutabaVfd.h Thu May 29 19:46:57 2014 +0200 +++ b/MiniDisplay/FutabaVfd.h Thu May 29 21:42:07 2014 +0200 @@ -166,7 +166,7 @@ Request AttemptRequestCompletion(); FutabaVfdReport& InputReport() {return iInputReport;} bool PowerOn(){return iPowerOn;} - + private: enum DW { @@ -179,6 +179,7 @@ void SendClearCommand(); void OffScreenTranslation(unsigned char& aX, unsigned char& aY); void ResetBuffers(); + void SendModifiedPixelBlocks(); private: unsigned char iDisplayPositionX; @@ -190,7 +191,13 @@ //FutabaVfdReport iReport; /// //unsigned char iFrameBuffer[256*64]; - BitArray* iFrameBuffer; + BitArray* iNextFrame; + BitArray* iCurrentFrame; + // + BitArray* iFrameAlpha; + BitArray* iFrameBeta; + // + bool iNeedFullFrameUpdate; //unsigned char iFrameBeta[256*64]; //unsigned char *iFrontBuffer; //unsigned char *iBackBuffer;