Cleaning up and customizing our frame diff algo.
1.1 --- a/MiniDisplay/FutabaVfd.cpp Fri May 30 13:45:14 2014 +0200
1.2 +++ b/MiniDisplay/FutabaVfd.cpp Fri May 30 15:02:15 2014 +0200
1.3 @@ -9,13 +9,8 @@
1.4 #include <QTextStream>
1.5 #endif
1.6
1.7 -//
1.8 -//
1.9 -//
1.10
1.11 -
1.12 -
1.13 -
1.14 +const int KNumberOfFrameBeforeDiffAlgo = 3;
1.15
1.16 //
1.17 //
1.18 @@ -79,6 +74,7 @@
1.19 GP1212A01A::GP1212A01A():
1.20 iDisplayPositionX(0),iDisplayPositionY(0),
1.21 iOffScreenMode(true),
1.22 + iUseFrameDiffAlgo(true),
1.23 iFrameNext(NULL),
1.24 iFrameCurrent(NULL),
1.25 iFramePrevious(NULL),
1.26 @@ -380,14 +376,15 @@
1.27 if (OffScreenMode())
1.28 {
1.29 //Send host back buffer to device back buffer
1.30 - if (iNeedFullFrameUpdate<3)
1.31 + if (!iUseFrameDiffAlgo || iNeedFullFrameUpdate<KNumberOfFrameBeforeDiffAlgo)
1.32 {
1.33 - //TODO: enable this once SendModifiedPixelBlocks works
1.34 iNeedFullFrameUpdate++;
1.35 SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameNext->Ptr());
1.36 }
1.37 else
1.38 {
1.39 + //Frame diff algo is enabled
1.40 + //We are going to send to our device only the differences between next frame and previous frame
1.41 SendModifiedPixelBlocks();
1.42 }
1.43 //Swap device front and back buffer
1.44 @@ -412,7 +409,6 @@
1.45 /**
1.46 * @brief GP1212A01A::SendModifiedPixelBlocks
1.47 * Compare our back and front buffer and send to the device only the modified pixels.
1.48 - * TODO: Get this working at some point.
1.49 */
1.50 void GP1212A01A::SendModifiedPixelBlocks()
1.51 {
1.52 @@ -420,13 +416,17 @@
1.53 //const int KBlocksPerRow = WidthInPixels()/16; //16
1.54 //const int KBlocksPerColumn = HeightInPixels()/16; //4
1.55
1.56 + const int KPixelBlockEdge = 16;
1.57 + const int KPixelBlockSizeInBits = KPixelBlockEdge*KPixelBlockEdge;
1.58 + const int KPixelBlockSizeInBytes = KPixelBlockSizeInBits/8;
1.59 +
1.60 int w=WidthInPixels();
1.61 int h=HeightInPixels();
1.62
1.63
1.64 -
1.65 //TODO: optimize with memcmp and 16 inc
1.66 /*
1.67 +
1.68 for (int i=0;i<w;i++)
1.69 {
1.70 for (int j=0;j<h;j++)
1.71 @@ -445,32 +445,34 @@
1.72 }
1.73 */
1.74
1.75 - BitArray nextBlock(16*16);
1.76 - BitArray previousBlock(16*16);
1.77 + BitArray nextBlock(KPixelBlockSizeInBits);
1.78 + BitArray previousBlock(KPixelBlockSizeInBits);
1.79
1.80 - for (int i=0;i<w;i+=16)
1.81 + for (int i=0;i<w;i+=KPixelBlockEdge)
1.82 {
1.83 - for (int j=0;j<h;j+=16)
1.84 + for (int j=0;j<h;j+=KPixelBlockEdge)
1.85 {
1.86 //aX*HeightInPixels()+aY
1.87 //int offset=(i*w/8)+(j/8);
1.88
1.89 #ifdef DEBUG_FRAME_DIFF
1.90 - QImage imagePrevious(16,16,QImage::Format_RGB32);
1.91 - QImage imageNext(16,16,QImage::Format_RGB32);
1.92 + QImage imagePrevious(KPixelBlockEdge,KPixelBlockEdge,QImage::Format_RGB32);
1.93 + QImage imageNext(KPixelBlockEdge,KPixelBlockEdge,QImage::Format_RGB32);
1.94 #endif
1.95
1.96 //Get both our blocks from our buffers
1.97 - for (int x=i;x<i+16;x++)
1.98 + for (int x=i;x<i+KPixelBlockEdge;x++)
1.99 {
1.100 - for (int y=j;y<j+16;y++)
1.101 + for (int y=j;y<j+KPixelBlockEdge;y++)
1.102 {
1.103 - nextBlock.SetBitValue((x-i)*16+(y-j),(*iFrameNext)[x*h+y]);
1.104 - previousBlock.SetBitValue((x-i)*16+(y-j),(*iFramePrevious)[x*h+y]);
1.105 + int blockOffset=(x-i)*KPixelBlockEdge+(y-j);
1.106 + int frameOffset=x*h+y;
1.107 + nextBlock.SetBitValue(blockOffset,(*iFrameNext)[frameOffset]);
1.108 + previousBlock.SetBitValue(blockOffset,(*iFramePrevious)[frameOffset]);
1.109
1.110 #ifdef DEBUG_FRAME_DIFF
1.111 - imageNext.setPixel(x-i,y-j,(nextBlock[(x-i)*16+(y-j)]?0xFFFFFFFF:0x00000000));
1.112 - imagePrevious.setPixel(x-i,y-j,(previousBlock[(x-i)*16+(y-j)]?0xFFFFFFFF:0x00000000));
1.113 + imageNext.setPixel(x-i,y-j,(nextBlock[blockOffset]?0xFFFFFFFF:0x00000000));
1.114 + imagePrevious.setPixel(x-i,y-j,(previousBlock[blockOffset]?0xFFFFFFFF:0x00000000));
1.115 #endif
1.116 }
1.117 }
1.118 @@ -486,10 +488,10 @@
1.119
1.120
1.121 //if (memcmp(iFrameNext->Ptr()+offset,iFramePrevious->Ptr()+offset,32 )) //32=(16*16/8)
1.122 - if (memcmp(nextBlock.Ptr(),previousBlock.Ptr(),32 )!=0) //32=(16*16/8)
1.123 + if (memcmp(nextBlock.Ptr(),previousBlock.Ptr(),KPixelBlockSizeInBytes)!=0)
1.124 {
1.125 //We need to update that block
1.126 - SetPixelBlock(i,j,15,32,nextBlock.Ptr());
1.127 + SetPixelBlock(i,j,KPixelBlockEdge-1,KPixelBlockSizeInBytes,nextBlock.Ptr());
1.128 //SetPixelBlock(i,j,15,32,0xFF/*nextBlock.Ptr()*/);
1.129 //SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.130 //SetDisplayPosition(iDisplayPositionX,OffScreenY());
2.1 --- a/MiniDisplay/FutabaVfd.h Fri May 30 13:45:14 2014 +0200
2.2 +++ b/MiniDisplay/FutabaVfd.h Fri May 30 15:02:15 2014 +0200
2.3 @@ -159,7 +159,9 @@
2.4 void ToggleOffScreenMode();
2.5 void SetOffScreenMode(bool aOn);
2.6 bool OffScreenMode() const {return iOffScreenMode;}
2.7 - //
2.8 + void SetFrameDiffAlgo(bool aOn);
2.9 + bool FrameDiffAlgo() const {return iUseFrameDiffAlgo;}
2.10 + //
2.11 bool RequestPending(){return iRequest!=ERequestNone;}
2.12 Request CurrentRequest(){return iRequest;}
2.13 void CancelRequest(){iRequest=ERequestNone;}
2.14 @@ -187,6 +189,8 @@
2.15 ///Off screen mode is the recommended default settings to avoid tearing.
2.16 ///Though turning it off can be useful for debugging
2.17 bool iOffScreenMode;
2.18 + ///Frame differences algo is used to reduce USB bus traffic and improve frame rate in typical use case
2.19 + bool iUseFrameDiffAlgo;
2.20 ///
2.21 //FutabaVfdReport iReport;
2.22 ///
3.1 --- a/TestsTab.qml Fri May 30 13:45:14 2014 +0200
3.2 +++ b/TestsTab.qml Fri May 30 15:02:15 2014 +0200
3.3 @@ -111,6 +111,7 @@
3.4 Timer {
3.5 id: timer
3.6 interval: splash.timeoutInterval; running: true; repeat: true
3.7 + property bool doFill: true
3.8 onTriggered: {
3.9 //visible = false
3.10
3.11 @@ -132,8 +133,20 @@
3.12 {
3.13 if (checkBoxFillOnly.checked)
3.14 {
3.15 - //Trying to make it a worth case scenario for our frame diff algo
3.16 - (splash.frameCounter%3?display.fill():display.clear());
3.17 + //Trying to make it a worse case scenario for our frame diff algo
3.18 + if (doFill)
3.19 + {
3.20 + display.fill();
3.21 + }
3.22 + else
3.23 + {
3.24 + display.clear();
3.25 + }
3.26 +
3.27 + if (splash.frameCounter%2)
3.28 + {
3.29 + doFill=!doFill;
3.30 + }
3.31 }
3.32 else if (checkBoxOnePixelOnly.checked)
3.33 {