RaspberryPi で pygame で x11 を使わず(?) 遊ぶ

「Raspberry Pi で framebuffer で遊ぶ」
https://qiita.com/nanbuwks/items/71062ada859846ec89eb
では、 fbi コマンドを使って簡単に framebuffer の描画を行いました。
ちらつきが激しいので、
別のやり方をすることにしました。

今回は python のライブラリ pygame を使ってみます。


# 環境

- Raspberry Pi 3B
- Raspberry Pi OS Lite (2024-07-04-raspios-bookworm-armhf-lite.img.xz)

「Raspberry Pi で pygame」
https://qiita.com/nanbuwks/items/1e0e32f449e64cd0d188https://qiita.com/nanbuwks/items/1e0e32f449e64cd0d188
でpygame を設定しています。


# プログラム

```
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import pygame
import os
from time import sleep
import random
import datetime

# os.putenv('SDL_FBDEV', '/dev/fb0')
# os.putenv('XDG_RUNTIME_DIR', os.getenv('HOME')+"/.cache/xdgr")
pygame.init()
pygame.mouse.set_visible(False)

display = pygame.display.set_mode((800,480))
display.fill((255,0,0))
font130= pygame.font.Font("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",130)
font45=pygame.font.Font("/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf",45)
font160=pygame.font.Font("/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf",160)
img=pygame.image.load("heartbeatbg2.png")
while 1:
  now=datetime.datetime.now()
  texttime = font160.render(now.strftime('%H:%M:%S'), True, (0xFFFFAA00))
  texthb = font130.render(str(random.randrange(50, 80)), True, (0xC0000000))
  textdate = font45.render(now.strftime('%Y/%m/%d %A'), True, (0xFFAA0000))
  display.blit(img,(0,0))
  display.blit(texttime, (40,10))
  display.blit(texthb, (520,230))
  display.blit(textdate, (60,430))
  pygame.display.update()
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      pygame.quit()
      sys.exit()
  sleep(1)

```


# 注意点

## フォント座標
フォントは、先の記事では convert コマンドで扱ってましたが、 左下が原点。
pygame だと左上が原点なので、座標を修正する必要があります。

## kill 

最初は `  for event in pygame.event.get():` からの処理を書いていなかったら、このプログラム起動時にシステムシャットダウンが妨げられました。
event 処理を入れて対処。

# 結果

ちらつきなく、高速に処理できています。負荷もずっと軽くなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9f33f5fe-48a0-5b7a-a9fe-fae8ad2dca55.png)


# 描画結果とX(?)

結果を framebuffer から取得しようとしたけれど、
/dev/fb0 の内容はこんなでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/01e70a2d-0782-f687-a031-6250c66d355d.png)

/dev/fb1 , 2, 7 を見てみましたが真っ黒でした。

pygame は SDL2 経由で framebuffer を使っているのだと思ったのだけれど違ったかな?

apt によるインストール時の内容を見ると、 SDL2 は入ってますが libx11-xcb1 とか入ってますね。
ビデオドライバー経由で描画しているのかな?


```
$ sudo apt install python3-pygame
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
以下の追加パッケージがインストールされます:
  fonts-freefont-ttf libasyncns0 libblas3 libdecor-0-0 libdecor-0-plugin-1-cairo libfluidsynth3 libgbm1
  libgfortran5 libinstpatch-1.0-2 libjack-jackd2-0 liblapack3 libmodplug1 libmp3lame0 libmpg123-0 libopus0
  libopusfile0 libportmidi0 libpulse0 libsdl2-2.0-0 libsdl2-image-2.0-0 libsdl2-mixer-2.0-0
  libsdl2-ttf-2.0-0 libsndfile1 libvorbisenc2 libvorbisfile3 libwayland-client0 libwayland-cursor0
  libwayland-egl1 libwayland-server0 libx11-xcb1 libxcb-randr0 libxcursor1 libxfixes3 libxi6 libxkbcommon0
  libxrandr2 libxss1 python3-numpy timgm6mb-soundfont
提案パッケージ:
  jackd2 opus-tools pulseaudio xdg-utils gfortran python3-pytest python-pygame-doc timidity
  fluid-soundfont-gm
以下のパッケージが新たにインストールされます:
  fonts-freefont-ttf libasyncns0 libblas3 libdecor-0-0 libdecor-0-plugin-1-cairo libfluidsynth3 libgbm1
  libgfortran5 libinstpatch-1.0-2 libjack-jackd2-0 liblapack3 libmodplug1 libmp3lame0 libmpg123-0 libopus0
  libopusfile0 libportmidi0 libpulse0 libsdl2-2.0-0 libsdl2-image-2.0-0 libsdl2-mixer-2.0-0
  libsdl2-ttf-2.0-0 libsndfile1 libvorbisenc2 libvorbisfile3 libwayland-client0 libwayland-cursor0
  libwayland-egl1 libwayland-server0 libx11-xcb1 libxcb-randr0 libxcursor1 libxfixes3 libxi6 libxkbcommon0
  libxrandr2 libxss1 python3-numpy python3-pygame timgm6mb-soundfont
アップグレード: 0 個、新規インストール: 40 個、削除: 0 個、保留: 0 個。
18.2 MB のアーカイブを取得する必要があります。
この操作後に追加で 61.2 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
```

```
$ sudo apt-get install libgl1-mesa-dri
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
・
・
・
提案パッケージ:
  lm-sensors
以下のパッケージが新たにインストールされます:
  libdrm-amdgpu1 libdrm-nouveau2 libdrm-radeon1 libgl1-mesa-dri libglapi-mesa libllvm15 libsensors-config
  libsensors5 libxcb-dri3-0 libz3-4
アップグレード: 0 個、新規インストール: 10 個、削除: 0 個、保留: 0 個。
33.0 MB のアーカイブを取得する必要があります。
この操作後に追加で 150 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
```
```
$ sudo apt-get install libegl-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
・
・
・
提案パッケージ:
  libx11-doc libxcb-doc
以下のパッケージが新たにインストールされます:
  libegl-dev libegl-mesa0 libegl1 libgl-dev libgl1 libglvnd0 libglx-dev libglx-mesa0 libglx0
  libpthread-stubs0-dev libx11-dev libxau-dev libxcb-dri2-0 libxcb-glx0 libxcb-present0 libxcb-sync1
  libxcb-xfixes0 libxcb1-dev libxdmcp-dev libxshmfence1 libxxf86vm1 x11proto-dev xorg-sgml-doctools
  xtrans-dev
アップグレード: 0 個、新規インストール: 24 個、削除: 0 個、保留: 0 個。
2,831 kB のアーカイブを取得する必要があります。
この操作後に追加で 11.5 MB のディスク容量が消費されます。
続行しますか? [Y/n] y]
```

x を使わずに軽いシステムで描画と思ったのですが、xベースのドライバで描画しているのかもしれません。インストールは 200MB 以上必要で、思いのほかヘビーでしたが、それでも x Desktop 立ち上げて Web ブラウザーをキオスクで立ち上げて表示などをするよりはずっと軽量です。

pygame と fbdev の関係はここらへん?
https://forums.raspberrypi.com/viewtopic.php?t=365776