Skip to content

Commit

Permalink
Merge pull request #1160 from derezzedex/dev/arm-support
Browse files Browse the repository at this point in the history
feat: add support to ARM devices (and older hardware)
  • Loading branch information
hecrj authored Jan 26, 2022
2 parents 4aa943c + 522368e commit 9b3cab8
Show file tree
Hide file tree
Showing 30 changed files with 1,108 additions and 280 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,29 @@ jobs:
with:
name: todos-x86_64-apple-darwin
path: target/release/todos

todos_raspberry:
runs-on: ubuntu-latest
steps:
- uses: hecrj/setup-rust-action@v1
- uses: actions/checkout@master
- name: Install cross
run: cargo install cross
- name: Enable Link Time Optimizations
run: |
echo "[profile.release]" >> Cargo.toml
echo "lto = true" >> Cargo.toml
- name: Build todos binary for Raspberry Pi 3/4 (64 bits)
run: cross build --verbose --release --package todos --target aarch64-unknown-linux-gnu
- name: Archive todos binary
uses: actions/upload-artifact@v1
with:
name: todos-aarch64-unknown-linux-gnu
path: target/aarch64-unknown-linux-gnu/release/todos
- name: Build todos binary for Raspberry Pi 2/3/4 (32 bits)
run: cross build --verbose --release --package todos --target armv7-unknown-linux-gnueabihf
- name: Archive todos binary
uses: actions/upload-artifact@v1
with:
name: todos-armv7-unknown-linux-gnueabihf
path: target/armv7-unknown-linux-gnueabihf/release/todos
7 changes: 7 additions & 0 deletions Cross.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[target.aarch64-unknown-linux-gnu]
image = "icedrs/iced:aarch64"
xargo = false

[target.armv7-unknown-linux-gnueabihf]
image = "icedrs/iced:armv7"
xargo = false
2 changes: 1 addition & 1 deletion ECOSYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The widgets of a _graphical_ user interface produce some primitives that eventua
Currently, there are two different official renderers:

- [`iced_wgpu`] is powered by [`wgpu`] and supports Vulkan, DirectX 12, and Metal.
- [`iced_glow`] is powered by [`glow`] and supports OpenGL 3.3+.
- [`iced_glow`] is powered by [`glow`] and supports OpenGL 2.1+ and OpenGL ES 2.0+.

Additionally, the [`iced_graphics`] subcrate contains a bunch of backend-agnostic types that can be leveraged to build renderers. Both of the renderers rely on the graphical foundations provided by this crate.

Expand Down
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ Inspired by [Elm].
* First-class support for async actions (use futures!)
* [Modular ecosystem] split into reusable parts:
* A [renderer-agnostic native runtime] enabling integration with existing systems
* A [built-in renderer] supporting Vulkan, Metal, DX11, and DX12
* Two [built-in renderers] leveraging [`wgpu`] and [`glow`]
* [`iced_wgpu`] supporting Vulkan, Metal and DX12
* [`iced_glow`] supporting OpenGL 2.1+ and OpenGL ES 2.0+
* A [windowing shell]
* A [web runtime] leveraging the DOM

Expand All @@ -49,7 +51,10 @@ __iced is currently experimental software.__ [Take a look at the roadmap],
[Modular ecosystem]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md
[renderer-agnostic native runtime]: https://github.com/hecrj/iced/tree/master/native
[`wgpu`]: https://github.com/gfx-rs/wgpu-rs
[built-in renderer]: https://github.com/hecrj/iced/tree/master/wgpu
[`glow`]: https://github.com/grovesNL/glow
[`iced_wgpu`]: https://github.com/hecrj/iced/tree/master/wgpu
[`iced_glow`]: https://github.com/hecrj/iced/tree/master/glow
[built-in renderers]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md#Renderers
[windowing shell]: https://github.com/hecrj/iced/tree/master/winit
[`dodrio`]: https://github.com/fitzgen/dodrio
[web runtime]: https://github.com/hecrj/iced/tree/master/web
Expand Down Expand Up @@ -195,6 +200,32 @@ end-user-oriented GUI library, while keeping [the ecosystem] modular:
[`ggez`]: https://github.com/ggez/ggez
[the ecosystem]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md

## Common problems

1. `Error: GraphicsAdapterNotFound`

This occurs when the selected [built-in renderer] is not able to create a context.

Often this will occur while using [`iced_wgpu`] as the renderer without
supported hardware (needs Vulkan, Metal or DX12). In this case, you could try using the
[`iced_glow`] renderer:

First, check if it works with
```console
$ cargo run --features "iced/glow iced/glow_canvas" --package game_of_life
```

and then use it in your project with
```toml
iced = { version = "0.3", default-features = false, features = ["glow"] }
```

**NOTE:** Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0,
but if you don't, right now there's no software fallback, so it means your hardware
doesn't support Iced.

[built-in renderer]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md#Renderers

## Contributing / Feedback
Contributions are greatly appreciated! If you want to contribute, please
read our [contributing guidelines] for more details.
Expand Down
1 change: 1 addition & 0 deletions examples/game_of_life/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
tokio = { version = "1.0", features = ["sync"] }
itertools = "0.9"
rustc-hash = "1.1"
env_logger = "0.9"
2 changes: 2 additions & 0 deletions examples/game_of_life/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use preset::Preset;
use std::time::{Duration, Instant};

pub fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();

GameOfLife::run(Settings {
antialiasing: true,
window: window::Settings {
Expand Down
1 change: 0 additions & 1 deletion examples/integration_opengl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ iced_glutin = { path = "../../glutin" }
iced_glow = { path = "../../glow" }
iced_winit = { path = "../../winit" }
env_logger = "0.8"
glow = "0.6"
11 changes: 5 additions & 6 deletions examples/integration_opengl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ mod scene;
use controls::Controls;
use scene::Scene;

use glow;
use glow::*;
use glutin::dpi::PhysicalPosition;
use glutin::event::{Event, ModifiersState, WindowEvent};
use glutin::event_loop::ControlFlow;
use iced_glow::glow;
use iced_glow::{Backend, Renderer, Settings, Viewport};
use iced_glutin::conversion;
use iced_glutin::glutin;
use iced_glutin::glutin::event::{Event, WindowEvent};
use iced_glutin::glutin::event_loop::ControlFlow;
use iced_glutin::{program, Clipboard, Debug, Size};
use iced_winit::conversion;
use iced_winit::winit;
use winit::{dpi::PhysicalPosition, event::ModifiersState};

pub fn main() {
env_logger::init();
Expand Down
1 change: 1 addition & 0 deletions examples/integration_opengl/src/scene.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use glow::*;
use iced_glow::glow;
use iced_glow::Color;

pub struct Scene {
Expand Down
4 changes: 2 additions & 2 deletions glow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ image = []
svg = []

[dependencies]
glow = "0.6"
glow_glyph = "0.4"
glow = "0.11.1"
glow_glyph = "0.5.0"
glyph_brush = "0.7"
euclid = "0.22"
bytemuck = "1.4"
Expand Down
51 changes: 51 additions & 0 deletions glow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# `iced_glow`
[![Documentation](https://docs.rs/iced_glow/badge.svg)][documentation]
[![Crates.io](https://img.shields.io/crates/v/iced_glow.svg)](https://crates.io/crates/iced_glow)
[![License](https://img.shields.io/crates/l/iced_glow.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)

`iced_glow` is a [`glow`] renderer for [`iced_native`]. This renderer supports OpenGL 3.0+ and OpenGL ES 2.0.

This is renderer is mostly used as a fallback for hardware that doesn't support [`wgpu`] (Vulkan, Metal or DX12).

Currently, `iced_glow` supports the following primitives:
- Text, which is rendered using [`glow_glyph`]. No shaping at all.
- Quads or rectangles, with rounded borders and a solid background color.
- Clip areas, useful to implement scrollables or hide overflowing content.
- Meshes of triangles, useful to draw geometry freely.

<p align="center">
<img alt="The native target" src="../docs/graphs/native.png" width="80%">
</p>

[documentation]: https://docs.rs/iced_glow
[`iced_native`]: ../native
[`glow`]: https://github.com/grovesNL/glow
[`wgpu`]: https://github.com/gfx-rs/wgpu
[`glow_glyph`]: https://github.com/hecrj/glow_glyph

## Installation
Add `iced_glow` as a dependency in your `Cargo.toml`:

```toml
iced_glow = "0.2"
```

__Iced moves fast and the `master` branch can contain breaking changes!__ If
you want to learn about a specific release, check out [the release list].

[the release list]: https://github.com/hecrj/iced/releases

## Current limitations

The current implementation is quite naive, it uses:

- A different pipeline/shader for each primitive
- A very simplistic layer model: every `Clip` primitive will generate new layers
- _Many_ render passes instead of preparing everything upfront
- A glyph cache that is trimmed incorrectly when there are multiple layers (a [`glyph_brush`] limitation)

Some of these issues are already being worked on! If you want to help, [get in touch!]

[get in touch!]: ../CONTRIBUTING.md
[`glyph_brush`]: https://github.com/alexheretic/glyph-brush
7 changes: 5 additions & 2 deletions glow/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::program;
use crate::quad;
use crate::text;
use crate::triangle;
Expand Down Expand Up @@ -30,8 +31,10 @@ impl Backend {
settings.text_multithreading,
);

let quad_pipeline = quad::Pipeline::new(gl);
let triangle_pipeline = triangle::Pipeline::new(gl);
let shader_version = program::Version::new(gl);

let quad_pipeline = quad::Pipeline::new(gl, &shader_version);
let triangle_pipeline = triangle::Pipeline::new(gl, &shader_version);

Self {
quad_pipeline,
Expand Down
2 changes: 2 additions & 0 deletions glow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#![forbid(rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg))]

pub use glow;

mod backend;
mod program;
mod quad;
Expand Down
130 changes: 112 additions & 18 deletions glow/src/program.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,122 @@
use glow::HasContext;

pub unsafe fn create(
gl: &glow::Context,
shader_sources: &[(u32, &str)],
) -> <glow::Context as HasContext>::Program {
let program = gl.create_program().expect("Cannot create program");
/// The [`Version`] of a `Program`.
pub struct Version {
vertex: String,
fragment: String,
}

impl Version {
pub fn new(gl: &glow::Context) -> Version {
let version = gl.version();

let (vertex, fragment) = match (
version.major,
version.minor,
version.is_embedded,
) {
// OpenGL 3.0+
(3, 0 | 1 | 2, false) => (
format!("#version 1{}0", version.minor + 3),
format!(
"#version 1{}0\n#define HIGHER_THAN_300 1",
version.minor + 3
),
),
// OpenGL 3.3+
(3 | 4, _, false) => (
format!("#version {}{}0", version.major, version.minor),
format!(
"#version {}{}0\n#define HIGHER_THAN_300 1",
version.major, version.minor
),
),
// OpenGL ES 3.0+
(3, _, true) => (
format!("#version 3{}0 es", version.minor),
format!(
"#version 3{}0 es\n#define HIGHER_THAN_300 1",
version.minor
),
),
// OpenGL ES 2.0+
(2, _, true) => (
String::from(
"#version 100\n#define in attribute\n#define out varying",
),
String::from("#version 100\n#define in varying"),
),
// OpenGL 2.1
(2, _, false) => (
String::from(
"#version 120\n#define in attribute\n#define out varying",
),
String::from("#version 120\n#define in varying"),
),
// OpenGL 1.1+
_ => panic!("Incompatible context version: {:?}", version),
};

let mut shaders = Vec::with_capacity(shader_sources.len());
log::info!("Shader directive: {}", vertex.lines().next().unwrap());

for (shader_type, shader_source) in shader_sources.iter() {
let shader = gl
.create_shader(*shader_type)
.expect("Cannot create shader");
Version { vertex, fragment }
}
}

pub struct Shader(<glow::Context as HasContext>::Shader);

impl Shader {
fn compile(gl: &glow::Context, stage: u32, content: &str) -> Shader {
unsafe {
let shader = gl.create_shader(stage).expect("Cannot create shader");

gl.shader_source(shader, shader_source);
gl.compile_shader(shader);
gl.shader_source(shader, &content);
gl.compile_shader(shader);

if !gl.get_shader_compile_status(shader) {
panic!("{}", gl.get_shader_info_log(shader));
if !gl.get_shader_compile_status(shader) {
panic!("{}", gl.get_shader_info_log(shader));
}

Shader(shader)
}
}

/// Creates a vertex [`Shader`].
pub fn vertex(
gl: &glow::Context,
version: &Version,
content: &'static str,
) -> Self {
let content = format!("{}\n{}", version.vertex, content);

gl.attach_shader(program, shader);
Shader::compile(gl, glow::VERTEX_SHADER, &content)
}

/// Creates a fragment [`Shader`].
pub fn fragment(
gl: &glow::Context,
version: &Version,
content: &'static str,
) -> Self {
let content = format!("{}\n{}", version.fragment, content);

Shader::compile(gl, glow::FRAGMENT_SHADER, &content)
}
}

pub unsafe fn create(
gl: &glow::Context,
shaders: &[Shader],
attributes: &[(u32, &str)],
) -> <glow::Context as HasContext>::Program {
let program = gl.create_program().expect("Cannot create program");

for shader in shaders {
gl.attach_shader(program, shader.0);
}

shaders.push(shader);
for (i, name) in attributes {
gl.bind_attrib_location(program, *i, name);
}

gl.link_program(program);
Expand All @@ -31,8 +125,8 @@ pub unsafe fn create(
}

for shader in shaders {
gl.detach_shader(program, shader);
gl.delete_shader(shader);
gl.detach_shader(program, shader.0);
gl.delete_shader(shader.0);
}

program
Expand Down
Loading

0 comments on commit 9b3cab8

Please sign in to comment.