2021-08-27 01:10 AM
Hello,
we try to display graphs as performant as possible.
Unfortunately the rendering takes a long time. Especially when several are integrated in ScrollWheels.
The CacheableContainer should be made for this.
We put a graph and more widgets in the container.
But we don't get the caching to work
The short explanation in the documentation doesn't help much:
The hpp of our CacheableContainer:
#ifndef CACHABLE_CURRENT_VALUE_HPP
#define CACHABLE_CURRENT_VALUE_HPP
#include "appinclude.h"
#include "guiinclude.hpp"
#include "basicinclude.h"
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/CacheableContainer.hpp>
#include <touchgfx/widgets/graph/GraphWrapAndOverwrite.hpp>
#include <touchgfx/widgets/graph/GraphElements.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>
#include <touchgfx/widgets/graph/GraphLabels.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
#include <touchgfx/widgets/graph/GraphWrapAndOverwrite.hpp>
#include <touchgfx/widgets/graph/GraphElements.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>
#include <touchgfx/widgets/graph/GraphLabels.hpp>
#include "gui/containers/cGraphLine.hpp"
#define CACHEABL_GRAPH_MAX_WIDTH 207
#define CACHEABL_GRAPH_MAX_HIGHT 118
class cCacheableCurrentValue : public touchgfx::CacheableContainer{
public:
cCacheableCurrentValue();
virtual ~cCacheableCurrentValue(){}
virtual void initialize(void);
void setContainerBuffer(uint16_t * bufferAdd, uint32_t bufferSize);
void setContent(cCurrentValueRow* cvr);
void updateContent(void);
protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}
//must be created outside in XRAM
uint16_t* containerBuffer;
uint32_t containerBufferSize;
cCurrentValueRow* mydata;
caString<50> result;
cuString<50> uname;
cuString<10> value;
cGraphData* graphData;
uint16_t lastStateID;
/*
* Member Declarations
*/
touchgfx::Box box1;
touchgfx::TextAreaWithOneWildcard textAreaValue;
touchgfx::TextAreaWithOneWildcard textAreaName;
touchgfx::TextAreaWithOneWildcard textAreaUnit;
touchgfx::GraphWrapAndOverwrite<144> dynamicGraph;
touchgfx::PainterRGB565 dynamicGraphArea1Painter;
touchgfx::PainterRGB565 dynamicGraph1Line1Painter;
touchgfx::GraphElementGridY dynamicGraph1MajorYAxisGrid;
touchgfx::GraphLabelsY dynamicGraph1MajorYAxisLabel;
cGraphLine graphLine; // GraphElementLine with same changes
/*
* Wildcard Buffers
*/
static const uint16_t TEXTAREAVALUE_SIZE = 10;
touchgfx::Unicode::UnicodeChar textAreaValueBuffer[TEXTAREAVALUE_SIZE];
static const uint16_t TEXTAREANAME_SIZE = 50;
touchgfx::Unicode::UnicodeChar textAreaNameBuffer[TEXTAREANAME_SIZE];
static const uint16_t TEXTAREAUNIT_SIZE = 10;
touchgfx::Unicode::UnicodeChar textAreaUnitBuffer[TEXTAREAUNIT_SIZE];
};
#endif
The cpp of our CacheableContainer:
#include <gui/containers/cCacheableCurrentValue.hpp>
#include <touchgfx/Color.hpp>
#include <texts/TextKeysAndLanguages.hpp>
cCacheableCurrentValue::cCacheableCurrentValue(){
setWidth(480);
setHeight(135);
box1.setPosition(0, 0, 480, 135);
box1.setColor(touchgfx::Color::getColorFrom24BitRGB(7, 0, 122));
textAreaValue.setXY(8, 36);
textAreaValue.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 255));
textAreaValue.setLinespacing(0);
Unicode::snprintf(textAreaValueBuffer, TEXTAREAVALUE_SIZE, "%s", touchgfx::TypedText(T_SINGLEUSEID67).getText());
textAreaValue.setWildcard(textAreaValueBuffer);
textAreaValue.resizeToCurrentText();
textAreaValue.setTypedText(touchgfx::TypedText(T_VAR1BIG));
textAreaName.setXY(8, 5);
textAreaName.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 255));
textAreaName.setLinespacing(0);
Unicode::snprintf(textAreaNameBuffer, TEXTAREANAME_SIZE, "%s", touchgfx::TypedText(T_SINGLEUSEID68).getText());
textAreaName.setWildcard(textAreaNameBuffer);
textAreaName.resizeToCurrentText();
textAreaName.setTypedText(touchgfx::TypedText(T_VAR1));
textAreaUnit.setXY(201, 84);
textAreaUnit.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 255));
textAreaUnit.setLinespacing(0);
Unicode::snprintf(textAreaUnitBuffer, TEXTAREAUNIT_SIZE, "%s", touchgfx::TypedText(T_SINGLEUSEID70).getText());
textAreaUnit.setWildcard(textAreaUnitBuffer);
textAreaUnit.resizeToCurrentText();
textAreaUnit.setTypedText(touchgfx::TypedText(T_VAR1));
//Graph init
dynamicGraph.setScale(1);
dynamicGraph.setGraphRangeX(0, 143);
dynamicGraph.setPosition(266, 6, 207, 118);
dynamicGraph.setGraphAreaMargin(2, 3, 40, 2);
dynamicGraph.setGraphAreaPadding(2, 0, 0, 2);
dynamicGraph.setGraphRangeY(0, 100);
dynamicGraph1MajorYAxisGrid.setScale(1);
dynamicGraph1MajorYAxisGrid.setColor(touchgfx::Color::getColorFrom24BitRGB(20, 151, 197));
dynamicGraph1MajorYAxisGrid.setInterval(20);
dynamicGraph1MajorYAxisGrid.setLineWidth(1);
dynamicGraph.addGraphElement(dynamicGraph1MajorYAxisGrid);
dynamicGraph1MajorYAxisLabel.setScale(1);
dynamicGraph1MajorYAxisLabel.setInterval(20);
dynamicGraph1MajorYAxisLabel.setLabelTypedText(touchgfx::TypedText(T_SINGLEUSEID88));
dynamicGraph1MajorYAxisLabel.setColor(touchgfx::Color::getColorFrom24BitRGB(183, 227, 242));
dynamicGraph.addRightElement(dynamicGraph1MajorYAxisLabel);
graphLine.setScale(1);
dynamicGraph1Line1Painter.setColor(touchgfx::Color::getColorFrom24BitRGB(252, 254, 255));
graphLine.setPainter(dynamicGraph1Line1Painter);
graphLine.setLineWidth(2);
dynamicGraph.addGraphElement(graphLine);
graphLine.setScale(1);
add(box1);
add(textAreaValue);
add(textAreaName);
add(textAreaUnit);
add(dynamicGraph);
mydata = nullptr;
containerBuffer = nullptr;
containerBufferSize = 0;
}
void cCacheableCurrentValue::initialize(void)
{
if (
(mydata==nullptr)
|| (containerBuffer == nullptr)
){
return; //if data not set yet, return
}
//set cache
Bitmap::setCache(containerBuffer, containerBufferSize, 1);
BitmapId dynamicBitmap = Bitmap::dynamicBitmapCreate(this->getWidth(), this->getHeight(), Bitmap::RGB565);
this->setCacheBitmap(dynamicBitmap);
// enable caching
this->enableCachedMode(true);
this->updateCache();
}
void cCacheableCurrentValue::setContainerBuffer(uint16_t* bufferAdd, uint32_t bufferSize){
this->containerBuffer = bufferAdd;
this->containerBufferSize = bufferSize;
}
void cCacheableCurrentValue::setContent(cCurrentValueRow* cvr) {
mydata = cvr;
result = mydata->result;
uname = mydata->uname;
value = mydata->value;
graphData = mydata->graphData;
setContainerBuffer(cvr->containerBuffer, cvr->containerBufferSize);
this->graphLine.setGraphData(graphData);
initialize();
updateContent();
}
void cCacheableCurrentValue::updateContent(void){
if (
(mydata==nullptr)
|| (containerBuffer == nullptr)
){
return;
}
{
//setnames
uname.assignToTextarea(&textAreaName, textAreaNameBuffer, TEXTAREANAME_SIZE);
value.assignToTextarea(&textAreaValue, textAreaValueBuffer, TEXTAREAVALUE_SIZE);
}
//update graph
uint16_t dataCount;
float * data;
uint16_t currentGraphDataStateID;
dataCount = graphData->getPointCount();
data = graphData->getValues();
currentGraphDataStateID = mydata->graphData->getStateID();
//data changed?
// -> draw new
if(currentGraphDataStateID != lastStateID){
//set vales
dynamicGraph.clear();
for(uint16_t i = 0; i < dataCount; i++){
dynamicGraph.addDataPoint(data[i]);
}
updateCache();
lastStateID = graphData->getStateID();
}
updateCache(); //draw new and use cache
}
The buffer inizalization:
#define CURRENT_VALUE_CONTAINER_BUFFER_SIZE (480*135)*2
uint16_t XRAM currentValueContainerBuffer[CURRENT_VALUE_CONTAINER_BUFFER_SIZE];
The result is that the containers are displayed correctly. But you can see that the same number of times is drawn as before and therefore the performance is the same.
The initialization and setting of the data is done correctly.
Have we forgotten anything?
What are we doing wrong? Does anyone have experience with CacheableContainers?
2022-11-02 02:32 AM
Hi JBenn.1
Did you eventually get the caching of the graph running?
I have the same problem. Any trick one needs to know?
Thanks