<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Takeshi Yaegashi</title>
    <description>The latest articles on DEV Community by Takeshi Yaegashi (@yaegashi).</description>
    <link>https://dev.to/yaegashi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F453225%2Fee591dd7-dfc6-4c8f-ad4c-00b798949b8b.jpg</url>
      <title>DEV Community: Takeshi Yaegashi</title>
      <link>https://dev.to/yaegashi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yaegashi"/>
    <language>en</language>
    <item>
      <title>Howto: Building Chromium on Ozone-GBM for RPi4</title>
      <dc:creator>Takeshi Yaegashi</dc:creator>
      <pubDate>Tue, 18 Aug 2020 06:49:42 +0000</pubDate>
      <link>https://dev.to/yaegashi/howto-building-chromium-on-ozone-gbm-for-rpi4-568e</link>
      <guid>https://dev.to/yaegashi/howto-building-chromium-on-ozone-gbm-for-rpi4-568e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I recently spent several days on building &lt;a href="https://www.chromium.org/Home"&gt;Chromium&lt;/a&gt; on &lt;a href="https://chromium.googlesource.com/chromium/src.git/+/master/docs/ozone_overview.md"&gt;the Ozone-GBM platform&lt;/a&gt; for &lt;a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/"&gt;Raspberry Pi 4 Model B&lt;/a&gt; (RPi4).&lt;/p&gt;

&lt;p&gt;This attempt is to gain smaller footprint and better performance for my embedded system projects, but unfortunately no satisfactory result for now.  In this article I'll share steps and tips I got so that you can join the effort as a tester or a developer.&lt;/p&gt;

&lt;p&gt;My former attempt with Ozone-Dispmanx for RPi3 has been shared in GitHub: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yaegashi"&gt;
        yaegashi
      &lt;/a&gt; / &lt;a href="https://github.com/yaegashi/ozone-dispmanx"&gt;
        ozone-dispmanx
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Chromium Ozone port to Raspberry Pi dispmanx
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Chromium Ozone port to Raspberry Pi dispmanx&lt;/h1&gt;
&lt;h2&gt;
Introduction&lt;/h2&gt;
&lt;p&gt;This is a &lt;a href="https://chromium.googlesource.com/chromium/src/+/master/docs/ozone_overview.md" rel="nofollow"&gt;Chromium Ozone&lt;/a&gt; port to Raspberry Pi using dispmanx.  &lt;a href="http://elinux.org/Raspberry_Pi_VideoCore_APIs" rel="nofollow"&gt;Dispmanx&lt;/a&gt; is a native display management API supporting OpenGL ES/EGL surfaces on VideoCore IV GPU equipped by Raspberry Pi.  It can achieve siginificant performance improvement compared to the traditional X11 platform.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=61sEBhJa7k8" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/cc62fa0de44b3b41b4c17e14b7f5e5ed127555ee/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f3631734542684a61376b382f302e6a7067" alt="YouTube video"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Current status:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only fullscreen &lt;code&gt;content_shell&lt;/code&gt; works (no navigation, no address bar, no bookmarks)&lt;/li&gt;
&lt;li&gt;No GPU process separation, run with &lt;code&gt;--in-process-gpu&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keyboard/mouse input support using evdev driver, but no VT console handling.&lt;/li&gt;
&lt;li&gt;It's forced to support WebGL - renderings are severely broken / no output for most pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Building&lt;/h2&gt;
&lt;p&gt;To build Chromium for Raspberry Pi, set up the build environment and check out &lt;a href="https://chromium.googlesource.com/chromium/src" rel="nofollow"&gt;src repository&lt;/a&gt; by following &lt;a href="https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md" rel="nofollow"&gt;the official guide&lt;/a&gt;.  Then follow the instruction below in &lt;code&gt;src&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;Set up ARM sysroot with dispmanx library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./build/linux/sysroot_scripts/install-sysroot.py --arch=arm
git clone --depth 1 https://github.com/raspberrypi/firmware
cp -R firmware/hardfp/opt build/linux/debian_wheezy_arm-sysroot
cp firmware/hardfp/opt/vc/lib/pkgconfig/bcm_host.pc build/linux/debian_wheezy_arm-sysroot/usr/lib/pkgconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yaegashi/ozone-dispmanx"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Cross building environment
&lt;/h2&gt;

&lt;p&gt;To build Chromium for RPi4, you'll first follow the generic instruction on &lt;a href="https://www.chromium.org/developers/how-tos/get-the-code"&gt;the official developer site&lt;/a&gt;. Read &lt;a href="https://chromium.googlesource.com/chromium/src/+/master/docs/linux/build_instructions.md"&gt;Checking out and building Chromium on Linux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;System requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux build machine 

&lt;ul&gt;
&lt;li&gt;Denoted as &lt;code&gt;(build)&lt;/code&gt; in this article&lt;/li&gt;
&lt;li&gt;OS: Ubuntu 18.04 or 20.04&lt;/li&gt;
&lt;li&gt;CPU: AMD64, more than 4 cores / 8 threads recommended&lt;/li&gt;
&lt;li&gt;Memory: more than 16GB recommended&lt;/li&gt;
&lt;li&gt;Storage: more than 100GB free space&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/"&gt;Raspberry Pi 4 Model B&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Denoted as &lt;code&gt;(pi)&lt;/code&gt; in this article&lt;/li&gt;
&lt;li&gt;OS: &lt;a href="https://www.raspberrypi.org/downloads/raspberry-pi-os/"&gt;Raspberry Pi OS (32-bit) with desktop&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Storage: 1GB free space&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we're going to build Chromium executable for 32-bit ARM (Debian armhf).&lt;/p&gt;

&lt;p&gt;Clone depot_tools.git anywhere you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Add its path to &lt;code&gt;PATH&lt;/code&gt;.  Put the following line in &lt;code&gt;~/.bashrc&lt;/code&gt; and restart your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/path/to/depot_tools
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;fetch&lt;/code&gt; to clone the Chromium sources anywhere you want, then run &lt;code&gt;install-build-deps.sh&lt;/code&gt; to set up build dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/chromium
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/chromium
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;fetch &lt;span class="nt"&gt;--nohooks&lt;/span&gt; chromium
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;./src/build/install-build-deps.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To run Chromium on Ozone-GBM, you have to set up the cross-build environment targeting ChromiumOS on ARM.  Details are explained in &lt;a href="https://chromium.googlesource.com/chromium/src/+/master/docs/linux/chromium_arm.md"&gt;Linux Chromium Arm Recipes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Edit &lt;code&gt;.gclient&lt;/code&gt; file generated by previous &lt;code&gt;fetch&lt;/code&gt;.  Append 2 lines as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target_cpu = ["arm"]
target_os = ["chromeos"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;gclient&lt;/code&gt; sync and runhooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;gclient &lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;gclient runhooks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This should acquire additional dependencies including ChromiumOS sources and install Debian armhf sysroot in &lt;code&gt;src/build/linux/debian_sid_arm-sysroot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;ccache&lt;/code&gt; is strongly recommended, so set it up now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ccache
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ccache &lt;span class="nt"&gt;-M&lt;/span&gt; 20GB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  First ninja build (ozone_demo)
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;gn&lt;/code&gt; in the source tree to prepare a directory for the production build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/chromium/src
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;gn args out/p1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This creates a build directory &lt;code&gt;out/p1&lt;/code&gt; and launch a text editor on &lt;code&gt;args.gn&lt;/code&gt; in it for you.  You should put the following lines and save it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Set build arguments here. See `gn help buildargs`.
cc_wrapper = "ccache"
dcheck_always_on = true
enable_nacl = false
has_native_accessibility = false
is_chrome_branded = false
is_debug = false
is_official_build = false
ozone_auto_platforms = false
ozone_platform = "gbm"
ozone_platform_gbm = true
target_cpu = "arm"
target_os = "chromeos"
target_sysroot = "//build/linux/debian_sid_arm-sysroot"
use_evdev_gestures = false
use_glib = false
use_gtk = false
use_ozone = true
use_pulseaudio = false
use_system_minigbm = false
use_vc4_minigbm = true
use_xkbcommon = false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can manually edit &lt;code&gt;out/p1/args.gn&lt;/code&gt;.  Make sure to run &lt;code&gt;gn gen out/p1&lt;/code&gt; after making any changes.&lt;/p&gt;

&lt;p&gt;Now you can run &lt;code&gt;ninja&lt;/code&gt; to build chromium executables.  For the first attempt, I recommend to build &lt;code&gt;ozone_demo&lt;/code&gt; for smoke testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ninja &lt;span class="nt"&gt;-C&lt;/span&gt; out/p1 &lt;span class="nt"&gt;-j16&lt;/span&gt; ozone_demo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-jN&lt;/code&gt; specifies the number of parallel build jobs.  The recommended &lt;code&gt;N&lt;/code&gt; setting is the number of CPU threads of the build machine.  &lt;code&gt;ozone_demo&lt;/code&gt; build contains less than 10k targets and it can take several hours depending on the spec of your build machine.&lt;/p&gt;

&lt;p&gt;Each time it builds, you need to bring executable files to your RPi4.  Because there're so many temporary files in the build directory, I use the following shell script &lt;code&gt;pack.sh&lt;/code&gt; to make an archive of files needed on runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

OUTDIR=${1-out/production}
DESTDIR=chromium-${OUTDIR##*/}
ARCHIVE=$DESTDIR.tar.gz

if ! test -d "$OUTDIR"; then
        echo "Not a directory: $OUTDIR"
        exit 1
fi

cd $OUTDIR
rm -rf $DESTDIR $ARCHIVE
mkdir -p $DESTDIR

tar     --exclude $DESTDIR \
        --exclude $ARCHIVE \
        --exclude gen \
        --exclude obj \
        --exclude pyproto \
        --exclude resources \
        --exclude Packages \
        --exclude 'newlib_*' \
        --exclude 'nacl_bootstrap*' \
        --exclude 'glibc_*' \
        --exclude 'clang_*' \
        --exclude 'irt_*' \
        --exclude '*.ninja*' \
        --exclude '*.runtime_deps' \
        --exclude '*.info' \
        --exclude '*.TOC' \
        -cf - . | tar -C $DESTDIR -xf -

tar -czvf $ARCHIVE $DESTDIR
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pack.sh&lt;/code&gt; creates a tar+gz archive in the build directory.  You can transfer it to your RPi4 host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;./pack.sh out/p1
&lt;span class="go"&gt;chromium-p1/
chromium-p1/libEGL.so
chromium-p1/ozone_demo
chromium-p1/libminigbm.so
chromium-p1/gn_logs.txt
chromium-p1/android_clang_arm64/
chromium-p1/icudtl.dat
chromium-p1/libGLESv2.so
chromium-p1/android_clang_arm/
chromium-p1/swiftshader/
chromium-p1/swiftshader/libEGL.so
chromium-p1/swiftshader/libGLESv2.so
chromium-p1/args.gn
&lt;/span&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; out/p1/chromium-p1.tar.gz 
&lt;span class="go"&gt;-rw-rw-r-- 1 yaegashi yaegashi 13M Aug 16 13:49 out/p1/chromium-p1.tar.gz
&lt;/span&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;scp out/p1/chromium-p1.tar.gz pi@raspberrypi.local:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  RPi4 settings
&lt;/h2&gt;

&lt;p&gt;This section is assuming Raspberry Pi 4B running the latest Raspbian 10 as of 2020-08-16.  Tested with RPi4s of RAM 4GB/8GB.&lt;/p&gt;

&lt;p&gt;First, check &lt;code&gt;/boot/config.txt&lt;/code&gt; for &lt;code&gt;dtoverlay=vc4-fkms-v3d&lt;/code&gt; and &lt;code&gt;gpu_mem&lt;/code&gt; with sufficient memory (&amp;gt;256MB) exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d
gpu_mem=256
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With vc4-fkms-v3d enabled, you should be able to see device files in &lt;code&gt;/dev/dri&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /dev/dri
&lt;span class="go"&gt;total 0
drwxr-xr-x  2 root root        100 Aug 16 15:15 by-path
crw-rw----+ 1 root video  226,   0 Aug 16 15:15 card0
crw-rw----+ 1 root video  226,   1 Aug 16 15:15 card1
crw-rw----+ 1 root render 226, 128 Aug 16 15:15 renderD128
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You have to be given permissions to access those devices.  Use &lt;code&gt;adduser&lt;/code&gt; to join &lt;code&gt;video&lt;/code&gt; and &lt;code&gt;render&lt;/code&gt; group, &lt;code&gt;id&lt;/code&gt; to check your current membership:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser pi video
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser pi render
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="go"&gt;... logging in another session
&lt;/span&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;
&lt;span class="go"&gt;uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),107(render),109(netdev),997(gpio),998(i2c),999(spi)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Unfortunately, the latest Raspbian kernel is known to have &lt;a href="https://www.raspberrypi.org/forums/viewtopic.php?f=67&amp;amp;t=280864"&gt;a problem&lt;/a&gt; in the DRM driver with Ozone-GBM as of the time I'm writing this article.  If your Raspberry Pi is already running kernel version 5.4.x or above, you have to downgrade it to version 4.19.118 in the previous release.&lt;/p&gt;

&lt;p&gt;Before downgrading, upgrade every package to the latest version, including Linux kernel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt dist-upgrade
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After reboot, manually downgrade &lt;code&gt;raspberrypi-kernel&lt;/code&gt; package to version 1.20200512-2 acquired from &lt;a href="http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/"&gt;the package repository&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wget http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20200512-2_armhf.deb
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; ./raspberrypi-kernel_1.20200512-2_armhf.deb 
&lt;span class="go"&gt;Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'raspberrypi-kernel' instead of './raspberrypi-kernel_1.20200512-2_armhf.deb'
The following packages will be DOWNGRADED:
  raspberrypi-kernel
0 upgraded, 0 newly installed, 1 downgraded, 0 to remove and 0 not upgraded.
Need to get 0 B/71.7 MB of archives.
After this operation, 1,245 kB disk space will be freed.
Do you want to continue? [Y/n] Y
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;Unpacking raspberrypi-kernel (1.20200512-2) over (1.20200811-1) ...
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After reboot, you should check the running kernel version by &lt;code&gt;uname -a&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="gp"&gt;Linux pi4b2 4.19.118-v7l+ #&lt;/span&gt;1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l GNU/Linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You cannot run Ozone-GBM executables and Raspbian GUI desktop at the same time.  To suspend the desktop, press  Ctrl + Alt + F1 to switch to the VT console.  To return to the desktop, press Alt + ← or → several times to get to VT7.&lt;/p&gt;

&lt;p&gt;Now you're ready to run your first build.  Extract copied archive and run &lt;code&gt;ozone_demo&lt;/code&gt; executable with the following environment variable and command line switches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzvf&lt;/span&gt; chromium-p1.tar.gz
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;chromium-p1
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;EGL_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;surfaceless ./ozone_demo &lt;span class="nt"&gt;--disable-explicit-dma-fences&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If everything goes well, you will be able to see your RPi4 cycling colors in the whole screen.  Press Ctrl + C to stop it.&lt;/p&gt;

&lt;p&gt;When it craches or renders unexpected output, you should collect debug log messages and examine what's going on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;EGL_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;surfaceless &lt;span class="nv"&gt;EGL_LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;debug ./ozone_demo &lt;span class="nt"&gt;--enable-logging&lt;/span&gt; &lt;span class="nt"&gt;--v&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--disable-explicit-dma-fences&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee &lt;/span&gt;debug.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pro Tip: you can run Ozone-GBM executables in the SSH remote sessions, and use &lt;code&gt;chvt&lt;/code&gt; to switch the VT console.  Allocating a new VT (8th or later) is the safer and recommended option.  Switch to 7th VT to return to the desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;chvt 8
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;EGL_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;surfaceless ./ozone_demo &lt;span class="nt"&gt;--disable-explicit-dma-fences&lt;/span&gt;
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;chvt 7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Building and running Chromium
&lt;/h2&gt;

&lt;p&gt;After succesfull smoke testing with &lt;code&gt;ozone_demo&lt;/code&gt;, let's continue bulding the next executable: &lt;code&gt;chrome&lt;/code&gt;, the chromium browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ninja &lt;span class="nt"&gt;-C&lt;/span&gt; out/p1 &lt;span class="nt"&gt;-j16&lt;/span&gt; chrome
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will display to you approx. 50k build targets and it can take 10+ hours to finish.&lt;/p&gt;

&lt;p&gt;When it builds, run again &lt;code&gt;pack.sh&lt;/code&gt; to make a new archive of the build directory and transfer to the RPi4 host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;./pack.sh out/p1
&lt;span class="gp"&gt;(build) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;scp out/p1/chromium-p1.tar.gz pi@raspberrypi.local:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Extract it on RPi4 host and run &lt;code&gt;chrome&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzvf&lt;/span&gt; chromium-p1.tar.gz
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;chromium-p1
&lt;span class="gp"&gt;(pi) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;EGL_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;surfaceless ./chrome &lt;span class="nt"&gt;--force-system-compositor-mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This finally brings you the Chromium browser on Ozone-GBM on RPi4, along with the mocked ChromiumOS desktop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5di0Mgwf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ewpiierumu78c7cdzsu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5di0Mgwf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ewpiierumu78c7cdzsu6.png" alt="Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current status and known problems
&lt;/h2&gt;

&lt;p&gt;Before you actually test it, I have to say we shouldn't expect too much on it for now.  You'll soon realize it's quite buggy, unstable compared to the Raspbian desktop (Xorg) version, and has too many issues to use in production.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always too many flickers on frame updates.  It often gets quite disordered and shows previous frames again.  Compositor problem?&lt;/li&gt;
&lt;li&gt;WebGL is working, not perfect though.

&lt;ul&gt;
&lt;li&gt;Many of &lt;a href="https://threejs.org/examples"&gt;three.js examples&lt;/a&gt; work, but the performance is terribly low with badly noticeable flickers.  &lt;a href="https://www.youtube.com/watch?v=61sEBhJa7k8"&gt;Broken rendering seen in Ozone-Dispmanx on RPi3&lt;/a&gt; gets fixed.&lt;/li&gt;
&lt;li&gt;You can play &lt;a href="https://beta.unity3d.com/jonas/AngryBots/"&gt;AngryBots2 (Unity's demo)&lt;/a&gt;, but it takes so long time to load the scene.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;For &lt;a href="https://youtube.com"&gt;YouTube&lt;/a&gt;, it often suffers intermittent interrupts of playbacks in the beginning of movies before it gets stably smooth.&lt;/li&gt;
&lt;li&gt;The mouse wheel input is not working.&lt;/li&gt;
&lt;li&gt;The keyboard input is also passed to the shell in the active VT console.  The current workaround would be to run on an unused VT console (&lt;code&gt;chvt 8&lt;/code&gt;) from the remote shell.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content_shell&lt;/code&gt; on Ozone-GBM cannot display anything, while the browser instance is running offscreen.  Apparently it's missing event handlers that should set up screens connected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prebuilt binaries for testing
&lt;/h2&gt;

&lt;p&gt;I've uploaded the archive of my build on OneDrive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://1drv.ms/u/s!ArStVFUJcWgSjHOsjfgt21fAB_pD?e=KBP7Vg"&gt;https://1drv.ms/u/s!ArStVFUJcWgSjHOsjfgt21fAB_pD?e=KBP7Vg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Download chromium-p1.tar.gz and test it on your RPi4 if you have interest with Chromium on Ozone-GBM development.  Beware that it won't run on the latest kernel from Raspbian and the special settings is needed.  Read the instruction in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Current Chromium on Ozone-GBM for RPi4 is experimental; it's full of issues and at limited performance, far from production use.  But you can say it's just immature and in the early stage of development, so there's a great margin to improve.&lt;/p&gt;

&lt;p&gt;After deprecation of dispmanx, Ozone-GBM with &lt;a href="https://www.kernel.org/doc/html/latest/gpu/v3d.html"&gt;drm/v3d driver&lt;/a&gt; would be in the right direction for Chromium of embedded use for RPi4, worth for us to make effort.&lt;/p&gt;

&lt;p&gt;I've shared the first step guide for developing and testing Ozone-GBM for RPi4, along with prebuilt binaries.  I'll update this article as needed in future.  Any comments and suggestions to improve Ozone-GBM and this article are much appreciated!&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;I thank people in &lt;a href="https://www.raspberrypi.org/forums/viewforum.php?f=67"&gt;Raspberry Pi's graphics programming forum&lt;/a&gt; for sharing valuable information.&lt;/p&gt;

</description>
      <category>chromium</category>
      <category>raspberrypi</category>
      <category>embedded</category>
    </item>
  </channel>
</rss>
