Skip to content

Commit

Permalink
Merge branch 'main' into vello-pr-722
Browse files Browse the repository at this point in the history
  • Loading branch information
yutannihilation committed Oct 31, 2024
2 parents 49af822 + da7de81 commit 5afd139
Show file tree
Hide file tree
Showing 30 changed files with 1,376 additions and 601 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
^src/rust/target$
^\.github$
^LICENSE\.md$

^src/rust/.vscode$
4 changes: 2 additions & 2 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
workspaces: src/rust
prefix-key: "v2-rust"
prefix-key: "v3-rust"

- uses: r-lib/actions/check-r-package@v2
with:
upload-results: 'never'
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'

- name: show install log
if: always()
run: |
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: vellogd
Title: 'Vello' Graphics Device For R
Title: A GPU-powered Interactive Graphics Device
Version: 0.0.0.9000
Authors@R:
c(person(given = "Hiroaki",
Expand Down
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Generated by roxygen2: do not edit by hand

S3method("$<-",savvy_vellogd__sealed)
S3method("[[<-",savvy_vellogd__sealed)
export(vellogd)
export(vellogd_with_server)
useDynLib(vellogd, .registration = TRUE)
14 changes: 14 additions & 0 deletions R/000-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ NULL
}
}

# Prohibit modifying environments

#' @export
`$<-.savvy_vellogd__sealed` <- function(x, name, value) {
class <- gsub("__bundle$", "", class(x)[1])
stop(class, " cannot be modified", call. = FALSE)
}

#' @export
`[[<-.savvy_vellogd__sealed` <- function(x, i, value) {
class <- gsub("__bundle$", "", class(x)[1])
stop(class, " cannot be modified", call. = FALSE)
}


`vellogd_impl` <- function(`filename`, `width`, `height`) {
invisible(.Call(savvy_vellogd_impl__impl, `filename`, `width`, `height`))
Expand Down
8 changes: 8 additions & 0 deletions R/vellogd-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#' A GPU-powered Interactive Graphics Device for R
#'
#' @keywords internal
"_PACKAGE"

## usethis namespace: start
## usethis namespace: end
NULL
76 changes: 60 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
vellogd: A Vello Graphics Device for R
======================================
vellogd: A GPU-powered Interactive Graphics Device for R
========================================================

[![R-CMD-check.yaml](https://github.com/yutannihilation/vellogd-r/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/yutannihilation/vellogd-r/actions/workflows/R-CMD-check.yaml)
[![vellogd status badge](https://yutannihilation.r-universe.dev/badges/vellogd)](https://yutannihilation.r-universe.dev/vellogd)

Vellogd is an experimental graphics device for R. It relies on these Rust crates:

* [vello]: Cross-platform 2D rendering engine with GPU
* [parley]: Rich text-layout
* [winit]: Cross-platform window management
Vellogd is an experimental graphics device for R. This is powered by [vello], a
cross-platform 2D rendering engine with GPU.

[vello]: https://github.com/linebender/vello
[parley]: https://github.com/linebender/parley
[winit]: https://docs.rs/winit/latest/winit/

# Why yet another graphics device?

You might wonder why we need vellogd while there are already high-quality,
cross-platform graphics devices like [ragg] and [svglite]. Behind vellogd, I
have mainly two motivations.

[ragg]: https://ragg.r-lib.org/
[svglite]: https://svglite.r-lib.org/

## "Interactive" graphics device with extra features

As far as I know, there's no cross-platform and **interactive** graphics device.
R provides interactive graphics devices, but they are not really cross-platform.
They are implemented differently, which makes some features missing on some
platform (e.g. [X11 on Windows doesn't provide `onIdle` event][coolbutuseless]).

[coolbutuseless]: https://coolbutuseless.github.io/2022/05/06/introducing-eventloop-realtime-interactive-rendering-in-r/

What's more exciting about crafting a new graphics device is, we might be able
to implement extra features beyond R's graphics API. What do you want an
interactive graphics device to be? Here's my wishlist, for example.

* Zoom in and out by mousewheel
* Support touch device
* Provide an API for [Lottie animation](https://airbnb.io/lottie/)
* Provide an API to draw a bezier curve (why R provides no API...?)

## A showcase of the power of WebGPU

One more thing I feel a bit frustrating about R's graphics ecosystem is, it's
too CPU-centric. I'm not an expert of GPU, but I think R can utilize the power
of GPU a lot more.

I understand it's difficult to use GPU in an R package because different
platforms and different vendors require different implementation. However, now
we have [**the WebGPU standard**](https://gpuweb.github.io/gpuweb/) and the
cross-platform implemntations of the API in C++ ([dawn], used by Chrome) and
Rust ([wgpu], used by Firefox and Deno).

[dawn]: https://dawn.googlesource.com/dawn/+/refs/heads/chromium-gpu-experimental/README.md
[wgpu]: https://wgpu.rs/

Unlike the name indicates, WebGPU is not only for web. It's a GPU-powered
graphics API, which is so **portable and safe** that it can be used on web
browsers. So, if you want to create a cross-platform R package using GPU, WebGPU
can be the best choice. I hope vellogd servers as a showcase of such an attempt.

(Personally, I'm hoping rayshader will use WebGPU!)

# Installation

Expand Down Expand Up @@ -80,7 +124,7 @@ cf. <https://github.com/r-devel/r-svn/blob/main/src/include/R_ext/GraphicsDevice
| `close` || |
| `newPage` || |
| `size` || |
| `mode` || TODO: server side |
| `mode` || TODO: server version |
| `newFrameConfirm` || Do nothing |
| `holdflush` | | |
| `locator` | | |
Expand All @@ -94,14 +138,14 @@ cf. <https://github.com/r-devel/r-svn/blob/main/src/include/R_ext/GraphicsDevice
| `raster` || TODO: server version, non-interpolated version |
| `metricInfo` || |
| `strWidth` || |
| `text` || (Partially supported) |
| `textUTF8` || (Partially supported) |
| `glyph` | | |
| `text` || |
| `textUTF8` || |
| `glyph` | | TODO: server version |
| `clip` || TODO: server version, can I hide the clipping rectangle? |
| `cap` | | |
| `eventHelper` | | |
| `setPattern` | | |
| `releasePattern` | | |
| `setPattern` | | TODO: tiling, fix #24 |
| `releasePattern` | | TODO: tiling, fix #24 |
| `setClipPath` | | |
| `releaseClipPath` | | |
| `setMask` | | |
Expand All @@ -112,7 +156,7 @@ cf. <https://github.com/r-devel/r-svn/blob/main/src/include/R_ext/GraphicsDevice
| `stroke` | | |
| `fill` | | |
| `fillStroke` | | |
| `capabilities` | | |
| `capabilities` | | |

[`kurbo::Line`]: https://docs.rs/kurbo/latest/kurbo/struct.Line.html
[`kurbo::Circle`]: https://docs.rs/kurbo/latest/kurbo/struct.Circle.html
Expand Down
9 changes: 9 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,17 @@ else
FEATURES="--features use_winit"
fi

# catch DEBUG envvar, which is passed from pkgbuild::compile_dll()
if [ "${DEBUG}" = "true" ]; then
FEATURES="${FEATURES} --features tracing"
PROFILE=dev
else
PROFILE=release
fi

sed \
-e "s/@TARGET@/${TARGET}/" \
-e "s/@PROFILE@/${PROFILE}/" \
-e "s/@FEATURES@/${FEATURES}/" \
-e "s/@ADDITIONAL_PKG_LIBS@/${ADDITIONAL_PKG_LIBS}/" \
-e "s|@CARGO_TARGET_DIR@|${CARGO_TARGET_DIR}|" \
Expand Down
12 changes: 10 additions & 2 deletions configure.win
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ RUSTC_VERSION="$(rustc --version || true)"
echo "using Rust package manager: '${CARGO_VERSION}'"
echo "using Rust compiler: '${RUSTC_VERSION}'"

# catch DEBUG envvar, which is passed from pkgbuild::compile_dll()
if [ "${DEBUG}" = "true" ]; then
FEATURES="--features use_winit --features tracing"
PROFILE=dev
else
FEATURES="--features use_winit"
PROFILE=release
fi

# In order to use rust-cache action, target dir needs to be a fixed, existing path.
if [ -d "${GITHUB_WORKSPACE}" ]; then
CARGO_TARGET_DIR=$(echo "${GITHUB_WORKSPACE}/src/rust/target" | sed -e 's|\\|/|g') # normalize path
Expand All @@ -29,10 +38,9 @@ else
CARGO_TARGET_DIR='$(CURDIR)/rust/target'
fi

FEATURES="--features use_winit"

sed \
-e "s/@TARGET@/x86_64-pc-windows-gnu/" \
-e "s/@PROFILE@/${PROFILE}/" \
-e "s/@FEATURES@/${FEATURES}/" \
-e "s|@CARGO_TARGET_DIR@|${CARGO_TARGET_DIR}|" \
src/Makevars.win.in > src/Makevars.win
19 changes: 19 additions & 0 deletions man/vellogd-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions src/Makevars.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
TARGET = @TARGET@

# catch DEBUG envvar, which is passed from pkgbuild::compile_dll()
PROFILE = $(subst x,release,$(subst truex,dev,$(DEBUG)x))
TRACING = $(subst x,,$(subst truex,--features tracing,$(DEBUG)x))
FEATURES = @FEATURES@ $(TRACING)
PROFILE = @PROFILE@
FEATURES = @FEATURES@

TARGET_DIR = @CARGO_TARGET_DIR@
LIBDIR = $(TARGET_DIR)/$(TARGET)/$(subst dev,debug,$(PROFILE))
Expand Down
6 changes: 2 additions & 4 deletions src/Makevars.win.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
TARGET = @TARGET@

# catch DEBUG envvar, which is passed from pkgbuild::compile_dll()
PROFILE = $(subst x,release,$(subst truex,dev,$(DEBUG)x))
TRACING = $(subst x,,$(subst truex,--features tracing,$(DEBUG)x))
FEATURES = @FEATURES@ $(TRACING)
PROFILE = @PROFILE@
FEATURES = @FEATURES@

TARGET_DIR = @CARGO_TARGET_DIR@
LIBDIR = $(TARGET_DIR)/$(TARGET)/$(subst dev,debug,$(PROFILE))
Expand Down
16 changes: 8 additions & 8 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use_winit = ["winit", "vellogd-shared/use_winit"]

[dependencies]
libc = "0.2.155"
savvy = "*"
savvy = "0.8.0"
vellogd-shared.workspace = true
vello.workspace = true
peniko.workspace = true
Expand Down Expand Up @@ -49,8 +49,6 @@ fastrace = { version = "0.7", features = ["enable"] }
peniko = { version = "*", default-features = false, features = ["serde"] }
kurbo = { version = "*", default-features = false, features = ["serde"] }

anyhow = "1.0"

[profile.release]
# By default, on release build, savvy terminates the R session when a panic
# occurs. This is the right behavior in that a panic means such a fatal event
Expand Down
Loading

0 comments on commit 5afd139

Please sign in to comment.