Skip to content

Instantly share code, notes, and snippets.

@Staars
Last active October 25, 2025 14:54
Show Gist options
  • Select an option

  • Save Staars/eed65a443970dfcc18f8063b8f753e77 to your computer and use it in GitHub Desktop.

Select an option

Save Staars/eed65a443970dfcc18f8063b8f753e77 to your computer and use it in GitHub Desktop.
gather some ideas
class LVGLBenchmark
var scr, hres, vres
var test_running, current_test, frame_count, start_time, test_duration
var status_label, test_objects, results, anim_counter, anim_loop
var font_small, font_normal, font_large
var header_height, result_line_height
var is_small_screen, is_large_screen, scale_factor
def init()
lv.start()
self.hres = lv.get_hor_res()
self.vres = lv.get_ver_res()
self.detect_screen_size()
self.setup_fonts()
self.test_running = false
self.current_test = 0
self.frame_count = 0
self.test_duration = 3000
self.test_objects = []
self.results = {}
self.anim_counter = 0
self.anim_loop = /->self.loop()
self.show_start_screen()
print(f"LVGL Benchmark ready - {self.hres}x{self.vres}")
end
def detect_screen_size()
var pixels = self.hres * self.vres
if pixels <= 320 * 480
self.is_small_screen = true
self.is_large_screen = false
self.header_height = 35
self.result_line_height = 16
self.scale_factor = 1.0
elif pixels >= 800 * 480
self.is_small_screen = false
self.is_large_screen = true
self.header_height = 60
self.result_line_height = 24
self.scale_factor = 2.0
else
self.is_small_screen = false
self.is_large_screen = false
self.header_height = 45
self.result_line_height = 20
self.scale_factor = 1.5
end
end
def setup_fonts()
if self.is_small_screen
self.font_small = lv.montserrat_font(10)
self.font_normal = lv.montserrat_font(14)
self.font_large = lv.montserrat_font(14)
elif self.is_large_screen
self.font_small = lv.montserrat_font(14)
self.font_normal = lv.montserrat_font(20)
self.font_large = lv.montserrat_font(28)
else
self.font_small = lv.montserrat_font(10)
self.font_normal = lv.montserrat_font(14)
self.font_large = lv.montserrat_font(20)
end
end
def show_start_screen()
self.scr = lv.scr_act()
self.scr.set_style_bg_color(lv.color(0x202020), lv.PART_MAIN | lv.STATE_DEFAULT)
self.scr.clean()
var title = lv.label(self.scr)
title.set_text("LVGL Benchmark")
title.set_pos(10, 10)
title.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_large != nil title.set_style_text_font(self.font_large, lv.PART_MAIN | lv.STATE_DEFAULT) end
var info = lv.label(self.scr)
var info_text = "14 Tests x 3 sec"
if !self.is_small_screen
info_text = "14 Tests x 3 seconds\nWeighted scoring"
end
info.set_text(info_text)
info.set_pos(10, 10 + int(self.header_height * 0.7))
info.set_style_text_color(lv.color(0xAAAAAA), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var device_info = lv.label(self.scr)
device_info.set_text(f"{self.hres}x{self.vres}")
device_info.set_pos(10, 10 + int(self.header_height * 1.3))
device_info.set_style_text_color(lv.color(0x666666), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil device_info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var btn_w = int(120 * self.scale_factor)
var btn_h = int(50 * self.scale_factor)
var start_btn = lv.btn(self.scr)
start_btn.set_size(btn_w, btn_h)
start_btn.set_pos(int(self.hres / 2) - int(btn_w / 2), int(self.vres / 2))
start_btn.set_style_bg_color(lv.color(0x00AA00), lv.PART_MAIN | lv.STATE_DEFAULT)
var btn_label = lv.label(start_btn)
btn_label.set_text("START")
if self.font_normal != nil btn_label.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end
btn_label.center()
start_btn.add_event_cb(/obj, evt -> self.start_benchmark(), lv.EVENT_CLICKED, 0)
end
def scaled(base_size)
return int(base_size * self.scale_factor)
end
def calc_grid(item_width, item_height)
var content_w = self.hres - 20
var content_h = self.vres - self.header_height - 10
var cols = int(content_w / item_width)
var rows = int(content_h / item_height)
if cols < 1 cols = 1 end
if rows < 1 rows = 1 end
return [cols, rows]
end
def start_benchmark()
print("\n=== Benchmark Started ===")
self.results = {}
self.current_test = 1
tasmota.add_fast_loop(self.anim_loop)
self.start_next_test()
end
def start_next_test()
if self.current_test > 14
self.show_results()
return
end
self.test_running = true
self.frame_count = 0
self.start_time = tasmota.millis()
self.anim_counter = 0
self.scr.clean()
self.scr.set_style_bg_color(lv.color(0xE0E0E0), lv.PART_MAIN | lv.STATE_DEFAULT)
self.status_label = lv.label(self.scr)
self.status_label.set_pos(10, 10)
self.status_label.set_style_text_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil self.status_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
self.test_objects = []
if self.current_test == 1
self.status_label.set_text("Test 1/13: Empty Screen")
self.test_empty_screen()
elif self.current_test == 2
self.status_label.set_text("Test 2/13: Single Rectangle")
self.test_single_rectangle()
elif self.current_test == 3
self.status_label.set_text("Test 3/13: Multiple Rectangles")
self.test_multiple_rectangles()
elif self.current_test == 4
self.status_label.set_text("Test 4/13: Multiple Images")
self.test_multiple_rgb_images()
elif self.current_test == 5
self.status_label.set_text("Test 5/13: Rotated Images")
self.test_rotated_images()
elif self.current_test == 6
self.status_label.set_text("Test 6/13: Multiple Labels")
self.test_multiple_labels()
elif self.current_test == 7
self.status_label.set_text("Test 7/13: Arcs")
self.test_multiple_arcs()
elif self.current_test == 8
self.status_label.set_text("Test 8/13: Containers")
self.test_containers()
elif self.current_test == 9
self.status_label.set_text("Test 9/13: Containers+Opa")
self.test_containers_with_opa()
elif self.current_test == 10
self.status_label.set_text("Test 10/13: Circles")
self.test_circles()
elif self.current_test == 11
self.status_label.set_text("Test 11/13: Lines")
self.test_lines()
elif self.current_test == 12
self.status_label.set_text("Test 12/13: Buttons")
self.test_buttons()
elif self.current_test == 13
self.status_label.set_text("Test 13/14: Scrolling")
self.test_scrolling()
elif self.current_test == 14
self.status_label.set_text("Test 14/14: Mixed Complex")
self.test_mixed_complex()
end
end
def test_empty_screen()
end
def test_single_rectangle()
var sz = self.scaled(80)
var rect = lv.obj(self.scr)
rect.remove_style_all()
rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
rect.set_size(sz, sz)
rect.center()
self.test_objects.push(rect)
end
def test_multiple_rectangles()
var rect_size = self.scaled(50)
var grid = self.calc_grid(rect_size + 10, rect_size + 10)
var cols = grid[0]
var rows = grid[1]
var row = 0
while row < rows
var col = 0
while col < cols
var rect = lv.obj(self.scr)
rect.remove_style_all()
rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
rect.set_size(rect_size, rect_size)
rect.set_pos(col * (rect_size + 10) + 10, row * (rect_size + 10) + self.header_height)
rect.set_style_radius(self.scaled(5), lv.PART_MAIN | lv.STATE_DEFAULT)
self.test_objects.push(rect)
col += 1
end
row += 1
end
end
def test_multiple_rgb_images()
var grid = self.calc_grid(80, 80)
var cols = grid[0]
var rows = grid[1]
var spacing_x = int(self.hres / cols)
var spacing_y = int((self.vres - self.header_height) / rows)
var row = 0
while row < rows
var col = 0
while col < cols
var logo = lv.img(self.scr)
logo.set_tasmota_logo()
var x = col * spacing_x + int(spacing_x / 2) - 32
var y = row * spacing_y + self.header_height + int(spacing_y / 2) - 32
logo.set_pos(x, y)
self.test_objects.push(logo)
col += 1
end
row += 1
end
end
def test_rotated_images()
var grid = self.calc_grid(100, 100)
var cols = grid[0]
var rows = grid[1]
var spacing_x = int(self.hres / cols)
var spacing_y = int((self.vres - self.header_height) / rows)
var row = 0
while row < rows
var col = 0
while col < cols
var logo = lv.img(self.scr)
logo.set_tasmota_logo()
var x = col * spacing_x + int(spacing_x / 2) - 32
var y = row * spacing_y + self.header_height + int(spacing_y / 2) - 32
logo.set_pos(x, y)
var angle = ((row * cols + col) * 234) % 3600
logo.set_style_transform_pivot_x(32, lv.PART_MAIN | lv.STATE_DEFAULT)
logo.set_style_transform_pivot_y(32, lv.PART_MAIN | lv.STATE_DEFAULT)
logo.set_style_transform_rotation(angle, lv.PART_MAIN | lv.STATE_DEFAULT)
self.test_objects.push(logo)
col += 1
end
row += 1
end
end
def test_multiple_labels()
var line_height = self.is_small_screen ? 18 : (self.is_large_screen ? 30 : 24)
var grid = self.calc_grid(100, line_height)
var cols = grid[0]
var rows = grid[1]
var row = 0
while row < rows
var col = 0
while col < cols
var label = lv.label(self.scr)
label.set_text("Hello LVGL!")
label.set_pos(col * int(self.hres / cols) + 10, row * line_height + self.header_height)
label.set_style_text_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
self.test_objects.push(label)
col += 1
end
row += 1
end
end
def test_multiple_arcs()
var arc_size = self.scaled(60)
var grid = self.calc_grid(arc_size + 20, arc_size + 20)
var cols = grid[0]
var rows = grid[1]
var spacing_x = int(self.hres / cols)
var spacing_y = int((self.vres - self.header_height) / rows)
var row = 0
while row < rows
var col = 0
while col < cols
var arc = lv.arc(self.scr)
arc.set_size(arc_size, arc_size)
var x = col * spacing_x + int(spacing_x / 2) - int(arc_size / 2)
var y = row * spacing_y + self.header_height + int(spacing_y / 2) - int(arc_size / 2)
arc.set_pos(x, y)
arc.set_bg_angles(0, 360)
arc.set_style_arc_opa(0, lv.PART_MAIN | lv.STATE_DEFAULT)
arc.set_style_arc_width(self.scaled(5), lv.PART_INDICATOR | lv.STATE_DEFAULT)
var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF]
var color_idx = (row * cols + col) % 6
arc.set_style_arc_color(lv.color(colors[color_idx]), lv.PART_INDICATOR | lv.STATE_DEFAULT)
self.test_objects.push(arc)
col += 1
end
row += 1
end
end
def test_containers()
var card_w = self.scaled(135)
var card_h = self.scaled(60)
var grid = self.calc_grid(card_w + 20, card_h + 20)
var cols = grid[0]
var rows = grid[1]
var row = 0
while row < rows
var col = 0
while col < cols
var card = self.create_card()
var x = col * int(self.hres / cols) + 10
var y = row * (card_h + 20) + self.header_height
card.set_pos(x, y)
self.test_objects.push(card)
col += 1
end
row += 1
end
end
def test_containers_with_opa()
var card_w = self.scaled(135)
var card_h = self.scaled(60)
var grid = self.calc_grid(card_w + 20, card_h + 20)
var cols = grid[0]
var rows = grid[1]
var row = 0
while row < rows
var col = 0
while col < cols
var card = self.create_card()
card.set_style_opa(180, lv.PART_MAIN | lv.STATE_DEFAULT)
var x = col * int(self.hres / cols) + 10
var y = row * (card_h + 20) + self.header_height
card.set_pos(x, y)
self.test_objects.push(card)
col += 1
end
row += 1
end
end
def test_circles()
var base_size = self.scaled(30)
var grid = self.calc_grid(base_size + 30, base_size + 30)
var cols = grid[0]
var rows = grid[1]
var count = 0
var row = 0
while row < rows
var col = 0
while col < cols
var circle = lv.obj(self.scr)
circle.remove_style_all()
circle.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
var sz = base_size + (count * 3)
circle.set_size(sz, sz)
var x = col * int(self.hres / cols) + 20
var y = row * (base_size + 30) + self.header_height + 10
circle.set_pos(x, y)
circle.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT)
self.test_objects.push(circle)
count += 1
col += 1
end
row += 1
end
end
def test_lines()
var num_lines = self.is_small_screen ? 10 : (self.is_large_screen ? 25 : 15)
var line_width = self.is_small_screen ? 2 : (self.is_large_screen ? 4 : 3)
var i = 0
var p1 = lv.point()
var p2 = lv.point()
while i < num_lines
var line = lv.line(self.scr)
var spacing = int((self.vres - self.header_height) / num_lines)
p1.x = 0
p1.y = i * spacing
p2.x = self.hres - 20
p2.y = (self.vres - self.header_height) - i * spacing
var pt_arr = lv.lv_point_arr([p1, p2])
line.set_points(pt_arr, 2)
line.set_style_line_width(line_width, lv.PART_MAIN | lv.STATE_DEFAULT)
line.set_style_line_color(lv.color(0x0066CC), lv.PART_MAIN | lv.STATE_DEFAULT)
line.set_pos(10, self.header_height)
self.test_objects.push(line)
i += 1
end
end
def test_buttons()
var btn_w = self.scaled(60)
var btn_h = self.scaled(30)
var grid = self.calc_grid(btn_w + 15, btn_h + 15)
var cols = grid[0]
var rows = grid[1]
var row = 0
while row < rows
var col = 0
while col < cols
var btn = lv.btn(self.scr)
btn.set_size(btn_w, btn_h)
btn.set_pos(col * (btn_w + 15) + 10, row * (btn_h + 15) + self.header_height)
var label = lv.label(btn)
var btn_text = self.is_small_screen ? f"B{row * cols + col + 1}" : f"Btn {row * cols + col + 1}"
label.set_text(btn_text)
if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
label.center()
self.test_objects.push(btn)
col += 1
end
row += 1
end
end
def test_scrolling()
var scroll_cont = lv.obj(self.scr)
scroll_cont.set_size(self.hres - 20, self.vres - self.header_height - 10)
scroll_cont.set_pos(10, self.header_height)
scroll_cont.set_style_bg_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
scroll_cont.set_style_border_width(0, lv.PART_MAIN | lv.STATE_DEFAULT)
scroll_cont.set_flex_flow(lv.FLEX_FLOW_COLUMN)
scroll_cont.set_style_pad_all(5, lv.PART_MAIN | lv.STATE_DEFAULT)
scroll_cont.set_style_pad_row(5, lv.PART_MAIN | lv.STATE_DEFAULT)
var num_items = self.is_small_screen ? 20 : (self.is_large_screen ? 40 : 30)
var item_h = self.scaled(40)
var i = 0
while i < num_items
var item = lv.obj(scroll_cont)
item.set_width(lv.pct(100))
item.set_height(item_h)
item.set_style_bg_color(lv.color(0xE0E0E0), lv.PART_MAIN | lv.STATE_DEFAULT)
item.set_style_radius(self.scaled(3), lv.PART_MAIN | lv.STATE_DEFAULT)
var label = lv.label(item)
label.set_text(f"Item {i + 1}")
label.set_pos(10, int(item_h / 2) - 7)
if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
i += 1
end
self.test_objects.push(scroll_cont)
end
def test_mixed_complex()
var base_size = self.scaled(40)
var num_each = self.is_small_screen ? 2 : 3
var i = 0
while i < num_each
var rect = lv.obj(self.scr)
rect.remove_style_all()
rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
rect.set_size(base_size, base_size)
rect.set_pos(i * (base_size + 15) + 10, self.header_height + 10)
rect.set_style_radius(self.scaled(5), lv.PART_MAIN | lv.STATE_DEFAULT)
self.test_objects.push(rect)
i += 1
end
i = 0
while i < num_each
var circle = lv.obj(self.scr)
circle.remove_style_all()
circle.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
circle.set_size(base_size - 5, base_size - 5)
circle.set_pos(i * (base_size + 15) + 10, self.header_height + base_size + 25)
circle.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT)
self.test_objects.push(circle)
i += 1
end
i = 0
var num_arcs = self.is_small_screen ? 1 : 2
while i < num_arcs
var arc = lv.arc(self.scr)
var arc_size = self.scaled(50)
arc.set_size(arc_size, arc_size)
arc.set_pos(i * (arc_size + 20) + 10, self.header_height + base_size * 2 + 40)
arc.set_style_arc_width(self.scaled(4), lv.PART_INDICATOR | lv.STATE_DEFAULT)
self.test_objects.push(arc)
i += 1
end
i = 0
var num_labels = self.is_small_screen ? 3 : 5
while i < num_labels
var label = lv.label(self.scr)
label.set_text(f"Text {i + 1}")
var label_x = self.is_large_screen ? int(self.hres / 2) : (self.hres - 100)
label.set_pos(label_x, self.header_height + 10 + i * 20)
if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
self.test_objects.push(label)
i += 1
end
end
def create_card()
var card_w = self.scaled(135)
var card_h = self.scaled(60)
var card = lv.obj(self.scr)
card.set_size(card_w, card_h)
card.set_style_bg_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
card.set_style_radius(self.scaled(4), lv.PART_MAIN | lv.STATE_DEFAULT)
card.set_style_pad_all(self.scaled(4), lv.PART_MAIN | lv.STATE_DEFAULT)
var avatar_size = self.scaled(30)
var avatar = lv.obj(card)
avatar.set_size(avatar_size, avatar_size)
avatar.set_pos(3, int(card_h / 2) - int(avatar_size / 2))
avatar.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT)
avatar.set_style_bg_color(lv.color(0x2196F3), lv.PART_MAIN | lv.STATE_DEFAULT)
var name = lv.label(card)
var name_text = self.is_small_screen ? "J. Smith" : "John Smith"
name.set_text(name_text)
name.set_pos(avatar_size + 8, 5)
if self.font_small != nil name.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var btn_w = self.scaled(40)
var btn_h = self.scaled(18)
var btn = lv.btn(card)
btn.set_size(btn_w, btn_h)
btn.set_pos(avatar_size + 8, card_h - btn_h - 8)
btn.set_style_bg_color(lv.color(0x4CAF50), lv.PART_MAIN | lv.STATE_DEFAULT)
var btn_label = lv.label(btn)
btn_label.set_text("OK")
btn_label.center()
if self.font_small != nil btn_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
return card
end
def animate_objects()
if !self.test_running return end
if self.current_test == 1
var colors = [0xFF0000, 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, 0xCCFF00, 0x99FF00, 0x66FF00, 0x33FF00, 0x00FF00, 0x00FF33, 0x00FF66, 0x00FF99, 0x00FFCC, 0x00FFFF, 0x00CCFF, 0x0099FF, 0x0066FF, 0x0033FF, 0x0000FF, 0x3300FF, 0x6600FF, 0x9900FF, 0xCC00FF, 0xFF00FF, 0xFF00CC, 0xFF0099, 0xFF0066, 0xFF0033]
var color_idx = (self.anim_counter / 3) % 30
self.scr.set_style_bg_color(lv.color(colors[color_idx]), lv.PART_MAIN | lv.STATE_DEFAULT)
end
if self.current_test == 2 && size(self.test_objects) > 0
var obj = self.test_objects[0]
var hue = (self.anim_counter * 6) % 360
var color_val = hue * 0x010101
obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
end
if self.current_test == 3
var i = 0
while i < size(self.test_objects)
var obj = self.test_objects[i]
var offset = (self.anim_counter + i * 10) % 360
var color_val = offset * 0x010101
obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 4
var i = 0
while i < size(self.test_objects)
var logo = self.test_objects[i]
var opa = 128 + int(127 * ((self.anim_counter + i * 20) % 100) / 100.0)
logo.set_style_img_opa(opa, lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 5
var i = 0
while i < size(self.test_objects)
var logo = self.test_objects[i]
var angle = (self.anim_counter * 10 + i * 100) % 3600
logo.set_style_transform_rotation(angle, lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 6
var i = 0
while i < size(self.test_objects)
var label = self.test_objects[i]
var offset = (self.anim_counter + i * 15) % 360
var color_val = offset * 0x010101
label.set_style_text_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 7
var i = 0
while i < size(self.test_objects)
var arc = self.test_objects[i]
var value = ((self.anim_counter + i * 10) % 100)
arc.set_value(value)
i += 1
end
end
if self.current_test == 8
var i = 0
while i < size(self.test_objects)
var card = self.test_objects[i]
var offset = (self.anim_counter + i * 20) % 100
var brightness = 200 + int(55 * offset / 100.0)
var gray = brightness * 0x010101
card.set_style_bg_color(lv.color(gray), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 9
var i = 0
while i < size(self.test_objects)
var card = self.test_objects[i]
var opa = 100 + int(155 * ((self.anim_counter + i * 15) % 100) / 100.0)
card.set_style_opa(opa, lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 10
var i = 0
while i < size(self.test_objects)
var circle = self.test_objects[i]
var offset = (self.anim_counter + i * 25) % 360
var color_val = offset * 0x010101
circle.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 11
var i = 0
while i < size(self.test_objects)
var line = self.test_objects[i]
var offset = (self.anim_counter + i * 30) % 360
var color_val = offset * 0x010101
line.set_style_line_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 12
var i = 0
while i < size(self.test_objects)
var btn = self.test_objects[i]
var offset = (self.anim_counter + i * 20) % 360
var color_val = offset * 0x010101
btn.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
if self.current_test == 13
var scroll_cont = self.test_objects[0]
var scroll_offset = (self.anim_counter * 2) % (self.vres * 2)
scroll_cont.scroll_to_y(scroll_offset, lv.ANIM_OFF)
end
if self.current_test == 14
var num_each = self.is_small_screen ? 2 : 3
var i = 0
while i < num_each && i < size(self.test_objects)
var obj = self.test_objects[i]
var offset = (self.anim_counter + i * 30) % 360
var color_val = offset * 0x010101
obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
i = 0
while i < num_each && (num_each + i) < size(self.test_objects)
var circle = self.test_objects[num_each + i]
var offset = (self.anim_counter + i * 40) % 360
var color_val = offset * 0x010101
circle.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
var arc_start = num_each * 2
var num_arcs = self.is_small_screen ? 1 : 2
i = 0
while i < num_arcs && (arc_start + i) < size(self.test_objects)
var arc = self.test_objects[arc_start + i]
var value = ((self.anim_counter + i * 15) % 100)
arc.set_value(value)
i += 1
end
var label_start = arc_start + num_arcs
var num_labels = self.is_small_screen ? 3 : 5
i = 0
while i < num_labels && (label_start + i) < size(self.test_objects)
var label = self.test_objects[label_start + i]
var offset = (self.anim_counter + i * 25) % 360
var color_val = offset * 0x010101
label.set_style_text_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT)
i += 1
end
end
self.anim_counter += 1
end
def loop()
if !self.test_running return end
self.frame_count += 1
self.animate_objects()
var now = tasmota.millis()
var elapsed = now - self.start_time
if elapsed >= self.test_duration
self.end_current_test()
end
end
def end_current_test()
self.test_running = false
var elapsed = tasmota.millis() - self.start_time
var fps = int((self.frame_count * 1000.0) / elapsed)
self.results[f"test{self.current_test}"] = fps
self.current_test += 1
tasmota.set_timer(500, /-> self.start_next_test())
end
def get_test_weight(test_num)
if test_num == 2 || test_num == 7
return 0.25
end
return 1.0
end
def show_results()
tasmota.remove_fast_loop(self.anim_loop)
self.scr.clean()
self.scr.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
var title = lv.label(self.scr)
title.set_text("Benchmark Results")
title.set_pos(10, 5)
title.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_normal != nil title.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end
var info = lv.label(self.scr)
info.set_text(f"{self.hres}x{self.vres}")
info.set_pos(10, 5 + int(self.result_line_height * 1.2))
info.set_style_text_color(lv.color(0x888888), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var y = 5 + int(self.result_line_height * 2.5)
var tests = ["Empty", "Single", "Rects", "Images", "Rotated", "Labels", "Arcs", "Cards", "Card+Opa", "Circles", "Lines", "Buttons", "Scroll", "Mixed"]
var weighted_sum = 0.0
var weight_total = 0.0
var i = 1
while i <= 14
var test_name = tests[i - 1]
var fps = self.results[f"test{i}"]
var weight = self.get_test_weight(i)
weighted_sum += fps * weight
weight_total += weight
var result = lv.label(self.scr)
var weight_marker = (weight < 1.0) ? "*" : ""
var result_text = self.is_small_screen ? f"{i}.{test_name}{weight_marker}" : f"{i}. {test_name}{weight_marker}"
result.set_text(result_text)
result.set_pos(10, y)
result.set_style_text_color(lv.color(0xCCCCCC), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil result.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var fps_label = lv.label(self.scr)
fps_label.set_text(f"{fps}")
var fps_x = self.is_small_screen ? (self.hres - 45) : (self.hres - 70)
fps_label.set_pos(fps_x, y)
var fps_color = 0x00FF00
if fps < 30 fps_color = 0xFF0000
elif fps < 45 fps_color = 0xFF6600
elif fps < 60 fps_color = 0xFFFF00
end
fps_label.set_style_text_color(lv.color(fps_color), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil fps_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
y += self.result_line_height
i += 1
end
var avg = int(weighted_sum / weight_total)
y += int(self.result_line_height * 0.3)
var note = lv.label(self.scr)
note.set_text("* weighted 0.25x")
note.set_pos(10, y)
note.set_style_text_color(lv.color(0x666666), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil note.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
y += int(self.result_line_height * 1.2)
var avg_label = lv.label(self.scr)
avg_label.set_text(f"Score: {avg} FPS")
avg_label.set_pos(10, y)
avg_label.set_style_text_color(lv.color(0xFFFF00), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_normal != nil avg_label.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end
var rating = "Excellent"
var rating_color = 0x00FF00
if avg < 20
rating = "Poor"
rating_color = 0xFF0000
elif avg < 35
rating = "Fair"
rating_color = 0xFF6600
elif avg < 50
rating = "Good"
rating_color = 0xFFFF00
end
y += int(self.result_line_height * 1.3)
var rating_label = lv.label(self.scr)
rating_label.set_text(rating)
rating_label.set_pos(10, y)
rating_label.set_style_text_color(lv.color(rating_color), lv.PART_MAIN | lv.STATE_DEFAULT)
if self.font_small != nil rating_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
var btn_w = self.scaled(50)
var btn_h = self.scaled(25)
var repeat_btn = lv.btn(self.scr)
repeat_btn.set_size(btn_w, btn_h)
repeat_btn.set_pos(int(self.hres / 2) - int(btn_w / 2), self.vres - btn_h - 10)
repeat_btn.set_style_bg_color(lv.color(0x0066CC), lv.PART_MAIN | lv.STATE_DEFAULT)
var btn_label = lv.label(repeat_btn)
btn_label.set_text("REPEAT")
btn_label.center()
if self.font_small != nil btn_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end
repeat_btn.add_event_cb(/obj, evt -> self.start_benchmark(), lv.EVENT_CLICKED, 0)
print(f"\n=== Results ({self.hres}x{self.vres}) ===")
i = 1
while i <= 14
var fps = self.results[f"test{i}"]
var weight = self.get_test_weight(i)
var marker = (weight < 1.0) ? " *" : ""
print(f"{tests[i-1]}: {fps}{marker}")
i += 1
end
print(f"Score: {avg} - {rating}")
end
end
benchmark = LVGLBenchmark()
tasmota.add_driver(benchmark)
print("LVGL Benchmark loaded - Click START")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment