- EGT-Ensemble Graphics Toolkit介绍
- EGT具备非常高的图形渲染效率EGT采用了非常优秀的开源2D图形处理引擎-Cairo开源2D图形处理引擎Cairo的优势Cairo 2D图像引擎的性能Cairo 2D图像引擎的实际应用案例彩蛋 - 开源EDA软件KiCAD也在使用Cairo
- EGT高效的秘诀还有哪些Cairo需要依赖PixmanPixman针对不同平台有优化
- EGT vs QT5实际效果PK
- 代码贴图
有些介绍资料直接来自豆包,仅代表个人意见和理解,不喜勿喷
EGT-Ensemble Graphics Toolkit介绍
The Ensemble Graphics Toolkit (EGT)是MIcrochip针对旗下ARM9、SAMA5处理器推出来的一款运行于嵌入式Linux的C++ GUI开发工具套件。EGT(嵌入式图形工具包)提供了现代化的图形用户界面(GUI)功能、外观样式,并在嵌入式 Linux 应用中尽可能贴近底层硬件的同时最大限度地提升性能。关键词是开源、免费商用
Ensemble Graphics Toolkit: Introduction
官方给出的EGT组件依赖框图
EGT具备非常高的图形渲染效率 EGT采用了非常优秀的开源2D图形处理引擎-Cairo
开源2D图形处理引擎Cairo的优势
Cairo 2D图像引擎的性能
Cairo 2D图像引擎的实际应用案例
彩蛋 - 开源EDA软件KiCAD也在使用Cairo
EGT高效的秘诀还有哪些
Cairo使用Pixman来加速底层像素的操作,Pixman能够提供图像的合成、alpha 通道处理、色彩空间转换等基本的像素级别的操作
Cairo需要依赖Pixman
Pixman针对不同平台有优化
Pixman针对ARM SIMD架构、带NEON或者MIPS、X86等架构,都有专门针对性的优化代码,来尽可能利用处理器硬件特性,加速像素的处理速度
EGT vs QT5实际效果PK
在Microchip SAMA5D27开发板上,跑Microchip EGT提供的潜水员例程,该例程会有潜水员的动态图片,同时也有2条鱼在界面上从左到右在游动,另外还不断有泡泡从底部冒出。同时将该例程功能移植到QT5上,然后两者在实际硬件上运行,对比CPU占用率的差异
QT vs Cairo性能大对比 视频对比 基于EGT开发的demo,全程CPU占用率在22%左右,而QT5基本都在70%以上
代码贴图
个人对QT开发不是很熟悉,欢迎提出更好的优化方案 以下是QT5
#include
#include
#include
#include
#include
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, fishFrame(0)
, fish2Frame(0)
, diverFrame(0)
, bubblePixmap(":/images/smallbubble.png")
{
ui->setupUi(this);
// Load fish images and split them into 6 parts
QPixmap fishPixmap(":/images/fish.png");
QPixmap fish2Pixmap(":/images/fish2.png");
QPixmap diverPixmap(":/images/diver.png");
int frameWidth = fishPixmap.width() /4;
int frameHeight = fishPixmap.height()/2;
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 4; ++i) {
fishPixmaps.push_back(fishPixmap.copy(i * frameWidth, frameHeight * j, frameWidth, frameHeight));
}
}
frameWidth = fish2Pixmap.width() /2;
frameHeight = fish2Pixmap.height()/3;
for (int j = 0; j < 3; j++) {
for (int i = 0; i < 2; ++i) {
fish2Pixmaps.push_back(fish2Pixmap.copy(i * frameWidth, frameHeight * j, frameWidth, frameHeight));
}
}
frameWidth = diverPixmap.width();
frameHeight = diverPixmap.height()/16;
for (int i = 0; i < 16 i diverpixmaps.push_backdiverpixmap.copy0 frameheight i framewidth frameheight set the background image ui->backgroundLabel->setPixmap(QPixmap(":/images/water_1080.png"));
ui->backgroundLabel->setScaledContents(true);
// Set the initial fish images
ui->fishLabel->setPixmap(fishPixmaps[0]);
ui->fishLabel->setScaledContents(true);
ui->fish2Label->setPixmap(fish2Pixmaps[0]);
ui->fish2Label->setScaledContents(true);
// Set the diver image
ui->diverLabel->setPixmap(diverPixmaps[0]);
ui->diverLabel->setScaledContents(true);
// Create timers for moving the fish
moveTimer = new QTimer(this);
connect(moveTimer, &QTimer::timeout, this, &MainWindow::moveFish);
moveTimer->start(50);
moveTimer2 = new QTimer(this);
connect(moveTimer2, &QTimer::timeout, this, &MainWindow::moveFish2);
moveTimer2->start(50);
// Create timers for animating the fish
animateTimer = new QTimer(this);
connect(animateTimer, &QTimer::timeout, this, &MainWindow::animateFish);
animateTimer->start(100);
animateTimer2 = new QTimer(this);
connect(animateTimer2, &QTimer::timeout, this, &MainWindow::animateFish2);
animateTimer2->start(100);
// Create timers for animating the diver
animateTimer3 = new QTimer(this);
connect(animateTimer3, &QTimer::timeout, this, &MainWindow::animateDiver);
animateTimer3->start(100);
cpuTimer = new QTimer(this);
connect(cpuTimer, &QTimer::timeout, this, &MainWindow::updateClock);
cpuTimer->start(1000); // 每秒更新一次时钟
// Create timer for creating bubbles
bubbleTimer = new QTimer(this);
connect(bubbleTimer, &QTimer::timeout, this, &MainWindow::createBubble);
bubbleTimer->start(1000);
// 显示 CPU 使用率的标签
cpuLabel = new QLabel(this);
cpuLabel->setGeometry(580, 5, 200, 40);
cpuLabel->setStyleSheet("font-size: 20px; color: red;");
cpuLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
cpuUsage = new CPUUsage(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::moveFish()
{
int x = ui->fishLabel->x() + 5;
if (x > this->width()) {
x = -ui->fishLabel->width();
int y = QRandomGenerator::global()->bounded(this->height() - ui->fishLabel->height());
ui->fishLabel->move(x, y);
} else {
ui->fishLabel->move(x, ui->fishLabel->y());
}
}
void MainWindow::moveFish2()
{
int x = ui->fish2Label->x() + 5;
if (x > this->width()) {
x = -ui->fish2Label->width();
int y = QRandomGenerator::global()->bounded(this->height() - ui->fish2Label->height());
ui->fish2Label->move(x, y);
} else {
ui->fish2Label->move(x, ui->fish2Label->y());
}
}
void MainWindow::animateFish()
{
fishFrame = (fishFrame + 1) % fishPixmaps.size();
ui->fishLabel->setPixmap(fishPixmaps[fishFrame]);
}
void MainWindow::animateFish2()
{
fish2Frame = (fish2Frame + 1) % fish2Pixmaps.size();
ui->fish2Label->setPixmap(fish2Pixmaps[fish2Frame]);
}
void MainWindow::animateDiver()
{
diverFrame = (diverFrame + 1) % diverPixmaps.size();
ui->diverLabel->setPixmap(diverPixmaps[diverFrame]);
}
void MainWindow::updateClock()
{
cpuLabel->setText(QString("CPU Usage: %1%").arg(cpuUsage->getCPUUsage(), 0, 'f', 2));
update();
}
void MainWindow::createBubble()
{
int bubbleCount = QRandomGenerator::global()->bounded(1, 4); // Random number of bubbles between 1 and 5
for (int i = 0; i < bubblecount i int x='QRandomGenerator::global()-'>bounded(this->width());
int y = this->height();
int size = QRandomGenerator::global()->bounded(5, 32); // Random size between 10 and 50
int xspeed = 0;
int yspeed = -QRandomGenerator::global()->bounded(5, 20); // Random speed between 1 and 10
Bubble* bubble = new Bubble(bubblePixmap, xspeed, yspeed, QPoint(x, y), size, this);
bubbles.push_back(bubble);
bubble->show();
if (bubble->getcount() >= 20) {
break;
}
}
}
以下是EGT
/*
* Copyright (C) 2018 Microchip Technology Inc. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include
#include
#include
#include
#include