Frame diff algo now working nicely and providing twice the frame rate.
1.1 --- a/MiniDisplay/FutabaVfd.cpp Fri May 30 10:56:20 2014 +0200
1.2 +++ b/MiniDisplay/FutabaVfd.cpp Fri May 30 13:45:14 2014 +0200
1.3 @@ -4,6 +4,11 @@
1.4 #include <string.h>
1.5
1.6
1.7 +#ifdef DEBUG_FRAME_DIFF
1.8 +#include <QImage>
1.9 +#include <QTextStream>
1.10 +#endif
1.11 +
1.12 //
1.13 //
1.14 //
1.15 @@ -378,7 +383,7 @@
1.16 if (iNeedFullFrameUpdate<3)
1.17 {
1.18 //TODO: enable this once SendModifiedPixelBlocks works
1.19 - //iNeedFullFrameUpdate++;
1.20 + iNeedFullFrameUpdate++;
1.21 SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameNext->Ptr());
1.22 }
1.23 else
1.24 @@ -387,14 +392,18 @@
1.25 }
1.26 //Swap device front and back buffer
1.27 SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.28 - //Swap host buffers
1.29 - //BitArray* nextFrame=iFrameNext;
1.30 - //iFrameCurrent = iFramePrevious;
1.31 - //iFrameNext = iFramePrevious;
1.32
1.33 + //Cycle through our frame buffers
1.34 + //We keep track of previous frame which is in fact our device back buffer.
1.35 + //We can then compare previous and next frame and send only the differences to our device.
1.36 + //This mechanism allows us to reduce traffic over our USB bus thus improving our frame rate from 14 FPS to 30 FPS.
1.37 + //Keep our previous frame pointer
1.38 BitArray* previousFrame=iFramePrevious;
1.39 + //Current frame becomes the previous one
1.40 iFramePrevious = iFrameCurrent;
1.41 + //Next frame becomes the current one
1.42 iFrameCurrent = iFrameNext;
1.43 + //Next frame is now our former previous
1.44 iFrameNext = previousFrame;
1.45 }
1.46 }
1.47 @@ -414,10 +423,10 @@
1.48 int w=WidthInPixels();
1.49 int h=HeightInPixels();
1.50
1.51 - BitArray block(16*16);
1.52
1.53
1.54 //TODO: optimize with memcmp and 16 inc
1.55 + /*
1.56 for (int i=0;i<w;i++)
1.57 {
1.58 for (int j=0;j<h;j++)
1.59 @@ -434,34 +443,61 @@
1.60 }
1.61 }
1.62 }
1.63 + */
1.64
1.65 - /*
1.66 + BitArray nextBlock(16*16);
1.67 + BitArray previousBlock(16*16);
1.68 +
1.69 for (int i=0;i<w;i+=16)
1.70 {
1.71 for (int j=0;j<h;j+=16)
1.72 {
1.73 //aX*HeightInPixels()+aY
1.74 - int offset=(i*w/8)+(j/8);
1.75 - if (memcmp(iNextFrame->Ptr()+offset,iCurrentFrame->Ptr()+offset,32 )) //32=(16*16/8)
1.76 + //int offset=(i*w/8)+(j/8);
1.77 +
1.78 +#ifdef DEBUG_FRAME_DIFF
1.79 + QImage imagePrevious(16,16,QImage::Format_RGB32);
1.80 + QImage imageNext(16,16,QImage::Format_RGB32);
1.81 +#endif
1.82 +
1.83 + //Get both our blocks from our buffers
1.84 + for (int x=i;x<i+16;x++)
1.85 + {
1.86 + for (int y=j;y<j+16;y++)
1.87 + {
1.88 + nextBlock.SetBitValue((x-i)*16+(y-j),(*iFrameNext)[x*h+y]);
1.89 + previousBlock.SetBitValue((x-i)*16+(y-j),(*iFramePrevious)[x*h+y]);
1.90 +
1.91 +#ifdef DEBUG_FRAME_DIFF
1.92 + imageNext.setPixel(x-i,y-j,(nextBlock[(x-i)*16+(y-j)]?0xFFFFFFFF:0x00000000));
1.93 + imagePrevious.setPixel(x-i,y-j,(previousBlock[(x-i)*16+(y-j)]?0xFFFFFFFF:0x00000000));
1.94 +#endif
1.95 + }
1.96 + }
1.97 +
1.98 +#ifdef DEBUG_FRAME_DIFF
1.99 + QString previousName;
1.100 + QString nextName;
1.101 + QTextStream(&previousName) << "p" << i << "x" << j << ".png";
1.102 + QTextStream(&nextName) << "n" << i << "x" << j << ".png";
1.103 + imagePrevious.save(previousName);
1.104 + imageNext.save(nextName);
1.105 +#endif
1.106 +
1.107 +
1.108 + //if (memcmp(iFrameNext->Ptr()+offset,iFramePrevious->Ptr()+offset,32 )) //32=(16*16/8)
1.109 + if (memcmp(nextBlock.Ptr(),previousBlock.Ptr(),32 )!=0) //32=(16*16/8)
1.110 {
1.111 //We need to update that block
1.112 -
1.113 - for (int x=i;x<i+16;x++)
1.114 - {
1.115 - for (int y=i;y<j+16;y++)
1.116 - {
1.117 - block.SetBitValue((x-i)*h+(y-j),(*iNextFrame)[x*h+y]);
1.118 - }
1.119 - }
1.120 - SetPixelBlock(i,j,15,32,block.Ptr());
1.121 + SetPixelBlock(i,j,15,32,nextBlock.Ptr());
1.122 + //SetPixelBlock(i,j,15,32,0xFF/*nextBlock.Ptr()*/);
1.123 //SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.124 //SetDisplayPosition(iDisplayPositionX,OffScreenY());
1.125
1.126 - //SetPixelBlock(i,j,15,32,iNextFrame->Ptr()+offset);
1.127 + //SetPixelBlock(i,j,15,32,iFrameNext->Ptr()+offset);
1.128 }
1.129 }
1.130 }
1.131 - */
1.132
1.133 }
1.134
2.1 --- a/TestsTab.qml Fri May 30 10:56:20 2014 +0200
2.2 +++ b/TestsTab.qml Fri May 30 13:45:14 2014 +0200
2.3 @@ -22,7 +22,10 @@
2.4 title: "Splash Window"
2.5 modality: Qt.NonModal
2.6 flags: Qt.SplashScreen
2.7 - property int timeoutInterval: 41
2.8 + //24 FPS
2.9 + //property int timeoutInterval: 41
2.10 + //32 FPS
2.11 + property int timeoutInterval: 33
2.12 signal timeout
2.13 //! [splash-properties]
2.14 //! [screen-properties]
2.15 @@ -129,7 +132,8 @@
2.16 {
2.17 if (checkBoxFillOnly.checked)
2.18 {
2.19 - display.fill();
2.20 + //Trying to make it a worth case scenario for our frame diff algo
2.21 + (splash.frameCounter%3?display.fill():display.clear());
2.22 }
2.23 else if (checkBoxOnePixelOnly.checked)
2.24 {
2.25 @@ -202,7 +206,7 @@
2.26
2.27 CheckBox {
2.28 id: checkBoxFillOnly
2.29 - text: qsTr("Fill only")
2.30 + text: qsTr("Only fill and clear")
2.31 checked: false
2.32 }
2.33