Optimize scrolling text performance for news ticker

This commit is contained in:
ChuckBuilds
2025-04-11 09:47:13 -05:00
parent 7925bf515b
commit e8aa05a0b4
2 changed files with 43 additions and 31 deletions

View File

@@ -36,18 +36,18 @@ class DisplayManager:
options.parallel = hardware_config.get('parallel', 1) options.parallel = hardware_config.get('parallel', 1)
options.hardware_mapping = hardware_config.get('hardware_mapping', 'adafruit-hat-pwm') options.hardware_mapping = hardware_config.get('hardware_mapping', 'adafruit-hat-pwm')
# Optimize display settings for chained panels # Optimize display settings for performance
options.brightness = 100 options.brightness = 100
options.pwm_bits = 11 options.pwm_bits = 8 # Reduced for better performance
options.pwm_lsb_nanoseconds = 200 # Increased for better stability options.pwm_lsb_nanoseconds = 100 # Reduced for faster updates
options.led_rgb_sequence = 'RGB' options.led_rgb_sequence = 'RGB'
options.pixel_mapper_config = '' options.pixel_mapper_config = ''
options.row_address_type = 0 options.row_address_type = 0
options.multiplexing = 0 options.multiplexing = 0
options.disable_hardware_pulsing = False # Enable hardware pulsing for better sync options.disable_hardware_pulsing = True # Disable pulsing for better performance
options.show_refresh_rate = False options.show_refresh_rate = False
options.limit_refresh_rate_hz = 60 # Reduced refresh rate for stability options.limit_refresh_rate_hz = 120 # Increased refresh rate
options.gpio_slowdown = 2 # Increased slowdown for better stability options.gpio_slowdown = 1 # Reduced slowdown for better performance
# Initialize the matrix # Initialize the matrix
self.matrix = RGBMatrix(options=options) self.matrix = RGBMatrix(options=options)
@@ -94,14 +94,13 @@ class DisplayManager:
# Copy the current image to the offscreen canvas # Copy the current image to the offscreen canvas
self.offscreen_canvas.SetImage(self.image) self.offscreen_canvas.SetImage(self.image)
# Wait for the next vsync before swapping # Swap buffers immediately without waiting for vsync
self.matrix.SwapOnVSync(self.offscreen_canvas) self.matrix.SwapOnVSync(self.offscreen_canvas, False)
# Swap our canvas references # Swap our canvas references
self.offscreen_canvas, self.current_canvas = self.current_canvas, self.offscreen_canvas self.offscreen_canvas, self.current_canvas = self.current_canvas, self.offscreen_canvas
# Small delay to ensure stable refresh # No delay needed since we're not waiting for vsync
time.sleep(0.001)
except Exception as e: except Exception as e:
logger.error(f"Error updating display: {e}") logger.error(f"Error updating display: {e}")

View File

@@ -205,28 +205,40 @@ class StockNewsManager:
separator = " - " # Visual separator between news items separator = " - " # Visual separator between news items
news_text = separator.join(news_texts) news_text = separator.join(news_texts)
# Pre-render the text image for efficient scrolling
text_image = self._create_text_image(news_text)
text_width = text_image.width
display_width = self.display_manager.matrix.width
# Calculate total width for scrolling
total_width = text_width + display_width
# Update scroll position with smooth acceleration
scroll_speed = min(self.scroll_speed * 1.1, 3) # Gradually increase speed up to max
self.scroll_position = (self.scroll_position + scroll_speed) % total_width
# Clear the display # Clear the display
self.display_manager.clear() self.display_manager.clear()
# Calculate text width for scrolling # Calculate source and destination regions for efficient blitting
bbox = self.display_manager.draw.textbbox((0, 0), news_text, font=self.display_manager.small_font) if self.scroll_position < display_width:
text_width = bbox[2] - bbox[0] # Text is entering from the right
src_x = text_width - (display_width - self.scroll_position)
# Calculate scroll position src_width = display_width - self.scroll_position
display_width = self.display_manager.matrix.width dst_x = self.scroll_position
total_width = text_width + display_width self.display_manager.image.paste(
text_image.crop((src_x, 0, src_x + src_width, text_image.height)),
# Update scroll position (dst_x, 0)
self.scroll_position = (self.scroll_position + self.scroll_speed) % total_width )
else:
# Draw the text at the current scroll position # Text is scrolling off the left
self.display_manager.draw_text( src_x = 0
news_text, src_width = text_width
x=display_width - self.scroll_position, dst_x = self.scroll_position - display_width
y=None, # Center vertically self.display_manager.image.paste(
color=(255, 255, 255), text_image.crop((src_x, 0, src_x + src_width, text_image.height)),
small_font=True (dst_x, 0)
) )
# Update the display # Update the display
self.display_manager.update_display() self.display_manager.update_display()
@@ -234,9 +246,10 @@ class StockNewsManager:
# If we've completed a full scroll, move to the next group # If we've completed a full scroll, move to the next group
if self.scroll_position == 0: if self.scroll_position == 0:
self.current_news_group = (self.current_news_group + 1) % ((total_headlines + headlines_per_rotation - 1) // headlines_per_rotation) self.current_news_group = (self.current_news_group + 1) % ((total_headlines + headlines_per_rotation - 1) // headlines_per_rotation)
self.scroll_speed = 1 # Reset speed for next group
# Small delay to control scroll speed # Minimal delay to control scroll speed while maintaining smoothness
time.sleep(self.scroll_delay) time.sleep(0.001)
# Log frame rate # Log frame rate
self._log_frame_rate() self._log_frame_rate()