mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Upgrade WebRender to e491e1ae637b2eed1e7195855d88357e5eb3ddf9 (#30323)
* Upgrade vendored version of WebRender * Patch WebRender: upgrade version of gleam * Restore hit testing implementation * Fix WebRender warnings * Adapt Servo to new WebRender * Update results * Add a workaround for #30313 This slightly expands text boundaries in order to take into account the fact that layout isn't measuring glyph boundaries.
This commit is contained in:
parent
c079acb3c3
commit
a9d37cb85a
563 changed files with 48524 additions and 51657 deletions
1752
third_party/webrender/Cargo.lock
generated
vendored
1752
third_party/webrender/Cargo.lock
generated
vendored
File diff suppressed because it is too large
Load diff
10
third_party/webrender/Cargo.toml
vendored
10
third_party/webrender/Cargo.toml
vendored
|
@ -1,6 +1,5 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"direct-composition",
|
||||
"examples",
|
||||
"webrender",
|
||||
"webrender_api",
|
||||
|
@ -16,6 +15,13 @@ panic = "abort"
|
|||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
# optimizing glsl more makes a big difference in swgl build times
|
||||
[profile.dev.package.glsl]
|
||||
opt-level = 2
|
||||
|
||||
[profile.release.package.glsl]
|
||||
opt-level = 2
|
||||
|
||||
# Running wrench on android built with master cargo-apk results in a crash
|
||||
# due to a mismatched version of android_glue (a dependency of winit).
|
||||
# Override it to use a suitable version of android_glue.
|
||||
|
@ -23,3 +29,5 @@ panic = "abort"
|
|||
# This can be removed once a new version of android_glue is published to crates.io.
|
||||
[patch.crates-io]
|
||||
android_glue = { git = "https://github.com/rust-windowing/android-rs-glue.git", rev = "e3ac6edea5814e1faca0c31ea8fac6877cb929ea" }
|
||||
# this is a version that fixes some incompatibilites with newer rust/aarch64
|
||||
winit = { version = "0.19", git = "https://github.com/jrmuizel/winit", branch="wr" }
|
||||
|
|
|
@ -14,15 +14,19 @@ test "$(whoami)" == 'root'
|
|||
# Install stuff we need
|
||||
apt-get -y update
|
||||
apt-get install -y \
|
||||
bison \
|
||||
bzip2 \
|
||||
cmake \
|
||||
curl \
|
||||
flex \
|
||||
gcc \
|
||||
git \
|
||||
g++ \
|
||||
libfontconfig1-dev \
|
||||
libgl1-mesa-dev \
|
||||
libx11-dev \
|
||||
llvm-dev \
|
||||
ninja-build \
|
||||
openjdk-8-jdk \
|
||||
pkg-config \
|
||||
python \
|
||||
|
@ -31,7 +35,10 @@ apt-get install -y \
|
|||
python-setuptools \
|
||||
python-voluptuous \
|
||||
python-yaml \
|
||||
software-properties-common
|
||||
python3-pip \
|
||||
python3-mako \
|
||||
software-properties-common \
|
||||
clang
|
||||
|
||||
# Other stuff we need
|
||||
pip install servo-tidy==0.3.0
|
||||
|
|
18
third_party/webrender/ci-scripts/etc/wr-darwin.meson
vendored
Normal file
18
third_party/webrender/ci-scripts/etc/wr-darwin.meson
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
[binaries]
|
||||
llvm-config = '/builds/worker/fetches/clang/bin/llvm-config'
|
||||
|
||||
[properties]
|
||||
# When linking `libOSMesa.dylib` Meson uses options provided by `llvm-config`.
|
||||
# The binary for `llvm-config` in Firefox CI comes from a native Linux clang,
|
||||
# which gives the link options for the Linux libLLVM-11.so in the Linux clang.
|
||||
# However, we want to link against a native macOS clang's libLLVM.dylib, which
|
||||
# we have available in a separate directory.
|
||||
# Meson will still have -lLLVM-11 on the command line, but the linker will
|
||||
# only warn that it has the wrong format (because it's not for macOS).
|
||||
cpp_link_args = ['-L/builds/worker/fetches/clang-mac/clang/lib', '-lLLVM']
|
||||
|
||||
[host_machine]
|
||||
system = 'darwin'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'i686'
|
||||
endian = 'little'
|
22
third_party/webrender/ci-scripts/install-meson.sh
vendored
Executable file
22
third_party/webrender/ci-scripts/install-meson.sh
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
# This file downloads and installs meson which is required for building
|
||||
# osmesa-src, a dependency of wrench.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
MESON_VER=0.55.1
|
||||
MESON_BASE_URL="https://github.com/mesonbuild/meson/releases/download"
|
||||
|
||||
curl -L ${MESON_BASE_URL}/${MESON_VER}/meson-${MESON_VER}.tar.gz -o meson.tar.gz
|
||||
tar -xf meson.tar.gz
|
||||
mv meson-${MESON_VER} meson
|
||||
cd meson
|
||||
ln -s meson.py meson
|
|
@ -32,5 +32,5 @@ cargo build ${CARGOFLAGS}
|
|||
popd
|
||||
|
||||
cargo test ${CARGOFLAGS} \
|
||||
--all --exclude compositor-windows --exclude compositor \
|
||||
--exclude glsl-to-cxx --exclude swgl
|
||||
--all --exclude compositor --exclude compositor-wayland \
|
||||
--exclude compositor-windows --exclude glsl-to-cxx --exclude swgl
|
||||
|
|
|
@ -16,7 +16,13 @@ set -o xtrace
|
|||
CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
||||
|
||||
pushd wrench
|
||||
# Test that all shaders compile successfully.
|
||||
python script/headless.py --precache test_init
|
||||
python script/headless.py --precache --use-unoptimized-shaders test_init
|
||||
|
||||
python script/headless.py reftest
|
||||
python script/headless.py rawtest
|
||||
cargo build ${CARGOFLAGS} --release
|
||||
python script/headless.py test_invalidation
|
||||
CXX=clang++ cargo run ${CARGOFLAGS} --release --features=software -- \
|
||||
--software --headless reftest
|
||||
popd
|
||||
|
|
|
@ -38,5 +38,5 @@ cargo check ${CARGOFLAGS}
|
|||
popd
|
||||
|
||||
cargo test ${CARGOFLAGS} ${CARGOTESTFLAGS} \
|
||||
--all --exclude compositor-windows --exclude compositor \
|
||||
--exclude glsl-to-cxx --exclude swgl
|
||||
--all --exclude compositor --exclude compositor-wayland \
|
||||
--exclude compositor-windows --exclude glsl-to-cxx --exclude swgl
|
||||
|
|
|
@ -19,7 +19,13 @@ CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
|||
WRENCH_BINARY=${WRENCH_BINARY:-""}
|
||||
|
||||
pushd wrench
|
||||
|
||||
# Test that all shaders compile successfully.
|
||||
python script/headless.py --precache test_init
|
||||
python script/headless.py --precache --use-unoptimized-shaders test_init
|
||||
|
||||
python script/headless.py reftest
|
||||
python script/headless.py test_invalidation
|
||||
if [[ -z "${WRENCH_BINARY}" ]]; then
|
||||
cargo build ${CARGOFLAGS} --release
|
||||
WRENCH_BINARY="../target/release/wrench"
|
||||
|
|
|
@ -21,6 +21,13 @@ popd
|
|||
pushd wrench
|
||||
cargo test --verbose
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
:: Test that all shaders compile successfully. --precache compiles all shaders
|
||||
:: during initialization, therefore if init is successful then the shaders compile.
|
||||
cargo run --release -- --angle --precache test_init
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
cargo run --release -- --angle --precache --use-unoptimized-shaders test_init
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
|
||||
cargo run --release -- --angle reftest
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
@ -29,8 +36,3 @@ pushd examples
|
|||
cargo check --verbose
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
||||
pushd direct-composition
|
||||
cargo check --verbose
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
|
6
third_party/webrender/debugger/.babelrc
vendored
6
third_party/webrender/debugger/.babelrc
vendored
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"presets": [
|
||||
["env", { "modules": false }],
|
||||
"stage-3"
|
||||
]
|
||||
}
|
11
third_party/webrender/debugger/.gitignore
vendored
11
third_party/webrender/debugger/.gitignore
vendored
|
@ -1,11 +0,0 @@
|
|||
.DS_Store
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
23
third_party/webrender/debugger/README.md
vendored
23
third_party/webrender/debugger/README.md
vendored
|
@ -1,23 +0,0 @@
|
|||
# WebRender Debugger
|
||||
A web based debugger for WebRender.
|
||||
|
||||
## Using the debugger
|
||||
Build your application with the debugger feature enabled, for example in wrench:
|
||||
|
||||
```
|
||||
cargo build --features=debugger
|
||||
```
|
||||
|
||||
Now, open your browser and open the debugger/index.html file. Click Connect and
|
||||
the debugger will attempt to connect to WR via websocket.
|
||||
|
||||
## Using the debugger with Gecko
|
||||
|
||||
In the Gecko source tree, open ```gfx/webrender_bindings/Cargo.toml``` in a text editor.
|
||||
|
||||
Add ```features = ['debugger']``` to the end of the file (in the ```dependencies.webrender``` section).
|
||||
|
||||
Vendor the rust dependencies locally for the debugger (we don't want these committed to the repo):
|
||||
```./mach vendor rust```
|
||||
|
||||
Now, build and run as usual, and the debugger will be available.
|
13
third_party/webrender/debugger/dist/build.js
vendored
13
third_party/webrender/debugger/dist/build.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
third_party/webrender/debugger/index.html
vendored
11
third_party/webrender/debugger/index.html
vendored
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebRender Debugger</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="dist/build.js"></script>
|
||||
</body>
|
||||
</html>
|
7606
third_party/webrender/debugger/package-lock.json
generated
vendored
7606
third_party/webrender/debugger/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load diff
36
third_party/webrender/debugger/package.json
vendored
36
third_party/webrender/debugger/package.json
vendored
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"name": "debugger",
|
||||
"description": "WebRender Debugger",
|
||||
"version": "1.0.0",
|
||||
"author": "Glenn Watson <github@intuitionlibrary.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
|
||||
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"buefy": "^0.6.7",
|
||||
"vue": "^2.5.11",
|
||||
"vue-material-design-icons": "^0.8.2",
|
||||
"vuex": "^3.0.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
],
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-stage-3": "^6.24.1",
|
||||
"cross-env": "^5.0.5",
|
||||
"css-loader": "^0.28.7",
|
||||
"file-loader": "^1.1.4",
|
||||
"vue-loader": "^13.0.5",
|
||||
"vue-template-compiler": "^2.4.4",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-dev-server": "^2.9.1"
|
||||
}
|
||||
}
|
55
third_party/webrender/debugger/src/App.vue
vendored
55
third_party/webrender/debugger/src/App.vue
vendored
|
@ -1,55 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-navbar></app-navbar>
|
||||
<div class="section">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-3">
|
||||
<app-navmenu></app-navmenu>
|
||||
</div>
|
||||
<div class="column">
|
||||
<app-options v-if="page == 'options'"></app-options>
|
||||
<app-passview v-if="page == 'passes'"></app-passview>
|
||||
<app-rendertaskview v-if="page == 'render_tasks'"></app-rendertaskview>
|
||||
<app-documentview v-if="page == 'documents'"></app-documentview>
|
||||
<app-clipscrolltreeview v-if="page == 'clip_scroll_tree'"></app-clipscrolltreeview>
|
||||
<app-screenshotview v-if="page == 'screenshot'"></app-screenshotview>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavBar from './components/NavBar.vue'
|
||||
import NavMenu from './components/NavMenu.vue'
|
||||
import OptionsPage from './components/OptionsPage.vue'
|
||||
import PassViewPage from './components/PassViewPage.vue'
|
||||
import RenderTaskViewPage from './components/RenderTaskViewPage.vue'
|
||||
import DocumentViewPage from './components/DocumentViewPage.vue'
|
||||
import ClipScrollTreeViewPage from './components/ClipScrollTreeViewPage.vue'
|
||||
import ScreenshotPage from './components/ScreenshotPage.vue'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
'app-navbar': NavBar,
|
||||
'app-navmenu': NavMenu,
|
||||
'app-options': OptionsPage,
|
||||
'app-passview': PassViewPage,
|
||||
'app-rendertaskview': RenderTaskViewPage,
|
||||
'app-documentview': DocumentViewPage,
|
||||
'app-clipscrolltreeview': ClipScrollTreeViewPage,
|
||||
'app-screenshotview': ScreenshotPage,
|
||||
},
|
||||
computed: {
|
||||
page() {
|
||||
return this.$store.state.page;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h1 class="title">Clip-Scroll Tree <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||
<hr/>
|
||||
<div>
|
||||
<ul>
|
||||
<app-treeview :model=clip_scroll_tree></app-treeview>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TreeView from './TreeView.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'app-treeview': TreeView,
|
||||
},
|
||||
methods: {
|
||||
fetch: function() {
|
||||
this.$store.dispatch('sendMessage', "fetch_clip_scroll_tree");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
},
|
||||
clip_scroll_tree() {
|
||||
return this.$store.state.clip_scroll_tree
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h1 class="title">Documents <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||
<hr/>
|
||||
<div>
|
||||
<ul>
|
||||
<app-treeview :model=documents></app-treeview>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TreeView from './TreeView.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'app-treeview': TreeView,
|
||||
},
|
||||
methods: {
|
||||
fetch: function() {
|
||||
this.$store.dispatch('sendMessage', "fetch_documents");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
},
|
||||
documents() {
|
||||
return this.$store.state.documents
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,41 +0,0 @@
|
|||
<template>
|
||||
<nav class="navbar has-shadow">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="#">WebRender Debugger</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start"></div>
|
||||
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<p class="control">
|
||||
<button v-if="isConnected" @click="disconnect" class="button is-danger">Disconnect</button>
|
||||
<button v-else @click="connect" class="button is-success">Connect</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
isConnected() {
|
||||
return this.$store.state.connected;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
connect() {
|
||||
this.$store.dispatch('connect');
|
||||
},
|
||||
disconnect() {
|
||||
this.$store.dispatch('disconnect');
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,33 +0,0 @@
|
|||
<template>
|
||||
<aside class="menu">
|
||||
<p class="menu-label">
|
||||
Pages
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li><a @click="setPage('options')" :class="{ 'is-active': page == 'options' }">Debug Options</a></li>
|
||||
<li><a @click="setPage('passes')" :class="{ 'is-active': page == 'passes' }">Passes</a></li>
|
||||
<li><a @click="setPage('render_tasks')" :class="{ 'is-active': page == 'render_tasks' }">Render Tasks</a></li>
|
||||
<li><a @click="setPage('documents')" :class="{ 'is-active': page == 'documents' }">Documents</a></li>
|
||||
<li><a @click="setPage('clip_scroll_tree')" v-bind:class="{ 'is-active': page == 'clip_scroll_tree' }">Clip-Scroll Tree</a></li>
|
||||
<li><a @click="setPage('screenshot')" v-bind:class="{ 'is-active': page == 'screenshot' }">Screenshot</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
setPage(name) {
|
||||
this.$store.commit('setPage', name);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
page() {
|
||||
return this.$store.state.page;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,162 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setProfiler($event.target.checked)">
|
||||
Profiler
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setTextureCacheDebugger($event.target.checked)">
|
||||
Texture cache debugger
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setRenderTargetDebugger($event.target.checked)">
|
||||
Render target debugger
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setAlphaRectsDebugger($event.target.checked)">
|
||||
Alpha primitive rects debugger
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setGpuTimeQueries($event.target.checked)">
|
||||
Enable GPU time queries
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setGpuSampleQueries($event.target.checked)">
|
||||
Enable GPU sample queries
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setOpaquePass(!$event.target.checked)">
|
||||
Disable opaque pass
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setAlphaPass(!$event.target.checked)">
|
||||
Disable alpha pass
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setClipMasks(!$event.target.checked)">
|
||||
Disable clip masks
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setTextPrims(!$event.target.checked)">
|
||||
Disable text primitives
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :disabled="disabled" v-on:click="setGradientPrims(!$event.target.checked)">
|
||||
Disable gradient primitives
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setProfiler(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_profiler");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_profiler");
|
||||
}
|
||||
},
|
||||
setTextureCacheDebugger(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_texture_cache_debug");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_texture_cache_debug");
|
||||
}
|
||||
},
|
||||
setRenderTargetDebugger(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_render_target_debug");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_render_target_debug");
|
||||
}
|
||||
},
|
||||
setAlphaRectsDebugger(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_alpha_rects_debug");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_alpha_rects_debug");
|
||||
}
|
||||
},
|
||||
setGpuTimeQueries(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_gpu_time_queries");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_gpu_time_queries");
|
||||
}
|
||||
},
|
||||
setGpuSampleQueries(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_gpu_sample_queries");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_gpu_sample_queries");
|
||||
}
|
||||
},
|
||||
setOpaquePass(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_opaque_pass");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_opaque_pass");
|
||||
}
|
||||
},
|
||||
setAlphaPass(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_alpha_pass");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_alpha_pass");
|
||||
}
|
||||
},
|
||||
setClipMasks(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_clip_masks");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_clip_masks");
|
||||
}
|
||||
},
|
||||
setTextPrims(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_text_prims");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_text_prims");
|
||||
}
|
||||
},
|
||||
setGradientPrims(enabled) {
|
||||
if (enabled) {
|
||||
this.$store.dispatch('sendMessage', "enable_gradient_prims");
|
||||
} else {
|
||||
this.$store.dispatch('sendMessage', "disable_gradient_prims");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h1 class="title">Passes <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||
<hr/>
|
||||
<div v-for="(pass, pass_index) in passes">
|
||||
<p class="has-text-black-bis">Pass {{pass_index}}</p>
|
||||
<div v-for="(target, target_index) in pass.targets">
|
||||
<p style="text-indent: 2em;" class="has-text-grey-dark">Target {{target_index}} ({{target.kind}})</p>
|
||||
<div v-for="(batch, batch_index) in target.batches">
|
||||
<p style="text-indent: 4em;" class="has-text-grey">Batch {{batch_index}} ({{batch.description}}, {{batch.kind}}, {{batch.count}} instances)</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
fetch: function() {
|
||||
this.$store.dispatch('sendMessage', "fetch_passes");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
},
|
||||
passes() {
|
||||
return this.$store.state.passes
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h1 class="title">Render Tasks <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||
<hr/>
|
||||
<div>
|
||||
<ul>
|
||||
<app-treeview :model=render_tasks></app-treeview>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TreeView from './TreeView.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'app-treeview': TreeView,
|
||||
},
|
||||
methods: {
|
||||
fetch: function() {
|
||||
this.$store.dispatch('sendMessage', "fetch_render_tasks");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
},
|
||||
render_tasks() {
|
||||
return this.$store.state.render_tasks
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,32 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h1 class="title">Screenshot <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||
<hr/>
|
||||
<div>
|
||||
<ul>
|
||||
<img v-if="screenshot.length > 0" style="transform: scaleY(-1); width: 1024px; height:768px" :src="'data:image/png;base64,' + screenshot" />
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
disabled() {
|
||||
return !this.$store.state.connected
|
||||
},
|
||||
screenshot() {
|
||||
return this.$store.state.screenshot
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetch: function() {
|
||||
this.$store.dispatch('sendMessage', "fetch_screenshot");
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,40 +0,0 @@
|
|||
<template>
|
||||
<li>
|
||||
<div v-on:click="toggle">
|
||||
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
|
||||
{{model.description}}
|
||||
</div>
|
||||
<ul style="padding-left: 1em; line-height: 1.5em;" v-show="open" v-if="isFolder">
|
||||
<treeview v-for="model in model.children" :model="model"></treeview>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'treeview',
|
||||
props: [
|
||||
'model',
|
||||
],
|
||||
data: function () {
|
||||
return {
|
||||
open: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isFolder: function () {
|
||||
return this.model.children && this.model.children.length
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle: function () {
|
||||
if (this.isFolder) {
|
||||
this.open = !this.open
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
14
third_party/webrender/debugger/src/main.js
vendored
14
third_party/webrender/debugger/src/main.js
vendored
|
@ -1,14 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import Buefy from 'buefy';
|
||||
import 'buefy/dist/buefy.css';
|
||||
import "vue-material-design-icons/styles.css";
|
||||
import App from './App.vue';
|
||||
import store from './store';
|
||||
|
||||
Vue.use(Buefy);
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
render: h => h(App)
|
||||
})
|
105
third_party/webrender/debugger/src/store/index.js
vendored
105
third_party/webrender/debugger/src/store/index.js
vendored
|
@ -1,105 +0,0 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
class Connection {
|
||||
constructor() {
|
||||
this.ws = null;
|
||||
}
|
||||
|
||||
connect(context) {
|
||||
var ws = new WebSocket("ws://127.0.0.1:3583");
|
||||
|
||||
ws.onopen = function() {
|
||||
context.commit('setConnected', true);
|
||||
}
|
||||
|
||||
ws.onmessage = function(evt) {
|
||||
var json = JSON.parse(evt.data);
|
||||
if (json['kind'] == "passes") {
|
||||
context.commit('setPasses', json['passes']);
|
||||
} else if (json['kind'] == "render_tasks") {
|
||||
context.commit('setRenderTasks', json['root']);
|
||||
} else if (json['kind'] == "documents") {
|
||||
context.commit('setDocuments', json['root']);
|
||||
} else if (json['kind'] == "clip_scroll_tree") {
|
||||
context.commit('setClipScrollTree', json['root']);
|
||||
} else if (json['kind'] == "screenshot") {
|
||||
context.commit('setScreenshot', json['data']);
|
||||
} else {
|
||||
console.warn("unknown message kind: " + json['kind']);
|
||||
}
|
||||
}
|
||||
|
||||
ws.onclose = function() {
|
||||
context.commit('setConnected', false);
|
||||
}
|
||||
|
||||
this.ws = ws;
|
||||
}
|
||||
|
||||
send(msg) {
|
||||
if (this.ws !== null) {
|
||||
this.ws.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.ws !== null) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var connection = new Connection();
|
||||
|
||||
const store = new Vuex.Store({
|
||||
strict: true,
|
||||
state: {
|
||||
connected: false,
|
||||
page: 'options',
|
||||
passes: [],
|
||||
render_tasks: [],
|
||||
documents: [],
|
||||
clip_scroll_tree: [],
|
||||
screenshot: [],
|
||||
},
|
||||
mutations: {
|
||||
setConnected(state, connected) {
|
||||
state.connected = connected;
|
||||
},
|
||||
setPage(state, name) {
|
||||
state.page = name;
|
||||
},
|
||||
setPasses(state, passes) {
|
||||
state.passes = passes;
|
||||
},
|
||||
setRenderTasks(state, render_tasks) {
|
||||
state.render_tasks = render_tasks;
|
||||
},
|
||||
setDocuments(state, documents) {
|
||||
state.documents = documents;
|
||||
},
|
||||
setClipScrollTree(state, clip_scroll_tree) {
|
||||
state.clip_scroll_tree = clip_scroll_tree;
|
||||
},
|
||||
setScreenshot(state, screenshot) {
|
||||
state.screenshot = screenshot;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
connect(context) {
|
||||
connection.connect(context);
|
||||
},
|
||||
disconnect(context) {
|
||||
connection.disconnect();
|
||||
},
|
||||
sendMessage(context, msg) {
|
||||
connection.send(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
81
third_party/webrender/debugger/webpack.config.js
vendored
81
third_party/webrender/debugger/webpack.config.js
vendored
|
@ -1,81 +0,0 @@
|
|||
var path = require('path')
|
||||
var webpack = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/main.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, './dist'),
|
||||
publicPath: '/dist/',
|
||||
filename: 'build.js'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
'css-loader'
|
||||
],
|
||||
}, {
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
loaders: {
|
||||
}
|
||||
// other vue-loader options go here
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js'
|
||||
},
|
||||
alias : {
|
||||
"icons": path.resolve(__dirname, "node_modules/vue-material-design-icons")
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json']
|
||||
},
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
noInfo: true,
|
||||
overlay: true
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
devtool: '#eval-source-map'
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports.devtool = '#source-map'
|
||||
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
sourceMap: true,
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
}),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
minimize: true
|
||||
})
|
||||
])
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
[package]
|
||||
name = "direct-composition"
|
||||
version = "0.1.0"
|
||||
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
||||
license = "MPL-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
euclid = "0.22"
|
||||
gleam = "0.12"
|
||||
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||
webrender = {path = "../webrender"}
|
||||
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
|
||||
winit = "0.19"
|
112
third_party/webrender/direct-composition/src/com.rs
vendored
112
third_party/webrender/direct-composition/src/com.rs
vendored
|
@ -1,112 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::ops;
|
||||
use std::ptr;
|
||||
use winapi::Interface;
|
||||
use winapi::ctypes::c_void;
|
||||
use winapi::shared::guiddef::GUID;
|
||||
use winapi::shared::winerror::HRESULT;
|
||||
use winapi::shared::winerror::SUCCEEDED;
|
||||
use winapi::um::unknwnbase::IUnknown;
|
||||
|
||||
pub fn as_ptr<T>(x: &T) -> *mut T {
|
||||
x as *const T as _
|
||||
}
|
||||
|
||||
pub trait CheckHResult {
|
||||
fn check_hresult(self);
|
||||
}
|
||||
|
||||
impl CheckHResult for HRESULT {
|
||||
fn check_hresult(self) {
|
||||
if !SUCCEEDED(self) {
|
||||
panic_com(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn panic_com(hresult: HRESULT) -> ! {
|
||||
panic!("COM error 0x{:08X}", hresult as u32)
|
||||
}
|
||||
|
||||
/// Forked from <https://github.com/retep998/wio-rs/blob/44093f7db8/src/com.rs>
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct ComPtr<T>(*mut T) where T: Interface;
|
||||
|
||||
impl<T> ComPtr<T> where T: Interface {
|
||||
/// Creates a `ComPtr` to wrap a raw pointer.
|
||||
/// It takes ownership over the pointer which means it does __not__ call `AddRef`.
|
||||
/// `T` __must__ be a COM interface that inherits from `IUnknown`.
|
||||
pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
|
||||
assert!(!ptr.is_null());
|
||||
ComPtr(ptr)
|
||||
}
|
||||
|
||||
/// For use with APIs that take an interface UUID and
|
||||
/// "return" a new COM object through a `*mut *mut c_void` out-parameter.
|
||||
pub unsafe fn new_with_uuid<F>(f: F) -> Self
|
||||
where F: FnOnce(&GUID, *mut *mut c_void) -> HRESULT
|
||||
{
|
||||
Self::new_with(|ptr| f(&T::uuidof(), ptr as _))
|
||||
}
|
||||
|
||||
/// For use with APIs that "return" a new COM object through a `*mut *mut T` out-parameter.
|
||||
pub unsafe fn new_with<F>(f: F) -> Self
|
||||
where F: FnOnce(*mut *mut T) -> HRESULT
|
||||
{
|
||||
let mut ptr = ptr::null_mut();
|
||||
let hresult = f(&mut ptr);
|
||||
if SUCCEEDED(hresult) {
|
||||
ComPtr::from_raw(ptr)
|
||||
} else {
|
||||
if !ptr.is_null() {
|
||||
let ptr = ptr as *mut IUnknown;
|
||||
(*ptr).Release();
|
||||
}
|
||||
panic_com(hresult)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_raw(&self) -> *mut T {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn as_unknown(&self) -> &IUnknown {
|
||||
unsafe {
|
||||
&*(self.0 as *mut IUnknown)
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs QueryInterface fun.
|
||||
pub fn cast<U>(&self) -> ComPtr<U> where U: Interface {
|
||||
unsafe {
|
||||
ComPtr::<U>::new_with_uuid(|uuid, ptr| self.as_unknown().QueryInterface(uuid, ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ops::Deref for ComPtr<T> where T: Interface {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { &*self.0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for ComPtr<T> where T: Interface {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
self.as_unknown().AddRef();
|
||||
ComPtr(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for ComPtr<T> where T: Interface {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.as_unknown().Release();
|
||||
}
|
||||
}
|
||||
}
|
174
third_party/webrender/direct-composition/src/egl.rs
vendored
174
third_party/webrender/direct-composition/src/egl.rs
vendored
|
@ -1,174 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use mozangle::egl::ffi::*;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use winapi::um::d3d11::ID3D11Device;
|
||||
use winapi::um::d3d11::ID3D11Texture2D;
|
||||
|
||||
pub use mozangle::egl::get_proc_address;
|
||||
|
||||
pub struct SharedEglThings {
|
||||
device: EGLDeviceEXT,
|
||||
display: types::EGLDisplay,
|
||||
config: types::EGLConfig,
|
||||
context: types::EGLContext,
|
||||
}
|
||||
|
||||
fn cast_attributes(slice: &[types::EGLenum]) -> &EGLint {
|
||||
unsafe {
|
||||
&*(slice.as_ptr() as *const EGLint)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! attributes {
|
||||
($( $key: expr => $value: expr, )*) => {
|
||||
cast_attributes(&[
|
||||
$( $key, $value, )*
|
||||
NONE,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl SharedEglThings {
|
||||
pub unsafe fn new(d3d_device: *mut ID3D11Device) -> Rc<Self> {
|
||||
let device = eglCreateDeviceANGLE(
|
||||
D3D11_DEVICE_ANGLE,
|
||||
d3d_device as *mut c_void,
|
||||
ptr::null(),
|
||||
).check();
|
||||
let display = GetPlatformDisplayEXT(
|
||||
PLATFORM_DEVICE_EXT,
|
||||
device,
|
||||
attributes! [
|
||||
EXPERIMENTAL_PRESENT_PATH_ANGLE => EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
|
||||
],
|
||||
).check();
|
||||
Initialize(display, ptr::null_mut(), ptr::null_mut()).check();
|
||||
|
||||
// Adapted from
|
||||
// https://searchfox.org/mozilla-central/rev/056a4057/gfx/gl/GLContextProviderEGL.cpp#635
|
||||
let mut configs = [ptr::null(); 64];
|
||||
let mut num_configs = 0;
|
||||
ChooseConfig(
|
||||
display,
|
||||
attributes! [
|
||||
SURFACE_TYPE => WINDOW_BIT,
|
||||
RENDERABLE_TYPE => OPENGL_ES2_BIT,
|
||||
RED_SIZE => 8,
|
||||
GREEN_SIZE => 8,
|
||||
BLUE_SIZE => 8,
|
||||
ALPHA_SIZE => 8,
|
||||
],
|
||||
configs.as_mut_ptr(),
|
||||
configs.len() as i32,
|
||||
&mut num_configs,
|
||||
).check();
|
||||
let config = pick_config(&configs[..num_configs as usize]);
|
||||
|
||||
let context = CreateContext(
|
||||
display, config, NO_CONTEXT,
|
||||
attributes![
|
||||
CONTEXT_CLIENT_VERSION => 3,
|
||||
]
|
||||
).check();
|
||||
MakeCurrent(display, NO_SURFACE, NO_SURFACE, context).check();
|
||||
|
||||
Rc::new(SharedEglThings { device, display, config, context })
|
||||
}
|
||||
}
|
||||
|
||||
fn pick_config(configs: &[types::EGLConfig]) -> types::EGLConfig {
|
||||
// FIXME: better criteria to make this choice?
|
||||
// Firefox uses GetConfigAttrib to find a config that has the requested r/g/b/a sizes
|
||||
// https://searchfox.org/mozilla-central/rev/056a4057/gfx/gl/GLContextProviderEGL.cpp#662-685
|
||||
|
||||
configs[0]
|
||||
}
|
||||
|
||||
impl Drop for SharedEglThings {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// FIXME does EGLDisplay or EGLConfig need clean up? How?
|
||||
DestroyContext(self.display, self.context).check();
|
||||
eglReleaseDeviceANGLE(self.device).check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PerVisualEglThings {
|
||||
shared: Rc<SharedEglThings>,
|
||||
surface: types::EGLSurface,
|
||||
}
|
||||
|
||||
impl PerVisualEglThings {
|
||||
pub unsafe fn new(shared: Rc<SharedEglThings>, buffer: *const ID3D11Texture2D,
|
||||
width: u32, height: u32)
|
||||
-> Self {
|
||||
let surface = CreatePbufferFromClientBuffer(
|
||||
shared.display,
|
||||
D3D_TEXTURE_ANGLE,
|
||||
buffer as types::EGLClientBuffer,
|
||||
shared.config,
|
||||
attributes! [
|
||||
WIDTH => width,
|
||||
HEIGHT => height,
|
||||
FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE => TRUE,
|
||||
],
|
||||
).check();
|
||||
|
||||
PerVisualEglThings { shared, surface }
|
||||
}
|
||||
|
||||
pub fn make_current(&self) {
|
||||
unsafe {
|
||||
MakeCurrent(self.shared.display, self.surface, self.surface, self.shared.context).check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PerVisualEglThings {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DestroySurface(self.shared.display, self.surface).check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_error() {
|
||||
unsafe {
|
||||
let error = GetError() as types::EGLenum;
|
||||
assert_eq!(error, SUCCESS, "0x{:x} != 0x{:x}", error, SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
trait Check {
|
||||
fn check(self) -> Self;
|
||||
}
|
||||
|
||||
impl Check for *const c_void {
|
||||
fn check(self) -> Self {
|
||||
check_error();
|
||||
assert!(!self.is_null());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Check for *mut c_void {
|
||||
fn check(self) -> Self {
|
||||
check_error();
|
||||
assert!(!self.is_null());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Check for types::EGLBoolean {
|
||||
fn check(self) -> Self {
|
||||
check_error();
|
||||
assert_eq!(self, TRUE);
|
||||
self
|
||||
}
|
||||
}
|
179
third_party/webrender/direct-composition/src/lib.rs
vendored
179
third_party/webrender/direct-composition/src/lib.rs
vendored
|
@ -1,179 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![cfg(windows)]
|
||||
|
||||
use gleam;
|
||||
use mozangle;
|
||||
use winapi;
|
||||
|
||||
use com::{ComPtr, CheckHResult, as_ptr};
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use winapi::shared::dxgi1_2::DXGI_SWAP_CHAIN_DESC1;
|
||||
use winapi::shared::dxgi1_2::IDXGIFactory2;
|
||||
use winapi::shared::minwindef::{TRUE, FALSE};
|
||||
use winapi::shared::windef::HWND;
|
||||
use winapi::um::d3d11::ID3D11Device;
|
||||
use winapi::um::dcomp::IDCompositionDevice;
|
||||
use winapi::um::dcomp::IDCompositionTarget;
|
||||
use winapi::um::dcomp::IDCompositionVisual;
|
||||
|
||||
mod com;
|
||||
mod egl;
|
||||
|
||||
pub struct DirectComposition {
|
||||
d3d_device: ComPtr<ID3D11Device>,
|
||||
dxgi_factory: ComPtr<IDXGIFactory2>,
|
||||
|
||||
egl: Rc<egl::SharedEglThings>,
|
||||
pub gleam: Rc<dyn gleam::gl::Gl>,
|
||||
|
||||
composition_device: ComPtr<IDCompositionDevice>,
|
||||
root_visual: ComPtr<IDCompositionVisual>,
|
||||
|
||||
#[allow(unused)] // Needs to be kept alive
|
||||
composition_target: ComPtr<IDCompositionTarget>,
|
||||
}
|
||||
|
||||
impl DirectComposition {
|
||||
/// Initialize DirectComposition in the given window
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `hwnd` must be a valid handle to a window.
|
||||
pub unsafe fn new(hwnd: HWND) -> Self {
|
||||
let d3d_device = ComPtr::new_with(|ptr_ptr| winapi::um::d3d11::D3D11CreateDevice(
|
||||
ptr::null_mut(),
|
||||
winapi::um::d3dcommon::D3D_DRIVER_TYPE_HARDWARE,
|
||||
ptr::null_mut(),
|
||||
winapi::um::d3d11::D3D11_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
if cfg!(debug_assertions) {
|
||||
winapi::um::d3d11::D3D11_CREATE_DEVICE_DEBUG
|
||||
} else {
|
||||
0
|
||||
},
|
||||
ptr::null_mut(),
|
||||
0,
|
||||
winapi::um::d3d11::D3D11_SDK_VERSION,
|
||||
ptr_ptr,
|
||||
&mut 0,
|
||||
ptr::null_mut(),
|
||||
));
|
||||
|
||||
let egl = egl::SharedEglThings::new(d3d_device.as_raw());
|
||||
let gleam = gleam::gl::GlesFns::load_with(egl::get_proc_address);
|
||||
|
||||
let dxgi_device = d3d_device.cast::<winapi::shared::dxgi::IDXGIDevice>();
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh404556(v=vs.85).aspx#code-snippet-1
|
||||
// “Because you can create a Direct3D device without creating a swap chain,
|
||||
// you might need to retrieve the factory that is used to create the device
|
||||
// in order to create a swap chain.”
|
||||
let adapter = ComPtr::new_with(|ptr_ptr| dxgi_device.GetAdapter(ptr_ptr));
|
||||
let dxgi_factory = ComPtr::<IDXGIFactory2>::new_with_uuid(|uuid, ptr_ptr| {
|
||||
adapter.GetParent(uuid, ptr_ptr)
|
||||
});
|
||||
|
||||
// Create the DirectComposition device object.
|
||||
let composition_device = ComPtr::<IDCompositionDevice>::new_with_uuid(|uuid, ptr_ptr| {
|
||||
winapi::um::dcomp::DCompositionCreateDevice(&*dxgi_device, uuid, ptr_ptr)
|
||||
});
|
||||
|
||||
// Create the composition target object based on the
|
||||
// specified application window.
|
||||
let composition_target = ComPtr::new_with(|ptr_ptr| {
|
||||
composition_device.CreateTargetForHwnd(hwnd, TRUE, ptr_ptr)
|
||||
});
|
||||
|
||||
let root_visual = ComPtr::new_with(|ptr_ptr| composition_device.CreateVisual(ptr_ptr));
|
||||
composition_target.SetRoot(&*root_visual).check_hresult();
|
||||
|
||||
DirectComposition {
|
||||
d3d_device, dxgi_factory,
|
||||
egl, gleam,
|
||||
composition_device, composition_target, root_visual,
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute changes to the DirectComposition scene.
|
||||
pub fn commit(&self) {
|
||||
unsafe {
|
||||
self.composition_device.Commit().check_hresult()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_angle_visual(&self, width: u32, height: u32) -> AngleVisual {
|
||||
unsafe {
|
||||
let desc = DXGI_SWAP_CHAIN_DESC1 {
|
||||
Width: width,
|
||||
Height: height,
|
||||
Format: winapi::shared::dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
Stereo: FALSE,
|
||||
SampleDesc: winapi::shared::dxgitype::DXGI_SAMPLE_DESC {
|
||||
Count: 1,
|
||||
Quality: 0,
|
||||
},
|
||||
BufferUsage: winapi::shared::dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
BufferCount: 2,
|
||||
Scaling: winapi::shared::dxgi1_2::DXGI_SCALING_STRETCH,
|
||||
SwapEffect: winapi::shared::dxgi::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
|
||||
AlphaMode: winapi::shared::dxgi1_2::DXGI_ALPHA_MODE_PREMULTIPLIED,
|
||||
Flags: 0,
|
||||
};
|
||||
let swap_chain = ComPtr::<winapi::shared::dxgi1_2::IDXGISwapChain1>::new_with(|ptr_ptr| {
|
||||
self.dxgi_factory.CreateSwapChainForComposition(
|
||||
as_ptr(&self.d3d_device),
|
||||
&desc,
|
||||
ptr::null_mut(),
|
||||
ptr_ptr,
|
||||
)
|
||||
});
|
||||
let back_buffer = ComPtr::<winapi::um::d3d11::ID3D11Texture2D>::new_with_uuid(|uuid, ptr_ptr| {
|
||||
swap_chain.GetBuffer(0, uuid, ptr_ptr)
|
||||
});
|
||||
let egl = egl::PerVisualEglThings::new(self.egl.clone(), &*back_buffer, width, height);
|
||||
let gleam = self.gleam.clone();
|
||||
|
||||
let visual = ComPtr::new_with(|ptr_ptr| self.composition_device.CreateVisual(ptr_ptr));
|
||||
visual.SetContent(&*****swap_chain).check_hresult();
|
||||
self.root_visual.AddVisual(&*visual, FALSE, ptr::null_mut()).check_hresult();
|
||||
|
||||
AngleVisual { visual, swap_chain, egl, gleam }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A DirectComposition "visual" configured for rendering with Direct3D.
|
||||
pub struct AngleVisual {
|
||||
visual: ComPtr<IDCompositionVisual>,
|
||||
swap_chain: ComPtr<winapi::shared::dxgi1_2::IDXGISwapChain1>,
|
||||
egl: egl::PerVisualEglThings,
|
||||
pub gleam: Rc<dyn gleam::gl::Gl>,
|
||||
}
|
||||
|
||||
impl AngleVisual {
|
||||
pub fn set_offset_x(&self, offset_x: f32) {
|
||||
unsafe {
|
||||
self.visual.SetOffsetX_1(offset_x).check_hresult()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_offset_y(&self, offset_y: f32) {
|
||||
unsafe {
|
||||
self.visual.SetOffsetY_1(offset_y).check_hresult()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_current(&self) {
|
||||
self.egl.make_current()
|
||||
}
|
||||
|
||||
pub fn present(&self) {
|
||||
self.gleam.finish();
|
||||
unsafe {
|
||||
self.swap_chain.Present(0, 0).check_hresult()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,212 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use direct_composition;
|
||||
use euclid;
|
||||
use gleam;
|
||||
use webrender;
|
||||
use winit;
|
||||
|
||||
use euclid::size2;
|
||||
use direct_composition::DirectComposition;
|
||||
use std::sync::mpsc;
|
||||
use webrender::api;
|
||||
use winit::os::windows::{WindowExt, WindowBuilderExt};
|
||||
use winit::dpi::LogicalSize;
|
||||
|
||||
fn main() {
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let notifier = Box::new(Notifier { events_proxy: events_loop.create_proxy(), tx });
|
||||
|
||||
let window = winit::WindowBuilder::new()
|
||||
.with_title("WebRender + ANGLE + DirectComposition")
|
||||
.with_dimensions(LogicalSize::new(1024., 768.))
|
||||
.with_decorations(true)
|
||||
.with_transparency(true)
|
||||
.with_no_redirection_bitmap(true)
|
||||
.build(&events_loop)
|
||||
.unwrap();
|
||||
|
||||
let composition = direct_composition_from_window(&window);
|
||||
let factor = window.get_hidpi_factor() as f32;
|
||||
|
||||
let mut clicks: usize = 0;
|
||||
let mut offset_y = 100.;
|
||||
let mut rects = [
|
||||
Rectangle::new(&composition, ¬ifier, factor, size2(300, 200), 0., 0.2, 0.4, 1.),
|
||||
Rectangle::new(&composition, ¬ifier, factor, size2(400, 300), 0., 0.5, 0., 0.5),
|
||||
];
|
||||
rects[0].render(factor, &rx);
|
||||
rects[1].render(factor, &rx);
|
||||
|
||||
rects[0].visual.set_offset_x(100.);
|
||||
rects[0].visual.set_offset_y(50.);
|
||||
|
||||
rects[1].visual.set_offset_x(200.);
|
||||
rects[1].visual.set_offset_y(offset_y);
|
||||
|
||||
composition.commit();
|
||||
|
||||
events_loop.run_forever(|event| {
|
||||
if let winit::Event::WindowEvent { event, .. } = event {
|
||||
match event {
|
||||
winit::WindowEvent::CloseRequested => {
|
||||
return winit::ControlFlow::Break
|
||||
}
|
||||
winit::WindowEvent::MouseWheel { delta, .. } => {
|
||||
let dy = match delta {
|
||||
winit::MouseScrollDelta::LineDelta(_, dy) => dy,
|
||||
winit::MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
||||
};
|
||||
offset_y = (offset_y - 10. * dy).max(0.).min(468.);
|
||||
|
||||
rects[1].visual.set_offset_y(offset_y);
|
||||
composition.commit();
|
||||
}
|
||||
winit::WindowEvent::MouseInput {
|
||||
button: winit::MouseButton::Left,
|
||||
state: winit::ElementState::Pressed,
|
||||
..
|
||||
} => {
|
||||
clicks += 1;
|
||||
let rect = &mut rects[clicks % 2];
|
||||
rect.color.g += 0.1;
|
||||
rect.color.g %= 1.;
|
||||
rect.render(factor, &rx)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
winit::ControlFlow::Continue
|
||||
});
|
||||
}
|
||||
|
||||
fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
|
||||
unsafe {
|
||||
DirectComposition::new(window.get_hwnd() as _)
|
||||
}
|
||||
}
|
||||
|
||||
struct Rectangle {
|
||||
visual: direct_composition::AngleVisual,
|
||||
renderer: Option<webrender::Renderer>,
|
||||
api: api::RenderApi,
|
||||
document_id: api::DocumentId,
|
||||
size: api::units::DeviceIntSize,
|
||||
color: api::ColorF,
|
||||
}
|
||||
|
||||
impl Rectangle {
|
||||
fn new(composition: &DirectComposition, notifier: &Box<Notifier>,
|
||||
device_pixel_ratio: f32, size: api::units::DeviceIntSize, r: f32, g: f32, b: f32, a: f32)
|
||||
-> Self {
|
||||
let visual = composition.create_angle_visual(size.width as u32, size.height as u32);
|
||||
visual.make_current();
|
||||
|
||||
let (renderer, sender) = webrender::Renderer::new(
|
||||
composition.gleam.clone(),
|
||||
notifier.clone(),
|
||||
webrender::RendererOptions {
|
||||
clear_color: Some(api::ColorF::new(0., 0., 0., 0.)),
|
||||
device_pixel_ratio,
|
||||
..webrender::RendererOptions::default()
|
||||
},
|
||||
None,
|
||||
size,
|
||||
).unwrap();
|
||||
let api = sender.create_api();
|
||||
|
||||
Rectangle {
|
||||
visual,
|
||||
renderer: Some(renderer),
|
||||
document_id: api.add_document(size, 0),
|
||||
api,
|
||||
size,
|
||||
color: api::ColorF { r, g, b, a },
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&mut self, device_pixel_ratio: f32, rx: &mpsc::Receiver<()>) {
|
||||
self.visual.make_current();
|
||||
|
||||
let pipeline_id = api::PipelineId(0, 0);
|
||||
let layout_size = self.size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
|
||||
|
||||
let rect = euclid::Rect::new(euclid::Point2D::zero(), layout_size);
|
||||
|
||||
let region = api::ComplexClipRegion::new(
|
||||
rect,
|
||||
api::BorderRadius::uniform(20.),
|
||||
api::ClipMode::Clip
|
||||
);
|
||||
let clip_id = builder.define_clip_rounded_rect(
|
||||
&api::SpaceAndClipInfo::root_scroll(pipeline_id),
|
||||
region,
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&api::CommonItemProperties::new(
|
||||
rect,
|
||||
api::SpaceAndClipInfo {
|
||||
spatial_id: api::SpatialId::root_scroll_node(pipeline_id),
|
||||
clip_id,
|
||||
},
|
||||
),
|
||||
rect,
|
||||
self.color,
|
||||
);
|
||||
|
||||
let mut transaction = api::Transaction::new();
|
||||
transaction.set_display_list(
|
||||
api::Epoch(0),
|
||||
None,
|
||||
layout_size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
transaction.set_root_pipeline(pipeline_id);
|
||||
transaction.generate_frame();
|
||||
self.api.send_transaction(self.document_id, transaction);
|
||||
rx.recv().unwrap();
|
||||
let renderer = self.renderer.as_mut().unwrap();
|
||||
renderer.update();
|
||||
renderer.render(self.size).unwrap();
|
||||
let _ = renderer.flush_pipeline_info();
|
||||
self.visual.present();
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Rectangle {
|
||||
fn drop(&mut self) {
|
||||
self.renderer.take().unwrap().deinit()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Notifier {
|
||||
events_proxy: winit::EventsLoopProxy,
|
||||
tx: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
impl api::RenderNotifier for Notifier {
|
||||
fn clone(&self) -> Box<dyn api::RenderNotifier> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
self.tx.send(()).unwrap();
|
||||
let _ = self.events_proxy.wakeup();
|
||||
}
|
||||
|
||||
fn new_frame_ready(&self,
|
||||
_: api::DocumentId,
|
||||
_: bool,
|
||||
_: bool,
|
||||
_: Option<u64>) {
|
||||
self.wake_up();
|
||||
}
|
||||
}
|
11
third_party/webrender/example-compositor/compositor-wayland/Cargo.toml
vendored
Normal file
11
third_party/webrender/example-compositor/compositor-wayland/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "compositor-wayland"
|
||||
version = "0.1.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>",
|
||||
"Robert Mader <robert.mader@posteo.de>"]
|
||||
edition = "2018"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
pkg-config = "^0.3.17"
|
63
third_party/webrender/example-compositor/compositor-wayland/build.rs
vendored
Normal file
63
third_party/webrender/example-compositor/compositor-wayland/build.rs
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::process::Command;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
extern crate pkg_config;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
|
||||
fs::create_dir_all(&format!("{}/include", out_dir)).unwrap();
|
||||
Command::new("wayland-scanner")
|
||||
.args(&["client-header", "/usr/share/wayland-protocols/stable/viewporter/viewporter.xml"])
|
||||
.arg(&format!("{}/include/viewporter-client-protocol.h", out_dir))
|
||||
.status().unwrap();
|
||||
|
||||
Command::new("wayland-scanner")
|
||||
.args(&["public-code", "/usr/share/wayland-protocols/stable/viewporter/viewporter.xml"])
|
||||
.arg(&format!("{}/viewporter-protocol.c", out_dir))
|
||||
.status().unwrap();
|
||||
|
||||
Command::new("wayland-scanner")
|
||||
.args(&["client-header", "/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml"])
|
||||
.arg(&format!("{}/include/xdg-shell-client-protocol.h", out_dir))
|
||||
.status().unwrap();
|
||||
|
||||
Command::new("wayland-scanner")
|
||||
.args(&["public-code", "/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml"])
|
||||
.arg(&format!("{}/xdg-shell-protocol.c", out_dir))
|
||||
.status().unwrap();
|
||||
|
||||
cc::Build::new()
|
||||
.include(&format!("{}/include", out_dir))
|
||||
.file("src/lib.cpp")
|
||||
.file(&format!("{}/viewporter-protocol.c", out_dir))
|
||||
.file(&format!("{}/xdg-shell-protocol.c", out_dir))
|
||||
.compile("wayland");
|
||||
|
||||
println!("cargo:rustc-link-lib=dylib=stdc++");
|
||||
|
||||
pkg_config::Config::new()
|
||||
.atleast_version("1")
|
||||
.probe("egl")
|
||||
.unwrap();
|
||||
pkg_config::Config::new()
|
||||
.atleast_version("1")
|
||||
.probe("gl")
|
||||
.unwrap();
|
||||
pkg_config::Config::new()
|
||||
.atleast_version("1")
|
||||
.probe("wayland-client")
|
||||
.unwrap();
|
||||
pkg_config::Config::new()
|
||||
.atleast_version("1")
|
||||
.probe("wayland-egl")
|
||||
.unwrap();
|
||||
|
||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
||||
println!("cargo:rerun-if-changed=src/lib.cpp");
|
||||
}
|
772
third_party/webrender/example-compositor/compositor-wayland/src/lib.cpp
vendored
Normal file
772
third_party/webrender/example-compositor/compositor-wayland/src/lib.cpp
vendored
Normal file
|
@ -0,0 +1,772 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define UNICODE
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
#define NUM_QUERIES 2
|
||||
|
||||
#define VIRTUAL_OFFSET 512 * 1024
|
||||
|
||||
enum SyncMode {
|
||||
None_ = 0,
|
||||
Swap = 1,
|
||||
Commit = 2,
|
||||
Flush = 3,
|
||||
Query = 4,
|
||||
};
|
||||
|
||||
// The OS compositor representation of a picture cache tile.
|
||||
struct Tile {
|
||||
uint64_t surface_id;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
struct wl_surface* surface;
|
||||
struct wl_subsurface* subsurface;
|
||||
struct wp_viewport* viewport;
|
||||
struct wl_egl_window* egl_window;
|
||||
EGLSurface egl_surface;
|
||||
bool is_visible;
|
||||
|
||||
std::vector<EGLint> damage_rects;
|
||||
};
|
||||
|
||||
struct TileKey {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
TileKey(int ax, int ay) : x(ax), y(ay) {}
|
||||
};
|
||||
|
||||
bool operator==(const TileKey& k0, const TileKey& k1) {
|
||||
return k0.x == k1.x && k0.y == k1.y;
|
||||
}
|
||||
|
||||
struct TileKeyHasher {
|
||||
size_t operator()(const TileKey& key) const { return key.x ^ key.y; }
|
||||
};
|
||||
|
||||
struct Surface {
|
||||
uint64_t id;
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
bool is_opaque;
|
||||
std::unordered_map<TileKey, Tile*, TileKeyHasher> tiles;
|
||||
};
|
||||
|
||||
struct WLDisplay {
|
||||
struct wl_display* display;
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
struct xdg_wm_base* wm_base;
|
||||
struct wl_seat* seat;
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_touch* touch;
|
||||
struct wl_keyboard* keyboard;
|
||||
struct wl_shm* shm;
|
||||
struct wl_cursor_theme* cursor_theme;
|
||||
struct wl_cursor* default_cursor;
|
||||
struct wl_surface* cursor_surface;
|
||||
struct wp_viewporter* viewporter;
|
||||
|
||||
PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
|
||||
};
|
||||
|
||||
struct WLGeometry {
|
||||
int width, height;
|
||||
};
|
||||
|
||||
struct WLWindow {
|
||||
WLGeometry geometry;
|
||||
bool enable_compositor;
|
||||
SyncMode sync_mode;
|
||||
bool closed;
|
||||
|
||||
WLDisplay* display;
|
||||
struct wl_surface* surface;
|
||||
struct xdg_surface* xdg_surface;
|
||||
struct xdg_toplevel* xdg_toplevel;
|
||||
struct wl_callback* callback;
|
||||
struct wp_viewport* viewport;
|
||||
bool wait_for_configure;
|
||||
|
||||
struct wl_egl_window* egl_window;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
EGLDeviceEXT eglDevice;
|
||||
EGLDisplay eglDisplay;
|
||||
EGLContext eglContext;
|
||||
EGLConfig config;
|
||||
|
||||
// Maintain list of layer state between frames to avoid visual tree rebuild.
|
||||
std::vector<uint64_t> currentLayers;
|
||||
std::vector<uint64_t> prevLayers;
|
||||
|
||||
// Maps WR surface IDs to each OS surface
|
||||
std::unordered_map<uint64_t, Surface> surfaces;
|
||||
std::vector<Tile*> destroyedTiles;
|
||||
std::vector<Tile*> hiddenTiles;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void init_wl_registry(WLWindow* window);
|
||||
static void init_xdg_window(WLWindow* window);
|
||||
|
||||
WLWindow* com_wl_create_window(int width, int height, bool enable_compositor,
|
||||
SyncMode sync_mode) {
|
||||
WLDisplay* display = new WLDisplay;
|
||||
WLWindow* window = new WLWindow;
|
||||
|
||||
window->display = display;
|
||||
window->geometry.width = width;
|
||||
window->geometry.height = height;
|
||||
window->enable_compositor = enable_compositor;
|
||||
window->sync_mode = sync_mode;
|
||||
window->closed = false;
|
||||
|
||||
display->display = wl_display_connect(NULL);
|
||||
assert(display->display);
|
||||
|
||||
init_wl_registry(window);
|
||||
if (enable_compositor && !display->viewporter) {
|
||||
fprintf(stderr, "Native compositor mode requires wp_viewporter support\n");
|
||||
window->closed = true;
|
||||
}
|
||||
|
||||
window->eglDisplay =
|
||||
eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, display->display, NULL);
|
||||
|
||||
eglInitialize(window->eglDisplay, nullptr, nullptr);
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
EGLint num_configs = 0;
|
||||
EGLint cfg_attribs[] = {EGL_SURFACE_TYPE,
|
||||
EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_BIT,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_DEPTH_SIZE,
|
||||
24,
|
||||
EGL_NONE};
|
||||
EGLConfig configs[32];
|
||||
|
||||
eglChooseConfig(window->eglDisplay, cfg_attribs, configs,
|
||||
sizeof(configs) / sizeof(EGLConfig), &num_configs);
|
||||
assert(num_configs > 0);
|
||||
window->config = configs[0];
|
||||
|
||||
EGLint ctx_attribs[] = {EGL_CONTEXT_OPENGL_PROFILE_MASK,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
EGL_CONTEXT_MAJOR_VERSION,
|
||||
3,
|
||||
EGL_CONTEXT_MINOR_VERSION,
|
||||
2,
|
||||
EGL_NONE};
|
||||
|
||||
// Create an EGL context that can be used for drawing
|
||||
window->eglContext = eglCreateContext(window->eglDisplay, window->config,
|
||||
EGL_NO_CONTEXT, ctx_attribs);
|
||||
|
||||
window->surface = wl_compositor_create_surface(display->compositor);
|
||||
init_xdg_window(window);
|
||||
|
||||
struct wl_region* region =
|
||||
wl_compositor_create_region(window->display->compositor);
|
||||
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
|
||||
wl_surface_set_opaque_region(window->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
if (enable_compositor) {
|
||||
xdg_toplevel_set_title(window->xdg_toplevel,
|
||||
"example-compositor (Wayland)");
|
||||
} else {
|
||||
xdg_toplevel_set_title(window->xdg_toplevel, "example-compositor (Simple)");
|
||||
}
|
||||
|
||||
window->wait_for_configure = true;
|
||||
wl_surface_commit(window->surface);
|
||||
|
||||
EGLBoolean ok = eglMakeCurrent(window->eglDisplay, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, window->eglContext);
|
||||
assert(ok);
|
||||
|
||||
display->swap_buffers_with_damage =
|
||||
(PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)eglGetProcAddress(
|
||||
"eglSwapBuffersWithDamageKHR");
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
bool com_wl_tick(WLWindow* window) {
|
||||
if (window->wait_for_configure) {
|
||||
int ret = 0;
|
||||
while (window->wait_for_configure && !window->closed && ret != -1) {
|
||||
wl_display_dispatch(window->display->display);
|
||||
}
|
||||
} else {
|
||||
wl_display_dispatch_pending(window->display->display);
|
||||
}
|
||||
|
||||
return !window->closed;
|
||||
}
|
||||
|
||||
static void unmap_hidden_tiles(WLWindow* window) {
|
||||
for (Tile* tile : window->hiddenTiles) {
|
||||
if (tile->subsurface) {
|
||||
wl_subsurface_destroy(tile->subsurface);
|
||||
tile->subsurface = nullptr;
|
||||
}
|
||||
}
|
||||
window->hiddenTiles.clear();
|
||||
}
|
||||
|
||||
static void clean_up_tiles(WLWindow* window) {
|
||||
for (Tile* tile : window->destroyedTiles) {
|
||||
eglDestroySurface(window->eglDisplay, tile->egl_surface);
|
||||
wl_egl_window_destroy(tile->egl_window);
|
||||
wp_viewport_destroy(tile->viewport);
|
||||
wl_surface_destroy(tile->surface);
|
||||
delete tile;
|
||||
}
|
||||
window->destroyedTiles.clear();
|
||||
}
|
||||
|
||||
static void handle_callback(void* data, struct wl_callback* callback,
|
||||
uint32_t time) {
|
||||
WLWindow* window = (WLWindow*)data;
|
||||
UNUSED(time);
|
||||
|
||||
assert(window->callback == callback);
|
||||
|
||||
wl_callback_destroy(callback);
|
||||
window->callback = nullptr;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {handle_callback};
|
||||
|
||||
void com_wl_swap_buffers(WLWindow* window) {
|
||||
if (window->enable_compositor) {
|
||||
for (auto surface_it = window->surfaces.begin();
|
||||
surface_it != window->surfaces.end(); ++surface_it) {
|
||||
Surface* surface = &surface_it->second;
|
||||
|
||||
for (auto tile_it = surface->tiles.begin();
|
||||
tile_it != surface->tiles.end(); ++tile_it) {
|
||||
Tile* tile = tile_it->second;
|
||||
|
||||
if (!tile->damage_rects.empty() && tile->is_visible) {
|
||||
eglMakeCurrent(window->eglDisplay, tile->egl_surface,
|
||||
tile->egl_surface, window->eglContext);
|
||||
eglSwapInterval(window->eglDisplay, 0);
|
||||
|
||||
/* if (window->display->swap_buffers_with_damage) {
|
||||
window->display->swap_buffers_with_damage(
|
||||
window->eglDisplay, tile->egl_surface,
|
||||
tile->damage_rects.data(), tile->damage_rects.size() / 4);
|
||||
} else */
|
||||
eglSwapBuffers(window->eglDisplay, tile->egl_surface);
|
||||
tile->damage_rects.clear();
|
||||
|
||||
eglMakeCurrent(window->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
window->eglContext);
|
||||
} else {
|
||||
wl_surface_commit(tile->surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
wl_surface_commit(window->surface);
|
||||
unmap_hidden_tiles(window);
|
||||
clean_up_tiles(window);
|
||||
|
||||
int ret = 0;
|
||||
switch (window->sync_mode) {
|
||||
case SyncMode::None_:
|
||||
wl_display_roundtrip(window->display->display);
|
||||
break;
|
||||
case SyncMode::Swap:
|
||||
window->callback = wl_surface_frame(window->surface);
|
||||
wl_callback_add_listener(window->callback, &frame_listener, window);
|
||||
wl_surface_commit(window->surface);
|
||||
|
||||
while (window->callback && !window->closed && ret != -1) {
|
||||
ret = wl_display_dispatch(window->display->display);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// If not using native mode, then do a normal EGL swap buffers.
|
||||
switch (window->sync_mode) {
|
||||
case SyncMode::None_:
|
||||
eglSwapInterval(window->eglDisplay, 0);
|
||||
break;
|
||||
case SyncMode::Swap:
|
||||
eglSwapInterval(window->eglDisplay, 1);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
eglSwapBuffers(window->eglDisplay, window->egl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new native surface
|
||||
void com_wl_create_surface(WLWindow* window, uint64_t surface_id,
|
||||
int tile_width, int tile_height, bool is_opaque) {
|
||||
assert(window->surfaces.count(surface_id) == 0);
|
||||
|
||||
Surface surface;
|
||||
surface.id = surface_id;
|
||||
surface.tile_width = tile_width;
|
||||
surface.tile_height = tile_height;
|
||||
surface.is_opaque = is_opaque;
|
||||
|
||||
window->surfaces.emplace(surface_id, surface);
|
||||
}
|
||||
|
||||
void com_wl_create_tile(WLWindow* window, uint64_t surface_id, int x, int y) {
|
||||
WLDisplay* display = window->display;
|
||||
|
||||
assert(window->surfaces.count(surface_id) == 1);
|
||||
Surface* surface = &window->surfaces.at(surface_id);
|
||||
|
||||
TileKey key(x, y);
|
||||
assert(surface->tiles.count(key) == 0);
|
||||
|
||||
Tile* tile = new Tile;
|
||||
tile->surface_id = surface_id;
|
||||
tile->x = x;
|
||||
tile->y = y;
|
||||
tile->is_visible = false;
|
||||
|
||||
tile->surface = wl_compositor_create_surface(display->compositor);
|
||||
tile->viewport =
|
||||
wp_viewporter_get_viewport(display->viewporter, tile->surface);
|
||||
|
||||
if (surface->is_opaque) {
|
||||
struct wl_region* region =
|
||||
wl_compositor_create_region(window->display->compositor);
|
||||
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
|
||||
wl_surface_set_opaque_region(tile->surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
tile->egl_window = wl_egl_window_create(tile->surface, surface->tile_width,
|
||||
surface->tile_height);
|
||||
tile->egl_surface = eglCreateWindowSurface(window->eglDisplay, window->config,
|
||||
tile->egl_window, NULL);
|
||||
assert(tile->egl_surface != EGL_NO_SURFACE);
|
||||
|
||||
surface->tiles.emplace(key, tile);
|
||||
}
|
||||
|
||||
static void show_tile(WLWindow* window, Tile* tile) {
|
||||
if (tile->is_visible) {
|
||||
assert(tile->subsurface);
|
||||
return;
|
||||
}
|
||||
|
||||
tile->subsurface = wl_subcompositor_get_subsurface(
|
||||
window->display->subcompositor, tile->surface, window->surface);
|
||||
|
||||
/* This is not comprehensive yet, see hide_tile() */
|
||||
Surface* surface = &window->surfaces.at(tile->surface_id);
|
||||
for (auto tile_it = surface->tiles.begin(); tile_it != surface->tiles.end();
|
||||
++tile_it) {
|
||||
Tile* other_tile = tile_it->second;
|
||||
|
||||
if (other_tile->is_visible) {
|
||||
wl_subsurface_place_above(tile->subsurface, other_tile->surface);
|
||||
}
|
||||
}
|
||||
|
||||
tile->is_visible = true;
|
||||
}
|
||||
|
||||
static void hide_tile(WLWindow* window, Tile* tile) {
|
||||
if (!tile->is_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a workaround for missing API on the egl-wayland platform. We
|
||||
* likely want to replace it a solution that detaches the buffer from
|
||||
* the surface, which would require us to manage buffers manually.
|
||||
*/
|
||||
wl_subsurface_set_position(tile->subsurface, window->geometry.width / 2,
|
||||
window->geometry.height / 2);
|
||||
wp_viewport_set_source(tile->viewport, wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(0), wl_fixed_from_int(1),
|
||||
wl_fixed_from_int(1));
|
||||
wl_subsurface_place_below(tile->subsurface, window->surface);
|
||||
tile->is_visible = false;
|
||||
window->hiddenTiles.push_back(tile);
|
||||
}
|
||||
|
||||
void com_wl_destroy_tile(WLWindow* window, uint64_t surface_id, int x, int y) {
|
||||
assert(window->surfaces.count(surface_id) == 1);
|
||||
|
||||
Surface* surface = &window->surfaces.at(surface_id);
|
||||
TileKey key(x, y);
|
||||
assert(surface->tiles.count(key) == 1);
|
||||
Tile* tile = surface->tiles[key];
|
||||
|
||||
hide_tile(window, tile);
|
||||
wl_surface_commit(tile->surface);
|
||||
|
||||
window->destroyedTiles.push_back(tile);
|
||||
surface->tiles.erase(key);
|
||||
}
|
||||
|
||||
void com_wl_destroy_surface(WLWindow* window, uint64_t surface_id) {
|
||||
assert(window->surfaces.count(surface_id) == 1);
|
||||
|
||||
Surface* surface = &window->surfaces.at(surface_id);
|
||||
for (auto tile_it = surface->tiles.begin(); tile_it != surface->tiles.end();
|
||||
tile_it = surface->tiles.begin()) {
|
||||
Tile* tile = tile_it->second;
|
||||
|
||||
com_wl_destroy_tile(window, surface_id, tile->x, tile->y);
|
||||
}
|
||||
|
||||
window->surfaces.erase(surface_id);
|
||||
}
|
||||
|
||||
void com_wl_destroy_window(WLWindow* window) {
|
||||
for (auto surface_it = window->surfaces.begin();
|
||||
surface_it != window->surfaces.end(); ++surface_it) {
|
||||
Surface& surface = surface_it->second;
|
||||
|
||||
com_wl_destroy_surface(window, surface.id);
|
||||
}
|
||||
|
||||
if (window->egl_surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(window->eglDisplay, window->egl_surface);
|
||||
}
|
||||
eglDestroyContext(window->eglDisplay, window->eglContext);
|
||||
eglTerminate(window->eglDisplay);
|
||||
|
||||
delete window;
|
||||
}
|
||||
|
||||
// Bind a native surface to allow issuing GL commands to it
|
||||
GLuint com_wl_bind_surface(WLWindow* window, uint64_t surface_id, int tile_x,
|
||||
int tile_y, int* x_offset, int* y_offset,
|
||||
int dirty_x0, int dirty_y0, int dirty_width,
|
||||
int dirty_height) {
|
||||
*x_offset = 0;
|
||||
*y_offset = 0;
|
||||
|
||||
assert(window->surfaces.count(surface_id) == 1);
|
||||
Surface* surface = &window->surfaces[surface_id];
|
||||
|
||||
TileKey key(tile_x, tile_y);
|
||||
assert(surface->tiles.count(key) == 1);
|
||||
Tile* tile = surface->tiles[key];
|
||||
|
||||
tile->damage_rects.push_back(dirty_x0);
|
||||
tile->damage_rects.push_back(dirty_y0);
|
||||
tile->damage_rects.push_back(dirty_width);
|
||||
tile->damage_rects.push_back(dirty_height);
|
||||
|
||||
EGLBoolean ok = eglMakeCurrent(window->eglDisplay, tile->egl_surface,
|
||||
tile->egl_surface, window->eglContext);
|
||||
assert(ok);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unbind a currently bound native surface
|
||||
void com_wl_unbind_surface(WLWindow* window) {
|
||||
eglMakeCurrent(window->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
window->eglContext);
|
||||
}
|
||||
|
||||
void com_wl_begin_transaction(WLWindow*) {}
|
||||
|
||||
// Add a native surface to the visual tree. Called per-frame to build the
|
||||
// composition.
|
||||
void com_wl_add_surface(WLWindow* window, uint64_t surface_id, int offset_x,
|
||||
int offset_y, int clip_x, int clip_y, int clip_w,
|
||||
int clip_h) {
|
||||
Surface* surface = &window->surfaces[surface_id];
|
||||
window->currentLayers.push_back(surface_id);
|
||||
|
||||
for (auto tile_it = surface->tiles.begin(); tile_it != surface->tiles.end();
|
||||
++tile_it) {
|
||||
Tile* tile = tile_it->second;
|
||||
|
||||
int pos_x = MAX((tile->x * surface->tile_width) + offset_x, clip_x);
|
||||
int pos_y = MAX((tile->y * surface->tile_height) + offset_y, clip_y);
|
||||
|
||||
float view_x = MAX((clip_x - offset_x) - tile->x * surface->tile_width, 0);
|
||||
float view_y = MAX((clip_y - offset_y) - tile->y * surface->tile_height, 0);
|
||||
|
||||
float view_w = MIN(surface->tile_width - view_x, (clip_x + clip_w) - pos_x);
|
||||
float view_h =
|
||||
MIN(surface->tile_height - view_y, (clip_y + clip_h) - pos_y);
|
||||
view_w = MIN(window->geometry.width - pos_x, view_w);
|
||||
view_h = MIN(window->geometry.height - pos_y, view_h);
|
||||
|
||||
if (view_w > 0 && view_h > 0) {
|
||||
show_tile(window, tile);
|
||||
|
||||
wl_surface_set_buffer_transform(tile->surface,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_180);
|
||||
wl_subsurface_set_position(tile->subsurface, pos_x, pos_y);
|
||||
wp_viewport_set_source(tile->viewport, wl_fixed_from_double(view_x),
|
||||
wl_fixed_from_double(view_y),
|
||||
wl_fixed_from_double(view_w),
|
||||
wl_fixed_from_double(view_h));
|
||||
} else {
|
||||
hide_tile(window, tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void com_wl_end_transaction(WLWindow* window) {
|
||||
bool same = window->prevLayers == window->currentLayers;
|
||||
if (!same) {
|
||||
struct wl_surface* prev_surface = window->surface;
|
||||
|
||||
for (auto it = window->currentLayers.begin();
|
||||
it != window->currentLayers.end(); ++it) {
|
||||
Surface* surface = &window->surfaces[*it];
|
||||
|
||||
struct wl_surface* next_surface = nullptr;
|
||||
for (auto tile_it = surface->tiles.begin();
|
||||
tile_it != surface->tiles.end(); ++tile_it) {
|
||||
Tile* tile = tile_it->second;
|
||||
|
||||
if (tile->is_visible) {
|
||||
wl_subsurface_place_above(tile->subsurface, prev_surface);
|
||||
|
||||
if (!next_surface) {
|
||||
next_surface = tile->surface;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev_surface = next_surface;
|
||||
}
|
||||
}
|
||||
|
||||
window->prevLayers.swap(window->currentLayers);
|
||||
window->currentLayers.clear();
|
||||
}
|
||||
|
||||
void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments,
|
||||
const GLenum* attachments) {
|
||||
UNUSED(target);
|
||||
UNUSED(numAttachments);
|
||||
UNUSED(attachments);
|
||||
}
|
||||
|
||||
// Get a pointer to an EGL symbol
|
||||
void* com_wl_get_proc_address(const char* name) {
|
||||
/* Disable glInvalidateFramebuffer for now as it triggers errors.
|
||||
* This is likely due to the egl-wayland platform, which we may want to
|
||||
* replace with a custom implementation in order to have more control
|
||||
* over the low-lever bits.
|
||||
*/
|
||||
if (strcmp(name, "glInvalidateFramebuffer") == 0) {
|
||||
return (void*)glInvalidateFramebuffer;
|
||||
}
|
||||
|
||||
return (void*)eglGetProcAddress(name);
|
||||
}
|
||||
|
||||
void com_wl_deinit(WLWindow* window) { UNUSED(window); }
|
||||
|
||||
static void handle_xdg_surface_configure(void* data,
|
||||
struct xdg_surface* surface,
|
||||
uint32_t serial) {
|
||||
WLWindow* window = (WLWindow*)data;
|
||||
|
||||
xdg_surface_ack_configure(surface, serial);
|
||||
|
||||
if (window->wait_for_configure) {
|
||||
if (window->enable_compositor) {
|
||||
int width = window->geometry.width;
|
||||
int height = window->geometry.height;
|
||||
|
||||
window->egl_window = wl_egl_window_create(window->surface, 1, 1);
|
||||
window->egl_surface = eglCreateWindowSurface(
|
||||
window->eglDisplay, window->config, window->egl_window, NULL);
|
||||
assert(window->egl_surface != EGL_NO_SURFACE);
|
||||
|
||||
EGLBoolean ok = eglMakeCurrent(window->eglDisplay, window->egl_surface,
|
||||
window->egl_surface, window->eglContext);
|
||||
assert(ok);
|
||||
|
||||
glClearColor(1.0, 1.0, 1.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
window->viewport = wp_viewporter_get_viewport(window->display->viewporter,
|
||||
window->surface);
|
||||
wp_viewport_set_destination(window->viewport, width, height);
|
||||
|
||||
eglSwapBuffers(window->eglDisplay, window->egl_surface);
|
||||
} else {
|
||||
window->egl_window = wl_egl_window_create(
|
||||
window->surface, window->geometry.width, window->geometry.height);
|
||||
window->egl_surface = eglCreateWindowSurface(
|
||||
window->eglDisplay, window->config, window->egl_window, NULL);
|
||||
assert(window->egl_surface != EGL_NO_SURFACE);
|
||||
|
||||
EGLBoolean ok = eglMakeCurrent(window->eglDisplay, window->egl_surface,
|
||||
window->egl_surface, window->eglContext);
|
||||
assert(ok);
|
||||
}
|
||||
}
|
||||
|
||||
window->wait_for_configure = false;
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
handle_xdg_surface_configure};
|
||||
|
||||
static void handle_xdg_toplevel_configure(void* data,
|
||||
struct xdg_toplevel* toplevel,
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array* states) {
|
||||
WLWindow* window = (WLWindow*)data;
|
||||
UNUSED(toplevel);
|
||||
UNUSED(states);
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
window->geometry.width = width;
|
||||
window->geometry.height = height;
|
||||
|
||||
if (!window->wait_for_configure) {
|
||||
if (window->enable_compositor) {
|
||||
wp_viewport_set_destination(window->viewport, window->geometry.width,
|
||||
window->geometry.height);
|
||||
} else {
|
||||
wl_egl_window_resize(window->egl_window, window->geometry.width,
|
||||
window->geometry.height, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_xdg_toplevel_close(void* data,
|
||||
struct xdg_toplevel* toplevel) {
|
||||
UNUSED(toplevel);
|
||||
WLWindow* window = (WLWindow*)data;
|
||||
window->closed = true;
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||
handle_xdg_toplevel_configure,
|
||||
handle_xdg_toplevel_close,
|
||||
};
|
||||
|
||||
static void xdg_wm_base_ping(void* data, struct xdg_wm_base* shell,
|
||||
uint32_t serial) {
|
||||
UNUSED(data);
|
||||
xdg_wm_base_pong(shell, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener wm_base_listener = {
|
||||
xdg_wm_base_ping,
|
||||
};
|
||||
|
||||
static void registry_handle_global(void* data, struct wl_registry* registry,
|
||||
uint32_t name, const char* interface,
|
||||
uint32_t version) {
|
||||
WLDisplay* d = (WLDisplay*)data;
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
d->compositor = (struct wl_compositor*)wl_registry_bind(
|
||||
registry, name, &wl_compositor_interface, MIN(version, 4));
|
||||
} else if (strcmp(interface, "wp_viewporter") == 0) {
|
||||
d->viewporter = (struct wp_viewporter*)wl_registry_bind(
|
||||
registry, name, &wp_viewporter_interface, 1);
|
||||
} else if (strcmp(interface, "xdg_wm_base") == 0) {
|
||||
d->wm_base = (struct xdg_wm_base*)wl_registry_bind(
|
||||
registry, name, &xdg_wm_base_interface, 1);
|
||||
xdg_wm_base_add_listener(d->wm_base, &wm_base_listener, NULL);
|
||||
} else if (strcmp(interface, "wl_subcompositor") == 0) {
|
||||
d->subcompositor = (struct wl_subcompositor*)wl_registry_bind(
|
||||
registry, name, &wl_subcompositor_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name) {
|
||||
UNUSED(data);
|
||||
UNUSED(registry);
|
||||
UNUSED(name);
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
registry_handle_global, registry_handle_global_remove};
|
||||
|
||||
static void init_wl_registry(WLWindow* window) {
|
||||
WLDisplay* display = window->display;
|
||||
|
||||
display->registry = wl_display_get_registry(display->display);
|
||||
wl_registry_add_listener(display->registry, ®istry_listener, display);
|
||||
|
||||
wl_display_roundtrip(display->display);
|
||||
|
||||
assert(display->compositor);
|
||||
assert(display->wm_base);
|
||||
assert(display->subcompositor);
|
||||
}
|
||||
|
||||
static void init_xdg_window(WLWindow* window) {
|
||||
window->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(window->display->wm_base, window->surface);
|
||||
assert(window->xdg_surface);
|
||||
xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window);
|
||||
|
||||
window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
|
||||
xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener,
|
||||
window);
|
||||
assert(window->xdg_toplevel);
|
||||
}
|
||||
}
|
269
third_party/webrender/example-compositor/compositor-wayland/src/lib.rs
vendored
Normal file
269
third_party/webrender/example-compositor/compositor-wayland/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::os::raw::{c_void, c_char};
|
||||
|
||||
/*
|
||||
|
||||
This is a very simple (and unsafe!) rust wrapper for the Wayland / EGL
|
||||
implementation in lib.cpp.
|
||||
|
||||
It just proxies the calls from the Compositor impl to the C99 code. This is very
|
||||
hacky and not suitable for production!
|
||||
|
||||
*/
|
||||
|
||||
// Opaque wrapper for the Window type in lib.cpp
|
||||
#[repr(C)]
|
||||
pub struct Window {
|
||||
_unused: [u8; 0]
|
||||
}
|
||||
|
||||
// C99 functions that do the compositor work
|
||||
extern {
|
||||
fn com_wl_create_window(
|
||||
width: i32,
|
||||
height: i32,
|
||||
enable_compositor: bool,
|
||||
sync_mode: i32,
|
||||
) -> *mut Window;
|
||||
fn com_wl_destroy_window(window: *mut Window);
|
||||
fn com_wl_tick(window: *mut Window) -> bool;
|
||||
fn com_wl_get_proc_address(name: *const c_char) -> *const c_void;
|
||||
fn com_wl_swap_buffers(window: *mut Window);
|
||||
|
||||
fn com_wl_create_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
tile_width: i32,
|
||||
tile_height: i32,
|
||||
is_opaque: bool,
|
||||
);
|
||||
|
||||
fn com_wl_create_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
);
|
||||
|
||||
fn com_wl_destroy_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
);
|
||||
|
||||
fn com_wl_destroy_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
);
|
||||
|
||||
fn com_wl_bind_surface(
|
||||
window: *mut Window,
|
||||
surface_id: u64,
|
||||
tile_x: i32,
|
||||
tile_y: i32,
|
||||
x_offset: &mut i32,
|
||||
y_offset: &mut i32,
|
||||
dirty_x0: i32,
|
||||
dirty_y0: i32,
|
||||
dirty_width: i32,
|
||||
dirty_height: i32,
|
||||
) -> u32;
|
||||
fn com_wl_unbind_surface(window: *mut Window);
|
||||
|
||||
fn com_wl_begin_transaction(window: *mut Window);
|
||||
|
||||
fn com_wl_add_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
clip_x: i32,
|
||||
clip_y: i32,
|
||||
clip_w: i32,
|
||||
clip_h: i32,
|
||||
);
|
||||
|
||||
fn com_wl_end_transaction(window: *mut Window);
|
||||
|
||||
fn com_wl_deinit(window: *mut Window);
|
||||
}
|
||||
|
||||
pub fn create_window(
|
||||
width: i32,
|
||||
height: i32,
|
||||
enable_compositor: bool,
|
||||
sync_mode: i32,
|
||||
) -> *mut Window {
|
||||
unsafe {
|
||||
com_wl_create_window(width, height, enable_compositor, sync_mode)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_window(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_destroy_window(window);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(window: *mut Window) -> bool {
|
||||
unsafe {
|
||||
com_wl_tick(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_proc_address(name: *const c_char) -> *const c_void {
|
||||
unsafe {
|
||||
com_wl_get_proc_address(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
tile_width: i32,
|
||||
tile_height: i32,
|
||||
is_opaque: bool,
|
||||
) {
|
||||
unsafe {
|
||||
com_wl_create_surface(
|
||||
window,
|
||||
id,
|
||||
tile_width,
|
||||
tile_height,
|
||||
is_opaque,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) {
|
||||
unsafe {
|
||||
com_wl_create_tile(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) {
|
||||
unsafe {
|
||||
com_wl_destroy_tile(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
) {
|
||||
unsafe {
|
||||
com_wl_destroy_surface(
|
||||
window,
|
||||
id,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind_surface(
|
||||
window: *mut Window,
|
||||
surface_id: u64,
|
||||
tile_x: i32,
|
||||
tile_y: i32,
|
||||
dirty_x0: i32,
|
||||
dirty_y0: i32,
|
||||
dirty_width: i32,
|
||||
dirty_height: i32,
|
||||
) -> (u32, i32, i32) {
|
||||
unsafe {
|
||||
let mut x_offset = 0;
|
||||
let mut y_offset = 0;
|
||||
|
||||
let fbo_id = com_wl_bind_surface(
|
||||
window,
|
||||
surface_id,
|
||||
tile_x,
|
||||
tile_y,
|
||||
&mut x_offset,
|
||||
&mut y_offset,
|
||||
dirty_x0,
|
||||
dirty_y0,
|
||||
dirty_width,
|
||||
dirty_height,
|
||||
);
|
||||
|
||||
(fbo_id, x_offset, y_offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
clip_x: i32,
|
||||
clip_y: i32,
|
||||
clip_w: i32,
|
||||
clip_h: i32,
|
||||
) {
|
||||
unsafe {
|
||||
com_wl_add_surface(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
clip_x,
|
||||
clip_y,
|
||||
clip_w,
|
||||
clip_h,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_transaction(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_begin_transaction(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unbind_surface(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_unbind_surface(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_transaction(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_end_transaction(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn swap_buffers(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_swap_buffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(window: *mut Window) {
|
||||
unsafe {
|
||||
com_wl_deinit(window);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -88,6 +88,8 @@ extern {
|
|||
);
|
||||
|
||||
fn com_dc_end_transaction(window: *mut Window);
|
||||
|
||||
fn deinit(window: *mut Window);
|
||||
}
|
||||
|
||||
pub fn create_window(
|
||||
|
@ -259,3 +261,7 @@ pub fn swap_buffers(window: *mut Window) {
|
|||
com_dc_swap_buffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(window: *mut Window) {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ license = "MPL-2.0"
|
|||
|
||||
[dependencies]
|
||||
webrender = { path = "../../webrender" }
|
||||
gleam = "0.12.0"
|
||||
gleam = "0.15"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
compositor-windows = { path = "../compositor-windows" }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
compositor-wayland = { path = "../compositor-wayland" }
|
||||
|
|
|
@ -16,10 +16,12 @@ use euclid::Angle;
|
|||
use gleam::gl;
|
||||
use std::ffi::CString;
|
||||
use std::sync::mpsc;
|
||||
use webrender::api::*;
|
||||
use webrender::{CompositorSurfaceTransform, Transaction, api::*, euclid::point2};
|
||||
use webrender::api::units::*;
|
||||
#[cfg(target_os = "windows")]
|
||||
use compositor_windows as compositor;
|
||||
#[cfg(target_os = "linux")]
|
||||
use compositor_wayland as compositor;
|
||||
use std::{env, f32, process};
|
||||
|
||||
// A very hacky integration with DirectComposite. It proxies calls from the compositor
|
||||
|
@ -42,6 +44,7 @@ impl webrender::Compositor for DirectCompositeInterface {
|
|||
fn create_surface(
|
||||
&mut self,
|
||||
id: webrender::NativeSurfaceId,
|
||||
_virtual_offset: DeviceIntPoint,
|
||||
tile_size: DeviceIntSize,
|
||||
is_opaque: bool,
|
||||
) {
|
||||
|
@ -89,6 +92,7 @@ impl webrender::Compositor for DirectCompositeInterface {
|
|||
&mut self,
|
||||
id: webrender::NativeTileId,
|
||||
dirty_rect: DeviceIntRect,
|
||||
_valid_rect: DeviceIntRect,
|
||||
) -> webrender::NativeSurfaceInfo {
|
||||
let (fbo_id, x, y) = compositor::bind_surface(
|
||||
self.window,
|
||||
|
@ -118,14 +122,15 @@ impl webrender::Compositor for DirectCompositeInterface {
|
|||
fn add_surface(
|
||||
&mut self,
|
||||
id: webrender::NativeSurfaceId,
|
||||
position: DeviceIntPoint,
|
||||
transform: CompositorSurfaceTransform,
|
||||
clip_rect: DeviceIntRect,
|
||||
_image_rendering: ImageRendering,
|
||||
) {
|
||||
compositor::add_surface(
|
||||
self.window,
|
||||
id.0,
|
||||
position.x,
|
||||
position.y,
|
||||
transform.transform_point2d(point2(0., 0.)).unwrap().x as i32,
|
||||
transform.transform_point2d(point2(0., 0.)).unwrap().y as i32,
|
||||
clip_rect.origin.x,
|
||||
clip_rect.origin.y,
|
||||
clip_rect.size.width,
|
||||
|
@ -136,6 +141,42 @@ impl webrender::Compositor for DirectCompositeInterface {
|
|||
fn end_frame(&mut self) {
|
||||
compositor::end_transaction(self.window);
|
||||
}
|
||||
fn create_external_surface(&mut self, _: webrender::NativeSurfaceId, _: bool) { todo!() }
|
||||
|
||||
fn attach_external_image(
|
||||
&mut self,
|
||||
_id: webrender::NativeSurfaceId,
|
||||
_external_image: ExternalImageId
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn enable_native_compositor(&mut self, _enable: bool) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn deinit(&mut self) {
|
||||
compositor::deinit(self.window);
|
||||
}
|
||||
|
||||
fn get_capabilities(&self) -> webrender::CompositorCapabilities {
|
||||
webrender::CompositorCapabilities {
|
||||
virtual_surface_size: 1024 * 1024,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn invalidate_tile(
|
||||
&mut self,
|
||||
_id: webrender::NativeTileId,
|
||||
_valid_rect: DeviceIntRect,
|
||||
) {}
|
||||
|
||||
fn start_compositing(
|
||||
&mut self,
|
||||
_dirty_rects: &[DeviceIntRect],
|
||||
_opaque_rects: &[DeviceIntRect],
|
||||
) {}
|
||||
}
|
||||
|
||||
// Simplisitic implementation of the WR notifier interface to know when a frame
|
||||
|
@ -159,7 +200,7 @@ impl RenderNotifier for Notifier {
|
|||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
fn wake_up(&self, _composite_needed: bool) {
|
||||
}
|
||||
|
||||
fn new_frame_ready(&self,
|
||||
|
@ -181,7 +222,7 @@ fn push_rotated_rect(
|
|||
time: f32,
|
||||
) {
|
||||
let color = color.scale_rgb(time);
|
||||
let rotation = LayoutTransform::create_rotation(
|
||||
let rotation = LayoutTransform::rotation(
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
|
@ -194,13 +235,16 @@ fn push_rotated_rect(
|
|||
);
|
||||
let transform = rotation
|
||||
.pre_translate(-transform_origin)
|
||||
.post_translate(transform_origin);
|
||||
.then_translate(transform_origin);
|
||||
let spatial_id = builder.push_reference_frame(
|
||||
LayoutPoint::zero(),
|
||||
spatial_id,
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Value(transform),
|
||||
ReferenceFrameKind::Transform,
|
||||
ReferenceFrameKind::Transform {
|
||||
is_2d_scale_translation: false,
|
||||
should_snap: false,
|
||||
},
|
||||
);
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
|
@ -235,7 +279,7 @@ fn build_display_list(
|
|||
|
||||
let scroll_space_info = builder.define_scroll_frame(
|
||||
&fixed_space_info,
|
||||
Some(scroll_id),
|
||||
scroll_id,
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||
ScrollSensitivity::Script,
|
||||
|
@ -289,6 +333,32 @@ fn build_display_list(
|
|||
0.1,
|
||||
time,
|
||||
);
|
||||
|
||||
push_rotated_rect(
|
||||
builder,
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(100.0, 600.0),
|
||||
LayoutSize::new(size_factor * 400.0, size_factor * 400.0),
|
||||
),
|
||||
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
||||
scroll_space_info.spatial_id,
|
||||
root_pipeline_id,
|
||||
time,
|
||||
time,
|
||||
);
|
||||
|
||||
push_rotated_rect(
|
||||
builder,
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(700.0, 600.0),
|
||||
LayoutSize::new(size_factor * 400.0, size_factor * 400.0),
|
||||
),
|
||||
ColorF::new(0.0, 1.0, 1.0, 1.0),
|
||||
scroll_space_info.spatial_id,
|
||||
root_pipeline_id,
|
||||
time,
|
||||
time,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -358,13 +428,15 @@ fn main() {
|
|||
} else {
|
||||
webrender::CompositorConfig::Draw {
|
||||
max_partial_present_rects: 0,
|
||||
draw_previous_partial_present_regions: false,
|
||||
partial_present: None,
|
||||
}
|
||||
};
|
||||
let opts = webrender::RendererOptions {
|
||||
clear_color: Some(ColorF::new(1.0, 1.0, 1.0, 1.0)),
|
||||
debug_flags,
|
||||
enable_picture_caching: true,
|
||||
compositor_config,
|
||||
surface_origin_is_top_left: false,
|
||||
..webrender::RendererOptions::default()
|
||||
};
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
@ -383,10 +455,9 @@ fn main() {
|
|||
notifier,
|
||||
opts,
|
||||
None,
|
||||
device_size,
|
||||
).unwrap();
|
||||
let api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
let mut api = sender.create_api();
|
||||
let document_id = api.add_document(device_size);
|
||||
let device_pixel_ratio = 1.0;
|
||||
let mut current_epoch = Epoch(0);
|
||||
let root_pipeline_id = PipelineId(0, 0);
|
||||
|
@ -399,7 +470,7 @@ fn main() {
|
|||
txn.set_root_pipeline(root_pipeline_id);
|
||||
|
||||
if let Invalidations::Scrolling = inv_mode {
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id);
|
||||
|
||||
build_display_list(
|
||||
&mut root_builder,
|
||||
|
@ -419,7 +490,7 @@ fn main() {
|
|||
);
|
||||
}
|
||||
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
// Tick the compositor (in this sample, we don't block on UI events)
|
||||
|
@ -429,7 +500,7 @@ fn main() {
|
|||
// Update and render. This will invoke the native compositor interface implemented above
|
||||
// as required.
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
renderer.render(device_size, 0).unwrap();
|
||||
let _ = renderer.flush_pipeline_info();
|
||||
|
||||
// Construct a simple display list that can be drawn and composited by DC.
|
||||
|
@ -437,7 +508,7 @@ fn main() {
|
|||
|
||||
match inv_mode {
|
||||
Invalidations::Small | Invalidations::Large => {
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id);
|
||||
|
||||
build_display_list(
|
||||
&mut root_builder,
|
||||
|
@ -466,7 +537,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
current_epoch.0 += 1;
|
||||
time += 0.001;
|
||||
|
|
8
third_party/webrender/examples/Cargo.toml
vendored
8
third_party/webrender/examples/Cargo.toml
vendored
|
@ -26,10 +26,6 @@ path = "blob.rs"
|
|||
name = "document"
|
||||
path = "document.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "frame_output"
|
||||
path = "frame_output.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "iframe"
|
||||
path = "iframe.rs"
|
||||
|
@ -55,13 +51,13 @@ name = "yuv"
|
|||
path = "yuv.rs"
|
||||
|
||||
[features]
|
||||
debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||
debug = ["webrender/capture", "webrender/profiler"]
|
||||
|
||||
[dependencies]
|
||||
app_units = "0.7"
|
||||
env_logger = "0.5"
|
||||
euclid = "0.22"
|
||||
gleam = "0.12"
|
||||
gleam = "0.15"
|
||||
glutin = "0.21"
|
||||
rayon = "1"
|
||||
webrender = { path = "../webrender" }
|
||||
|
|
11
third_party/webrender/examples/alpha_perf.rs
vendored
11
third_party/webrender/examples/alpha_perf.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -14,6 +14,7 @@ mod boilerplate;
|
|||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use std::cmp;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::DeviceIntSize;
|
||||
|
||||
|
||||
|
|
18
third_party/webrender/examples/animation.rs
vendored
18
third_party/webrender/examples/animation.rs
vendored
|
@ -10,11 +10,11 @@
|
|||
//! rounded cornered rectangle, which is done automatically during the
|
||||
//! scene building for render optimization.
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -22,6 +22,7 @@ mod boilerplate;
|
|||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::Angle;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
|
@ -62,7 +63,10 @@ impl App {
|
|||
SpatialId::root_scroll_node(pipeline_id),
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Binding(property_key, LayoutTransform::identity()),
|
||||
ReferenceFrameKind::Transform,
|
||||
ReferenceFrameKind::Transform {
|
||||
is_2d_scale_translation: false,
|
||||
should_snap: false,
|
||||
},
|
||||
);
|
||||
|
||||
builder.push_simple_stacking_context_with_filters(
|
||||
|
@ -194,7 +198,7 @@ impl Example for App {
|
|||
colors: vec![],
|
||||
},
|
||||
);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
_ => (),
|
||||
|
|
17
third_party/webrender/examples/basic.rs
vendored
17
third_party/webrender/examples/basic.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -17,6 +17,7 @@ use winit::TouchPhase;
|
|||
use std::collections::HashMap;
|
||||
use webrender::ShaderPrecacheFlags;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
|
@ -190,7 +191,7 @@ impl Example for App {
|
|||
pipeline_id: PipelineId,
|
||||
_document_id: DocumentId,
|
||||
) {
|
||||
let content_bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
let content_bounds = LayoutRect::new(LayoutPoint::zero(), LayoutSize::new(800.0, 600.0));
|
||||
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
let spatial_id = root_space_and_clip.spatial_id;
|
||||
|
||||
|
@ -220,6 +221,8 @@ impl Example for App {
|
|||
let mask_clip_id = builder.define_clip_image_mask(
|
||||
&root_space_and_clip,
|
||||
mask,
|
||||
&vec![],
|
||||
FillRule::Nonzero,
|
||||
);
|
||||
let clip_id = builder.define_clip_rounded_rect(
|
||||
&SpaceAndClipInfo {
|
||||
|
@ -312,7 +315,7 @@ impl Example for App {
|
|||
}
|
||||
|
||||
if !txn.is_empty() {
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
|
||||
|
|
13
third_party/webrender/examples/blob.rs
vendored
13
third_party/webrender/examples/blob.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gleam;
|
||||
use glutin;
|
||||
use rayon;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate rayon;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -16,9 +16,10 @@ use rayon::{ThreadPool, ThreadPoolBuilder};
|
|||
use rayon::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use webrender::api::{self, DisplayListBuilder, DocumentId, PipelineId, PrimitiveFlags, RenderApi, Transaction};
|
||||
use webrender::api::{self, DisplayListBuilder, DocumentId, PipelineId, PrimitiveFlags};
|
||||
use webrender::api::{ColorF, CommonItemProperties, SpaceAndClipInfo, ImageDescriptorFlags};
|
||||
use webrender::api::units::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::euclid::size2;
|
||||
|
||||
// This example shows how to implement a very basic BlobImageHandler that can only render
|
||||
|
|
|
@ -10,6 +10,7 @@ use webrender;
|
|||
use winit;
|
||||
use webrender::{DebugFlags, ShaderPrecacheFlags};
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
struct Notifier {
|
||||
|
@ -29,7 +30,7 @@ impl RenderNotifier for Notifier {
|
|||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
fn wake_up(&self, _composite_needed: bool) {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _ = self.events_proxy.wakeup();
|
||||
}
|
||||
|
@ -37,9 +38,9 @@ impl RenderNotifier for Notifier {
|
|||
fn new_frame_ready(&self,
|
||||
_: DocumentId,
|
||||
_scrolled: bool,
|
||||
_composite_needed: bool,
|
||||
composite_needed: bool,
|
||||
_render_time: Option<u64>) {
|
||||
self.wake_up();
|
||||
self.wake_up(composite_needed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,12 +89,11 @@ pub trait Example {
|
|||
) -> bool {
|
||||
false
|
||||
}
|
||||
fn get_image_handlers(
|
||||
fn get_image_handler(
|
||||
&mut self,
|
||||
_gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
(None, None)
|
||||
) -> Option<Box<dyn ExternalImageHandler>> {
|
||||
None
|
||||
}
|
||||
fn draw_custom(&mut self, _gl: &dyn gl::Gl) {
|
||||
}
|
||||
|
@ -183,16 +183,11 @@ pub fn main_wrapper<E: Example>(
|
|||
notifier,
|
||||
opts,
|
||||
None,
|
||||
device_size,
|
||||
).unwrap();
|
||||
let mut api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
let document_id = api.add_document(device_size);
|
||||
|
||||
let (external, output) = example.get_image_handlers(&*gl);
|
||||
|
||||
if let Some(output_image_handler) = output {
|
||||
renderer.set_output_image_handler(output_image_handler);
|
||||
}
|
||||
let external = example.get_image_handler(&*gl);
|
||||
|
||||
if let Some(external_image_handler) = external {
|
||||
renderer.set_external_image_handler(external_image_handler);
|
||||
|
@ -201,7 +196,7 @@ pub fn main_wrapper<E: Example>(
|
|||
let epoch = Epoch(0);
|
||||
let pipeline_id = PipelineId(0, 0);
|
||||
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id);
|
||||
let mut txn = Transaction::new();
|
||||
|
||||
example.render(
|
||||
|
@ -220,7 +215,7 @@ pub fn main_wrapper<E: Example>(
|
|||
true,
|
||||
);
|
||||
txn.set_root_pipeline(pipeline_id);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
println!("Entering event loop");
|
||||
|
@ -259,14 +254,10 @@ pub fn main_wrapper<E: Example>(
|
|||
winit::VirtualKeyCode::P => debug_flags.toggle(DebugFlags::PROFILER_DBG),
|
||||
winit::VirtualKeyCode::O => debug_flags.toggle(DebugFlags::RENDER_TARGET_DBG),
|
||||
winit::VirtualKeyCode::I => debug_flags.toggle(DebugFlags::TEXTURE_CACHE_DBG),
|
||||
winit::VirtualKeyCode::S => debug_flags.toggle(DebugFlags::COMPACT_PROFILER),
|
||||
winit::VirtualKeyCode::T => debug_flags.toggle(DebugFlags::PICTURE_CACHING_DBG),
|
||||
winit::VirtualKeyCode::Q => debug_flags.toggle(
|
||||
DebugFlags::GPU_TIME_QUERIES | DebugFlags::GPU_SAMPLE_QUERIES
|
||||
),
|
||||
winit::VirtualKeyCode::F => debug_flags.toggle(
|
||||
DebugFlags::NEW_FRAME_INDICATOR | DebugFlags::NEW_SCENE_INDICATOR
|
||||
),
|
||||
winit::VirtualKeyCode::G => debug_flags.toggle(DebugFlags::GPU_CACHE_DBG),
|
||||
winit::VirtualKeyCode::Key1 => txn.set_document_view(
|
||||
device_size.into(),
|
||||
|
@ -304,7 +295,7 @@ pub fn main_wrapper<E: Example>(
|
|||
}
|
||||
|
||||
if custom_event {
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id);
|
||||
|
||||
example.render(
|
||||
&mut api,
|
||||
|
@ -321,12 +312,12 @@ pub fn main_wrapper<E: Example>(
|
|||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
}
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
renderer.render(device_size, 0).unwrap();
|
||||
let _ = renderer.flush_pipeline_info();
|
||||
example.draw_custom(&*gl);
|
||||
windowed_context.swap_buffers().ok();
|
||||
|
|
30
third_party/webrender/examples/document.rs
vendored
30
third_party/webrender/examples/document.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -14,6 +14,7 @@ mod boilerplate;
|
|||
use crate::boilerplate::Example;
|
||||
use euclid::Scale;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
// This example creates multiple documents overlapping each other with
|
||||
|
@ -39,35 +40,31 @@ impl App {
|
|||
let init_data = vec![
|
||||
(
|
||||
PipelineId(1, 0),
|
||||
-2,
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||
DeviceIntPoint::new(0, 0),
|
||||
),
|
||||
(
|
||||
PipelineId(2, 0),
|
||||
-1,
|
||||
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
||||
DeviceIntPoint::new(200, 0),
|
||||
),
|
||||
(
|
||||
PipelineId(3, 0),
|
||||
0,
|
||||
ColorF::new(1.0, 0.0, 0.0, 1.0),
|
||||
DeviceIntPoint::new(200, 200),
|
||||
),
|
||||
(
|
||||
PipelineId(4, 0),
|
||||
1,
|
||||
ColorF::new(1.0, 0.0, 1.0, 1.0),
|
||||
DeviceIntPoint::new(0, 200),
|
||||
),
|
||||
];
|
||||
|
||||
for (pipeline_id, layer, color, offset) in init_data {
|
||||
for (pipeline_id, color, offset) in init_data {
|
||||
let size = DeviceIntSize::new(250, 250);
|
||||
let bounds = DeviceIntRect::new(offset, size);
|
||||
|
||||
let document_id = api.add_document(size, layer);
|
||||
let document_id = api.add_document(size);
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_document_view(bounds, device_pixel_ratio);
|
||||
txn.set_root_pipeline(pipeline_id);
|
||||
|
@ -90,25 +87,22 @@ impl Example for App {
|
|||
fn render(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
base_builder: &mut DisplayListBuilder,
|
||||
_base_builder: &mut DisplayListBuilder,
|
||||
_txn: &mut Transaction,
|
||||
device_size: DeviceIntSize,
|
||||
_device_size: DeviceIntSize,
|
||||
_pipeline_id: PipelineId,
|
||||
_: DocumentId,
|
||||
) {
|
||||
if self.documents.is_empty() {
|
||||
let device_pixel_ratio = device_size.width as f32 /
|
||||
base_builder.content_size().width;
|
||||
// this is the first run, hack around the boilerplate,
|
||||
// which assumes an example only needs one document
|
||||
self.init(api, device_pixel_ratio);
|
||||
self.init(api, 1.0);
|
||||
}
|
||||
|
||||
for doc in &self.documents {
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(doc.pipeline_id);
|
||||
let mut builder = DisplayListBuilder::new(
|
||||
doc.pipeline_id,
|
||||
doc.content_rect.size,
|
||||
);
|
||||
let local_rect = LayoutRect::new(
|
||||
LayoutPoint::zero(),
|
||||
|
@ -135,7 +129,7 @@ impl Example for App {
|
|||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(doc.id, txn);
|
||||
}
|
||||
}
|
||||
|
|
238
third_party/webrender/examples/frame_output.rs
vendored
238
third_party/webrender/examples/frame_output.rs
vendored
|
@ -1,238 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::Scale;
|
||||
use gleam::gl;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
// This example demonstrates using the frame output feature to copy
|
||||
// the output of a WR framebuffer to a custom texture.
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Document {
|
||||
id: DocumentId,
|
||||
pipeline_id: PipelineId,
|
||||
content_rect: LayoutRect,
|
||||
color: ColorF,
|
||||
}
|
||||
|
||||
|
||||
struct App {
|
||||
external_image_key: Option<ImageKey>,
|
||||
output_document: Option<Document>
|
||||
}
|
||||
|
||||
struct OutputHandler {
|
||||
texture_id: gl::GLuint
|
||||
}
|
||||
|
||||
struct ExternalHandler {
|
||||
texture_id: gl::GLuint
|
||||
}
|
||||
|
||||
impl OutputImageHandler for OutputHandler {
|
||||
fn lock(&mut self, _id: PipelineId) -> Option<(u32, FramebufferIntSize)> {
|
||||
Some((self.texture_id, FramebufferIntSize::new(500, 500)))
|
||||
}
|
||||
|
||||
fn unlock(&mut self, _id: PipelineId) {}
|
||||
}
|
||||
|
||||
impl ExternalImageHandler for ExternalHandler {
|
||||
fn lock(
|
||||
&mut self,
|
||||
_key: ExternalImageId,
|
||||
_channel_index: u8,
|
||||
_rendering: ImageRendering
|
||||
) -> ExternalImage {
|
||||
ExternalImage {
|
||||
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||
source: ExternalImageSource::NativeTexture(self.texture_id),
|
||||
}
|
||||
}
|
||||
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn init_output_document(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
device_size: DeviceIntSize,
|
||||
device_pixel_ratio: f32,
|
||||
) {
|
||||
// Generate the external image key that will be used to render the output document to the root document.
|
||||
self.external_image_key = Some(api.generate_image_key());
|
||||
|
||||
let pipeline_id = PipelineId(1, 0);
|
||||
let layer = 1;
|
||||
let color = ColorF::new(1., 1., 0., 1.);
|
||||
let document_id = api.add_document(device_size, layer);
|
||||
api.enable_frame_output(document_id, pipeline_id, true);
|
||||
api.set_document_view(
|
||||
document_id,
|
||||
device_size.into(),
|
||||
device_pixel_ratio,
|
||||
);
|
||||
|
||||
let document = Document {
|
||||
id: document_id,
|
||||
pipeline_id,
|
||||
content_rect: LayoutRect::new(
|
||||
LayoutPoint::zero(),
|
||||
device_size.to_f32() / Scale::new(device_pixel_ratio),
|
||||
),
|
||||
color,
|
||||
};
|
||||
|
||||
let mut txn = Transaction::new();
|
||||
|
||||
txn.add_image(
|
||||
self.external_image_key.unwrap(),
|
||||
ImageDescriptor::new(100, 100, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(0),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(TextureTarget::Default),
|
||||
}),
|
||||
None,
|
||||
);
|
||||
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
let mut builder = DisplayListBuilder::new(
|
||||
document.pipeline_id,
|
||||
document.content_rect.size,
|
||||
);
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
document.content_rect.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(document.content_rect, space_and_clip),
|
||||
document.content_rect,
|
||||
ColorF::new(1.0, 1.0, 0.0, 1.0)
|
||||
);
|
||||
builder.pop_stacking_context();
|
||||
|
||||
txn.set_root_pipeline(pipeline_id);
|
||||
txn.set_display_list(
|
||||
Epoch(0),
|
||||
Some(document.color),
|
||||
document.content_rect.size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document.id, txn);
|
||||
self.output_document = Some(document);
|
||||
}
|
||||
}
|
||||
|
||||
impl Example for App {
|
||||
fn render(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
builder: &mut DisplayListBuilder,
|
||||
_txn: &mut Transaction,
|
||||
device_size: DeviceIntSize,
|
||||
pipeline_id: PipelineId,
|
||||
_document_id: DocumentId,
|
||||
) {
|
||||
if self.output_document.is_none() {
|
||||
let device_pixel_ratio = device_size.width as f32 /
|
||||
builder.content_size().width;
|
||||
self.init_output_document(api, DeviceIntSize::new(200, 200), device_pixel_ratio);
|
||||
}
|
||||
|
||||
let bounds = (100, 100).to(200, 200);
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
builder.push_image(
|
||||
&CommonItemProperties::new(bounds, space_and_clip),
|
||||
bounds,
|
||||
ImageRendering::Auto,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
self.external_image_key.unwrap(),
|
||||
ColorF::WHITE,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn get_image_handlers(
|
||||
&mut self,
|
||||
gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
let texture_id = gl.gen_textures(1)[0];
|
||||
|
||||
gl.bind_texture(gl::TEXTURE_2D, texture_id);
|
||||
gl.tex_parameter_i(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TEXTURE_MAG_FILTER,
|
||||
gl::LINEAR as gl::GLint,
|
||||
);
|
||||
gl.tex_parameter_i(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TEXTURE_MIN_FILTER,
|
||||
gl::LINEAR as gl::GLint,
|
||||
);
|
||||
gl.tex_parameter_i(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TEXTURE_WRAP_S,
|
||||
gl::CLAMP_TO_EDGE as gl::GLint,
|
||||
);
|
||||
gl.tex_parameter_i(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TEXTURE_WRAP_T,
|
||||
gl::CLAMP_TO_EDGE as gl::GLint,
|
||||
);
|
||||
gl.tex_image_2d(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as gl::GLint,
|
||||
100,
|
||||
100,
|
||||
0,
|
||||
gl::BGRA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
None,
|
||||
);
|
||||
gl.bind_texture(gl::TEXTURE_2D, 0);
|
||||
|
||||
(
|
||||
Some(Box::new(ExternalHandler { texture_id })),
|
||||
Some(Box::new(OutputHandler { texture_id }))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
external_image_key: None,
|
||||
output_document: None
|
||||
};
|
||||
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
16
third_party/webrender/examples/iframe.rs
vendored
16
third_party/webrender/examples/iframe.rs
vendored
|
@ -2,16 +2,17 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
// This example uses the push_iframe API to nest a second pipeline's displaylist
|
||||
|
@ -35,7 +36,7 @@ impl Example for App {
|
|||
let sub_bounds = (0, 0).to(sub_size.width as i32, sub_size.height as i32);
|
||||
|
||||
let sub_pipeline_id = PipelineId(pipeline_id.0, 42);
|
||||
let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size);
|
||||
let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id);
|
||||
let mut space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
|
||||
sub_builder.push_simple_stacking_context(
|
||||
|
@ -67,7 +68,10 @@ impl Example for App {
|
|||
space_and_clip.spatial_id,
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Binding(PropertyBindingKey::new(42), LayoutTransform::identity()),
|
||||
ReferenceFrameKind::Transform,
|
||||
ReferenceFrameKind::Transform {
|
||||
is_2d_scale_translation: false,
|
||||
should_snap: false,
|
||||
},
|
||||
);
|
||||
|
||||
// And this is for the root pipeline
|
||||
|
|
11
third_party/webrender/examples/image_resize.rs
vendored
11
third_party/webrender/examples/image_resize.rs
vendored
|
@ -2,10 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -14,6 +14,7 @@ mod image_helper;
|
|||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
struct App {
|
||||
|
@ -103,7 +104,7 @@ impl Example for App {
|
|||
&DirtyRect::All,
|
||||
);
|
||||
let mut txn = Transaction::new();
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
_ => {}
|
||||
|
|
29
third_party/webrender/examples/multiwindow.rs
vendored
29
third_party/webrender/examples/multiwindow.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
use gleam::gl;
|
||||
use glutin::NotCurrent;
|
||||
|
@ -14,6 +14,7 @@ use std::fs::File;
|
|||
use std::io::Read;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::DebugFlags;
|
||||
use winit::dpi::LogicalSize;
|
||||
|
||||
|
@ -34,7 +35,7 @@ impl RenderNotifier for Notifier {
|
|||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
fn wake_up(&self, _composite_needed: bool) {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _ = self.events_proxy.wakeup();
|
||||
}
|
||||
|
@ -42,9 +43,9 @@ impl RenderNotifier for Notifier {
|
|||
fn new_frame_ready(&self,
|
||||
_: DocumentId,
|
||||
_scrolled: bool,
|
||||
_composite_needed: bool,
|
||||
composite_needed: bool,
|
||||
_render_time: Option<u64>) {
|
||||
self.wake_up();
|
||||
self.wake_up(composite_needed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,9 +105,9 @@ impl Window {
|
|||
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||
};
|
||||
let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
|
||||
let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts, None, device_size).unwrap();
|
||||
let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts, None).unwrap();
|
||||
let mut api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
let document_id = api.add_document(device_size);
|
||||
|
||||
let epoch = Epoch(0);
|
||||
let pipeline_id = PipelineId(0, 0);
|
||||
|
@ -183,10 +184,10 @@ impl Window {
|
|||
};
|
||||
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||
let mut txn = Transaction::new();
|
||||
let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);
|
||||
let mut builder = DisplayListBuilder::new(self.pipeline_id);
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
|
||||
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size);
|
||||
builder.push_simple_stacking_context(
|
||||
bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
|
@ -284,11 +285,11 @@ impl Window {
|
|||
true,
|
||||
);
|
||||
txn.set_root_pipeline(self.pipeline_id);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
api.send_transaction(self.document_id, txn);
|
||||
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
renderer.render(device_size, 0).unwrap();
|
||||
context.swap_buffers().ok();
|
||||
|
||||
self.context = Some(unsafe { context.make_not_current().unwrap() });
|
||||
|
|
82
third_party/webrender/examples/scrolling.rs
vendored
82
third_party/webrender/examples/scrolling.rs
vendored
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid;
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -14,12 +14,17 @@ mod boilerplate;
|
|||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::SideOffsets2D;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
use winit::dpi::LogicalPosition;
|
||||
|
||||
|
||||
const EXT_SCROLL_ID_ROOT: u64 = 1;
|
||||
const EXT_SCROLL_ID_CONTENT: u64 = 2;
|
||||
|
||||
struct App {
|
||||
cursor_position: WorldPoint,
|
||||
scroll_origin: LayoutPoint,
|
||||
}
|
||||
|
||||
impl Example for App {
|
||||
|
@ -51,7 +56,7 @@ impl Example for App {
|
|||
// set the scrolling clip
|
||||
let space_and_clip1 = builder.define_scroll_frame(
|
||||
&root_space_and_clip,
|
||||
None,
|
||||
ExternalScrollId(EXT_SCROLL_ID_ROOT, PipelineId::dummy()),
|
||||
(0, 0).by(1000, 1000),
|
||||
scrollbox,
|
||||
ScrollSensitivity::ScriptAndInputEvents,
|
||||
|
@ -60,22 +65,22 @@ impl Example for App {
|
|||
|
||||
// now put some content into it.
|
||||
// start with a white background
|
||||
let mut info = CommonItemProperties::new((0, 0).to(1000, 1000), space_and_clip1);
|
||||
info.hit_info = Some((0, 1));
|
||||
let info = CommonItemProperties::new((0, 0).to(1000, 1000), space_and_clip1);
|
||||
builder.push_hit_test(&info, (0, 1));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(1.0, 1.0, 1.0, 1.0));
|
||||
|
||||
// let's make a 50x50 blue square as a visual reference
|
||||
let mut info = CommonItemProperties::new((0, 0).to(50, 50), space_and_clip1);
|
||||
info.hit_info = Some((0, 2));
|
||||
let info = CommonItemProperties::new((0, 0).to(50, 50), space_and_clip1);
|
||||
builder.push_hit_test(&info, (0, 2));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
// and a 50x50 green square next to it with an offset clip
|
||||
// to see what that looks like
|
||||
let mut info = CommonItemProperties::new(
|
||||
let info = CommonItemProperties::new(
|
||||
(50, 0).to(100, 50).intersection(&(60, 10).to(110, 60)).unwrap(),
|
||||
space_and_clip1,
|
||||
);
|
||||
info.hit_info = Some((0, 3));
|
||||
builder.push_hit_test(&info, (0, 3));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 0.0, 1.0));
|
||||
|
||||
// Below the above rectangles, set up a nested scrollbox. It's still in
|
||||
|
@ -83,7 +88,7 @@ impl Example for App {
|
|||
// be relative to the stacking context.
|
||||
let space_and_clip2 = builder.define_scroll_frame(
|
||||
&space_and_clip1,
|
||||
None,
|
||||
ExternalScrollId(EXT_SCROLL_ID_CONTENT, PipelineId::dummy()),
|
||||
(0, 100).to(300, 1000),
|
||||
(0, 100).to(200, 300),
|
||||
ScrollSensitivity::ScriptAndInputEvents,
|
||||
|
@ -92,17 +97,17 @@ impl Example for App {
|
|||
|
||||
// give it a giant gray background just to distinguish it and to easily
|
||||
// visually identify the nested scrollbox
|
||||
let mut info = CommonItemProperties::new(
|
||||
let info = CommonItemProperties::new(
|
||||
(-1000, -1000).to(5000, 5000),
|
||||
space_and_clip2,
|
||||
);
|
||||
info.hit_info = Some((0, 4));
|
||||
builder.push_hit_test(&info, (0, 4));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.5, 0.5, 0.5, 1.0));
|
||||
|
||||
// add a teal square to visualize the scrolling/clipping behaviour
|
||||
// as you scroll the nested scrollbox
|
||||
let mut info = CommonItemProperties::new((0, 200).to(50, 250), space_and_clip2);
|
||||
info.hit_info = Some((0, 5));
|
||||
let info = CommonItemProperties::new((0, 200).to(50, 250), space_and_clip2);
|
||||
builder.push_hit_test(&info, (0, 5));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 1.0, 1.0));
|
||||
|
||||
// Add a sticky frame. It will "stick" twice while scrolling, once
|
||||
|
@ -118,14 +123,14 @@ impl Example for App {
|
|||
LayoutVector2D::new(0.0, 0.0)
|
||||
);
|
||||
|
||||
let mut info = CommonItemProperties::new(
|
||||
let info = CommonItemProperties::new(
|
||||
(50, 350).by(50, 50),
|
||||
SpaceAndClipInfo {
|
||||
spatial_id: sticky_id,
|
||||
clip_id: space_and_clip2.clip_id,
|
||||
},
|
||||
);
|
||||
info.hit_info = Some((0, 6));
|
||||
builder.push_hit_test(&info, (0, 6));
|
||||
builder.push_rect(
|
||||
&info,
|
||||
info.clip_rect,
|
||||
|
@ -134,11 +139,11 @@ impl Example for App {
|
|||
|
||||
// just for good measure add another teal square further down and to
|
||||
// the right, which can be scrolled into view by the user
|
||||
let mut info = CommonItemProperties::new(
|
||||
let info = CommonItemProperties::new(
|
||||
(250, 350).to(300, 400),
|
||||
space_and_clip2,
|
||||
);
|
||||
info.hit_info = Some((0, 7));
|
||||
builder.push_hit_test(&info, (0, 7));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 1.0, 1.0));
|
||||
|
||||
builder.pop_stacking_context();
|
||||
|
@ -159,10 +164,10 @@ impl Example for App {
|
|||
..
|
||||
} => {
|
||||
let offset = match key {
|
||||
winit::VirtualKeyCode::Down => Some((0.0, -10.0)),
|
||||
winit::VirtualKeyCode::Up => Some((0.0, 10.0)),
|
||||
winit::VirtualKeyCode::Right => Some((-10.0, 0.0)),
|
||||
winit::VirtualKeyCode::Left => Some((10.0, 0.0)),
|
||||
winit::VirtualKeyCode::Down => Some(LayoutVector2D::new(0.0, -10.0)),
|
||||
winit::VirtualKeyCode::Up => Some(LayoutVector2D::new(0.0, 10.0)),
|
||||
winit::VirtualKeyCode::Right => Some(LayoutVector2D::new(-10.0, 0.0)),
|
||||
winit::VirtualKeyCode::Left => Some(LayoutVector2D::new(10.0, 0.0)),
|
||||
_ => None,
|
||||
};
|
||||
let zoom = match key {
|
||||
|
@ -173,15 +178,18 @@ impl Example for App {
|
|||
};
|
||||
|
||||
if let Some(offset) = offset {
|
||||
txn.scroll(
|
||||
ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
|
||||
self.cursor_position,
|
||||
self.scroll_origin += offset;
|
||||
|
||||
txn.scroll_node_with_id(
|
||||
self.scroll_origin,
|
||||
ExternalScrollId(EXT_SCROLL_ID_CONTENT, PipelineId::dummy()),
|
||||
ScrollClamping::ToContentBounds,
|
||||
);
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
}
|
||||
if let Some(zoom) = zoom {
|
||||
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||
txn.generate_frame();
|
||||
txn.generate_frame(0);
|
||||
}
|
||||
}
|
||||
winit::WindowEvent::CursorMoved { position: LogicalPosition { x, y }, .. } => {
|
||||
|
@ -194,18 +202,21 @@ impl Example for App {
|
|||
winit::MouseScrollDelta::PixelDelta(pos) => (pos.x as f32, pos.y as f32),
|
||||
};
|
||||
|
||||
txn.scroll(
|
||||
ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
|
||||
self.cursor_position,
|
||||
self.scroll_origin += LayoutVector2D::new(dx, dy);
|
||||
|
||||
txn.scroll_node_with_id(
|
||||
self.scroll_origin,
|
||||
ExternalScrollId(EXT_SCROLL_ID_CONTENT, PipelineId::dummy()),
|
||||
ScrollClamping::ToContentBounds,
|
||||
);
|
||||
txn.generate_frame();
|
||||
|
||||
txn.generate_frame(0);
|
||||
}
|
||||
winit::WindowEvent::MouseInput { .. } => {
|
||||
let results = api.hit_test(
|
||||
document_id,
|
||||
None,
|
||||
self.cursor_position,
|
||||
HitTestFlags::FIND_ALL
|
||||
);
|
||||
|
||||
println!("Hit test results:");
|
||||
|
@ -226,6 +237,7 @@ impl Example for App {
|
|||
fn main() {
|
||||
let mut app = App {
|
||||
cursor_position: WorldPoint::zero(),
|
||||
scroll_origin: LayoutPoint::zero(),
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -14,6 +14,7 @@ use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
|||
use gleam::gl;
|
||||
use std::mem;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
|
@ -301,12 +302,11 @@ impl Example for App {
|
|||
false
|
||||
}
|
||||
|
||||
fn get_image_handlers(
|
||||
fn get_image_handler(
|
||||
&mut self,
|
||||
_gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
(Some(Box::new(ImageGenerator::new())), None)
|
||||
) -> Option<Box<dyn ExternalImageHandler>> {
|
||||
Some(Box::new(ImageGenerator::new()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
27
third_party/webrender/examples/yuv.rs
vendored
27
third_party/webrender/examples/yuv.rs
vendored
|
@ -2,10 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gleam;
|
||||
use glutin;
|
||||
use webrender;
|
||||
use winit;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
@ -13,6 +13,7 @@ mod boilerplate;
|
|||
use crate::boilerplate::Example;
|
||||
use gleam::gl;
|
||||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
|
@ -93,7 +94,7 @@ impl Example for App {
|
|||
pipeline_id: PipelineId,
|
||||
_document_id: DocumentId,
|
||||
) {
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), LayoutSize::new(500.0, 500.0));
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
|
@ -113,7 +114,7 @@ impl Example for App {
|
|||
id: ExternalImageId(0),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
|
@ -125,7 +126,7 @@ impl Example for App {
|
|||
id: ExternalImageId(1),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
|
@ -137,7 +138,7 @@ impl Example for App {
|
|||
id: ExternalImageId(2),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
|
@ -149,7 +150,7 @@ impl Example for App {
|
|||
id: ExternalImageId(3),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
|
@ -195,14 +196,13 @@ impl Example for App {
|
|||
false
|
||||
}
|
||||
|
||||
fn get_image_handlers(
|
||||
fn get_image_handler(
|
||||
&mut self,
|
||||
gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
) -> Option<Box<dyn ExternalImageHandler>> {
|
||||
let provider = YuvImageProvider::new(gl);
|
||||
self.texture_id = provider.texture_ids[0];
|
||||
(Some(Box::new(provider)), None)
|
||||
Some(Box::new(provider))
|
||||
}
|
||||
|
||||
fn draw_custom(&mut self, gl: &dyn gl::Gl) {
|
||||
|
@ -218,7 +218,6 @@ fn main() {
|
|||
};
|
||||
|
||||
let opts = webrender::RendererOptions {
|
||||
debug_flags: webrender::DebugFlags::NEW_FRAME_INDICATOR | webrender::DebugFlags::NEW_SCENE_INDICATOR,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
2
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
2
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
|
@ -2,7 +2,7 @@
|
|||
name = "glsl-to-cxx"
|
||||
version = "0.1.0"
|
||||
license = "MPL-2.0"
|
||||
authors = ["The Mozilla Project Developers"]
|
||||
authors = ["The Mozilla Project Developers", "Dimitri Sabadie"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
18
third_party/webrender/glsl-to-cxx/README.md
vendored
18
third_party/webrender/glsl-to-cxx/README.md
vendored
|
@ -1,3 +1,21 @@
|
|||
A GLSL to C++ translator.
|
||||
|
||||
Translates GLSL to vectorized C++. Intended for use with WebRender software backend.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
GLSL code is parsed by the glsl crate. In hir.rs we traverse the resulting AST
|
||||
and build a higher level representation by doing type checking and name
|
||||
resolution. The resulting hir tree is traversed by lib.rs to output C++ code.
|
||||
|
||||
The generated C++ code is 4x wider then the original glsl. i.e. a glsl 'float'
|
||||
becomes a C++ 'Float' which is represented by a xmm register (a vector of 4 floats).
|
||||
Likewise, a vec4 becomes a struct of 4 'Float's for a total of 4 xmm registers and
|
||||
16 floating point values.
|
||||
|
||||
Vector branching is flattened to non-branching code that unconditionally runs both
|
||||
sides of the branch and combines the results with a mask based on the condition.
|
||||
|
||||
The compiler also supports scalarization. Values that are known to be the same
|
||||
across all vector lanes are translated to scalars instead of vectors. Branches on
|
||||
scalars are translated as actual branches.
|
||||
|
|
1015
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
1015
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
File diff suppressed because it is too large
Load diff
358
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
358
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use glsl;
|
||||
extern crate glsl;
|
||||
|
||||
mod hir;
|
||||
|
||||
|
@ -61,8 +61,6 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
|
|||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
let frag_include = args.next();
|
||||
|
||||
let (vs_state, vs_hir, vs_is_frag) = parse_shader(vertex_file);
|
||||
let (fs_state, fs_hir, fs_is_frag) = parse_shader(frag_file);
|
||||
|
||||
|
@ -79,7 +77,6 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
|
|||
vs_hir,
|
||||
vs_is_frag,
|
||||
&uniform_indices,
|
||||
None,
|
||||
);
|
||||
result += "\n";
|
||||
result += &translate_shader(
|
||||
|
@ -88,7 +85,6 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
|
|||
fs_hir,
|
||||
fs_is_frag,
|
||||
&uniform_indices,
|
||||
frag_include,
|
||||
);
|
||||
result
|
||||
}
|
||||
|
@ -120,7 +116,6 @@ fn translate_shader(
|
|||
hir: hir::TranslationUnit,
|
||||
is_frag: bool,
|
||||
uniform_indices: &UniformIndices,
|
||||
include_file: Option<String>,
|
||||
) -> String {
|
||||
//println!("{:#?}", state);
|
||||
|
||||
|
@ -185,8 +180,6 @@ fn translate_shader(
|
|||
uses_discard: false,
|
||||
used_fragcoord: Cell::new(0),
|
||||
use_perspective: false,
|
||||
has_draw_span_rgba8: false,
|
||||
has_draw_span_r8: false,
|
||||
used_globals: RefCell::new(Vec::new()),
|
||||
texel_fetches: RefCell::new(Vec::new()),
|
||||
};
|
||||
|
@ -215,10 +208,6 @@ fn translate_shader(
|
|||
|
||||
show_translation_unit(&mut state, &hir);
|
||||
|
||||
if let Some(include_file) = include_file {
|
||||
write_include_file(&mut state, include_file);
|
||||
}
|
||||
|
||||
let pruned_inputs: Vec<_> = inputs
|
||||
.iter()
|
||||
.filter(|i| state.used_globals.borrow().contains(i))
|
||||
|
@ -250,6 +239,7 @@ fn translate_shader(
|
|||
write!(state, " return this;\n}}\n");
|
||||
write!(state, "FragmentShaderImpl* get_fragment_shader() override {{\n");
|
||||
write!(state, " return this;\n}}\n");
|
||||
write!(state, "const char* get_name() const override {{ return \"{}\"; }}\n", name);
|
||||
write!(state, "static ProgramImpl* loader() {{ return new {}_program; }}\n", name);
|
||||
write!(state, "}};\n\n");
|
||||
}
|
||||
|
@ -302,8 +292,7 @@ fn write_program_samplers(state: &mut OutputState, uniform_indices: &UniformIndi
|
|||
match tk {
|
||||
hir::TypeKind::Sampler2D
|
||||
| hir::TypeKind::Sampler2DRect
|
||||
| hir::TypeKind::ISampler2D
|
||||
| hir::TypeKind::Sampler2DArray => {
|
||||
| hir::TypeKind::ISampler2D => {
|
||||
write!(state, " ");
|
||||
show_type_kind(state, &tk);
|
||||
let suffix = if let hir::StorageClass::Sampler(format) = storage {
|
||||
|
@ -326,8 +315,7 @@ fn write_program_samplers(state: &mut OutputState, uniform_indices: &UniformIndi
|
|||
match tk {
|
||||
hir::TypeKind::Sampler2D
|
||||
| hir::TypeKind::Sampler2DRect
|
||||
| hir::TypeKind::ISampler2D
|
||||
| hir::TypeKind::Sampler2DArray => {
|
||||
| hir::TypeKind::ISampler2D => {
|
||||
write!(state, " case {}:\n", index);
|
||||
write!(state, " {}_slot = value;\n", name);
|
||||
write!(state, " return true;\n");
|
||||
|
@ -355,9 +343,6 @@ fn write_bind_textures(state: &mut OutputState, uniforms: &UniformIndices) {
|
|||
hir::TypeKind::ISampler2D => write!(state,
|
||||
" {0} = lookup_isampler(&samplers.{0}_impl, samplers.{0}_slot);\n",
|
||||
name),
|
||||
hir::TypeKind::Sampler2DArray => write!(state,
|
||||
" {0} = lookup_sampler_array(&samplers.{0}_impl, samplers.{0}_slot);\n",
|
||||
name),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
@ -408,9 +393,8 @@ fn write_set_uniform_4fv(
|
|||
if float4_compatible(tk.clone()) {
|
||||
write!(
|
||||
state,
|
||||
" self->{} = {}_scalar(value);\n",
|
||||
name,
|
||||
tk.glsl_primitive_type_name().unwrap(),
|
||||
" self->{} = vec4_scalar::load_from_ptr(value);\n",
|
||||
name
|
||||
);
|
||||
} else {
|
||||
write!(state, " assert(0); // {}\n", name);
|
||||
|
@ -551,6 +535,9 @@ fn write_load_attribs(state: &mut OutputState, attribs: &[hir::SymRef]) {
|
|||
fn write_store_outputs(state: &mut OutputState, outputs: &[hir::SymRef]) {
|
||||
let is_scalar = state.is_scalar.replace(true);
|
||||
write!(state, "public:\nstruct InterpOutputs {{\n");
|
||||
if state.hir.used_clip_dist != 0 {
|
||||
state.write(" Float swgl_ClipDistance;\n");
|
||||
}
|
||||
for i in outputs {
|
||||
let sym = state.hir.sym(*i);
|
||||
match &sym.decl {
|
||||
|
@ -576,6 +563,15 @@ fn write_store_outputs(state: &mut OutputState, outputs: &[hir::SymRef]) {
|
|||
state,
|
||||
" auto* dest = reinterpret_cast<InterpOutputs*>(dest_ptr);\n"
|
||||
);
|
||||
if state.hir.used_clip_dist != 0 {
|
||||
for (i, comp) in "xyzw".chars().enumerate() {
|
||||
if (state.hir.used_clip_dist & (1 << i)) != 0 {
|
||||
write!(state, " dest->swgl_ClipDistance.{} = get_nth(gl_ClipDistance[{}], n);\n", comp, i);
|
||||
} else {
|
||||
write!(state, " dest->swgl_ClipDistance.{} = 0.0f;\n", comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
for i in outputs {
|
||||
let sym = state.hir.sym(*i);
|
||||
match &sym.decl {
|
||||
|
@ -626,7 +622,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
|
||||
write!(state,
|
||||
"static void read_interp_inputs(\
|
||||
Self *self, const InterpInputs *init, const InterpInputs *step, float step_width) {{\n");
|
||||
Self *self, const InterpInputs *init, const InterpInputs *step) {{\n");
|
||||
for i in inputs {
|
||||
let sym = state.hir.sym(*i);
|
||||
match &sym.decl {
|
||||
|
@ -640,7 +636,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
);
|
||||
write!(
|
||||
state,
|
||||
" self->interp_step.{0} = step->{0} * step_width;\n",
|
||||
" self->interp_step.{0} = step->{0} * 4.0f;\n",
|
||||
name
|
||||
);
|
||||
}
|
||||
|
@ -657,7 +653,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
if state.use_perspective {
|
||||
write!(state,
|
||||
"static void read_perspective_inputs(\
|
||||
Self *self, const InterpInputs *init, const InterpInputs *step, float step_width) {{\n");
|
||||
Self *self, const InterpInputs *init, const InterpInputs *step) {{\n");
|
||||
if has_varying {
|
||||
write!(state, " Float w = 1.0f / self->gl_FragCoord.w;\n");
|
||||
}
|
||||
|
@ -675,7 +671,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
write!(state, " self->{0} = self->interp_perspective.{0} * w;\n", name);
|
||||
write!(
|
||||
state,
|
||||
" self->interp_step.{0} = step->{0} * step_width;\n",
|
||||
" self->interp_step.{0} = step->{0} * 4.0f;\n",
|
||||
name
|
||||
);
|
||||
}
|
||||
|
@ -686,9 +682,12 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
write!(state, "}}\n");
|
||||
}
|
||||
|
||||
write!(state, "ALWAYS_INLINE void step_interp_inputs() {{\n");
|
||||
write!(state, "ALWAYS_INLINE void step_interp_inputs(int steps = 4) {{\n");
|
||||
if (used_fragcoord & 1) != 0 {
|
||||
write!(state, " step_fragcoord();\n");
|
||||
write!(state, " step_fragcoord(steps);\n");
|
||||
}
|
||||
if !inputs.is_empty() {
|
||||
write!(state, " float chunks = steps * 0.25f;\n");
|
||||
}
|
||||
for i in inputs {
|
||||
let sym = state.hir.sym(*i);
|
||||
|
@ -696,7 +695,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
hir::SymDecl::Global(_, _, _, run_class) => {
|
||||
if *run_class != hir::RunClass::Scalar {
|
||||
let name = sym.name.as_str();
|
||||
write!(state, " {0} += interp_step.{0};\n", name);
|
||||
write!(state, " {0} += interp_step.{0} * chunks;\n", name);
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
|
@ -705,11 +704,14 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
write!(state, "}}\n");
|
||||
|
||||
if state.use_perspective {
|
||||
write!(state, "ALWAYS_INLINE void step_perspective_inputs() {{\n");
|
||||
write!(state, "ALWAYS_INLINE void step_perspective_inputs(int steps = 4) {{\n");
|
||||
if (used_fragcoord & 1) != 0 {
|
||||
write!(state, " step_fragcoord();\n");
|
||||
write!(state, " step_fragcoord(steps);\n");
|
||||
}
|
||||
write!(state, " step_perspective(steps);\n");
|
||||
if !inputs.is_empty() {
|
||||
write!(state, " float chunks = steps * 0.25f;\n");
|
||||
}
|
||||
write!(state, " step_perspective();\n");
|
||||
if has_varying {
|
||||
write!(state, " Float w = 1.0f / gl_FragCoord.w;\n");
|
||||
}
|
||||
|
@ -719,7 +721,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
hir::SymDecl::Global(_, _, _, run_class) => {
|
||||
if *run_class != hir::RunClass::Scalar {
|
||||
let name = sym.name.as_str();
|
||||
write!(state, " interp_perspective.{0} += interp_step.{0};\n", name);
|
||||
write!(state, " interp_perspective.{0} += interp_step.{0} * chunks;\n", name);
|
||||
write!(state, " {0} = w * interp_perspective.{0};\n", name);
|
||||
}
|
||||
}
|
||||
|
@ -728,58 +730,6 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
|
|||
}
|
||||
write!(state, "}}\n");
|
||||
}
|
||||
|
||||
if state.has_draw_span_rgba8 || state.has_draw_span_r8 {
|
||||
write!(
|
||||
state,
|
||||
"ALWAYS_INLINE void step_interp_inputs(int chunks) {{\n"
|
||||
);
|
||||
if (used_fragcoord & 1) != 0 {
|
||||
write!(state, " step_fragcoord(chunks);\n");
|
||||
}
|
||||
for i in inputs {
|
||||
let sym = state.hir.sym(*i);
|
||||
match &sym.decl {
|
||||
hir::SymDecl::Global(_, _, _, run_class) => {
|
||||
if *run_class != hir::RunClass::Scalar {
|
||||
let name = sym.name.as_str();
|
||||
write!(state, " {0} += interp_step.{0} * chunks;\n", name);
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
write!(state, "}}\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn write_include_file(state: &mut OutputState, include_file: String) {
|
||||
let include_contents = std::fs::read_to_string(&include_file).unwrap();
|
||||
|
||||
let mut offset = 0;
|
||||
while offset < include_contents.len() {
|
||||
let s = &include_contents[offset ..];
|
||||
if let Some(start_proto) = s.find("draw_span") {
|
||||
let s = &s[start_proto ..];
|
||||
if let Some(end_proto) = s.find(')') {
|
||||
let proto = &s[.. end_proto];
|
||||
if proto.contains("uint32_t") {
|
||||
state.has_draw_span_rgba8 = true;
|
||||
} else if proto.contains("uint8_t") {
|
||||
state.has_draw_span_r8 = true;
|
||||
}
|
||||
offset += start_proto + end_proto;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
let include_name = std::path::Path::new(&include_file)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy();
|
||||
write!(state, "\n#include \"{}\"\n\n", include_name);
|
||||
}
|
||||
|
||||
pub struct OutputState {
|
||||
|
@ -804,8 +754,6 @@ pub struct OutputState {
|
|||
uses_discard: bool,
|
||||
used_fragcoord: Cell<i32>,
|
||||
use_perspective: bool,
|
||||
has_draw_span_rgba8: bool,
|
||||
has_draw_span_r8: bool,
|
||||
used_globals: RefCell<Vec<hir::SymRef>>,
|
||||
texel_fetches: RefCell<Vec<(hir::SymRef, hir::SymRef, hir::TexelFetchOffsets)>>,
|
||||
}
|
||||
|
@ -874,7 +822,7 @@ fn add_used_global(state: &OutputState, i: &hir::SymRef) {
|
|||
pub fn show_sym(state: &OutputState, i: &hir::SymRef) {
|
||||
let sym = state.hir.sym(*i);
|
||||
match &sym.decl {
|
||||
hir::SymDecl::NativeFunction(_, ref cxx_name) => {
|
||||
hir::SymDecl::NativeFunction(_, ref cxx_name, _) => {
|
||||
let mut name = sym.name.as_str();
|
||||
if state.output_cxx {
|
||||
name = cxx_name.unwrap_or(name);
|
||||
|
@ -1567,8 +1515,10 @@ fn expr_run_class(state: &OutputState, expr: &hir::Expr) -> hir::RunClass {
|
|||
});
|
||||
match fun {
|
||||
hir::FunIdentifier::Identifier(ref sym) => match &state.hir.sym(*sym).decl {
|
||||
hir::SymDecl::NativeFunction(..) => {
|
||||
if arg_mask != 0 {
|
||||
hir::SymDecl::NativeFunction(_, _, ref ret_class) => {
|
||||
if *ret_class != hir::RunClass::Unknown {
|
||||
*ret_class
|
||||
} else if arg_mask != 0 {
|
||||
hir::RunClass::Vector
|
||||
} else {
|
||||
hir::RunClass::Scalar
|
||||
|
@ -1896,33 +1846,21 @@ pub fn show_hir_expr_inner(state: &OutputState, expr: &hir::Expr, top_level: boo
|
|||
&state.hir, &args[0], &args[1], &args[3],
|
||||
) {
|
||||
let base_sym = state.hir.sym(base);
|
||||
if symbol_run_class(&base_sym.decl, state.vector_mask)
|
||||
== hir::RunClass::Scalar
|
||||
{
|
||||
let sampler_sym = state.hir.sym(sampler);
|
||||
add_used_global(state, &sampler);
|
||||
if let hir::SymDecl::Global(..) = &base_sym.decl {
|
||||
add_used_global(state, &base);
|
||||
}
|
||||
if y != 0 {
|
||||
write!(
|
||||
state,
|
||||
"{}_{}_fetch[{}+{}*{}->stride]",
|
||||
sampler_sym.name,
|
||||
base_sym.name,
|
||||
x,
|
||||
y,
|
||||
sampler_sym.name
|
||||
);
|
||||
} else {
|
||||
write!(
|
||||
state,
|
||||
"{}_{}_fetch[{}]",
|
||||
sampler_sym.name, base_sym.name, x
|
||||
);
|
||||
}
|
||||
return;
|
||||
let sampler_sym = state.hir.sym(sampler);
|
||||
add_used_global(state, &sampler);
|
||||
if let hir::SymDecl::Global(..) = &base_sym.decl {
|
||||
add_used_global(state, &base);
|
||||
}
|
||||
write!(
|
||||
state,
|
||||
"texelFetchUnchecked({}, {}_{}_fetch, {}, {})",
|
||||
sampler_sym.name,
|
||||
sampler_sym.name,
|
||||
base_sym.name,
|
||||
x,
|
||||
y,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
show_sym(state, name)
|
||||
|
@ -2358,15 +2296,12 @@ pub fn show_declaration(state: &mut OutputState, d: &hir::Declaration) {
|
|||
let base = list.head.name;
|
||||
let base_sym = state.hir.sym(base);
|
||||
if let hir::SymDecl::Local(..) = &base_sym.decl {
|
||||
if symbol_run_class(&base_sym.decl, state.vector_mask) == hir::RunClass::Scalar
|
||||
let mut texel_fetches = state.texel_fetches.borrow_mut();
|
||||
while let Some(idx) = texel_fetches.iter().position(|&(_, b, _)| b == base)
|
||||
{
|
||||
let mut texel_fetches = state.texel_fetches.borrow_mut();
|
||||
while let Some(idx) = texel_fetches.iter().position(|&(_, b, _)| b == base)
|
||||
{
|
||||
let (sampler, _, offsets) = texel_fetches.remove(idx);
|
||||
let sampler_sym = state.hir.sym(sampler);
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
}
|
||||
let (sampler, _, offsets) = texel_fetches.remove(idx);
|
||||
let sampler_sym = state.hir.sym(sampler);
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2384,19 +2319,22 @@ pub fn show_declaration(state: &mut OutputState, d: &hir::Declaration) {
|
|||
//state.write(";\n");
|
||||
}
|
||||
hir::Declaration::Global(ref qual, ref identifiers) => {
|
||||
show_type_qualifier(state, &qual);
|
||||
// We only want to output GLSL layout qualifiers if not C++
|
||||
if !state.output_cxx {
|
||||
show_type_qualifier(state, &qual);
|
||||
|
||||
if !identifiers.is_empty() {
|
||||
let mut iter = identifiers.iter();
|
||||
let first = iter.next().unwrap();
|
||||
show_identifier(state, first);
|
||||
if !identifiers.is_empty() {
|
||||
let mut iter = identifiers.iter();
|
||||
let first = iter.next().unwrap();
|
||||
show_identifier(state, first);
|
||||
|
||||
for identifier in iter {
|
||||
let _ = write!(state, ", {}", identifier);
|
||||
for identifier in iter {
|
||||
let _ = write!(state, ", {}", identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.write(";\n");
|
||||
state.write(";\n");
|
||||
}
|
||||
}
|
||||
hir::Declaration::StructDefinition(ref sym) => {
|
||||
show_sym_decl(state, sym);
|
||||
|
@ -2672,32 +2610,32 @@ fn define_texel_fetch_ptr(
|
|||
offsets: &hir::TexelFetchOffsets,
|
||||
) {
|
||||
show_indent(state);
|
||||
if let hir::SymDecl::Global(_, _, ty, _) = &sampler_sym.decl {
|
||||
match ty.kind {
|
||||
hir::TypeKind::Sampler2D
|
||||
| hir::TypeKind::Sampler2DRect => {
|
||||
write!(
|
||||
state,
|
||||
"vec4_scalar* {}_{}_fetch = ",
|
||||
sampler_sym.name, base_sym.name
|
||||
);
|
||||
let ptr_type = if let hir::SymDecl::Global(_, _, ty, _) = &sampler_sym.decl {
|
||||
if symbol_run_class(&base_sym.decl, state.vector_mask) == hir::RunClass::Scalar {
|
||||
match ty.kind {
|
||||
hir::TypeKind::Sampler2D
|
||||
| hir::TypeKind::Sampler2DRect => "vec4_scalar*",
|
||||
hir::TypeKind::ISampler2D => "ivec4_scalar*",
|
||||
_ => panic!(),
|
||||
}
|
||||
hir::TypeKind::ISampler2D => {
|
||||
write!(
|
||||
state,
|
||||
"ivec4_scalar* {}_{}_fetch = ",
|
||||
sampler_sym.name, base_sym.name
|
||||
);
|
||||
}
|
||||
_ => panic!(),
|
||||
} else {
|
||||
"I32"
|
||||
}
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
};
|
||||
write!(
|
||||
state,
|
||||
"texelFetchPtr({}, {}, {}, {}, {}, {});\n",
|
||||
sampler_sym.name, base_sym.name, offsets.min_x, offsets.max_x, offsets.min_y, offsets.max_y
|
||||
"{} {}_{}_fetch = texelFetchPtr({}, {}, {}, {}, {}, {});\n",
|
||||
ptr_type,
|
||||
sampler_sym.name,
|
||||
base_sym.name,
|
||||
sampler_sym.name,
|
||||
base_sym.name,
|
||||
offsets.min_x,
|
||||
offsets.max_x,
|
||||
offsets.min_y,
|
||||
offsets.max_y,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2750,27 +2688,64 @@ pub fn show_function_definition(
|
|||
}
|
||||
|
||||
if state.output_cxx {
|
||||
match fd.prototype.name.as_str() {
|
||||
"swgl_drawSpanRGBA8" |
|
||||
"swgl_drawSpanR8" => {
|
||||
// Partial spans are not drawn using span shaders, but rather drawn with a fragment shader
|
||||
// where the span shader left off. We need to undo any changes to the interpolants made by
|
||||
// the span shaders so that we can reset the interpolants to where the fragment shader
|
||||
// expects them. We do this by saving them in an _Undo_ struct on entry to the span shader,
|
||||
// and then restore them in the _Undo_ struct destructor.
|
||||
let mut needs_undo = vec![];
|
||||
for global in &fd.globals {
|
||||
let sym = state.hir.sym(*global);
|
||||
match &sym.decl {
|
||||
hir::SymDecl::Global(hir::StorageClass::In, _, ty, hir::RunClass::Vector) => {
|
||||
if needs_undo.is_empty() {
|
||||
state.write("struct _Undo_ {\nSelf* self;\n");
|
||||
}
|
||||
show_type(state, ty);
|
||||
write!(state, " {};\n", sym.name);
|
||||
needs_undo.push(sym.name.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !needs_undo.is_empty() {
|
||||
state.write("explicit _Undo_(Self* self) : self(self)");
|
||||
for name in &needs_undo {
|
||||
write!(state, ", {0}(self->{0})", name);
|
||||
}
|
||||
state.write(" {}\n");
|
||||
state.write("~_Undo_() {\n");
|
||||
for name in &needs_undo {
|
||||
write!(state, "self->{0} = {0};\n", name);
|
||||
}
|
||||
state.write("}} _undo_(this);\n");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let mut texel_fetches = state.texel_fetches.borrow_mut();
|
||||
texel_fetches.clear();
|
||||
for ((sampler, base), offsets) in fd.texel_fetches.iter() {
|
||||
add_used_global(state, sampler);
|
||||
let sampler_sym = state.hir.sym(*sampler);
|
||||
let base_sym = state.hir.sym(*base);
|
||||
if symbol_run_class(&base_sym.decl, vector_mask) == hir::RunClass::Scalar {
|
||||
add_used_global(state, sampler);
|
||||
let sampler_sym = state.hir.sym(*sampler);
|
||||
match &base_sym.decl {
|
||||
hir::SymDecl::Global(..) => {
|
||||
add_used_global(state, base);
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
}
|
||||
hir::SymDecl::Local(..) => {
|
||||
if fd.prototype.has_parameter(*base) {
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
} else {
|
||||
texel_fetches.push((*sampler, *base, offsets.clone()));
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
match &base_sym.decl {
|
||||
hir::SymDecl::Global(..) => {
|
||||
add_used_global(state, base);
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
}
|
||||
hir::SymDecl::Local(..) => {
|
||||
if fd.prototype.has_parameter(*base) {
|
||||
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
|
||||
} else {
|
||||
texel_fetches.push((*sampler, *base, offsets.clone()));
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3195,7 +3170,7 @@ pub fn show_iteration_statement(state: &mut OutputState, ist: &hir::IterationSta
|
|||
show_statement(state, body);
|
||||
state.write(" while (");
|
||||
show_hir_expr(state, cond);
|
||||
state.write(")\n");
|
||||
state.write(");\n");
|
||||
}
|
||||
hir::IterationStatement::For(ref init, ref rest, ref body) => {
|
||||
state.write("for (");
|
||||
|
@ -3266,7 +3241,7 @@ pub fn show_jump_statement(state: &mut OutputState, j: &hir::JumpStatement) {
|
|||
if state.output_cxx {
|
||||
state.uses_discard = true;
|
||||
if let Some(mask) = &state.mask {
|
||||
state.write("isPixelDiscarded |= (");
|
||||
state.write("swgl_IsPixelDiscarded |= (");
|
||||
show_hir_expr(state, mask);
|
||||
state.write(")");
|
||||
if state.return_declared {
|
||||
|
@ -3274,7 +3249,7 @@ pub fn show_jump_statement(state: &mut OutputState, j: &hir::JumpStatement) {
|
|||
}
|
||||
state.write(";\n");
|
||||
} else {
|
||||
state.write("isPixelDiscarded = true;\n");
|
||||
state.write("swgl_IsPixelDiscarded = true;\n");
|
||||
}
|
||||
} else {
|
||||
state.write("discard;\n");
|
||||
|
@ -3579,9 +3554,11 @@ pub fn show_translation_unit(state: &mut OutputState, tu: &hir::TranslationUnit)
|
|||
state.flush_buffer();
|
||||
}
|
||||
if state.output_cxx {
|
||||
if let Some(name) = state.hir.lookup("main") {
|
||||
show_cxx_function_definition(state, name, 0);
|
||||
state.flush_buffer();
|
||||
for name in &["main", "swgl_drawSpanRGBA8", "swgl_drawSpanR8"] {
|
||||
if let Some(sym) = state.hir.lookup(name) {
|
||||
show_cxx_function_definition(state, sym, 0);
|
||||
state.flush_buffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3591,37 +3568,33 @@ fn write_abi(state: &mut OutputState) {
|
|||
ShaderKind::Fragment => {
|
||||
state.write("static void run(Self *self) {\n");
|
||||
if state.uses_discard {
|
||||
state.write(" self->isPixelDiscarded = false;\n");
|
||||
state.write(" self->swgl_IsPixelDiscarded = false;\n");
|
||||
}
|
||||
state.write(" self->main();\n");
|
||||
state.write(" self->step_interp_inputs();\n");
|
||||
state.write("}\n");
|
||||
state.write("static void skip(Self* self, int chunks) {\n");
|
||||
state.write(" self->step_interp_inputs();\n");
|
||||
state.write(" while (--chunks > 0) self->step_interp_inputs();\n");
|
||||
state.write("static void skip(Self* self, int steps) {\n");
|
||||
state.write(" self->step_interp_inputs(steps);\n");
|
||||
state.write("}\n");
|
||||
if state.use_perspective {
|
||||
state.write("static void run_perspective(Self *self) {\n");
|
||||
if state.uses_discard {
|
||||
state.write(" self->isPixelDiscarded = false;\n");
|
||||
state.write(" self->swgl_IsPixelDiscarded = false;\n");
|
||||
}
|
||||
state.write(" self->main();\n");
|
||||
state.write(" self->step_perspective_inputs();\n");
|
||||
state.write("}\n");
|
||||
state.write("static void skip_perspective(Self* self, int chunks) {\n");
|
||||
state.write(" self->step_perspective_inputs();\n");
|
||||
state.write(" while (--chunks > 0) self->step_perspective_inputs();\n");
|
||||
state.write("static void skip_perspective(Self* self, int steps) {\n");
|
||||
state.write(" self->step_perspective_inputs(steps);\n");
|
||||
state.write("}\n");
|
||||
}
|
||||
if state.has_draw_span_rgba8 {
|
||||
if state.hir.lookup("swgl_drawSpanRGBA8").is_some() {
|
||||
state.write(
|
||||
"static void draw_span_RGBA8(Self* self, uint32_t* buf, int len) { \
|
||||
DISPATCH_DRAW_SPAN(self, buf, len); }\n");
|
||||
"static int draw_span_RGBA8(Self* self) { DISPATCH_DRAW_SPAN(self, RGBA8); }\n");
|
||||
}
|
||||
if state.has_draw_span_r8 {
|
||||
if state.hir.lookup("swgl_drawSpanR8").is_some() {
|
||||
state.write(
|
||||
"static void draw_span_R8(Self* self, uint8_t* buf, int len) { \
|
||||
DISPATCH_DRAW_SPAN(self, buf, len); }\n");
|
||||
"static int draw_span_R8(Self* self) { DISPATCH_DRAW_SPAN(self, R8); }\n");
|
||||
}
|
||||
|
||||
write!(state, "public:\n{}_frag() {{\n", state.name);
|
||||
|
@ -3643,10 +3616,10 @@ fn write_abi(state: &mut OutputState) {
|
|||
state.write(" init_span_func = (InitSpanFunc)&read_interp_inputs;\n");
|
||||
state.write(" run_func = (RunFunc)&run;\n");
|
||||
state.write(" skip_func = (SkipFunc)&skip;\n");
|
||||
if state.has_draw_span_rgba8 {
|
||||
if state.hir.lookup("swgl_drawSpanRGBA8").is_some() {
|
||||
state.write(" draw_span_RGBA8_func = (DrawSpanRGBA8Func)&draw_span_RGBA8;\n");
|
||||
}
|
||||
if state.has_draw_span_r8 {
|
||||
if state.hir.lookup("swgl_drawSpanR8").is_some() {
|
||||
state.write(" draw_span_R8_func = (DrawSpanR8Func)&draw_span_R8;\n");
|
||||
}
|
||||
if state.uses_discard {
|
||||
|
@ -3670,6 +3643,9 @@ fn write_abi(state: &mut OutputState) {
|
|||
state.write(" init_batch_func = (InitBatchFunc)&init_batch;\n");
|
||||
state.write(" load_attribs_func = (LoadAttribsFunc)&load_attribs;\n");
|
||||
state.write(" run_primitive_func = (RunPrimitiveFunc)&run;\n");
|
||||
if state.hir.used_clip_dist != 0 {
|
||||
state.write(" enable_clip_distance();\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
state.write("}\n");
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
From 34d968adeda2e06b057a13d14a88df5766b38eda Mon Sep 17 00:00:00 2001
|
||||
From: Josh Matthews <josh@joshmatthews.net>
|
||||
Date: Mon, 6 Jul 2020 14:37:42 -0400
|
||||
Subject: [PATCH] Add signal handler to catch segfault in build script.
|
||||
|
||||
---
|
||||
Cargo.lock | 11 +++++
|
||||
webrender/Cargo.toml | 5 ++
|
||||
webrender/backtrace.rs | 103 +++++++++++++++++++++++++++++++++++++++++
|
||||
webrender/build.rs | 30 ++++++++++++
|
||||
4 files changed, 149 insertions(+)
|
||||
create mode 100644 webrender/backtrace.rs
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index afdd336ae..cf91162d5 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -1477,6 +1477,14 @@ dependencies = [
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
+[[package]]
|
||||
+name = "sig"
|
||||
+version = "1.0.0"
|
||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
+dependencies = [
|
||||
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+]
|
||||
+
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
@@ -1750,6 +1758,7 @@ dependencies = [
|
||||
name = "webrender"
|
||||
version = "0.61.0"
|
||||
dependencies = [
|
||||
+ "backtrace 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1780,6 +1789,7 @@ dependencies = [
|
||||
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"svg_fmt 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2178,6 +2188,7 @@ dependencies = [
|
||||
"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
|
||||
"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
|
||||
+"checksum sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6567e29578f9bfade6a5d94a32b9a4256348358d2a3f448cab0021f9a02614a2"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
|
||||
"checksum smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a"
|
||||
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||
index dcf26d913..f7679da57 100644
|
||||
--- a/webrender/Cargo.toml
|
||||
+++ b/webrender/Cargo.toml
|
||||
@@ -59,6 +59,11 @@ tracy-rs = { version = "0.1" }
|
||||
mozangle = "0.3.1"
|
||||
rand = "0.4"
|
||||
|
||||
+[target.'cfg(any(target_os = "macos", target_os = "linux"))'.build-dependencies]
|
||||
+backtrace = "0.3"
|
||||
+sig = "1.0"
|
||||
+libc = "0.2"
|
||||
+
|
||||
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||
freetype = { version = "0.4", default-features = false }
|
||||
libc = "0.2"
|
||||
diff --git a/webrender/backtrace.rs b/webrender/backtrace.rs
|
||||
new file mode 100644
|
||||
index 000000000..aa6bb6b32
|
||||
--- /dev/null
|
||||
+++ b/webrender/backtrace.rs
|
||||
@@ -0,0 +1,103 @@
|
||||
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
+
|
||||
+//! Similar to `println!("{:?}", Backtrace::new())`, but doesn’t allocate.
|
||||
+//!
|
||||
+//! Seems to fix some deadlocks: https://github.com/servo/servo/issues/24881
|
||||
+//!
|
||||
+//! FIXME: if/when a future version of the `backtrace` crate has
|
||||
+//! https://github.com/rust-lang/backtrace-rs/pull/265, use that instead.
|
||||
+
|
||||
+use std::fmt::{self, Write};
|
||||
+use backtrace::{BytesOrWideString, PrintFmt};
|
||||
+
|
||||
+#[inline(never)]
|
||||
+pub(crate) fn print(w: &mut dyn std::io::Write) -> Result<(), std::io::Error> {
|
||||
+ write!(w, "{:?}", Print {
|
||||
+ print_fn_address: print as usize,
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+struct Print {
|
||||
+ print_fn_address: usize,
|
||||
+}
|
||||
+
|
||||
+impl fmt::Debug for Print {
|
||||
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
+ // Safety: we’re in a signal handler that is about to call `libc::_exit`.
|
||||
+ // Potential data races from using `*_unsynchronized` functions are perhaps
|
||||
+ // less bad than potential deadlocks?
|
||||
+ unsafe {
|
||||
+ let mut print_fn_frame = 0;
|
||||
+ let mut frame_count = 0;
|
||||
+ backtrace::trace_unsynchronized(|frame| {
|
||||
+ let found = frame.symbol_address() as usize == self.print_fn_address;
|
||||
+ if found {
|
||||
+ print_fn_frame = frame_count;
|
||||
+ }
|
||||
+ frame_count += 1;
|
||||
+ !found
|
||||
+ });
|
||||
+
|
||||
+ let mode = PrintFmt::Short;
|
||||
+ let mut p = print_path;
|
||||
+ let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
|
||||
+ f.add_context()?;
|
||||
+ let mut result = Ok(());
|
||||
+ let mut frame_count = 0;
|
||||
+ backtrace::trace_unsynchronized(|frame| {
|
||||
+ let skip = frame_count < print_fn_frame;
|
||||
+ frame_count += 1;
|
||||
+ if skip {
|
||||
+ return true
|
||||
+ }
|
||||
+
|
||||
+ let mut frame_fmt = f.frame();
|
||||
+ let mut any_symbol = false;
|
||||
+ backtrace::resolve_frame_unsynchronized(frame, |symbol| {
|
||||
+ any_symbol = true;
|
||||
+ if let Err(e) = frame_fmt.symbol(frame, symbol) {
|
||||
+ result = Err(e)
|
||||
+ }
|
||||
+ });
|
||||
+ if !any_symbol {
|
||||
+ if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
|
||||
+ result = Err(e)
|
||||
+ }
|
||||
+ }
|
||||
+ result.is_ok()
|
||||
+ });
|
||||
+ result?;
|
||||
+ f.finish()
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result {
|
||||
+ match path {
|
||||
+ BytesOrWideString::Bytes(mut bytes) => {
|
||||
+ loop {
|
||||
+ match std::str::from_utf8(bytes) {
|
||||
+ Ok(s) => {
|
||||
+ fmt.write_str(s)?;
|
||||
+ break;
|
||||
+ }
|
||||
+ Err(err) => {
|
||||
+ fmt.write_char(std::char::REPLACEMENT_CHARACTER)?;
|
||||
+ match err.error_len() {
|
||||
+ Some(len) => bytes = &bytes[err.valid_up_to() + len..],
|
||||
+ None => break,
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ BytesOrWideString::Wide(wide) => {
|
||||
+ for c in std::char::decode_utf16(wide.iter().cloned()) {
|
||||
+ fmt.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ Ok(())
|
||||
+}
|
||||
diff --git a/webrender/build.rs b/webrender/build.rs
|
||||
index 3521d1342..36a7f17a8 100644
|
||||
--- a/webrender/build.rs
|
||||
+++ b/webrender/build.rs
|
||||
@@ -244,7 +244,37 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
+mod backtrace;
|
||||
+
|
||||
+#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
+extern "C" fn handler(sig: i32) {
|
||||
+ use std::sync::atomic;
|
||||
+ static BEEN_HERE_BEFORE: atomic::AtomicBool = atomic::AtomicBool::new(false);
|
||||
+ if !BEEN_HERE_BEFORE.swap(true, atomic::Ordering::SeqCst) {
|
||||
+ let stdout = std::io::stdout();
|
||||
+ let mut stdout = stdout.lock();
|
||||
+ let _ = write!(&mut stdout, "Stack trace");
|
||||
+ if let Some(name) = std::thread::current().name() {
|
||||
+ let _ = write!(&mut stdout, " for thread \"{}\"", name);
|
||||
+ }
|
||||
+ let _ = write!(&mut stdout, "\n");
|
||||
+ let _ = backtrace::print(&mut stdout);
|
||||
+ }
|
||||
+ unsafe {
|
||||
+ libc::_exit(sig);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
+ #[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
+ {
|
||||
+ sig::signal!(sig::ffi::Sig::SEGV, handler); // handle segfaults
|
||||
+ sig::signal!(sig::ffi::Sig::ILL, handler); // handle stack overflow and unsupported CPUs
|
||||
+ sig::signal!(sig::ffi::Sig::IOT, handler); // handle double panics
|
||||
+ sig::signal!(sig::ffi::Sig::BUS, handler); // handle invalid memory access
|
||||
+ }
|
||||
+
|
||||
let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());
|
||||
|
||||
let shaders_file_path = Path::new(&out_dir).join("shaders.rs");
|
||||
--
|
||||
2.39.2
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
From 299c4db222eb9f0acd9623b66b8f3d0a8a8f77f2 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Date: Fri, 19 Jun 2020 04:10:02 +0000
|
||||
Subject: [PATCH 2/6] Bug 1646741 - Update gleam to 0.12. r=kvark
|
||||
|
||||
For stride calculation and SSBOs
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D80191
|
||||
|
||||
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/ef8485a16d099e24f4832178664c5a93a28396ec
|
||||
---
|
||||
Cargo.lock | 16 ++++++++--------
|
||||
direct-composition/Cargo.toml | 2 +-
|
||||
example-compositor/compositor/Cargo.toml | 2 +-
|
||||
examples/Cargo.toml | 2 +-
|
||||
swgl/Cargo.toml | 2 +-
|
||||
webrender/Cargo.toml | 2 +-
|
||||
wrench/Cargo.toml | 2 +-
|
||||
7 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index cf91162d5..3eb484f26 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -257,7 +257,7 @@ name = "compositor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"compositor-windows 0.1.0",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
]
|
||||
|
||||
@@ -435,7 +435,7 @@ name = "direct-composition"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -617,7 +617,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gleam"
|
||||
-version = "0.11.0"
|
||||
+version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1545,7 +1545,7 @@ name = "swgl"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glsl-to-cxx 0.1.0",
|
||||
"webrender_build 0.0.1",
|
||||
]
|
||||
@@ -1773,7 +1773,7 @@ dependencies = [
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1808,7 +1808,7 @@ dependencies = [
|
||||
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
@@ -1938,7 +1938,7 @@ dependencies = [
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2087,7 +2087,7 @@ dependencies = [
|
||||
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
"checksum gl_generator 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca98bbde17256e02d17336a6bdb5a50f7d0ccacee502e191d3e3d0ec2f96f84a"
|
||||
"checksum gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
|
||||
-"checksum gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a13b5bb12ab457c15400b43cbba5971df5c1898b6a9c30cc8c52cb01baa112"
|
||||
+"checksum gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d023b0b00c16960f0f82816f2f546dabe937e75b25c7d6ce09a63e6a52d71e"
|
||||
"checksum gleam 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cae10d7c99d0e77b4766e850a60898a17c1abaf01075531f1066f03dc7dc5fc5"
|
||||
"checksum glsl 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "766443890761b3c4edcce86cafaac97971b200662fbdd0446eb7c6b99b4401ea"
|
||||
"checksum glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f22b383fcf6f85c4a268af39a0758ec40970e5f9f8fe9809e4415d48409b8379"
|
||||
diff --git a/direct-composition/Cargo.toml b/direct-composition/Cargo.toml
|
||||
index d099402d8..3506aec02 100644
|
||||
--- a/direct-composition/Cargo.toml
|
||||
+++ b/direct-composition/Cargo.toml
|
||||
@@ -7,7 +7,7 @@ edition = "2018"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
euclid = "0.20"
|
||||
-gleam = "0.11"
|
||||
+gleam = "0.12"
|
||||
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||
webrender = {path = "../webrender"}
|
||||
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
|
||||
diff --git a/example-compositor/compositor/Cargo.toml b/example-compositor/compositor/Cargo.toml
|
||||
index ce4d61928..d505e9ad2 100644
|
||||
--- a/example-compositor/compositor/Cargo.toml
|
||||
+++ b/example-compositor/compositor/Cargo.toml
|
||||
@@ -7,7 +7,7 @@ license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
webrender = { path = "../../webrender" }
|
||||
-gleam = "0.11.0"
|
||||
+gleam = "0.12.0"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
compositor-windows = { path = "../compositor-windows" }
|
||||
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
|
||||
index 31c695f98..09e658ca2 100644
|
||||
--- a/examples/Cargo.toml
|
||||
+++ b/examples/Cargo.toml
|
||||
@@ -61,7 +61,7 @@ debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||
app_units = "0.7"
|
||||
env_logger = "0.5"
|
||||
euclid = "0.20"
|
||||
-gleam = "0.11"
|
||||
+gleam = "0.12"
|
||||
glutin = "0.21"
|
||||
rayon = "1"
|
||||
webrender = { path = "../webrender" }
|
||||
diff --git a/swgl/Cargo.toml b/swgl/Cargo.toml
|
||||
index 3d57edbab..bc5a04b0a 100644
|
||||
--- a/swgl/Cargo.toml
|
||||
+++ b/swgl/Cargo.toml
|
||||
@@ -12,4 +12,4 @@ glsl-to-cxx = { path = "../glsl-to-cxx" }
|
||||
webrender_build = { path = "../webrender_build" }
|
||||
|
||||
[dependencies]
|
||||
-gleam = "0.11.0"
|
||||
+gleam = "0.12.0"
|
||||
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||
index f7679da57..2b0ab14fb 100644
|
||||
--- a/webrender/Cargo.toml
|
||||
+++ b/webrender/Cargo.toml
|
||||
@@ -34,7 +34,7 @@ cfg-if = "0.1.2"
|
||||
cstr = "0.1.2"
|
||||
euclid = { version = "0.20.0", features = ["serde"] }
|
||||
fxhash = "0.2.1"
|
||||
-gleam = "0.11.0"
|
||||
+gleam = "0.12.0"
|
||||
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
diff --git a/wrench/Cargo.toml b/wrench/Cargo.toml
|
||||
index 988e2537a..4ba95e4c4 100644
|
||||
--- a/wrench/Cargo.toml
|
||||
+++ b/wrench/Cargo.toml
|
||||
@@ -12,7 +12,7 @@ bincode = "1.0"
|
||||
byteorder = "1.0"
|
||||
env_logger = { version = "0.5", optional = true }
|
||||
euclid = "0.20"
|
||||
-gleam = "0.11"
|
||||
+gleam = "0.12"
|
||||
glutin = "0.21"
|
||||
app_units = "0.7"
|
||||
clap = { version = "2", features = ["yaml"] }
|
||||
--
|
||||
2.39.2
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
From 3767bd8938b5b849bc23bb7ac490cb0c27655560 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Date: Sat, 11 Jul 2020 09:42:33 +0000
|
||||
Subject: [PATCH 3/6] Bug 1651889. Update to gleam 0.12.1. r=kvark
|
||||
|
||||
This should fix a crash caused by an unexpected pixel type.
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D83167
|
||||
|
||||
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/b850773b54e129888b8fb2f1e3bc68f528aeccbf
|
||||
---
|
||||
Cargo.lock | 16 ++++++++--------
|
||||
webrender/Cargo.toml | 2 +-
|
||||
2 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index 3eb484f26..24f92084c 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -257,7 +257,7 @@ name = "compositor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"compositor-windows 0.1.0",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
]
|
||||
|
||||
@@ -435,7 +435,7 @@ name = "direct-composition"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -617,7 +617,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gleam"
|
||||
-version = "0.12.0"
|
||||
+version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1545,7 +1545,7 @@ name = "swgl"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glsl-to-cxx 0.1.0",
|
||||
"webrender_build 0.0.1",
|
||||
]
|
||||
@@ -1773,7 +1773,7 @@ dependencies = [
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1808,7 +1808,7 @@ dependencies = [
|
||||
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
@@ -1938,7 +1938,7 @@ dependencies = [
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2087,7 +2087,7 @@ dependencies = [
|
||||
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
"checksum gl_generator 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca98bbde17256e02d17336a6bdb5a50f7d0ccacee502e191d3e3d0ec2f96f84a"
|
||||
"checksum gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
|
||||
-"checksum gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d023b0b00c16960f0f82816f2f546dabe937e75b25c7d6ce09a63e6a52d71e"
|
||||
+"checksum gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdef5b9df6d3a261b80a5ac55e13bf93945725df2463c1b0a2e5a527dce0d37"
|
||||
"checksum gleam 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cae10d7c99d0e77b4766e850a60898a17c1abaf01075531f1066f03dc7dc5fc5"
|
||||
"checksum glsl 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "766443890761b3c4edcce86cafaac97971b200662fbdd0446eb7c6b99b4401ea"
|
||||
"checksum glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f22b383fcf6f85c4a268af39a0758ec40970e5f9f8fe9809e4415d48409b8379"
|
||||
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||
index 2b0ab14fb..3fa6630bd 100644
|
||||
--- a/webrender/Cargo.toml
|
||||
+++ b/webrender/Cargo.toml
|
||||
@@ -34,7 +34,7 @@ cfg-if = "0.1.2"
|
||||
cstr = "0.1.2"
|
||||
euclid = { version = "0.20.0", features = ["serde"] }
|
||||
fxhash = "0.2.1"
|
||||
-gleam = "0.12.0"
|
||||
+gleam = "0.12.1"
|
||||
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
--
|
||||
2.39.2
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
From 920168aff79a7cf52980b0c90965a591f2f4204a Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Date: Fri, 24 Jul 2020 09:54:10 +0000
|
||||
Subject: [PATCH 4/6] Bug 1654699. Update core-foundation/core-graphics.
|
||||
r=kvark,keeler,chunmin
|
||||
|
||||
This includes updates to authenticator, cubeb-coreaudio,
|
||||
metal, gfx-backend-vulkan, gfx-backend-metal, freetype
|
||||
|
||||
libloading is duplicated because of ash
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D84688
|
||||
|
||||
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/45fc4a780b2b4a9e047eceba73b39b988f719c58
|
||||
---
|
||||
Cargo.lock | 110 +++++++++++++++++++++++++--------------
|
||||
webrender/Cargo.toml | 10 ++--
|
||||
webrender_api/Cargo.toml | 4 +-
|
||||
wrench/Cargo.toml | 6 +--
|
||||
4 files changed, 80 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index 24f92084c..617092292 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -286,6 +286,15 @@ dependencies = [
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
+[[package]]
|
||||
+name = "core-foundation"
|
||||
+version = "0.9.0"
|
||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
+dependencies = [
|
||||
+ "core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+]
|
||||
+
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.6.2"
|
||||
@@ -296,6 +305,11 @@ name = "core-foundation-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
+[[package]]
|
||||
+name = "core-foundation-sys"
|
||||
+version = "0.8.0"
|
||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
+
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.17.3"
|
||||
@@ -309,22 +323,34 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
-version = "0.19.0"
|
||||
+version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+]
|
||||
+
|
||||
+[[package]]
|
||||
+name = "core-graphics-types"
|
||||
+version = "0.1.0"
|
||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
+dependencies = [
|
||||
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-text"
|
||||
-version = "15.0.0"
|
||||
+version = "19.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -510,13 +536,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "font-loader"
|
||||
-version = "0.9.0"
|
||||
+version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "servo-fontconfig 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -535,11 +561,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "freetype"
|
||||
-version = "0.4.1"
|
||||
+version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
+ "freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+]
|
||||
+
|
||||
+[[package]]
|
||||
+name = "freetype-sys"
|
||||
+version = "0.13.1"
|
||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
+dependencies = [
|
||||
+ "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1431,29 +1467,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "servo-fontconfig"
|
||||
-version = "0.4.0"
|
||||
+version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "servo-fontconfig-sys 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "servo-fontconfig-sys 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo-fontconfig-sys"
|
||||
-version = "4.0.9"
|
||||
+version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
-]
|
||||
-
|
||||
-[[package]]
|
||||
-name = "servo-freetype-sys"
|
||||
-version = "4.0.5"
|
||||
-source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
-dependencies = [
|
||||
- "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1765,13 +1792,13 @@ dependencies = [
|
||||
"build-parallel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "freetype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1822,8 +1849,8 @@ dependencies = [
|
||||
"app_units 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive_more 0.99.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1931,13 +1958,13 @@ dependencies = [
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2051,11 +2078,14 @@ dependencies = [
|
||||
"checksum cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54"
|
||||
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
|
||||
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
|
||||
+"checksum core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
|
||||
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
||||
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||
+"checksum core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
|
||||
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
|
||||
-"checksum core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd"
|
||||
-"checksum core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "131b3fd1f8bd5db9f2b398fa4fdb6008c64afc04d447c306ac2c7e98fba2a61d"
|
||||
+"checksum core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6082396a349fa49674ba1bda4077332a18bf150e8fa75745ece07085e29a113"
|
||||
+"checksum core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e92f5d519093a4178296707dbaa3880eae85a5ef5386675f361a1cf25376e93c"
|
||||
+"checksum core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04dfae50af11e72657fe7174cddb1ecddc5398037f7f6f39533ad69207c9a4e2"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be"
|
||||
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
@@ -2075,10 +2105,11 @@ dependencies = [
|
||||
"checksum euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6a5b0c779cd0b744c73a1d2083faf181080d696903cdad99a3b03d015d7030"
|
||||
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
-"checksum font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "933a61458662fbc8e3cd22cdb8331edbd78545fc044e1e2cd3d742f6ce06aa41"
|
||||
+"checksum font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c49d6b4c11dca1a1dd931a34a9f397e2da91abe3de4110505f3530a80e560b52"
|
||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
-"checksum freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "11926b2b410b469d0e9399eca4cbbe237a9ef02176c485803b29216307e8e028"
|
||||
+"checksum freetype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6"
|
||||
+"checksum freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
@@ -2183,9 +2214,8 @@ dependencies = [
|
||||
"checksum serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae"
|
||||
"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
||||
"checksum serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9"
|
||||
-"checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
|
||||
-"checksum servo-fontconfig-sys 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "62b3e166450f523f4db06c14f02a2d39e76d49b5d8cbd224338d93e3595c156c"
|
||||
-"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
|
||||
+"checksum servo-fontconfig 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c"
|
||||
+"checksum servo-fontconfig-sys 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388"
|
||||
"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
|
||||
"checksum sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6567e29578f9bfade6a5d94a32b9a4256348358d2a3f448cab0021f9a02614a2"
|
||||
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||
index 3fa6630bd..d05cf5979 100644
|
||||
--- a/webrender/Cargo.toml
|
||||
+++ b/webrender/Cargo.toml
|
||||
@@ -10,7 +10,7 @@ edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["freetype-lib"]
|
||||
-freetype-lib = ["freetype/servo-freetype-sys"]
|
||||
+freetype-lib = ["freetype/freetype-sys"]
|
||||
profiler = ["tracy-rs/enable_profiler"]
|
||||
debugger = ["ws", "serde_json", "serde", "image_loader", "base64"]
|
||||
capture = ["api/serialize", "ron", "serde", "smallvec/serde"]
|
||||
@@ -65,13 +65,13 @@ sig = "1.0"
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||
-freetype = { version = "0.4", default-features = false }
|
||||
+freetype = { version = "0.7", default-features = false }
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
dwrote = "0.11"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
-core-foundation = "0.7"
|
||||
-core-graphics = "0.19"
|
||||
-core-text = { version = "15", default-features = false }
|
||||
+core-foundation = "0.9"
|
||||
+core-graphics = "0.22"
|
||||
+core-text = { version = "19", default-features = false }
|
||||
diff --git a/webrender_api/Cargo.toml b/webrender_api/Cargo.toml
|
||||
index 6b8b1e5f2..4ed7ce8e2 100644
|
||||
--- a/webrender_api/Cargo.toml
|
||||
+++ b/webrender_api/Cargo.toml
|
||||
@@ -28,5 +28,5 @@ malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "
|
||||
peek-poke = { version = "0.2", path = "../peek-poke", features = ["extras"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
-core-foundation = "0.7"
|
||||
-core-graphics = "0.19"
|
||||
+core-foundation = "0.9"
|
||||
+core-graphics = "0.22"
|
||||
diff --git a/wrench/Cargo.toml b/wrench/Cargo.toml
|
||||
index 4ba95e4c4..33679485a 100644
|
||||
--- a/wrench/Cargo.toml
|
||||
+++ b/wrench/Cargo.toml
|
||||
@@ -38,8 +38,8 @@ default-features = false
|
||||
features = ["png"]
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
-core-graphics = "0.19"
|
||||
-core-foundation = "0.7"
|
||||
+core-graphics = "0.22"
|
||||
+core-foundation = "0.9"
|
||||
|
||||
[features]
|
||||
default = [ "env_logger" ]
|
||||
@@ -51,7 +51,7 @@ dwrote = "0.11"
|
||||
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "android")))'.dependencies]
|
||||
-font-loader = "0.9"
|
||||
+font-loader = "0.11"
|
||||
|
||||
# Configuration information used when building wrench as an APK.
|
||||
[package.metadata.android]
|
||||
--
|
||||
2.39.2
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,53 +0,0 @@
|
|||
From 415b9ba32648667313f6f4ce7965752285bf0b26 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Robinson <mrobinson@igalia.com>
|
||||
Date: Thu, 12 Jan 2023 12:35:31 +0100
|
||||
Subject: [PATCH 2/2] Bump procedural-masquerade to 0.1.7
|
||||
|
||||
This fixes a build issue in this branch.
|
||||
---
|
||||
Cargo.lock | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index b6085604cae8e18de3273bcddac43fa0a7e1abd1..b7055733e57fcd0acff07881ef72369b560c2abe 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -417,7 +417,7 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cstr-macros 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
- "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -425,7 +425,7 @@ name = "cstr-macros"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
- "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
+ "procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1212,7 +1212,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "procedural-masquerade"
|
||||
-version = "0.1.6"
|
||||
+version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -2182,7 +2182,7 @@ dependencies = [
|
||||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||
-"checksum procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"
|
||||
+"checksum procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1383dff4092fe903ac180e391a8d4121cc48f08ccf850614b0290c6673b69d"
|
||||
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||
--
|
||||
2.39.2
|
||||
|
|
@ -1,601 +0,0 @@
|
|||
diff --git a/direct-composition/src/lib.rs b/direct-composition/src/lib.rs
|
||||
index fadb8f2b72..fa94b4b0e3 100644
|
||||
--- a/direct-composition/src/lib.rs
|
||||
+++ b/direct-composition/src/lib.rs
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#![cfg(windows)]
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate mozangle;
|
||||
-extern crate winapi;
|
||||
+use gleam;
|
||||
+use mozangle;
|
||||
+use winapi;
|
||||
|
||||
use com::{ComPtr, CheckHResult, as_ptr};
|
||||
use std::ptr;
|
||||
diff --git a/direct-composition/src/main_windows.rs b/direct-composition/src/main_windows.rs
|
||||
index 18f1300a51..ff6608b4f0 100644
|
||||
--- a/direct-composition/src/main_windows.rs
|
||||
+++ b/direct-composition/src/main_windows.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate direct_composition;
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use direct_composition;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
use euclid::size2;
|
||||
use direct_composition::DirectComposition;
|
||||
diff --git a/examples/alpha_perf.rs b/examples/alpha_perf.rs
|
||||
index 56dc5b1abe..9200e65c8d 100644
|
||||
--- a/examples/alpha_perf.rs
|
||||
+++ b/examples/alpha_perf.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/animation.rs b/examples/animation.rs
|
||||
index 612d891178..2e87e78b17 100644
|
||||
--- a/examples/animation.rs
|
||||
+++ b/examples/animation.rs
|
||||
@@ -10,11 +10,11 @@
|
||||
//! rounded cornered rectangle, which is done automatically during the
|
||||
//! scene building for render optimization.
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/basic.rs b/examples/basic.rs
|
||||
index 79e0a87c46..0844994400 100644
|
||||
--- a/examples/basic.rs
|
||||
+++ b/examples/basic.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/blob.rs b/examples/blob.rs
|
||||
index dd58b17f38..ea6536cea8 100644
|
||||
--- a/examples/blob.rs
|
||||
+++ b/examples/blob.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate rayon;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use rayon;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/document.rs b/examples/document.rs
|
||||
index 56f5eedc8f..e33eff4665 100644
|
||||
--- a/examples/document.rs
|
||||
+++ b/examples/document.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/frame_output.rs b/examples/frame_output.rs
|
||||
index dc1c1d83f0..2cd612c9b4 100644
|
||||
--- a/examples/frame_output.rs
|
||||
+++ b/examples/frame_output.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/iframe.rs b/examples/iframe.rs
|
||||
index 50e8b46f30..32c0b3a8fe 100644
|
||||
--- a/examples/iframe.rs
|
||||
+++ b/examples/iframe.rs
|
||||
@@ -2,10 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/image_resize.rs b/examples/image_resize.rs
|
||||
index f45add1e7a..e28dd8e03d 100644
|
||||
--- a/examples/image_resize.rs
|
||||
+++ b/examples/image_resize.rs
|
||||
@@ -2,10 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs
|
||||
index 9b20960a94..2183b94144 100644
|
||||
--- a/examples/multiwindow.rs
|
||||
+++ b/examples/multiwindow.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
use gleam::gl;
|
||||
use glutin::NotCurrent;
|
||||
diff --git a/examples/scrolling.rs b/examples/scrolling.rs
|
||||
index 34cd14304f..745c4f9bd3 100644
|
||||
--- a/examples/scrolling.rs
|
||||
+++ b/examples/scrolling.rs
|
||||
@@ -2,11 +2,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate euclid;
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use euclid;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/texture_cache_stress.rs b/examples/texture_cache_stress.rs
|
||||
index d2e6818302..a065649b73 100644
|
||||
--- a/examples/texture_cache_stress.rs
|
||||
+++ b/examples/texture_cache_stress.rs
|
||||
@@ -2,10 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/examples/yuv.rs b/examples/yuv.rs
|
||||
index a8f36b33d7..3943bd23a6 100644
|
||||
--- a/examples/yuv.rs
|
||||
+++ b/examples/yuv.rs
|
||||
@@ -2,10 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate gleam;
|
||||
-extern crate glutin;
|
||||
-extern crate webrender;
|
||||
-extern crate winit;
|
||||
+use gleam;
|
||||
+use glutin;
|
||||
+use webrender;
|
||||
+use winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
diff --git a/glsl-to-cxx/src/lib.rs b/glsl-to-cxx/src/lib.rs
|
||||
index e40418aaab..409af02d58 100644
|
||||
--- a/glsl-to-cxx/src/lib.rs
|
||||
+++ b/glsl-to-cxx/src/lib.rs
|
||||
@@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate glsl;
|
||||
+use glsl;
|
||||
|
||||
mod hir;
|
||||
|
||||
diff --git a/peek-poke/peek-poke-derive/src/lib.rs b/peek-poke/peek-poke-derive/src/lib.rs
|
||||
index 7000f28bf1..92d538e516 100644
|
||||
--- a/peek-poke/peek-poke-derive/src/lib.rs
|
||||
+++ b/peek-poke/peek-poke-derive/src/lib.rs
|
||||
@@ -223,7 +223,7 @@ fn peek_poke_derive(mut s: Structure) -> TokenStream {
|
||||
};
|
||||
|
||||
let poke_impl = s.gen_impl(quote! {
|
||||
- extern crate peek_poke;
|
||||
+ use peek_poke;
|
||||
|
||||
gen unsafe impl peek_poke::Poke for @Self {
|
||||
#max_size_fn
|
||||
@@ -249,7 +249,7 @@ fn peek_poke_derive(mut s: Structure) -> TokenStream {
|
||||
let peek_impl = quote! {
|
||||
#[allow(non_upper_case_globals)]
|
||||
const #dummy_const: () = {
|
||||
- extern crate peek_poke;
|
||||
+ use peek_poke;
|
||||
|
||||
impl #impl_generics peek_poke::Peek for #name #ty_generics #where_clause {
|
||||
#peek_from_fn
|
||||
diff --git a/swgl/build.rs b/swgl/build.rs
|
||||
index 1de3568aa0..5133e9f397 100644
|
||||
--- a/swgl/build.rs
|
||||
+++ b/swgl/build.rs
|
||||
@@ -2,9 +2,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate cc;
|
||||
-extern crate glsl_to_cxx;
|
||||
-extern crate webrender_build;
|
||||
+use cc;
|
||||
+use glsl_to_cxx;
|
||||
+use webrender_build;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
diff --git a/swgl/src/lib.rs b/swgl/src/lib.rs
|
||||
index e8fc030e0c..e19e85fd51 100644
|
||||
--- a/swgl/src/lib.rs
|
||||
+++ b/swgl/src/lib.rs
|
||||
@@ -5,7 +5,7 @@
|
||||
#![crate_name = "swgl"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
-extern crate gleam;
|
||||
+use gleam;
|
||||
|
||||
mod swgl_fns;
|
||||
|
||||
diff --git a/webrender/build.rs b/webrender/build.rs
|
||||
index 36a7f17a8e..caea4dd5c2 100644
|
||||
--- a/webrender/build.rs
|
||||
+++ b/webrender/build.rs
|
||||
@@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate webrender_build;
|
||||
+use webrender_build;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
diff --git a/webrender/src/device/gl.rs b/webrender/src/device/gl.rs
|
||||
index 6ad0e98eef..3eac572081 100644
|
||||
--- a/webrender/src/device/gl.rs
|
||||
+++ b/webrender/src/device/gl.rs
|
||||
@@ -373,7 +373,7 @@ impl<T> Drop for VBO<T> {
|
||||
pub struct ExternalTexture {
|
||||
id: gl::GLuint,
|
||||
target: gl::GLuint,
|
||||
- swizzle: Swizzle,
|
||||
+ _swizzle: Swizzle,
|
||||
uv_rect: TexelRect,
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ impl ExternalTexture {
|
||||
ExternalTexture {
|
||||
id,
|
||||
target: get_gl_target(target),
|
||||
- swizzle,
|
||||
+ _swizzle: swizzle,
|
||||
uv_rect,
|
||||
}
|
||||
}
|
||||
@@ -520,7 +520,7 @@ impl Texture {
|
||||
let ext = ExternalTexture {
|
||||
id: self.id,
|
||||
target: self.target,
|
||||
- swizzle: Swizzle::default(),
|
||||
+ _swizzle: Swizzle::default(),
|
||||
// TODO(gw): Support custom UV rect for external textures during captures
|
||||
uv_rect: TexelRect::new(
|
||||
0.0,
|
||||
diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs
|
||||
index bae74efcfa..321afd2221 100644
|
||||
--- a/webrender/src/internal_types.rs
|
||||
+++ b/webrender/src/internal_types.rs
|
||||
@@ -568,13 +568,13 @@ pub enum ResultMsg {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ResourceCacheError {
|
||||
- description: String,
|
||||
+ _description: String,
|
||||
}
|
||||
|
||||
impl ResourceCacheError {
|
||||
pub fn new(description: String) -> ResourceCacheError {
|
||||
ResourceCacheError {
|
||||
- description,
|
||||
+ _description: description,
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs
|
||||
index 965f7dbc89..0db5feae9e 100644
|
||||
--- a/webrender/src/lib.rs
|
||||
+++ b/webrender/src/lib.rs
|
||||
@@ -72,8 +72,7 @@ extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate tracy_rs;
|
||||
|
||||
-extern crate malloc_size_of;
|
||||
-extern crate svg_fmt;
|
||||
+use malloc_size_of;
|
||||
|
||||
#[macro_use]
|
||||
mod profiler;
|
||||
@@ -155,49 +154,34 @@ mod platform {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
-extern crate core_foundation;
|
||||
+use core_foundation;
|
||||
#[cfg(target_os = "macos")]
|
||||
-extern crate core_graphics;
|
||||
+use core_graphics;
|
||||
#[cfg(target_os = "macos")]
|
||||
-extern crate core_text;
|
||||
-
|
||||
-#[cfg(all(unix, not(target_os = "macos")))]
|
||||
-extern crate freetype;
|
||||
-#[cfg(all(unix, not(target_os = "macos")))]
|
||||
-extern crate libc;
|
||||
+use core_text;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
-extern crate dwrote;
|
||||
-
|
||||
-extern crate bincode;
|
||||
-extern crate byteorder;
|
||||
-pub extern crate euclid;
|
||||
-extern crate fxhash;
|
||||
-extern crate gleam;
|
||||
-extern crate num_traits;
|
||||
-extern crate plane_split;
|
||||
-extern crate rayon;
|
||||
-#[cfg(feature = "ron")]
|
||||
-extern crate ron;
|
||||
+use dwrote;
|
||||
+
|
||||
+pub use euclid;
|
||||
#[cfg(feature = "debugger")]
|
||||
-extern crate serde_json;
|
||||
+use serde_json;
|
||||
#[macro_use]
|
||||
extern crate smallvec;
|
||||
-extern crate time;
|
||||
#[cfg(feature = "debugger")]
|
||||
-extern crate ws;
|
||||
+use ws;
|
||||
#[cfg(feature = "debugger")]
|
||||
-extern crate image_loader;
|
||||
+use image_loader;
|
||||
#[cfg(feature = "debugger")]
|
||||
-extern crate base64;
|
||||
+use base64;
|
||||
#[cfg(all(feature = "capture", feature = "png"))]
|
||||
-extern crate png;
|
||||
+use png;
|
||||
#[cfg(test)]
|
||||
-extern crate rand;
|
||||
+use rand;
|
||||
|
||||
#[macro_use]
|
||||
pub extern crate api;
|
||||
-extern crate webrender_build;
|
||||
+use webrender_build;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use crate::composite::{CompositorConfig, Compositor, CompositorCapabilities};
|
||||
diff --git a/webrender/src/render_target.rs b/webrender/src/render_target.rs
|
||||
index 9a3c953f42..9c62297c92 100644
|
||||
--- a/webrender/src/render_target.rs
|
||||
+++ b/webrender/src/render_target.rs
|
||||
@@ -1003,10 +1003,10 @@ fn add_svg_filter_instances(
|
||||
let generic_int = match filter {
|
||||
SvgFilterInfo::Blend(mode) => *mode as u16,
|
||||
SvgFilterInfo::ComponentTransfer(data) =>
|
||||
- ((data.r_func.to_int() << 12 |
|
||||
+ (data.r_func.to_int() << 12 |
|
||||
data.g_func.to_int() << 8 |
|
||||
data.b_func.to_int() << 4 |
|
||||
- data.a_func.to_int()) as u16),
|
||||
+ data.a_func.to_int()) as u16,
|
||||
SvgFilterInfo::Composite(operator) =>
|
||||
operator.as_int() as u16,
|
||||
SvgFilterInfo::LinearToSrgb |
|
||||
diff --git a/webrender/tests/angle_shader_validation.rs b/webrender/tests/angle_shader_validation.rs
|
||||
index 0a099d0b04..dda275dfda 100644
|
||||
--- a/webrender/tests/angle_shader_validation.rs
|
||||
+++ b/webrender/tests/angle_shader_validation.rs
|
||||
@@ -2,9 +2,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate mozangle;
|
||||
-extern crate webrender;
|
||||
-extern crate webrender_build;
|
||||
+use mozangle;
|
||||
+use webrender;
|
||||
+use webrender_build;
|
||||
|
||||
use mozangle::shaders::{BuiltInResources, Output, ShaderSpec, ShaderValidator};
|
||||
use webrender_build::shader::{ShaderFeatureFlags, ShaderVersion, build_shader_strings, get_shader_features};
|
||||
diff --git a/webrender_api/src/api.rs b/webrender_api/src/api.rs
|
||||
index 3e8a99e921..94962ad712 100644
|
||||
--- a/webrender_api/src/api.rs
|
||||
+++ b/webrender_api/src/api.rs
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
-extern crate serde_bytes;
|
||||
-
|
||||
use peek_poke::PeekPoke;
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
diff --git a/webrender_api/src/image.rs b/webrender_api/src/image.rs
|
||||
index deaeb92aeb..4a664bddcf 100644
|
||||
--- a/webrender_api/src/image.rs
|
||||
+++ b/webrender_api/src/image.rs
|
||||
@@ -340,7 +340,7 @@ pub enum ImageData {
|
||||
}
|
||||
|
||||
mod serde_image_data_raw {
|
||||
- extern crate serde_bytes;
|
||||
+ use serde_bytes;
|
||||
|
||||
use std::sync::Arc;
|
||||
use serde::{Deserializer, Serializer};
|
||||
diff --git a/webrender_api/src/lib.rs b/webrender_api/src/lib.rs
|
||||
index 5f274753e8..848f4740c9 100644
|
||||
--- a/webrender_api/src/lib.rs
|
||||
+++ b/webrender_api/src/lib.rs
|
||||
@@ -15,28 +15,23 @@
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp, clippy::too_many_arguments))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal, clippy::new_without_default))]
|
||||
|
||||
-extern crate app_units;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
-extern crate byteorder;
|
||||
#[cfg(feature = "nightly")]
|
||||
-extern crate core;
|
||||
+use core;
|
||||
#[cfg(target_os = "macos")]
|
||||
-extern crate core_foundation;
|
||||
+use core_foundation;
|
||||
#[cfg(target_os = "macos")]
|
||||
-extern crate core_graphics;
|
||||
+use core_graphics;
|
||||
#[macro_use]
|
||||
extern crate derive_more;
|
||||
-pub extern crate euclid;
|
||||
+pub use euclid;
|
||||
#[macro_use]
|
||||
extern crate malloc_size_of_derive;
|
||||
-extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
-extern crate time;
|
||||
|
||||
-extern crate malloc_size_of;
|
||||
-extern crate peek_poke;
|
||||
+use malloc_size_of;
|
||||
|
||||
mod api;
|
||||
pub mod channel;
|
||||
diff --git a/wr_malloc_size_of/lib.rs b/wr_malloc_size_of/lib.rs
|
||||
index 49a9666342..2a34508974 100644
|
||||
--- a/wr_malloc_size_of/lib.rs
|
||||
+++ b/wr_malloc_size_of/lib.rs
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
//! A reduced fork of Firefox's malloc_size_of crate, for bundling with WebRender.
|
||||
|
||||
-extern crate app_units;
|
||||
-extern crate euclid;
|
||||
+use app_units;
|
||||
+use euclid;
|
||||
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::mem::size_of;
|
250
third_party/webrender/patches/001-Restore-hit-testing-api.diff
vendored
Normal file
250
third_party/webrender/patches/001-Restore-hit-testing-api.diff
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
diff --git a/webrender/src/hit_test.rs b/webrender/src/hit_test.rs
|
||||
index 4a73e2158d..e095d8db0c 100644
|
||||
--- a/webrender/src/hit_test.rs
|
||||
+++ b/webrender/src/hit_test.rs
|
||||
@@ -2,13 +2,14 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-use api::{BorderRadius, ClipMode, HitTestItem, HitTestResult, ItemTag, PrimitiveFlags};
|
||||
+use api::{BorderRadius, ClipMode, HitTestItem, HitTestResult, ItemTag, PrimitiveFlags, HitTestFlags};
|
||||
use api::{PipelineId, ApiHitTester, ClipId};
|
||||
use api::units::*;
|
||||
use crate::clip::{ClipItemKind, ClipStore, ClipNode, rounded_rectangle_contains_point};
|
||||
use crate::clip::{polygon_contains_point};
|
||||
use crate::prim_store::PolygonKey;
|
||||
use crate::scene_builder_thread::Interners;
|
||||
+use crate::spatial_node::SpatialNodeType;
|
||||
use crate::spatial_tree::{SpatialNodeIndex, SpatialTree};
|
||||
use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo};
|
||||
use std::ops;
|
||||
@@ -45,8 +46,9 @@ impl ApiHitTester for SharedHitTester {
|
||||
fn hit_test(&self,
|
||||
pipeline_id: Option<PipelineId>,
|
||||
point: WorldPoint,
|
||||
+ flags: HitTestFlags,
|
||||
) -> HitTestResult {
|
||||
- self.get_ref().hit_test(HitTest::new(pipeline_id, point))
|
||||
+ self.get_ref().hit_test(HitTest::new(pipeline_id, point, flags))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +357,7 @@ impl HitTester {
|
||||
self.spatial_nodes.clear();
|
||||
|
||||
self.spatial_nodes.reserve(spatial_tree.spatial_nodes.len());
|
||||
+ self.pipeline_root_nodes.clear();
|
||||
for (index, node) in spatial_tree.spatial_nodes.iter().enumerate() {
|
||||
let index = SpatialNodeIndex::new(index);
|
||||
|
||||
@@ -380,6 +383,8 @@ impl HitTester {
|
||||
}
|
||||
|
||||
pub fn hit_test(&self, test: HitTest) -> HitTestResult {
|
||||
+ let point = test.get_absolute_point(self);
|
||||
+
|
||||
let mut result = HitTestResult::default();
|
||||
|
||||
let mut current_spatial_node_index = SpatialNodeIndex::INVALID;
|
||||
@@ -402,7 +407,7 @@ impl HitTester {
|
||||
point_in_layer = scroll_node
|
||||
.world_content_transform
|
||||
.inverse()
|
||||
- .and_then(|inverted| inverted.transform_point2d(test.point));
|
||||
+ .and_then(|inverted| inverted.transform_point2d(point));
|
||||
current_spatial_node_index = item.spatial_node_index;
|
||||
}
|
||||
|
||||
@@ -426,7 +431,7 @@ impl HitTester {
|
||||
.world_content_transform;
|
||||
let transformed_point = match transform
|
||||
.inverse()
|
||||
- .and_then(|inverted| inverted.transform_point2d(test.point))
|
||||
+ .and_then(|inverted| inverted.transform_point2d(point))
|
||||
{
|
||||
Some(point) => point,
|
||||
None => {
|
||||
@@ -457,7 +462,7 @@ impl HitTester {
|
||||
point_in_viewport = root_node
|
||||
.world_viewport_transform
|
||||
.inverse()
|
||||
- .and_then(|inverted| inverted.transform_point2d(test.point))
|
||||
+ .and_then(|inverted| inverted.transform_point2d(point))
|
||||
.map(|pt| pt - scroll_node.external_scroll_offset);
|
||||
|
||||
current_root_spatial_node_index = root_spatial_node_index;
|
||||
@@ -470,6 +475,10 @@ impl HitTester {
|
||||
point_in_viewport,
|
||||
point_relative_to_item: point_in_layer - item.rect.origin.to_vector(),
|
||||
});
|
||||
+
|
||||
+ if !test.flags.contains(HitTestFlags::FIND_ALL) {
|
||||
+ return result;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,24 +486,51 @@ impl HitTester {
|
||||
result.items.dedup();
|
||||
result
|
||||
}
|
||||
+
|
||||
+ fn get_pipeline_root(&self, pipeline_id: PipelineId) -> &HitTestSpatialNode {
|
||||
+ &self.spatial_nodes[self.pipeline_root_nodes[&pipeline_id].0 as usize]
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct HitTest {
|
||||
pipeline_id: Option<PipelineId>,
|
||||
point: WorldPoint,
|
||||
+ flags: HitTestFlags,
|
||||
}
|
||||
|
||||
impl HitTest {
|
||||
pub fn new(
|
||||
pipeline_id: Option<PipelineId>,
|
||||
point: WorldPoint,
|
||||
+ flags: HitTestFlags,
|
||||
) -> HitTest {
|
||||
HitTest {
|
||||
pipeline_id,
|
||||
point,
|
||||
+ flags
|
||||
}
|
||||
}
|
||||
+
|
||||
+ fn get_absolute_point(&self, hit_tester: &HitTester) -> WorldPoint {
|
||||
+ if !self.flags.contains(HitTestFlags::POINT_RELATIVE_TO_PIPELINE_VIEWPORT) {
|
||||
+ return self.point;
|
||||
+ }
|
||||
+
|
||||
+ let point = LayoutPoint::new(self.point.x, self.point.y);
|
||||
+ self.pipeline_id
|
||||
+ .and_then(|id|
|
||||
+ hit_tester
|
||||
+ .get_pipeline_root(id)
|
||||
+ .world_viewport_transform
|
||||
+ .transform_point2d(point)
|
||||
+ )
|
||||
+ .unwrap_or_else(|| {
|
||||
+ WorldPoint::new(self.point.x, self.point.y)
|
||||
+ })
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
/// Collect clips for a given ClipId, convert and add them to the hit testing
|
||||
diff --git a/webrender/src/render_api.rs b/webrender/src/render_api.rs
|
||||
index b84fa2c63a..b2c8a64e88 100644
|
||||
--- a/webrender/src/render_api.rs
|
||||
+++ b/webrender/src/render_api.rs
|
||||
@@ -10,6 +10,7 @@ use std::marker::PhantomData;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::u32;
|
||||
+use api::HitTestFlags;
|
||||
use time::precise_time_ns;
|
||||
//use crate::api::peek_poke::PeekPoke;
|
||||
use crate::api::channel::{Sender, single_msg_channel, unbounded_channel};
|
||||
@@ -812,7 +813,7 @@ pub enum FrameMsg {
|
||||
///
|
||||
UpdateEpoch(PipelineId, Epoch),
|
||||
///
|
||||
- HitTest(Option<PipelineId>, WorldPoint, Sender<HitTestResult>),
|
||||
+ HitTest(Option<PipelineId>, WorldPoint, HitTestFlags, Sender<HitTestResult>),
|
||||
///
|
||||
RequestHitTester(Sender<Arc<dyn ApiHitTester>>),
|
||||
///
|
||||
@@ -1297,12 +1298,13 @@ impl RenderApi {
|
||||
document_id: DocumentId,
|
||||
pipeline_id: Option<PipelineId>,
|
||||
point: WorldPoint,
|
||||
+ flags: HitTestFlags,
|
||||
) -> HitTestResult {
|
||||
let (tx, rx) = single_msg_channel();
|
||||
|
||||
self.send_frame_msg(
|
||||
document_id,
|
||||
- FrameMsg::HitTest(pipeline_id, point, tx)
|
||||
+ FrameMsg::HitTest(pipeline_id, point, flags, tx)
|
||||
);
|
||||
rx.recv().unwrap()
|
||||
}
|
||||
diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs
|
||||
index 96bc600484..825e981b5c 100644
|
||||
--- a/webrender/src/render_backend.rs
|
||||
+++ b/webrender/src/render_backend.rs
|
||||
@@ -535,14 +535,14 @@ impl Document {
|
||||
FrameMsg::UpdateEpoch(pipeline_id, epoch) => {
|
||||
self.scene.pipeline_epochs.insert(pipeline_id, epoch);
|
||||
}
|
||||
- FrameMsg::HitTest(pipeline_id, point, tx) => {
|
||||
+ FrameMsg::HitTest(pipeline_id, point, flags, tx) => {
|
||||
if !self.hit_tester_is_valid {
|
||||
self.rebuild_hit_tester();
|
||||
}
|
||||
|
||||
let result = match self.hit_tester {
|
||||
Some(ref hit_tester) => {
|
||||
- hit_tester.hit_test(HitTest::new(pipeline_id, point))
|
||||
+ hit_tester.hit_test(HitTest::new(pipeline_id, point, flags))
|
||||
}
|
||||
None => HitTestResult { items: Vec::new() },
|
||||
};
|
||||
diff --git a/webrender_api/src/lib.rs b/webrender_api/src/lib.rs
|
||||
index 7dc887ade9..b0446c1d0b 100644
|
||||
--- a/webrender_api/src/lib.rs
|
||||
+++ b/webrender_api/src/lib.rs
|
||||
@@ -278,7 +278,7 @@ pub trait ApiHitTester: Send + Sync {
|
||||
/// hit results so that only items inside that pipeline are matched. The vector
|
||||
/// of hit results will contain all display items that match, ordered from
|
||||
/// front to back.
|
||||
- fn hit_test(&self, pipeline_id: Option<PipelineId>, point: WorldPoint) -> HitTestResult;
|
||||
+ fn hit_test(&self, pipeline_id: Option<PipelineId>, point: WorldPoint, flags: HitTestFlags) -> HitTestResult;
|
||||
}
|
||||
|
||||
/// A hit tester requested to the render backend thread but not necessarily ready yet.
|
||||
@@ -322,6 +322,17 @@ pub struct HitTestResult {
|
||||
pub items: Vec<HitTestItem>,
|
||||
}
|
||||
|
||||
+bitflags! {
|
||||
+ #[derive(Deserialize, MallocSizeOf, Serialize)]
|
||||
+ ///
|
||||
+ pub struct HitTestFlags: u8 {
|
||||
+ ///
|
||||
+ const FIND_ALL = 0b00000001;
|
||||
+ ///
|
||||
+ const POINT_RELATIVE_TO_PIPELINE_VIEWPORT = 0b00000010;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
impl Drop for NotificationRequest {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
diff --git a/wrench/src/main.rs b/wrench/src/main.rs
|
||||
index 7dc037ebb2..843512f595 100644
|
||||
--- a/wrench/src/main.rs
|
||||
+++ b/wrench/src/main.rs
|
||||
@@ -965,6 +965,7 @@ fn render<'a>(
|
||||
wrench.document_id,
|
||||
None,
|
||||
cursor_position,
|
||||
+ HitTestFlags::empty(),
|
||||
);
|
||||
|
||||
println!("Hit test results:");
|
||||
diff --git a/wrench/src/rawtest.rs b/wrench/src/rawtest.rs
|
||||
index 580f1cb015..b86b583617 100644
|
||||
--- a/wrench/src/rawtest.rs
|
||||
+++ b/wrench/src/rawtest.rs
|
||||
@@ -1393,6 +1393,7 @@ impl<'a> RawtestHarness<'a> {
|
||||
self.wrench.document_id,
|
||||
None,
|
||||
point,
|
||||
+ HitTetFlags::empty(),
|
||||
)
|
||||
};
|
||||
|
62
third_party/webrender/patches/002-Upgrade-version-of-gleam.diff
vendored
Normal file
62
third_party/webrender/patches/002-Upgrade-version-of-gleam.diff
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
diff --git a/example-compositor/compositor/Cargo.toml b/example-compositor/compositor/Cargo.toml
|
||||
index 4202332c41..02c6ebe0ce 100644
|
||||
--- a/example-compositor/compositor/Cargo.toml
|
||||
+++ b/example-compositor/compositor/Cargo.toml
|
||||
@@ -7,7 +7,7 @@ license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
webrender = { path = "../../webrender" }
|
||||
-gleam = "0.13.1"
|
||||
+gleam = "0.15"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
compositor-windows = { path = "../compositor-windows" }
|
||||
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
|
||||
index 556b67d1ed..f1a4718b04 100644
|
||||
--- a/examples/Cargo.toml
|
||||
+++ b/examples/Cargo.toml
|
||||
@@ -57,7 +57,7 @@ debug = ["webrender/capture", "webrender/profiler"]
|
||||
app_units = "0.7"
|
||||
env_logger = "0.5"
|
||||
euclid = "0.22"
|
||||
-gleam = "0.13"
|
||||
+gleam = "0.15"
|
||||
glutin = "0.21"
|
||||
rayon = "1"
|
||||
webrender = { path = "../webrender" }
|
||||
diff --git a/swgl/Cargo.toml b/swgl/Cargo.toml
|
||||
index 9b7624b13e..2e84e2267c 100644
|
||||
--- a/swgl/Cargo.toml
|
||||
+++ b/swgl/Cargo.toml
|
||||
@@ -12,4 +12,4 @@ glsl-to-cxx = { path = "../glsl-to-cxx" }
|
||||
webrender_build = { path = "../webrender_build" }
|
||||
|
||||
[dependencies]
|
||||
-gleam = "0.13.1"
|
||||
+gleam = "0.15"
|
||||
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||
index 40064a1573..e82ac85718 100644
|
||||
--- a/webrender/Cargo.toml
|
||||
+++ b/webrender/Cargo.toml
|
||||
@@ -33,7 +33,7 @@ byteorder = "1.0"
|
||||
cstr = "0.2"
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
fxhash = "0.2.1"
|
||||
-gleam = "0.13.1"
|
||||
+gleam = "0.15"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
malloc_size_of_derive = "0.1"
|
||||
diff --git a/wrench/Cargo.toml b/wrench/Cargo.toml
|
||||
index 7d2345be43..f51e4202ff 100644
|
||||
--- a/wrench/Cargo.toml
|
||||
+++ b/wrench/Cargo.toml
|
||||
@@ -9,7 +9,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
base64 = "0.12"
|
||||
env_logger = { version = "0.5", optional = true }
|
||||
-gleam = "0.13"
|
||||
+gleam = "0.15"
|
||||
glutin = "0.21"
|
||||
clap = { version = "2", features = ["yaml"] }
|
||||
log = "0.4"
|
221
third_party/webrender/patches/003-Fix-WebRender-warnings.diff
vendored
Normal file
221
third_party/webrender/patches/003-Fix-WebRender-warnings.diff
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
diff --git a/webrender/build.rs b/webrender/build.rs
|
||||
index 60b4a96c23..adc5dbf2e8 100644
|
||||
--- a/webrender/build.rs
|
||||
+++ b/webrender/build.rs
|
||||
@@ -2,8 +2,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
-extern crate webrender_build;
|
||||
-
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::fs::{canonicalize, read_dir, File};
|
||||
diff --git a/webrender/src/device/gl.rs b/webrender/src/device/gl.rs
|
||||
index eb272e56d6..5e0c050378 100644
|
||||
--- a/webrender/src/device/gl.rs
|
||||
+++ b/webrender/src/device/gl.rs
|
||||
@@ -386,6 +386,7 @@ impl<T> Drop for VBO<T> {
|
||||
pub struct ExternalTexture {
|
||||
id: gl::GLuint,
|
||||
target: gl::GLuint,
|
||||
+ #[allow(dead_code)]
|
||||
swizzle: Swizzle,
|
||||
uv_rect: TexelRect,
|
||||
}
|
||||
diff --git a/webrender/src/hit_test.rs b/webrender/src/hit_test.rs
|
||||
index e095d8db0c..0bd02cd426 100644
|
||||
--- a/webrender/src/hit_test.rs
|
||||
+++ b/webrender/src/hit_test.rs
|
||||
@@ -6,10 +6,9 @@ use api::{BorderRadius, ClipMode, HitTestItem, HitTestResult, ItemTag, Primitive
|
||||
use api::{PipelineId, ApiHitTester, ClipId};
|
||||
use api::units::*;
|
||||
use crate::clip::{ClipItemKind, ClipStore, ClipNode, rounded_rectangle_contains_point};
|
||||
-use crate::clip::{polygon_contains_point};
|
||||
+use crate::clip::polygon_contains_point;
|
||||
use crate::prim_store::PolygonKey;
|
||||
use crate::scene_builder_thread::Interners;
|
||||
-use crate::spatial_node::SpatialNodeType;
|
||||
use crate::spatial_tree::{SpatialNodeIndex, SpatialTree};
|
||||
use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo};
|
||||
use std::ops;
|
||||
diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs
|
||||
index 07f937c6a0..9819850db0 100644
|
||||
--- a/webrender/src/internal_types.rs
|
||||
+++ b/webrender/src/internal_types.rs
|
||||
@@ -536,6 +536,7 @@ pub enum ResultMsg {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ResourceCacheError {
|
||||
+ #[allow(dead_code)]
|
||||
description: String,
|
||||
}
|
||||
|
||||
diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs
|
||||
index 34bc9fb49b..cc200e30eb 100644
|
||||
--- a/webrender/src/lib.rs
|
||||
+++ b/webrender/src/lib.rs
|
||||
@@ -71,8 +71,7 @@ extern crate serde;
|
||||
extern crate tracy_rs;
|
||||
#[macro_use]
|
||||
extern crate derive_more;
|
||||
-extern crate malloc_size_of;
|
||||
-extern crate svg_fmt;
|
||||
+use malloc_size_of;
|
||||
|
||||
#[macro_use]
|
||||
mod profiler;
|
||||
@@ -163,41 +162,14 @@ mod platform {
|
||||
}
|
||||
}
|
||||
|
||||
-#[cfg(target_os = "macos")]
|
||||
-extern crate core_foundation;
|
||||
-#[cfg(target_os = "macos")]
|
||||
-extern crate core_graphics;
|
||||
-#[cfg(target_os = "macos")]
|
||||
-extern crate core_text;
|
||||
-
|
||||
-#[cfg(all(unix, not(target_os = "macos")))]
|
||||
-extern crate freetype;
|
||||
-#[cfg(all(unix, not(target_os = "macos")))]
|
||||
-extern crate libc;
|
||||
-
|
||||
-#[cfg(target_os = "windows")]
|
||||
-extern crate dwrote;
|
||||
-
|
||||
-extern crate bincode;
|
||||
-extern crate byteorder;
|
||||
-pub extern crate euclid;
|
||||
-extern crate fxhash;
|
||||
-extern crate gleam;
|
||||
-extern crate num_traits;
|
||||
-extern crate plane_split;
|
||||
-extern crate rayon;
|
||||
-#[cfg(feature = "ron")]
|
||||
-extern crate ron;
|
||||
+pub use euclid;
|
||||
#[macro_use]
|
||||
extern crate smallvec;
|
||||
-extern crate time;
|
||||
-#[cfg(all(feature = "capture", feature = "png"))]
|
||||
-extern crate png;
|
||||
#[cfg(test)]
|
||||
-extern crate rand;
|
||||
+use rand;
|
||||
|
||||
-pub extern crate api;
|
||||
-extern crate webrender_build;
|
||||
+pub use api;
|
||||
+use webrender_build;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use crate::composite::{CompositorConfig, Compositor, CompositorCapabilities, CompositorSurfaceTransform};
|
||||
diff --git a/webrender/src/profiler.rs b/webrender/src/profiler.rs
|
||||
index 40c091d617..702fa634ff 100644
|
||||
--- a/webrender/src/profiler.rs
|
||||
+++ b/webrender/src/profiler.rs
|
||||
@@ -1362,6 +1362,7 @@ pub struct Counter {
|
||||
change_indicator: u8,
|
||||
|
||||
/// Only used to check that the constants match the real index.
|
||||
+ #[allow(dead_code)]
|
||||
index: usize,
|
||||
|
||||
graph: Option<Graph>,
|
||||
diff --git a/webrender/src/render_target.rs b/webrender/src/render_target.rs
|
||||
index d31176047b..301ce4ec4d 100644
|
||||
--- a/webrender/src/render_target.rs
|
||||
+++ b/webrender/src/render_target.rs
|
||||
@@ -10,7 +10,7 @@ use crate::batch::{ClipBatcher, BatchBuilder};
|
||||
use crate::spatial_tree::{SpatialTree, ROOT_SPATIAL_NODE_INDEX};
|
||||
use crate::clip::ClipStore;
|
||||
use crate::composite::CompositeState;
|
||||
-use crate::frame_builder::{FrameGlobalResources};
|
||||
+use crate::frame_builder::FrameGlobalResources;
|
||||
use crate::gpu_cache::{GpuCache, GpuCacheAddress};
|
||||
use crate::gpu_types::{BorderInstance, SvgFilterInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance};
|
||||
use crate::gpu_types::{TransformPalette, ZBufferIdGenerator};
|
||||
@@ -819,10 +819,10 @@ fn add_svg_filter_instances(
|
||||
let generic_int = match filter {
|
||||
SvgFilterInfo::Blend(mode) => *mode as u16,
|
||||
SvgFilterInfo::ComponentTransfer(data) =>
|
||||
- ((data.r_func.to_int() << 12 |
|
||||
+ (data.r_func.to_int() << 12 |
|
||||
data.g_func.to_int() << 8 |
|
||||
data.b_func.to_int() << 4 |
|
||||
- data.a_func.to_int()) as u16),
|
||||
+ data.a_func.to_int()) as u16,
|
||||
SvgFilterInfo::Composite(operator) =>
|
||||
operator.as_int() as u16,
|
||||
SvgFilterInfo::LinearToSrgb |
|
||||
diff --git a/webrender_api/src/image.rs b/webrender_api/src/image.rs
|
||||
index 238d004814..23c660b647 100644
|
||||
--- a/webrender_api/src/image.rs
|
||||
+++ b/webrender_api/src/image.rs
|
||||
@@ -326,10 +326,9 @@ pub enum ImageData {
|
||||
}
|
||||
|
||||
mod serde_image_data_raw {
|
||||
- extern crate serde_bytes;
|
||||
-
|
||||
- use std::sync::Arc;
|
||||
use serde::{Deserializer, Serializer};
|
||||
+ use serde_bytes;
|
||||
+ use std::sync::Arc;
|
||||
|
||||
pub fn serialize<S: Serializer>(bytes: &Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serde_bytes::serialize(bytes.as_slice(), serializer)
|
||||
diff --git a/webrender_api/src/lib.rs b/webrender_api/src/lib.rs
|
||||
index b0446c1d0b..f5cda1fbf6 100644
|
||||
--- a/webrender_api/src/lib.rs
|
||||
+++ b/webrender_api/src/lib.rs
|
||||
@@ -15,29 +15,20 @@
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp, clippy::too_many_arguments))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal, clippy::new_without_default))]
|
||||
|
||||
-pub extern crate crossbeam_channel;
|
||||
-pub extern crate euclid;
|
||||
+pub use crossbeam_channel;
|
||||
+pub use euclid;
|
||||
|
||||
-extern crate app_units;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
-extern crate byteorder;
|
||||
#[cfg(feature = "nightly")]
|
||||
extern crate core;
|
||||
-#[cfg(target_os = "macos")]
|
||||
-extern crate core_foundation;
|
||||
-#[cfg(target_os = "macos")]
|
||||
-extern crate core_graphics;
|
||||
-extern crate derive_more;
|
||||
#[macro_use]
|
||||
extern crate malloc_size_of_derive;
|
||||
-extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
-extern crate time;
|
||||
|
||||
-extern crate malloc_size_of;
|
||||
-extern crate peek_poke;
|
||||
+use malloc_size_of;
|
||||
+use peek_poke;
|
||||
|
||||
pub mod channel;
|
||||
mod color;
|
||||
diff --git a/wr_malloc_size_of/lib.rs b/wr_malloc_size_of/lib.rs
|
||||
index 38b049095e..abd982ffe8 100644
|
||||
--- a/wr_malloc_size_of/lib.rs
|
||||
+++ b/wr_malloc_size_of/lib.rs
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
//! A reduced fork of Firefox's malloc_size_of crate, for bundling with WebRender.
|
||||
|
||||
-extern crate app_units;
|
||||
-extern crate euclid;
|
||||
+use app_units;
|
||||
+use euclid;
|
||||
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::mem::size_of;
|
2
third_party/webrender/patches/head
vendored
2
third_party/webrender/patches/head
vendored
|
@ -1 +1 @@
|
|||
1175acad2d4f49fa712e105c84149ac7f394261d
|
||||
e491e1ae637b2eed1e7195855d88357e5eb3ddf9
|
||||
|
|
10
third_party/webrender/patches/series
vendored
10
third_party/webrender/patches/series
vendored
|
@ -1,7 +1,3 @@
|
|||
0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
|
||||
0002-Bug-1646741-Update-gleam-to-0.12.-r-kvark.patch
|
||||
0003-Bug-1651889.-Update-to-gleam-0.12.1.-r-kvark.patch
|
||||
0004-Bug-1654699.-Update-core-foundation-core-graphics.-r.patch
|
||||
0005-Bug-1656236-Update-to-euclid-0.22.-r-kvark.patch
|
||||
0006-Bump-procedural-masquerade-to-0.1.7.patch
|
||||
0007-Fix-warnings.patch
|
||||
001-Restore-hit-testing-api.diff
|
||||
002-Upgrade-version-of-gleam.diff
|
||||
003-Fix-WebRender-warnings.diff
|
||||
|
|
|
@ -43,10 +43,7 @@ fn get_discriminant_size_type(len: usize) -> TokenStream {
|
|||
|
||||
fn is_struct(s: &Structure) -> bool {
|
||||
// a single variant with no prefix is 'struct'
|
||||
match &s.variants()[..] {
|
||||
[v] if v.prefix.is_none() => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(&s.variants()[..], [v] if v.prefix.is_none())
|
||||
}
|
||||
|
||||
fn derive_max_size(s: &Structure) -> TokenStream {
|
||||
|
@ -223,7 +220,7 @@ fn peek_poke_derive(mut s: Structure) -> TokenStream {
|
|||
};
|
||||
|
||||
let poke_impl = s.gen_impl(quote! {
|
||||
use peek_poke;
|
||||
extern crate peek_poke;
|
||||
|
||||
gen unsafe impl peek_poke::Poke for @Self {
|
||||
#max_size_fn
|
||||
|
@ -249,7 +246,7 @@ fn peek_poke_derive(mut s: Structure) -> TokenStream {
|
|||
let peek_impl = quote! {
|
||||
#[allow(non_upper_case_globals)]
|
||||
const #dummy_const: () = {
|
||||
use peek_poke;
|
||||
extern crate peek_poke;
|
||||
|
||||
impl #impl_generics peek_poke::Peek for #name #ty_generics #where_clause {
|
||||
#peek_from_fn
|
||||
|
|
23
third_party/webrender/peek-poke/src/euclid.rs
vendored
23
third_party/webrender/peek-poke/src/euclid.rs
vendored
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use crate::{Peek, Poke};
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, Vector2D};
|
||||
use euclid::{Point2D, Rect, Box2D, SideOffsets2D, Size2D, Transform3D, Vector2D};
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Point2D<T, U> {
|
||||
#[inline(always)]
|
||||
|
@ -53,6 +53,27 @@ impl<T: Peek, U> Peek for Rect<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Box2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
Point2D::<T, U>::max_size() * 2
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.min.poke_into(bytes);
|
||||
let bytes = self.max.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for Box2D<T, U> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = Point2D::<T, U>::peek_from(bytes, &mut (*output).min);
|
||||
let bytes = Point2D::<T, U>::peek_from(bytes, &mut (*output).max);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for SideOffsets2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
|
|
14
third_party/webrender/peek-poke/src/lib.rs
vendored
14
third_party/webrender/peek-poke/src/lib.rs
vendored
|
@ -113,6 +113,20 @@ pub fn ensure_red_zone<T: Poke>(bytes: &mut Vec<u8>) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Remove the "red zone" (padding of zeroes) from the end of the vec of `bytes`.
|
||||
/// This is effectively the inverse of `ensure_red_zone`, with the caveat that
|
||||
/// space reserved for the red zone is not un-reserved. Callers are repsonsible
|
||||
/// for making sure the vec actually has a red zone, otherwise data bytes can
|
||||
/// get stripped instead.
|
||||
pub fn strip_red_zone<T: Poke>(bytes: &mut Vec<u8>) {
|
||||
assert!(bytes.len() >= T::max_size());
|
||||
unsafe {
|
||||
let end_ptr = bytes.as_end_mut_ptr();
|
||||
end_ptr.write_bytes(0, T::max_size());
|
||||
bytes.set_end_ptr(end_ptr.sub(T::max_size()));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn read_verbatim<T>(src: *const u8, dst: *mut T) -> *const u8 {
|
||||
*dst = (src as *const T).read_unaligned();
|
||||
|
|
3
third_party/webrender/servo-tidy.toml
vendored
3
third_party/webrender/servo-tidy.toml
vendored
|
@ -6,18 +6,17 @@ check-alphabetical-order = false
|
|||
[ignore]
|
||||
# Ignored packages with duplicated versions
|
||||
packages = [
|
||||
"cfg-if",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"core-graphics",
|
||||
"gl_generator",
|
||||
"gleam",
|
||||
"rand",
|
||||
"rand_core",
|
||||
# https://github.com/trimental/andrew/issues/5
|
||||
"rusttype",
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1615148
|
||||
"smallvec",
|
||||
"winapi",
|
||||
"yaml-rust",
|
||||
# These are tracked in bug 1587468, see there for pending work.
|
||||
"proc-macro2",
|
||||
|
|
2
third_party/webrender/swgl/Cargo.toml
vendored
2
third_party/webrender/swgl/Cargo.toml
vendored
|
@ -12,4 +12,4 @@ glsl-to-cxx = { path = "../glsl-to-cxx" }
|
|||
webrender_build = { path = "../webrender_build" }
|
||||
|
||||
[dependencies]
|
||||
gleam = "0.12.0"
|
||||
gleam = "0.15"
|
||||
|
|
220
third_party/webrender/swgl/README.md
vendored
220
third_party/webrender/swgl/README.md
vendored
|
@ -1,4 +1,220 @@
|
|||
swgl
|
||||
========
|
||||
# swgl
|
||||
|
||||
Software OpenGL implementation for WebRender
|
||||
|
||||
## Overview
|
||||
This is a relatively simple single threaded software rasterizer designed
|
||||
for use by WebRender. It will shade one quad at a time using a 4xf32 vector
|
||||
with one vertex per lane. It rasterizes quads usings spans and shades that
|
||||
span 4 pixels at a time.
|
||||
|
||||
## Building
|
||||
clang-cl is required to build on Windows. This can be done by installing
|
||||
the llvm binaries from https://releases.llvm.org/ and adding the installation
|
||||
to the path with something like `set PATH=%PATH%;C:\Program Files\LLVM\bin`.
|
||||
Then `set CC=clang-cl` and `set CXX=clang-cl`. That should be sufficient
|
||||
for `cc-rs` to use `clang-cl` instead of `cl`.
|
||||
|
||||
## Extensions
|
||||
SWGL contains a number of OpenGL and GLSL extensions designed to both ease
|
||||
integration with WebRender and to help accelerate span rasterization.
|
||||
|
||||
GLSL extension intrinsics are generally prefixed with `swgl_` to distinguish
|
||||
them from other items in the GLSL namespace.
|
||||
|
||||
Inside GLSL, the `SWGL` preprocessor token is defined so that usage of SWGL
|
||||
extensions may be conditionally compiled.
|
||||
|
||||
```
|
||||
void swgl_drawSpanRGBA8();
|
||||
void swgl_drawSpanR8();
|
||||
|
||||
int swgl_SpanLength;
|
||||
int swgl_StepSize;
|
||||
|
||||
mixed swgl_interpStep(mixed varying_input);
|
||||
void swgl_stepInterp();
|
||||
```
|
||||
|
||||
SWGL's default fragment processing calls a fragment shader's `main` function
|
||||
on groups of fragments in units of `swgl_StepSize`. On return, the value of
|
||||
gl_FragColor is read, packed to an appropriate pixel format, and sent to the
|
||||
blend stage for output to the destination framebuffer. This can be inefficient
|
||||
for some types of fragment shaders, such as those that must lookup from a
|
||||
texture and immediately output it, unpacking the texels only to subsequently
|
||||
repack them at cost. Also, various per-fragment conditions in the shader might
|
||||
need to be repeatedly checked, even though they are actually constant over
|
||||
the entire primitive.
|
||||
|
||||
To work around this inefficiency, SWGL allows fragments to optionally be
|
||||
processed over entire spans. This can both side-step the packing inefficiency
|
||||
as well as more efficiently deal with conditions that remain constant over an
|
||||
entire span. SWGL also introduces various specialized intrinsics for more
|
||||
efficiently dealing with certain types of primitive spans with optimal
|
||||
fixed-function processing.
|
||||
|
||||
Inside a fragment shader, a `swgl_drawSpan` function may be defined to override
|
||||
the normal fragment processing for that fragment shader. The function must then
|
||||
call some form of `swgl_commit` intrinsic to actually output to the destination
|
||||
framebuffer via the blend stage, as normal fragment processing does not take
|
||||
place otherwise as would have happened in `main`. This function is used by the
|
||||
rasterizer to process an entire span of fragments that have passed the depth
|
||||
test (if applicable) and clipping, but have not yet been output to the blend
|
||||
stage.
|
||||
|
||||
The amount of fragments within the span to be processed is designated by
|
||||
`swgl_SpanLength` and is always aligned to units of `swgl_StepSize`.
|
||||
The size of a group of fragments in terms of which `swgl_commit` intrinsics
|
||||
process and output fragments is designated by `swgl_StepSize`. The
|
||||
`swgl_commit` intrinsics will deduct accordingly from `swgl_SpanLength` in
|
||||
units of `swgl_StepSize` to reflect the fragments actually processed, which
|
||||
may be less than the entire span or up to the entire span.
|
||||
|
||||
Fragments should be output until `swgl_SpanLength` becomes zero to process the
|
||||
entire span. If `swgl_drawSpan` returns while leaving any fragments unprocessed,
|
||||
the remaining fragments will be processed as normal by the fragment shader's
|
||||
`main` function. This can be used to conditionally handle certain fast-paths
|
||||
in a fragment shader by otherwise defaulting to the `main` function if
|
||||
`swgl_drawSpan` can't appropriately process some or all of the fragments.
|
||||
|
||||
The values of any varying inputs to the fragment shader will be set to their
|
||||
values for the start of the span, but do not automatically update over the
|
||||
the course of a span within a given call to `swgl_drawSpan`. The
|
||||
`swgl_interpStep` intrinsic may be used to get the derivative per `swgl_StepSize`
|
||||
group of fragments of a varying input so that the caller may update such
|
||||
variables manually if desired or otherwise use that information for processing.
|
||||
The `swgl_stepInterp` intrinsic forces all such varying inputs to advance by
|
||||
a single step.
|
||||
|
||||
The RGBA8 version will be used when the destination framebuffer is RGBA8 format,
|
||||
and the R8 version will be used when the destination framebuffer is R8. Various
|
||||
other intrinsics described below may have restrictions on whether they can be
|
||||
used only with a certain destination framebuffer format and are noted as such if
|
||||
so.
|
||||
|
||||
```
|
||||
void swgl_clipMask(sampler2D mask, vec2 offset, vec2 bb_origin, vec2 bb_size);
|
||||
```
|
||||
|
||||
When called from the the vertex shader, this specifies a clip mask texture to
|
||||
be used to mask the currently drawn primitive while blending is enabled. This
|
||||
mask will only apply to the current primitive.
|
||||
|
||||
The mask must be an R8 texture that will be interpreted as alpha weighting
|
||||
applied to the source pixel prior to the blend stage. It is sampled 1:1 with
|
||||
nearest filtering without any applied transform. The given offset specifies
|
||||
the positioning of the clip mask relative to the framebuffer's viewport.
|
||||
|
||||
The supplied bounding box constrains sampling of the clip mask to only fall
|
||||
within the given rectangle, specified relative to the clip mask offset.
|
||||
Anything falling outside this rectangle will be clipped entirely. If the
|
||||
rectangle is empty, then the clip mask will be ignored.
|
||||
|
||||
```
|
||||
void swgl_antiAlias(int edgeMask);
|
||||
```
|
||||
|
||||
When called from the vertex shader, this enables anti-aliasing for the
|
||||
currently drawn primitive while blending is enabled. This setting will only
|
||||
apply to the current primitive. Anti-aliasing will be applied only to the
|
||||
edges corresponding to bits supplied in the mask. For simple use-cases,
|
||||
the edge mask can be set to all 1 bits to enable AA for the entire quad.
|
||||
|
||||
The order of the bits in the edge mask must match the winding order in which
|
||||
the vertices are output in the vertex shader if processed as a quad, so that
|
||||
the edge ends on that vertex. The easiest way to understand this ordering
|
||||
is that for a rectangle (x0,y0,x1,y1) then the edge Nth edge bit corresponds
|
||||
to the edge where Nth coordinate in the rectangle is constant.
|
||||
|
||||
SWGL tries to use an anti-aliasing method that is reasonably close to WR's
|
||||
signed-distance field approximation. WR would normally try to discern the
|
||||
2D local-space coordinates of a given destination pixel relative to the
|
||||
2D local-space bounding rectangle of a primitive. It then uses the screen-
|
||||
space derivative to try to determine the how many local-space units equate
|
||||
to a distance of around one screen-space pixel. A distance approximation
|
||||
of coverage is then used based on the distance in local-space from the
|
||||
the current pixel's center, roughly at half-intensity at pixel center
|
||||
and ranging to zero or full intensity within a radius of half a pixel
|
||||
away from the center. To account for AAing going outside the normal geometry
|
||||
boundaries of the primitive, WR has to extrude the primitive by a local-space
|
||||
estimate to allow some AA to happen within the extruded region.
|
||||
|
||||
SWGL can ultimately do this approximation more simply and get around the
|
||||
extrusion limitations by just ensuring spans encompass any pixel that is
|
||||
partially covered when computing span boundaries. Further, since SWGL already
|
||||
knows the slope of an edge and the coordinate of the span relative to the span
|
||||
boundaries, finding the partial coverage of a given span becomes easy to do
|
||||
without requiring any extra interpolants to track against local-space bounds.
|
||||
Essentially, SWGL just performs anti-aliasing on the actual geometry bounds,
|
||||
but when the pixels on a span's edge are determined to be partially covered
|
||||
during span rasterization, it uses the same distance field method as WR on
|
||||
those span boundary pixels to estimate the coverage based on edge slope.
|
||||
|
||||
```
|
||||
void swgl_commitTextureLinearRGBA8(sampler, vec2 uv, vec4 uv_bounds);
|
||||
void swgl_commitTextureLinearR8(sampler, vec2 uv, vec4 uv_bounds);
|
||||
void swgl_commitTextureLinearR8ToRGBA8(sampler, vec2 uv, vec4 uv_bounds);
|
||||
|
||||
void swgl_commitTextureLinearColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
|
||||
void swgl_commitTextureLinearColorR8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
|
||||
void swgl_commitTextureLinearColorR8ToRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitTextureLinearRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
|
||||
void swgl_commitTextureLinearRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitTextureNearestRGBA8(sampler, vec2 uv, vec4 uv_bounds);
|
||||
void swgl_commitTextureNearestColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitTextureNearestRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
|
||||
void swgl_commitTextureNearestRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitTextureRGBA8(sampler, vec2 uv, vec4 uv_bounds);
|
||||
void swgl_commitTextureColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitTextureRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
|
||||
void swgl_commitTextureRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
|
||||
|
||||
void swgl_commitPartialTextureLinearR8(int len, sampler, vec2 uv, vec4 uv_bounds);
|
||||
void swgl_commitPartialTextureLinearInvertR8(int len, sampler, vec2 uv, vec4 uv_bounds);
|
||||
```
|
||||
|
||||
Samples and commits an entire span of texture starting at the given uv and
|
||||
within the supplied uv bounds. The color variations also accept a supplied color
|
||||
that modulates the result.
|
||||
|
||||
The RGBA8 versions may only be used to commit within `swgl_drawSpanRGBA8`, and
|
||||
the R8 versions may only be used to commit within `swgl_drawSpanR8`. The R8ToRGBA8
|
||||
versions may be used to sample from an R8 source while committing to an RGBA8
|
||||
framebuffer.
|
||||
|
||||
The Linear variations use a linear filter that bilinearly interpolates between
|
||||
the four samples near the pixel. The Nearest variations use a nearest filter
|
||||
that chooses the closest aliased sample to the center of the pixel. If neither
|
||||
Linear nor Nearest is specified in the `swgl_commitTexture` variation name, then
|
||||
it will automatically select either the Linear or Nearest variation depending
|
||||
on the sampler's specified filter.
|
||||
|
||||
The Repeat variations require an optional repeat rect that specifies how to
|
||||
scale and offset the UVs, assuming the UVs are normalized to repeat in the
|
||||
range 0 to 1. For NearestRepeat variations, it is assumed the repeat rect is
|
||||
always within the bounds. The tile repeat limit, if non-zero, specifies the
|
||||
maximum number of repetitions allowed.
|
||||
|
||||
The Partial variations allow committing only a sub-span rather the entire
|
||||
remaining span. These are currently only implemented in linear R8 variants
|
||||
for optimizing clip shaders in WebRender. The Invert variant of these is
|
||||
useful for implementing clip-out modes by inverting the source texture value.
|
||||
|
||||
```
|
||||
// Premultiplied alpha over blend, but with source color set to source alpha modulated with a constant color.
|
||||
void swgl_blendDropShadow(vec4 color);
|
||||
// Premultiplied alpha over blend, but treats the source as a subpixel mask modulated with a constant color.
|
||||
void swgl_blendSubpixelText(vec4 color);
|
||||
```
|
||||
|
||||
SWGL allows overriding the blend mode per-primitive by calling `swgl_blend`
|
||||
intrinsics in the vertex shader. The existing blend mode set by the GL is
|
||||
replaced with the one specified by the intrinsic for the current primitive.
|
||||
The blend mode will be reset to the blend mode set by the GL for the next
|
||||
primitive after the current one, even within the same draw call.
|
||||
|
||||
|
|
101
third_party/webrender/swgl/build.rs
vendored
101
third_party/webrender/swgl/build.rs
vendored
|
@ -2,9 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use cc;
|
||||
use glsl_to_cxx;
|
||||
use webrender_build;
|
||||
extern crate cc;
|
||||
extern crate glsl_to_cxx;
|
||||
extern crate webrender_build;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
|
@ -52,7 +52,7 @@ fn process_imports(shader_dir: &str, shader: &str, included: &mut HashSet<String
|
|||
}
|
||||
|
||||
fn translate_shader(shader_key: &str, shader_dir: &str) {
|
||||
let mut imported = String::from("#define SWGL 1\n");
|
||||
let mut imported = String::from("#define SWGL 1\n#define __VERSION__ 150\n");
|
||||
let _ = write!(imported, "#define WR_MAX_VERTEX_TEXTURE_WIDTH {}U\n",
|
||||
webrender_build::MAX_VERTEX_TEXTURE_WIDTH);
|
||||
|
||||
|
@ -73,11 +73,21 @@ fn translate_shader(shader_key: &str, shader_dir: &str) {
|
|||
std::fs::write(&imp_name, imported).unwrap();
|
||||
|
||||
let mut build = cc::Build::new();
|
||||
if build.get_compiler().is_like_msvc() {
|
||||
build.flag("/EP");
|
||||
} else {
|
||||
build.flag("-xc").flag("-P");
|
||||
build.no_default_flags(true);
|
||||
if let Ok(tool) = build.try_get_compiler() {
|
||||
if tool.is_like_msvc() {
|
||||
build.flag("/EP");
|
||||
if tool.path().to_str().map_or(false, |p| p.contains("clang")) {
|
||||
build.flag("/clang:-undef");
|
||||
} else {
|
||||
build.flag("/u");
|
||||
}
|
||||
} else {
|
||||
build.flag("-xc").flag("-P").flag("-undef");
|
||||
}
|
||||
}
|
||||
// Use SWGLPP target to avoid pulling CFLAGS/CXXFLAGS.
|
||||
build.target("SWGLPP");
|
||||
build.file(&imp_name);
|
||||
let vs = build.clone()
|
||||
.define("WR_VERTEX_SHADER", Some("1"))
|
||||
|
@ -90,16 +100,11 @@ fn translate_shader(shader_key: &str, shader_dir: &str) {
|
|||
std::fs::write(&vs_name, vs).unwrap();
|
||||
std::fs::write(&fs_name, fs).unwrap();
|
||||
|
||||
let mut args = vec![
|
||||
let args = vec![
|
||||
"glsl_to_cxx".to_string(),
|
||||
vs_name,
|
||||
fs_name,
|
||||
];
|
||||
let frag_include = format!("{}/{}.frag.h", shader_dir, shader);
|
||||
if std::path::Path::new(&frag_include).exists() {
|
||||
println!("cargo:rerun-if-changed={}/{}.frag.h", shader_dir, shader);
|
||||
args.push(frag_include);
|
||||
}
|
||||
let result = glsl_to_cxx::translate(&mut args.into_iter());
|
||||
std::fs::write(format!("{}/{}.h", out_dir, shader), result).unwrap();
|
||||
}
|
||||
|
@ -112,7 +117,9 @@ fn main() {
|
|||
|
||||
let shader_flags =
|
||||
ShaderFeatureFlags::GL |
|
||||
ShaderFeatureFlags::DUAL_SOURCE_BLENDING;
|
||||
ShaderFeatureFlags::DUAL_SOURCE_BLENDING |
|
||||
ShaderFeatureFlags::ADVANCED_BLEND_EQUATION |
|
||||
ShaderFeatureFlags::DEBUG;
|
||||
let mut shaders: Vec<String> = Vec::new();
|
||||
for (name, features) in get_shader_features(shader_flags) {
|
||||
shaders.extend(features.iter().map(|f| {
|
||||
|
@ -122,26 +129,74 @@ fn main() {
|
|||
|
||||
shaders.sort();
|
||||
|
||||
// We need to ensure that the C preprocessor does not pull compiler flags from
|
||||
// the host or target environment. Set up a SWGLPP target with empty flags to
|
||||
// work around this.
|
||||
if let Ok(target) = std::env::var("TARGET") {
|
||||
if let Ok(cc) = std::env::var(format!("CC_{}", target))
|
||||
.or(std::env::var(format!("CC_{}", target.replace("-", "_")))) {
|
||||
std::env::set_var("CC_SWGLPP", cc);
|
||||
}
|
||||
}
|
||||
std::env::set_var("CFLAGS_SWGLPP", "");
|
||||
|
||||
for shader in &shaders {
|
||||
translate_shader(shader, &shader_dir);
|
||||
}
|
||||
|
||||
write_load_shader(&shaders);
|
||||
|
||||
println!("cargo:rerun-if-changed=src/blend.h");
|
||||
println!("cargo:rerun-if-changed=src/composite.h");
|
||||
println!("cargo:rerun-if-changed=src/gl_defs.h");
|
||||
println!("cargo:rerun-if-changed=src/glsl.h");
|
||||
println!("cargo:rerun-if-changed=src/program.h");
|
||||
println!("cargo:rerun-if-changed=src/rasterize.h");
|
||||
println!("cargo:rerun-if-changed=src/swgl_ext.h");
|
||||
println!("cargo:rerun-if-changed=src/texture.h");
|
||||
println!("cargo:rerun-if-changed=src/vector_type.h");
|
||||
println!("cargo:rerun-if-changed=src/gl.cc");
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.file("src/gl.cc")
|
||||
.flag("-std=c++14")
|
||||
.flag("-UMOZILLA_CONFIG_H")
|
||||
.flag("-fno-exceptions")
|
||||
.flag("-fno-rtti")
|
||||
.flag("-fno-math-errno")
|
||||
let mut build = cc::Build::new();
|
||||
build.cpp(true);
|
||||
|
||||
if let Ok(tool) = build.try_get_compiler() {
|
||||
if tool.is_like_msvc() {
|
||||
build.flag("/std:c++17")
|
||||
.flag("/EHs-")
|
||||
.flag("/GR-")
|
||||
.flag("/UMOZILLA_CONFIG_H");
|
||||
} else {
|
||||
build.flag("-std=c++17")
|
||||
.flag("-fno-exceptions")
|
||||
.flag("-fno-rtti")
|
||||
.flag("-fno-math-errno")
|
||||
.flag("-UMOZILLA_CONFIG_H");
|
||||
}
|
||||
// SWGL relies heavily on inlining for performance so override -Oz with -O2
|
||||
if tool.args().contains(&"-Oz".into()) {
|
||||
build.flag("-O2");
|
||||
}
|
||||
|
||||
// Most GLSL compilers assume something like fast-math so we turn it on.
|
||||
// However, reciprocal division makes it so 1/1 = 0.999994 which can produce a lot of fuzz
|
||||
// in reftests and the use of reciprocal instructions usually involves a refinement step
|
||||
// which bloats our already bloated code. Further, our shader code is sufficiently parallel
|
||||
// that we're more likely to be throughput bound vs latency bound. Having fewer
|
||||
// instructions makes things easier on the processor and in places where it matters we can
|
||||
// probably explicitly use reciprocal instructions and avoid the refinement step.
|
||||
if tool.is_like_msvc() {
|
||||
build.flag("/fp:fast")
|
||||
.flag("-Xclang")
|
||||
.flag("-mrecip=none");
|
||||
} else if tool.is_like_clang() {
|
||||
// gcc only supports -mrecip=none on some targets so to keep
|
||||
// things simple we don't use -ffast-math with gcc at all
|
||||
build.flag("-ffast-math")
|
||||
.flag("-mrecip=none");
|
||||
}
|
||||
}
|
||||
|
||||
build.file("src/gl.cc")
|
||||
.define("_GLIBCXX_USE_CXX11_ABI", Some("0"))
|
||||
.include(shader_dir)
|
||||
.include("src")
|
||||
|
|
864
third_party/webrender/swgl/src/blend.h
vendored
Normal file
864
third_party/webrender/swgl/src/blend.h
vendored
Normal file
|
@ -0,0 +1,864 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
static ALWAYS_INLINE HalfRGBA8 packRGBA8(I32 a, I32 b) {
|
||||
#if USE_SSE2
|
||||
return _mm_packs_epi32(a, b);
|
||||
#elif USE_NEON
|
||||
return vcombine_u16(vqmovun_s32(a), vqmovun_s32(b));
|
||||
#else
|
||||
return CONVERT(combine(a, b), HalfRGBA8);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8(const vec4& v,
|
||||
float scale = 255.0f) {
|
||||
ivec4 i = round_pixel(v, scale);
|
||||
HalfRGBA8 xz = packRGBA8(i.z, i.x);
|
||||
HalfRGBA8 yw = packRGBA8(i.y, i.w);
|
||||
HalfRGBA8 xyzwl = zipLow(xz, yw);
|
||||
HalfRGBA8 xyzwh = zipHigh(xz, yw);
|
||||
HalfRGBA8 lo = zip2Low(xyzwl, xyzwh);
|
||||
HalfRGBA8 hi = zip2High(xyzwl, xyzwh);
|
||||
return combine(lo, hi);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8(Float alpha,
|
||||
float scale = 255.0f) {
|
||||
I32 i = round_pixel(alpha, scale);
|
||||
HalfRGBA8 c = packRGBA8(i, i);
|
||||
c = zipLow(c, c);
|
||||
return zip(c, c);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8(float alpha,
|
||||
float scale = 255.0f) {
|
||||
I32 i = round_pixel(alpha, scale);
|
||||
return repeat2(packRGBA8(i, i));
|
||||
}
|
||||
|
||||
UNUSED static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8(const vec4_scalar& v,
|
||||
float scale = 255.0f) {
|
||||
I32 i = round_pixel((Float){v.z, v.y, v.x, v.w}, scale);
|
||||
return repeat2(packRGBA8(i, i));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8() {
|
||||
return pack_pixels_RGBA8(fragment_shader->gl_FragColor);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 pack_pixels_RGBA8(WideRGBA32F v,
|
||||
float scale = 255.0f) {
|
||||
ivec4 i = round_pixel(bit_cast<vec4>(v), scale);
|
||||
return combine(packRGBA8(i.x, i.y), packRGBA8(i.z, i.w));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideR8 packR8(I32 a) {
|
||||
#if USE_SSE2
|
||||
return lowHalf(bit_cast<V8<uint16_t>>(_mm_packs_epi32(a, a)));
|
||||
#elif USE_NEON
|
||||
return vqmovun_s32(a);
|
||||
#else
|
||||
return CONVERT(a, WideR8);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideR8 pack_pixels_R8(Float c, float scale = 255.0f) {
|
||||
return packR8(round_pixel(c, scale));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideR8 pack_pixels_R8() {
|
||||
return pack_pixels_R8(fragment_shader->gl_FragColor.x);
|
||||
}
|
||||
|
||||
// Load a partial span > 0 and < 4 pixels.
|
||||
template <typename V, typename P>
|
||||
static ALWAYS_INLINE V partial_load_span(const P* src, int span) {
|
||||
return bit_cast<V>(
|
||||
(span >= 2
|
||||
? combine(unaligned_load<V2<P>>(src),
|
||||
V2<P>{span > 2 ? unaligned_load<P>(src + 2) : P(0), 0})
|
||||
: V4<P>{unaligned_load<P>(src), 0, 0, 0}));
|
||||
}
|
||||
|
||||
// Store a partial span > 0 and < 4 pixels.
|
||||
template <typename V, typename P>
|
||||
static ALWAYS_INLINE void partial_store_span(P* dst, V src, int span) {
|
||||
auto pixels = bit_cast<V4<P>>(src);
|
||||
if (span >= 2) {
|
||||
unaligned_store(dst, lowHalf(pixels));
|
||||
if (span > 2) {
|
||||
unaligned_store(dst + 2, pixels.z);
|
||||
}
|
||||
} else {
|
||||
unaligned_store(dst, pixels.x);
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatcher that chooses when to load a full or partial span
|
||||
template <typename V, typename P>
|
||||
static ALWAYS_INLINE V load_span(const P* src, int span) {
|
||||
if (span >= 4) {
|
||||
return unaligned_load<V, P>(src);
|
||||
} else {
|
||||
return partial_load_span<V, P>(src, span);
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatcher that chooses when to store a full or partial span
|
||||
template <typename V, typename P>
|
||||
static ALWAYS_INLINE void store_span(P* dst, V src, int span) {
|
||||
if (span >= 4) {
|
||||
unaligned_store<V, P>(dst, src);
|
||||
} else {
|
||||
partial_store_span<V, P>(dst, src, span);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static ALWAYS_INLINE T muldiv256(T x, T y) {
|
||||
return (x * y) >> 8;
|
||||
}
|
||||
|
||||
// (x*y + x) >> 8, cheap approximation of (x*y) / 255
|
||||
template <typename T>
|
||||
static ALWAYS_INLINE T muldiv255(T x, T y) {
|
||||
return (x * y + x) >> 8;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static ALWAYS_INLINE WideRGBA8 pack_span(uint32_t*, const V& v,
|
||||
float scale = 255.0f) {
|
||||
return pack_pixels_RGBA8(v, scale);
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
static ALWAYS_INLINE WideR8 pack_span(uint8_t*, C c, float scale = 255.0f) {
|
||||
return pack_pixels_R8(c, scale);
|
||||
}
|
||||
|
||||
// Helper functions to apply a color modulus when available.
|
||||
struct NoColor {};
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE P applyColor(P src, NoColor) {
|
||||
return src;
|
||||
}
|
||||
|
||||
struct InvertColor {};
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE P applyColor(P src, InvertColor) {
|
||||
return 255 - src;
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE P applyColor(P src, P color) {
|
||||
return muldiv255(color, src);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 applyColor(PackedRGBA8 src, WideRGBA8 color) {
|
||||
return applyColor(unpack(src), color);
|
||||
}
|
||||
|
||||
template <typename P, typename C>
|
||||
static ALWAYS_INLINE auto packColor(P* buf, C color) {
|
||||
return pack_span(buf, color, 255.0f);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE NoColor packColor(UNUSED P* buf, NoColor noColor) {
|
||||
return noColor;
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE InvertColor packColor(UNUSED P* buf,
|
||||
InvertColor invertColor) {
|
||||
return invertColor;
|
||||
}
|
||||
|
||||
// Single argument variation that takes an explicit destination buffer type.
|
||||
template <typename P, typename C>
|
||||
static ALWAYS_INLINE auto packColor(C color) {
|
||||
// Just pass in a typed null pointer, as the pack routines never use the
|
||||
// pointer's value, just its type.
|
||||
return packColor((P*)0, color);
|
||||
}
|
||||
|
||||
// Byte-wise addition for when x or y is a signed 8-bit value stored in the
|
||||
// low byte of a larger type T only with zeroed-out high bits, where T is
|
||||
// greater than 8 bits, i.e. uint16_t. This can result when muldiv255 is used
|
||||
// upon signed operands, using up all the precision in a 16 bit integer, and
|
||||
// potentially losing the sign bit in the last >> 8 shift. Due to the
|
||||
// properties of two's complement arithmetic, even though we've discarded the
|
||||
// sign bit, we can still represent a negative number under addition (without
|
||||
// requiring any extra sign bits), just that any negative number will behave
|
||||
// like a large unsigned number under addition, generating a single carry bit
|
||||
// on overflow that we need to discard. Thus, just doing a byte-wise add will
|
||||
// overflow without the troublesome carry, giving us only the remaining 8 low
|
||||
// bits we actually need while keeping the high bits at zero.
|
||||
template <typename T>
|
||||
static ALWAYS_INLINE T addlow(T x, T y) {
|
||||
typedef VectorType<uint8_t, sizeof(T)> bytes;
|
||||
return bit_cast<T>(bit_cast<bytes>(x) + bit_cast<bytes>(y));
|
||||
}
|
||||
|
||||
// Replace color components of each pixel with the pixel's alpha values.
|
||||
template <typename T>
|
||||
static ALWAYS_INLINE T alphas(T c) {
|
||||
return SHUFFLE(c, c, 3, 3, 3, 3, 7, 7, 7, 7, 11, 11, 11, 11, 15, 15, 15, 15);
|
||||
}
|
||||
|
||||
// Replace the alpha values of the first vector with alpha values from the
|
||||
// second, while leaving the color components unmodified.
|
||||
template <typename T>
|
||||
static ALWAYS_INLINE T set_alphas(T c, T a) {
|
||||
return SHUFFLE(c, a, 0, 1, 2, 19, 4, 5, 6, 23, 8, 9, 10, 27, 12, 13, 14, 31);
|
||||
}
|
||||
|
||||
// Miscellaneous helper functions for working with packed RGBA8 data.
|
||||
static ALWAYS_INLINE HalfRGBA8 if_then_else(V8<int16_t> c, HalfRGBA8 t,
|
||||
HalfRGBA8 e) {
|
||||
return bit_cast<HalfRGBA8>((c & t) | (~c & e));
|
||||
}
|
||||
|
||||
template <typename T, typename C, int N>
|
||||
static ALWAYS_INLINE VectorType<T, N> if_then_else(VectorType<C, N> c,
|
||||
VectorType<T, N> t,
|
||||
VectorType<T, N> e) {
|
||||
return combine(if_then_else(lowHalf(c), lowHalf(t), lowHalf(e)),
|
||||
if_then_else(highHalf(c), highHalf(t), highHalf(e)));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE HalfRGBA8 min(HalfRGBA8 x, HalfRGBA8 y) {
|
||||
#if USE_SSE2
|
||||
return bit_cast<HalfRGBA8>(
|
||||
_mm_min_epi16(bit_cast<V8<int16_t>>(x), bit_cast<V8<int16_t>>(y)));
|
||||
#elif USE_NEON
|
||||
return vminq_u16(x, y);
|
||||
#else
|
||||
return if_then_else(x < y, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
static ALWAYS_INLINE VectorType<T, N> min(VectorType<T, N> x,
|
||||
VectorType<T, N> y) {
|
||||
return combine(min(lowHalf(x), lowHalf(y)), min(highHalf(x), highHalf(y)));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE HalfRGBA8 max(HalfRGBA8 x, HalfRGBA8 y) {
|
||||
#if USE_SSE2
|
||||
return bit_cast<HalfRGBA8>(
|
||||
_mm_max_epi16(bit_cast<V8<int16_t>>(x), bit_cast<V8<int16_t>>(y)));
|
||||
#elif USE_NEON
|
||||
return vmaxq_u16(x, y);
|
||||
#else
|
||||
return if_then_else(x > y, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
static ALWAYS_INLINE VectorType<T, N> max(VectorType<T, N> x,
|
||||
VectorType<T, N> y) {
|
||||
return combine(max(lowHalf(x), lowHalf(y)), max(highHalf(x), highHalf(y)));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
static ALWAYS_INLINE VectorType<T, N> recip(VectorType<T, N> v) {
|
||||
return combine(recip(lowHalf(v)), recip(highHalf(v)));
|
||||
}
|
||||
|
||||
// Helper to get the reciprocal if the value is non-zero, or otherwise default
|
||||
// to the supplied fallback value.
|
||||
template <typename V>
|
||||
static ALWAYS_INLINE V recip_or(V v, float f) {
|
||||
return if_then_else(v != V(0.0f), recip(v), V(f));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
static ALWAYS_INLINE VectorType<T, N> inversesqrt(VectorType<T, N> v) {
|
||||
return combine(inversesqrt(lowHalf(v)), inversesqrt(highHalf(v)));
|
||||
}
|
||||
|
||||
// Extract the alpha components so that we can cheaply calculate the reciprocal
|
||||
// on a single SIMD register. Then multiply the duplicated alpha reciprocal with
|
||||
// the pixel data. 0 alpha is treated as transparent black.
|
||||
static ALWAYS_INLINE WideRGBA32F unpremultiply(WideRGBA32F v) {
|
||||
Float a = recip_or((Float){v[3], v[7], v[11], v[15]}, 0.0f);
|
||||
return v * a.xxxxyyyyzzzzwwww;
|
||||
}
|
||||
|
||||
// Packed RGBA32F data is AoS in BGRA order. Transpose it to SoA and swizzle to
|
||||
// RGBA to unpack.
|
||||
static ALWAYS_INLINE vec4 unpack(PackedRGBA32F c) {
|
||||
return bit_cast<vec4>(
|
||||
SHUFFLE(c, c, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12, 3, 7, 11, 15));
|
||||
}
|
||||
|
||||
// The following lum/sat functions mostly follow the KHR_blend_equation_advanced
|
||||
// specification but are rearranged to work on premultiplied data.
|
||||
static ALWAYS_INLINE Float lumv3(vec3 v) {
|
||||
return v.x * 0.30f + v.y * 0.59f + v.z * 0.11f;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE Float minv3(vec3 v) { return min(min(v.x, v.y), v.z); }
|
||||
|
||||
static ALWAYS_INLINE Float maxv3(vec3 v) { return max(max(v.x, v.y), v.z); }
|
||||
|
||||
static inline vec3 clip_color(vec3 v, Float lum, Float alpha) {
|
||||
Float mincol = max(-minv3(v), lum);
|
||||
Float maxcol = max(maxv3(v), alpha - lum);
|
||||
return lum + v * (lum * (alpha - lum) * recip_or(mincol * maxcol, 0.0f));
|
||||
}
|
||||
|
||||
static inline vec3 set_lum(vec3 base, vec3 ref, Float alpha) {
|
||||
return clip_color(base - lumv3(base), lumv3(ref), alpha);
|
||||
}
|
||||
|
||||
static inline vec3 set_lum_sat(vec3 base, vec3 sref, vec3 lref, Float alpha) {
|
||||
vec3 diff = base - minv3(base);
|
||||
Float sbase = maxv3(diff);
|
||||
Float ssat = maxv3(sref) - minv3(sref);
|
||||
// The sbase range is rescaled to ssat. If sbase has 0 extent, then rescale
|
||||
// to black, as per specification.
|
||||
return set_lum(diff * ssat * recip_or(sbase, 0.0f), lref, alpha);
|
||||
}
|
||||
|
||||
// Flags the reflect the current blend-stage clipping to be applied.
|
||||
enum SWGLClipFlag {
|
||||
SWGL_CLIP_FLAG_MASK = 1 << 0,
|
||||
SWGL_CLIP_FLAG_AA = 1 << 1,
|
||||
SWGL_CLIP_FLAG_BLEND_OVERRIDE = 1 << 2,
|
||||
};
|
||||
static int swgl_ClipFlags = 0;
|
||||
static BlendKey swgl_BlendOverride = BLEND_KEY_NONE;
|
||||
static WideRGBA8 swgl_BlendColorRGBA8 = {0};
|
||||
static WideRGBA8 swgl_BlendAlphaRGBA8 = {0};
|
||||
|
||||
// A pointer into the color buffer for the start of the span.
|
||||
static void* swgl_SpanBuf = nullptr;
|
||||
// A pointer into the clip mask for the start of the span.
|
||||
static uint8_t* swgl_ClipMaskBuf = nullptr;
|
||||
|
||||
static ALWAYS_INLINE WideR8 expand_mask(UNUSED uint8_t* buf, WideR8 mask) {
|
||||
return mask;
|
||||
}
|
||||
static ALWAYS_INLINE WideRGBA8 expand_mask(UNUSED uint32_t* buf, WideR8 mask) {
|
||||
WideRG8 maskRG = zip(mask, mask);
|
||||
return zip(maskRG, maskRG);
|
||||
}
|
||||
|
||||
// Loads a chunk of clip masks. The current pointer into the color buffer is
|
||||
// used to reconstruct the relative position within the span. From there, the
|
||||
// pointer into the clip mask can be generated from the start of the clip mask
|
||||
// span.
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE uint8_t* get_clip_mask(P* buf) {
|
||||
return &swgl_ClipMaskBuf[buf - (P*)swgl_SpanBuf];
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE auto load_clip_mask(P* buf, int span)
|
||||
-> decltype(expand_mask(buf, 0)) {
|
||||
return expand_mask(buf,
|
||||
unpack(load_span<PackedR8>(get_clip_mask(buf), span)));
|
||||
}
|
||||
|
||||
// Temporarily removes masking from the blend stage, assuming the caller will
|
||||
// handle it.
|
||||
static ALWAYS_INLINE void override_clip_mask() {
|
||||
blend_key = BlendKey(blend_key - MASK_BLEND_KEY_NONE);
|
||||
}
|
||||
|
||||
// Restores masking to the blend stage, assuming it was previously overridden.
|
||||
static ALWAYS_INLINE void restore_clip_mask() {
|
||||
blend_key = BlendKey(MASK_BLEND_KEY_NONE + blend_key);
|
||||
}
|
||||
|
||||
// A pointer to the start of the opaque destination region of the span for AA.
|
||||
static const uint8_t* swgl_OpaqueStart = nullptr;
|
||||
// The size, in bytes, of the opaque region.
|
||||
static uint32_t swgl_OpaqueSize = 0;
|
||||
// AA coverage distance offsets for the left and right edges.
|
||||
static Float swgl_LeftAADist = 0.0f;
|
||||
static Float swgl_RightAADist = 0.0f;
|
||||
// AA coverage slope values used for accumulating coverage for each step.
|
||||
static Float swgl_AASlope = 0.0f;
|
||||
|
||||
// Get the amount of pixels we need to process before the start of the opaque
|
||||
// region.
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE int get_aa_opaque_start(P* buf) {
|
||||
return max(int((P*)swgl_OpaqueStart - buf), 0);
|
||||
}
|
||||
|
||||
// Assuming we are already in the opaque part of the span, return the remaining
|
||||
// size of the opaque part.
|
||||
template <typename P>
|
||||
static ALWAYS_INLINE int get_aa_opaque_size(P* buf) {
|
||||
return max(int((P*)&swgl_OpaqueStart[swgl_OpaqueSize] - buf), 0);
|
||||
}
|
||||
|
||||
// Temporarily removes anti-aliasing from the blend stage, assuming the caller
|
||||
// will handle it.
|
||||
static ALWAYS_INLINE void override_aa() {
|
||||
blend_key = BlendKey(blend_key - AA_BLEND_KEY_NONE);
|
||||
}
|
||||
|
||||
// Restores anti-aliasing to the blend stage, assuming it was previously
|
||||
// overridden.
|
||||
static ALWAYS_INLINE void restore_aa() {
|
||||
blend_key = BlendKey(AA_BLEND_KEY_NONE + blend_key);
|
||||
}
|
||||
|
||||
static PREFER_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst,
|
||||
WideRGBA8 src, int span = 4) {
|
||||
WideRGBA8 dst = unpack(pdst);
|
||||
const WideRGBA8 RGB_MASK = {0xFFFF, 0xFFFF, 0xFFFF, 0, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0, 0xFFFF, 0xFFFF, 0xFFFF, 0,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0};
|
||||
const WideRGBA8 ALPHA_MASK = {0, 0, 0, 0xFFFF, 0, 0, 0, 0xFFFF,
|
||||
0, 0, 0, 0xFFFF, 0, 0, 0, 0xFFFF};
|
||||
const WideRGBA8 ALPHA_OPAQUE = {0, 0, 0, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 0, 0, 0, 255};
|
||||
|
||||
// clang-format off
|
||||
// Computes AA for the given pixel based on the offset of the pixel within
|
||||
// destination row. Given the initial coverage offsets for the left and right
|
||||
// edges, the offset is scaled by the slope and accumulated to find the
|
||||
// minimum coverage value for the pixel. A final weight is generated that
|
||||
// can be used to scale the source pixel.
|
||||
#define DO_AA(format, body) \
|
||||
do { \
|
||||
int offset = int((const uint8_t*)buf - swgl_OpaqueStart); \
|
||||
if (uint32_t(offset) >= swgl_OpaqueSize) { \
|
||||
Float delta = swgl_AASlope * float(offset); \
|
||||
Float dist = clamp(min(swgl_LeftAADist + delta.x, \
|
||||
swgl_RightAADist + delta.y), \
|
||||
0.0f, 256.0f); \
|
||||
auto aa = pack_pixels_##format(dist, 1.0f); \
|
||||
body; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Each blend case is preceded by the MASK_ variant. The MASK_ case first
|
||||
// loads the mask values and multiplies the source value by them. After, it
|
||||
// falls through to the normal blending case using the masked source. The
|
||||
// AA_ variations may further precede the blend cases, in which case the
|
||||
// source value is further modified before use.
|
||||
#define BLEND_CASE_KEY(key) \
|
||||
case AA_##key: \
|
||||
DO_AA(RGBA8, src = muldiv256(src, aa)); \
|
||||
goto key; \
|
||||
case AA_MASK_##key: \
|
||||
DO_AA(RGBA8, src = muldiv256(src, aa)); \
|
||||
FALLTHROUGH; \
|
||||
case MASK_##key: \
|
||||
src = muldiv255(src, load_clip_mask(buf, span)); \
|
||||
FALLTHROUGH; \
|
||||
case key: key
|
||||
|
||||
#define BLEND_CASE(...) BLEND_CASE_KEY(BLEND_KEY(__VA_ARGS__))
|
||||
|
||||
switch (blend_key) {
|
||||
BLEND_CASE(GL_ONE, GL_ZERO):
|
||||
return src;
|
||||
BLEND_CASE(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE,
|
||||
GL_ONE_MINUS_SRC_ALPHA):
|
||||
// dst + src.a*(src.rgb1 - dst)
|
||||
// use addlow for signed overflow
|
||||
return addlow(dst, muldiv255(alphas(src), (src | ALPHA_OPAQUE) - dst));
|
||||
BLEND_CASE(GL_ONE, GL_ONE_MINUS_SRC_ALPHA):
|
||||
return src + dst - muldiv255(dst, alphas(src));
|
||||
BLEND_CASE(GL_ZERO, GL_ONE_MINUS_SRC_COLOR):
|
||||
return dst - muldiv255(dst, src);
|
||||
BLEND_CASE(GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE):
|
||||
return dst - (muldiv255(dst, src) & RGB_MASK);
|
||||
BLEND_CASE(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA):
|
||||
return dst - muldiv255(dst, alphas(src));
|
||||
BLEND_CASE(GL_ZERO, GL_SRC_COLOR):
|
||||
return muldiv255(src, dst);
|
||||
BLEND_CASE(GL_ONE, GL_ONE):
|
||||
return src + dst;
|
||||
BLEND_CASE(GL_ONE, GL_ONE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA):
|
||||
return src + dst - (muldiv255(dst, src) & ALPHA_MASK);
|
||||
BLEND_CASE(GL_ONE_MINUS_DST_ALPHA, GL_ONE, GL_ZERO, GL_ONE):
|
||||
// src*(1-dst.a) + dst*1 = src - src*dst.a + dst
|
||||
return dst + ((src - muldiv255(src, alphas(dst))) & RGB_MASK);
|
||||
BLEND_CASE(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR):
|
||||
// src*k + (1-src)*dst = src*k + dst -
|
||||
// src*dst = dst + src*(k - dst) use addlow
|
||||
// for signed overflow
|
||||
return addlow(
|
||||
dst, muldiv255(src, repeat2(ctx->blendcolor) - dst));
|
||||
|
||||
// We must explicitly handle the masked/anti-aliased secondary blend case.
|
||||
// The secondary color as well as the source must be multiplied by the
|
||||
// weights.
|
||||
case BLEND_KEY(GL_ONE, GL_ONE_MINUS_SRC1_COLOR): {
|
||||
WideRGBA8 secondary =
|
||||
applyColor(dst,
|
||||
packColor<uint32_t>(fragment_shader->gl_SecondaryFragColor));
|
||||
return src + dst - secondary;
|
||||
}
|
||||
case MASK_BLEND_KEY(GL_ONE, GL_ONE_MINUS_SRC1_COLOR): {
|
||||
WideRGBA8 secondary =
|
||||
applyColor(dst,
|
||||
packColor<uint32_t>(fragment_shader->gl_SecondaryFragColor));
|
||||
WideRGBA8 mask = load_clip_mask(buf, span);
|
||||
return muldiv255(src, mask) + dst - muldiv255(secondary, mask);
|
||||
}
|
||||
case AA_BLEND_KEY(GL_ONE, GL_ONE_MINUS_SRC1_COLOR): {
|
||||
WideRGBA8 secondary =
|
||||
applyColor(dst,
|
||||
packColor<uint32_t>(fragment_shader->gl_SecondaryFragColor));
|
||||
DO_AA(RGBA8, {
|
||||
src = muldiv256(src, aa);
|
||||
secondary = muldiv256(secondary, aa);
|
||||
});
|
||||
return src + dst - secondary;
|
||||
}
|
||||
case AA_MASK_BLEND_KEY(GL_ONE, GL_ONE_MINUS_SRC1_COLOR): {
|
||||
WideRGBA8 secondary =
|
||||
applyColor(dst,
|
||||
packColor<uint32_t>(fragment_shader->gl_SecondaryFragColor));
|
||||
WideRGBA8 mask = load_clip_mask(buf, span);
|
||||
DO_AA(RGBA8, mask = muldiv256(mask, aa));
|
||||
return muldiv255(src, mask) + dst - muldiv255(secondary, mask);
|
||||
}
|
||||
|
||||
BLEND_CASE(GL_MIN):
|
||||
return min(src, dst);
|
||||
BLEND_CASE(GL_MAX):
|
||||
return max(src, dst);
|
||||
|
||||
// The KHR_blend_equation_advanced spec describes the blend equations such
|
||||
// that the unpremultiplied values Cs, Cd, As, Ad and function f combine to
|
||||
// the result:
|
||||
// Cr = f(Cs,Cd)*As*Ad + Cs*As*(1-Ad) + Cd*AD*(1-As)
|
||||
// Ar = As*Ad + As*(1-Ad) + Ad*(1-As)
|
||||
// However, working with unpremultiplied values requires expensive math to
|
||||
// unpremultiply and premultiply again during blending. We can use the fact
|
||||
// that premultiplied value P = C*A and simplify the equations such that no
|
||||
// unpremultiplied colors are necessary, allowing us to stay with integer
|
||||
// math that avoids floating-point conversions in the common case. Some of
|
||||
// the blend modes require division or sqrt, in which case we do convert
|
||||
// to (possibly transposed/unpacked) floating-point to implement the mode.
|
||||
// However, most common modes can still use cheaper premultiplied integer
|
||||
// math. As an example, the multiply mode f(Cs,Cd) = Cs*Cd is simplified
|
||||
// to:
|
||||
// Cr = Cs*Cd*As*Ad + Cs*As*(1-Ad) + Cd*Ad*(1-As)
|
||||
// .. Pr = Ps*Pd + Ps - Ps*Ad + Pd - Pd*As
|
||||
// Ar = As*Ad + As - As*Ad + Ad - Ad*As
|
||||
// .. Ar = As + Ad - As*Ad
|
||||
// Note that the alpha equation is the same for all blend equations, such
|
||||
// that so long as the implementation results in As + Ad - As*Ad, we can
|
||||
// avoid using separate instructions to compute the alpha result, which is
|
||||
// dependent on the math used to implement each blend mode. The exact
|
||||
// reductions used to get the final math for every blend mode are too
|
||||
// involved to show here in comments, but mostly follows from replacing
|
||||
// Cs*As and Cd*Ad with Ps and Ps while factoring out as many common terms
|
||||
// as possible.
|
||||
|
||||
BLEND_CASE(GL_MULTIPLY_KHR): {
|
||||
WideRGBA8 diff = muldiv255(alphas(src) - (src & RGB_MASK),
|
||||
alphas(dst) - (dst & RGB_MASK));
|
||||
return src + dst + (diff & RGB_MASK) - alphas(diff);
|
||||
}
|
||||
BLEND_CASE(GL_SCREEN_KHR):
|
||||
return src + dst - muldiv255(src, dst);
|
||||
BLEND_CASE(GL_OVERLAY_KHR): {
|
||||
WideRGBA8 srcA = alphas(src);
|
||||
WideRGBA8 dstA = alphas(dst);
|
||||
WideRGBA8 diff = muldiv255(src, dst) + muldiv255(srcA - src, dstA - dst);
|
||||
return src + dst +
|
||||
if_then_else(dst * 2 <= dstA, (diff & RGB_MASK) - alphas(diff),
|
||||
-diff);
|
||||
}
|
||||
BLEND_CASE(GL_DARKEN_KHR):
|
||||
return src + dst -
|
||||
max(muldiv255(src, alphas(dst)), muldiv255(dst, alphas(src)));
|
||||
BLEND_CASE(GL_LIGHTEN_KHR):
|
||||
return src + dst -
|
||||
min(muldiv255(src, alphas(dst)), muldiv255(dst, alphas(src)));
|
||||
|
||||
BLEND_CASE(GL_COLORDODGE_KHR): {
|
||||
// Color-dodge and color-burn require division, so we convert to FP math
|
||||
// here, but avoid transposing to a vec4.
|
||||
WideRGBA32F srcF = CONVERT(src, WideRGBA32F);
|
||||
WideRGBA32F srcA = alphas(srcF);
|
||||
WideRGBA32F dstF = CONVERT(dst, WideRGBA32F);
|
||||
WideRGBA32F dstA = alphas(dstF);
|
||||
return pack_pixels_RGBA8(
|
||||
srcA * set_alphas(
|
||||
min(dstA, dstF * srcA * recip_or(srcA - srcF, 255.0f)),
|
||||
dstF) +
|
||||
srcF * (255.0f - dstA) + dstF * (255.0f - srcA),
|
||||
1.0f / 255.0f);
|
||||
}
|
||||
BLEND_CASE(GL_COLORBURN_KHR): {
|
||||
WideRGBA32F srcF = CONVERT(src, WideRGBA32F);
|
||||
WideRGBA32F srcA = alphas(srcF);
|
||||
WideRGBA32F dstF = CONVERT(dst, WideRGBA32F);
|
||||
WideRGBA32F dstA = alphas(dstF);
|
||||
return pack_pixels_RGBA8(
|
||||
srcA * set_alphas((dstA - min(dstA, (dstA - dstF) * srcA *
|
||||
recip_or(srcF, 255.0f))),
|
||||
dstF) +
|
||||
srcF * (255.0f - dstA) + dstF * (255.0f - srcA),
|
||||
1.0f / 255.0f);
|
||||
}
|
||||
BLEND_CASE(GL_HARDLIGHT_KHR): {
|
||||
WideRGBA8 srcA = alphas(src);
|
||||
WideRGBA8 dstA = alphas(dst);
|
||||
WideRGBA8 diff = muldiv255(src, dst) + muldiv255(srcA - src, dstA - dst);
|
||||
return src + dst +
|
||||
if_then_else(src * 2 <= srcA, (diff & RGB_MASK) - alphas(diff),
|
||||
-diff);
|
||||
}
|
||||
|
||||
BLEND_CASE(GL_SOFTLIGHT_KHR): {
|
||||
// Soft-light requires an unpremultiply that can't be factored out as
|
||||
// well as a sqrt, so we convert to FP math here, but avoid transposing
|
||||
// to a vec4.
|
||||
WideRGBA32F srcF = CONVERT(src, WideRGBA32F);
|
||||
WideRGBA32F srcA = alphas(srcF);
|
||||
WideRGBA32F dstF = CONVERT(dst, WideRGBA32F);
|
||||
WideRGBA32F dstA = alphas(dstF);
|
||||
WideRGBA32F dstU = unpremultiply(dstF);
|
||||
WideRGBA32F scale = srcF + srcF - srcA;
|
||||
return pack_pixels_RGBA8(
|
||||
dstF * (255.0f +
|
||||
set_alphas(
|
||||
scale *
|
||||
if_then_else(scale < 0.0f, 1.0f - dstU,
|
||||
min((16.0f * dstU - 12.0f) * dstU + 3.0f,
|
||||
inversesqrt(dstU) - 1.0f)),
|
||||
WideRGBA32F(0.0f))) +
|
||||
srcF * (255.0f - dstA),
|
||||
1.0f / 255.0f);
|
||||
}
|
||||
BLEND_CASE(GL_DIFFERENCE_KHR): {
|
||||
WideRGBA8 diff =
|
||||
min(muldiv255(dst, alphas(src)), muldiv255(src, alphas(dst)));
|
||||
return src + dst - diff - (diff & RGB_MASK);
|
||||
}
|
||||
BLEND_CASE(GL_EXCLUSION_KHR): {
|
||||
WideRGBA8 diff = muldiv255(src, dst);
|
||||
return src + dst - diff - (diff & RGB_MASK);
|
||||
}
|
||||
|
||||
// The HSL blend modes are non-separable and require complicated use of
|
||||
// division. It is advantageous to convert to FP and transpose to vec4
|
||||
// math to more easily manipulate the individual color components.
|
||||
#define DO_HSL(rgb) \
|
||||
do { \
|
||||
vec4 srcV = unpack(CONVERT(src, PackedRGBA32F)); \
|
||||
vec4 dstV = unpack(CONVERT(dst, PackedRGBA32F)); \
|
||||
Float srcA = srcV.w * (1.0f / 255.0f); \
|
||||
Float dstA = dstV.w * (1.0f / 255.0f); \
|
||||
Float srcDstA = srcV.w * dstA; \
|
||||
vec3 srcC = vec3(srcV) * dstA; \
|
||||
vec3 dstC = vec3(dstV) * srcA; \
|
||||
return pack_pixels_RGBA8(vec4(rgb + vec3(srcV) - srcC + vec3(dstV) - dstC, \
|
||||
srcV.w + dstV.w - srcDstA), \
|
||||
1.0f); \
|
||||
} while (0)
|
||||
|
||||
BLEND_CASE(GL_HSL_HUE_KHR):
|
||||
DO_HSL(set_lum_sat(srcC, dstC, dstC, srcDstA));
|
||||
BLEND_CASE(GL_HSL_SATURATION_KHR):
|
||||
DO_HSL(set_lum_sat(dstC, srcC, dstC, srcDstA));
|
||||
BLEND_CASE(GL_HSL_COLOR_KHR):
|
||||
DO_HSL(set_lum(srcC, dstC, srcDstA));
|
||||
BLEND_CASE(GL_HSL_LUMINOSITY_KHR):
|
||||
DO_HSL(set_lum(dstC, srcC, srcDstA));
|
||||
|
||||
// SWGL-specific extended blend modes.
|
||||
BLEND_CASE(SWGL_BLEND_DROP_SHADOW): {
|
||||
// Premultiplied alpha over blend, but with source color set to source alpha
|
||||
// modulated with a constant color.
|
||||
WideRGBA8 color = applyColor(alphas(src), swgl_BlendColorRGBA8);
|
||||
return color + dst - muldiv255(dst, alphas(color));
|
||||
}
|
||||
|
||||
BLEND_CASE(SWGL_BLEND_SUBPIXEL_TEXT):
|
||||
// Premultiplied alpha over blend, but treats the source as a subpixel mask
|
||||
// modulated with a constant color.
|
||||
return applyColor(src, swgl_BlendColorRGBA8) + dst -
|
||||
muldiv255(dst, applyColor(src, swgl_BlendAlphaRGBA8));
|
||||
|
||||
default:
|
||||
UNREACHABLE;
|
||||
// return src;
|
||||
}
|
||||
|
||||
#undef BLEND_CASE
|
||||
#undef BLEND_CASE_KEY
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static PREFER_INLINE WideR8 blend_pixels(uint8_t* buf, WideR8 dst, WideR8 src,
|
||||
int span = 4) {
|
||||
// clang-format off
|
||||
#define BLEND_CASE_KEY(key) \
|
||||
case AA_##key: \
|
||||
DO_AA(R8, src = muldiv256(src, aa)); \
|
||||
goto key; \
|
||||
case AA_MASK_##key: \
|
||||
DO_AA(R8, src = muldiv256(src, aa)); \
|
||||
FALLTHROUGH; \
|
||||
case MASK_##key: \
|
||||
src = muldiv255(src, load_clip_mask(buf, span)); \
|
||||
FALLTHROUGH; \
|
||||
case key: key
|
||||
|
||||
#define BLEND_CASE(...) BLEND_CASE_KEY(BLEND_KEY(__VA_ARGS__))
|
||||
|
||||
switch (blend_key) {
|
||||
BLEND_CASE(GL_ONE, GL_ZERO):
|
||||
return src;
|
||||
BLEND_CASE(GL_ZERO, GL_SRC_COLOR):
|
||||
return muldiv255(src, dst);
|
||||
BLEND_CASE(GL_ONE, GL_ONE):
|
||||
return src + dst;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
// return src;
|
||||
}
|
||||
|
||||
#undef BLEND_CASE
|
||||
#undef BLEND_CASE_KEY
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint32_t* buf, WideRGBA8 r) {
|
||||
unaligned_store(buf, pack(r));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint32_t* buf, WideRGBA8 r, int len) {
|
||||
partial_store_span(buf, pack(r), len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 blend_span(uint32_t* buf, WideRGBA8 r) {
|
||||
return blend_pixels(buf, unaligned_load<PackedRGBA8>(buf), r);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideRGBA8 blend_span(uint32_t* buf, WideRGBA8 r, int len) {
|
||||
return blend_pixels(buf, partial_load_span<PackedRGBA8>(buf, len), r, len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint32_t* buf, PackedRGBA8 r) {
|
||||
unaligned_store(buf, r);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint32_t* buf, PackedRGBA8 r, int len) {
|
||||
partial_store_span(buf, r, len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE PackedRGBA8 blend_span(uint32_t* buf, PackedRGBA8 r) {
|
||||
return pack(blend_span(buf, unpack(r)));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE PackedRGBA8 blend_span(uint32_t* buf, PackedRGBA8 r,
|
||||
int len) {
|
||||
return pack(blend_span(buf, unpack(r), len));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint8_t* buf, WideR8 r) {
|
||||
unaligned_store(buf, pack(r));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint8_t* buf, WideR8 r, int len) {
|
||||
partial_store_span(buf, pack(r), len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideR8 blend_span(uint8_t* buf, WideR8 r) {
|
||||
return blend_pixels(buf, unpack(unaligned_load<PackedR8>(buf)), r);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE WideR8 blend_span(uint8_t* buf, WideR8 r, int len) {
|
||||
return blend_pixels(buf, unpack(partial_load_span<PackedR8>(buf, len)), r,
|
||||
len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint8_t* buf, PackedR8 r) {
|
||||
unaligned_store(buf, r);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void commit_span(uint8_t* buf, PackedR8 r, int len) {
|
||||
partial_store_span(buf, r, len);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE PackedR8 blend_span(uint8_t* buf, PackedR8 r) {
|
||||
return pack(blend_span(buf, unpack(r)));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE PackedR8 blend_span(uint8_t* buf, PackedR8 r, int len) {
|
||||
return pack(blend_span(buf, unpack(r), len));
|
||||
}
|
||||
|
||||
template <bool BLEND, typename P, typename R>
|
||||
static ALWAYS_INLINE void commit_blend_span(P* buf, R r) {
|
||||
if (BLEND) {
|
||||
commit_span(buf, blend_span(buf, r));
|
||||
} else {
|
||||
commit_span(buf, r);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool BLEND, typename P, typename R>
|
||||
static ALWAYS_INLINE void commit_blend_span(P* buf, R r, int len) {
|
||||
if (BLEND) {
|
||||
commit_span(buf, blend_span(buf, r, len), len);
|
||||
} else {
|
||||
commit_span(buf, r, len);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P, typename R>
|
||||
static ALWAYS_INLINE void commit_blend_solid_span(P* buf, R r, int len) {
|
||||
for (P* end = &buf[len & ~3]; buf < end; buf += 4) {
|
||||
commit_span(buf, blend_span(buf, r));
|
||||
}
|
||||
len &= 3;
|
||||
if (len > 0) {
|
||||
partial_store_span(buf, pack(blend_span(buf, r, len)), len);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool BLEND>
|
||||
static void commit_solid_span(uint32_t* buf, WideRGBA8 r, int len) {
|
||||
commit_blend_solid_span(buf, r, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
ALWAYS_INLINE void commit_solid_span<false>(uint32_t* buf, WideRGBA8 r,
|
||||
int len) {
|
||||
fill_n(buf, len, bit_cast<U32>(pack(r)).x);
|
||||
}
|
||||
|
||||
template <bool BLEND>
|
||||
static void commit_solid_span(uint8_t* buf, WideR8 r, int len) {
|
||||
commit_blend_solid_span(buf, r, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
ALWAYS_INLINE void commit_solid_span<false>(uint8_t* buf, WideR8 r, int len) {
|
||||
PackedR8 p = pack(r);
|
||||
if (uintptr_t(buf) & 3) {
|
||||
int align = 4 - (uintptr_t(buf) & 3);
|
||||
align = min(align, len);
|
||||
partial_store_span(buf, p, align);
|
||||
buf += align;
|
||||
len -= align;
|
||||
}
|
||||
fill_n((uint32_t*)buf, len / 4, bit_cast<uint32_t>(p));
|
||||
buf += len & ~3;
|
||||
len &= 3;
|
||||
if (len > 0) {
|
||||
partial_store_span(buf, p, len);
|
||||
}
|
||||
}
|
1069
third_party/webrender/swgl/src/composite.h
vendored
Normal file
1069
third_party/webrender/swgl/src/composite.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
3198
third_party/webrender/swgl/src/gl.cc
vendored
3198
third_party/webrender/swgl/src/gl.cc
vendored
File diff suppressed because it is too large
Load diff
42
third_party/webrender/swgl/src/gl_defs.h
vendored
42
third_party/webrender/swgl/src/gl_defs.h
vendored
|
@ -15,20 +15,27 @@ typedef float GLfloat;
|
|||
typedef double GLdouble;
|
||||
|
||||
typedef uint32_t GLenum;
|
||||
typedef int32_t GLboolean;
|
||||
typedef uint8_t GLboolean;
|
||||
typedef uint32_t GLbitfield;
|
||||
|
||||
typedef int32_t GLsizei;
|
||||
typedef size_t GLsizeiptr;
|
||||
typedef intptr_t GLintptr;
|
||||
|
||||
#define GL_FALSE 0
|
||||
#define GL_TRUE 1
|
||||
|
||||
#define GL_NONE 0
|
||||
|
||||
#define GL_NO_ERROR 0
|
||||
|
||||
#define GL_RGBA32F 0x8814
|
||||
#define GL_RGBA8 0x8058
|
||||
#define GL_R8 0x8229
|
||||
#define GL_R16 0x822A
|
||||
#define GL_RGBA32I 0x8D82
|
||||
#define GL_BGRA8 0x93A1
|
||||
#define GL_RG8 0x822B
|
||||
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
|
@ -37,6 +44,7 @@ typedef intptr_t GLintptr;
|
|||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_DOUBLE 0x1408
|
||||
|
||||
#define GL_RED 0x1903
|
||||
#define GL_GREEN 0x1904
|
||||
|
@ -46,6 +54,7 @@ typedef intptr_t GLintptr;
|
|||
#define GL_RGBA 0x1908
|
||||
#define GL_RGBA_INTEGER 0x8D99
|
||||
#define GL_BGRA 0x80E1
|
||||
#define GL_RG 0x8227
|
||||
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
|
@ -146,6 +155,8 @@ typedef intptr_t GLintptr;
|
|||
#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
|
||||
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_MIN 0x8007
|
||||
#define GL_MAX 0x8008
|
||||
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
|
@ -165,6 +176,9 @@ typedef intptr_t GLintptr;
|
|||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
#define GL_MINOR_VERSION 0x821C
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
|
@ -174,3 +188,29 @@ typedef intptr_t GLintptr;
|
|||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
#define GL_QUADS 0x0007
|
||||
|
||||
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
|
||||
#define GL_RGB_422_APPLE 0x8A1F
|
||||
#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
|
||||
#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
|
||||
#define GL_RGB_RAW_422_APPLE 0x8A51
|
||||
|
||||
#define GL_MULTIPLY_KHR 0x9294
|
||||
#define GL_SCREEN_KHR 0x9295
|
||||
#define GL_OVERLAY_KHR 0x9296
|
||||
#define GL_DARKEN_KHR 0x9297
|
||||
#define GL_LIGHTEN_KHR 0x9298
|
||||
#define GL_COLORDODGE_KHR 0x9299
|
||||
#define GL_COLORBURN_KHR 0x929A
|
||||
#define GL_HARDLIGHT_KHR 0x929B
|
||||
#define GL_SOFTLIGHT_KHR 0x929C
|
||||
#define GL_DIFFERENCE_KHR 0x929E
|
||||
#define GL_EXCLUSION_KHR 0x92A0
|
||||
#define GL_HSL_HUE_KHR 0x92AD
|
||||
#define GL_HSL_SATURATION_KHR 0x92AE
|
||||
#define GL_HSL_COLOR_KHR 0x92AF
|
||||
#define GL_HSL_LUMINOSITY_KHR 0x92B0
|
||||
|
||||
#define SWGL_BLEND_DROP_SHADOW 0xB001
|
||||
#define SWGL_BLEND_SUBPIXEL_TEXT 0xB002
|
||||
|
|
1312
third_party/webrender/swgl/src/glsl.h
vendored
1312
third_party/webrender/swgl/src/glsl.h
vendored
File diff suppressed because it is too large
Load diff
2
third_party/webrender/swgl/src/lib.rs
vendored
2
third_party/webrender/swgl/src/lib.rs
vendored
|
@ -5,7 +5,7 @@
|
|||
#![crate_name = "swgl"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use gleam;
|
||||
extern crate gleam;
|
||||
|
||||
mod swgl_fns;
|
||||
|
||||
|
|
82
third_party/webrender/swgl/src/program.h
vendored
82
third_party/webrender/swgl/src/program.h
vendored
|
@ -12,6 +12,12 @@ namespace glsl {
|
|||
// to operate in Float-sized chunks.
|
||||
typedef vec3 Interpolants;
|
||||
|
||||
// Clip distances, if enabled, are always stored in the first SIMD chunk of the
|
||||
// interpolants.
|
||||
static ALWAYS_INLINE Float get_clip_distances(const Interpolants& interp) {
|
||||
return interp.x;
|
||||
}
|
||||
|
||||
struct VertexShaderImpl;
|
||||
struct FragmentShaderImpl;
|
||||
|
||||
|
@ -23,10 +29,14 @@ struct ProgramImpl {
|
|||
virtual size_t interpolants_size() const = 0;
|
||||
virtual VertexShaderImpl* get_vertex_shader() = 0;
|
||||
virtual FragmentShaderImpl* get_fragment_shader() = 0;
|
||||
virtual const char* get_name() const = 0;
|
||||
};
|
||||
|
||||
typedef ProgramImpl* (*ProgramLoader)();
|
||||
|
||||
// The maximum size of the gl_ClipDistance array.
|
||||
constexpr int32_t gl_MaxClipDistances = 4;
|
||||
|
||||
struct VertexShaderImpl {
|
||||
typedef void (*SetUniform1iFunc)(VertexShaderImpl*, int index, int value);
|
||||
typedef void (*SetUniform4fvFunc)(VertexShaderImpl*, int index,
|
||||
|
@ -46,7 +56,17 @@ struct VertexShaderImpl {
|
|||
LoadAttribsFunc load_attribs_func = nullptr;
|
||||
RunPrimitiveFunc run_primitive_func = nullptr;
|
||||
|
||||
enum FLAGS {
|
||||
CLIP_DISTANCE = 1 << 0,
|
||||
};
|
||||
int flags = 0;
|
||||
void enable_clip_distance() { flags |= CLIP_DISTANCE; }
|
||||
ALWAYS_INLINE bool use_clip_distance() const {
|
||||
return (flags & CLIP_DISTANCE) != 0;
|
||||
}
|
||||
|
||||
vec4 gl_Position;
|
||||
Float gl_ClipDistance[gl_MaxClipDistances];
|
||||
|
||||
void set_uniform_1i(int index, int value) {
|
||||
(*set_uniform_1i_func)(this, index, value);
|
||||
|
@ -72,18 +92,20 @@ struct VertexShaderImpl {
|
|||
}
|
||||
};
|
||||
|
||||
// The number of pixels in a step.
|
||||
constexpr int32_t swgl_StepSize = 4;
|
||||
|
||||
struct FragmentShaderImpl {
|
||||
typedef void (*InitSpanFunc)(FragmentShaderImpl*, const void* interps,
|
||||
const void* step, float step_width);
|
||||
const void* step);
|
||||
typedef void (*RunFunc)(FragmentShaderImpl*);
|
||||
typedef void (*SkipFunc)(FragmentShaderImpl*, int chunks);
|
||||
typedef void (*SkipFunc)(FragmentShaderImpl*, int steps);
|
||||
typedef void (*InitSpanWFunc)(FragmentShaderImpl*, const void* interps,
|
||||
const void* step, float step_width);
|
||||
const void* step);
|
||||
typedef void (*RunWFunc)(FragmentShaderImpl*);
|
||||
typedef void (*SkipWFunc)(FragmentShaderImpl*, int chunks);
|
||||
typedef void (*DrawSpanRGBA8Func)(FragmentShaderImpl*, uint32_t* buf,
|
||||
int len);
|
||||
typedef void (*DrawSpanR8Func)(FragmentShaderImpl*, uint8_t* buf, int len);
|
||||
typedef void (*SkipWFunc)(FragmentShaderImpl*, int steps);
|
||||
typedef int (*DrawSpanRGBA8Func)(FragmentShaderImpl*);
|
||||
typedef int (*DrawSpanR8Func)(FragmentShaderImpl*);
|
||||
|
||||
InitSpanFunc init_span_func = nullptr;
|
||||
RunFunc run_func = nullptr;
|
||||
|
@ -107,31 +129,27 @@ struct FragmentShaderImpl {
|
|||
}
|
||||
|
||||
vec4 gl_FragCoord;
|
||||
vec2_scalar stepZW;
|
||||
Bool isPixelDiscarded = false;
|
||||
vec4 gl_FragColor;
|
||||
vec4 gl_SecondaryFragColor;
|
||||
|
||||
ALWAYS_INLINE void step_fragcoord() { gl_FragCoord.x += 4; }
|
||||
vec2_scalar swgl_StepZW;
|
||||
Bool swgl_IsPixelDiscarded = false;
|
||||
// The current buffer position for committing span output.
|
||||
uint32_t* swgl_OutRGBA8 = nullptr;
|
||||
uint8_t* swgl_OutR8 = nullptr;
|
||||
// The remaining number of pixels in the span.
|
||||
int32_t swgl_SpanLength = 0;
|
||||
|
||||
ALWAYS_INLINE void step_fragcoord(int chunks) {
|
||||
gl_FragCoord.x += 4 * chunks;
|
||||
}
|
||||
ALWAYS_INLINE void step_fragcoord(int steps = 4) { gl_FragCoord.x += steps; }
|
||||
|
||||
ALWAYS_INLINE void step_perspective() {
|
||||
gl_FragCoord.z += stepZW.x;
|
||||
gl_FragCoord.w += stepZW.y;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void step_perspective(int chunks) {
|
||||
gl_FragCoord.z += stepZW.x * chunks;
|
||||
gl_FragCoord.w += stepZW.y * chunks;
|
||||
ALWAYS_INLINE void step_perspective(int steps = 4) {
|
||||
gl_FragCoord.z += swgl_StepZW.x * steps;
|
||||
gl_FragCoord.w += swgl_StepZW.y * steps;
|
||||
}
|
||||
|
||||
template <bool W = false>
|
||||
ALWAYS_INLINE void init_span(const void* interps, const void* step,
|
||||
float step_width) {
|
||||
(*(W ? init_span_w_func : init_span_func))(this, interps, step, step_width);
|
||||
ALWAYS_INLINE void init_span(const void* interps, const void* step) {
|
||||
(*(W ? init_span_w_func : init_span_func))(this, interps, step);
|
||||
}
|
||||
|
||||
template <bool W = false>
|
||||
|
@ -140,20 +158,24 @@ struct FragmentShaderImpl {
|
|||
}
|
||||
|
||||
template <bool W = false>
|
||||
ALWAYS_INLINE void skip(int chunks = 1) {
|
||||
(*(W ? skip_w_func : skip_func))(this, chunks);
|
||||
ALWAYS_INLINE void skip(int steps = 4) {
|
||||
(*(W ? skip_w_func : skip_func))(this, steps);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void draw_span(uint32_t* buf, int len) {
|
||||
(*draw_span_RGBA8_func)(this, buf, len);
|
||||
ALWAYS_INLINE int draw_span(uint32_t* buf, int len) {
|
||||
swgl_OutRGBA8 = buf;
|
||||
swgl_SpanLength = len;
|
||||
return (*draw_span_RGBA8_func)(this);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool has_draw_span(uint32_t*) {
|
||||
return draw_span_RGBA8_func != nullptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void draw_span(uint8_t* buf, int len) {
|
||||
(*draw_span_R8_func)(this, buf, len);
|
||||
ALWAYS_INLINE int draw_span(uint8_t* buf, int len) {
|
||||
swgl_OutR8 = buf;
|
||||
swgl_SpanLength = len;
|
||||
return (*draw_span_R8_func)(this);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool has_draw_span(uint8_t*) {
|
||||
|
|
1670
third_party/webrender/swgl/src/rasterize.h
vendored
Normal file
1670
third_party/webrender/swgl/src/rasterize.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1826
third_party/webrender/swgl/src/swgl_ext.h
vendored
Normal file
1826
third_party/webrender/swgl/src/swgl_ext.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
513
third_party/webrender/swgl/src/swgl_fns.rs
vendored
513
third_party/webrender/swgl/src/swgl_fns.rs
vendored
|
@ -14,8 +14,12 @@ macro_rules! debug {
|
|||
($($x:tt)*) => {};
|
||||
}
|
||||
|
||||
extern "C" {}
|
||||
#[repr(C)]
|
||||
struct LockedTexture {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
extern "C" {
|
||||
fn ActiveTexture(texture: GLenum);
|
||||
fn BindTexture(target: GLenum, texture: GLuint);
|
||||
|
@ -61,19 +65,7 @@ extern "C" {
|
|||
level: GLint,
|
||||
);
|
||||
fn CheckFramebufferStatus(target: GLenum) -> GLenum;
|
||||
fn InvalidateFramebuffer(
|
||||
target: GLenum,
|
||||
num_attachments: GLsizei,
|
||||
attachments: *const GLenum,
|
||||
);
|
||||
fn TexStorage3D(
|
||||
target: GLenum,
|
||||
levels: GLint,
|
||||
internal_format: GLenum,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
);
|
||||
fn InvalidateFramebuffer(target: GLenum, num_attachments: GLsizei, attachments: *const GLenum);
|
||||
fn TexImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
|
@ -85,18 +77,6 @@ extern "C" {
|
|||
ty: GLenum,
|
||||
data: *const c_void,
|
||||
);
|
||||
fn TexImage3D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
internal_format: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
border: GLint,
|
||||
format: GLenum,
|
||||
ty: GLenum,
|
||||
data: *const c_void,
|
||||
);
|
||||
fn TexSubImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
|
@ -108,19 +88,6 @@ extern "C" {
|
|||
ty: GLenum,
|
||||
data: *const c_void,
|
||||
);
|
||||
fn TexSubImage3D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
zoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
format: GLenum,
|
||||
ty: GLenum,
|
||||
data: *const c_void,
|
||||
);
|
||||
fn GenerateMipmap(target: GLenum);
|
||||
fn GetUniformLocation(program: GLuint, name: *const GLchar) -> GLint;
|
||||
fn BindAttribLocation(program: GLuint, index: GLuint, name: *const GLchar);
|
||||
|
@ -152,26 +119,19 @@ extern "C" {
|
|||
transpose: GLboolean,
|
||||
value: *const GLfloat,
|
||||
);
|
||||
|
||||
fn DrawElementsInstanced(
|
||||
mode: GLenum,
|
||||
count: GLsizei,
|
||||
type_: GLenum,
|
||||
indices: *const c_void,
|
||||
indices: GLintptr,
|
||||
instancecount: GLsizei,
|
||||
);
|
||||
fn EnableVertexAttribArray(index: GLuint);
|
||||
fn VertexAttribDivisor(index: GLuint, divisor: GLuint);
|
||||
fn LinkProgram(program: GLuint);
|
||||
fn GetLinkStatus(program: GLuint) -> GLint;
|
||||
fn UseProgram(program: GLuint);
|
||||
fn SetViewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei);
|
||||
fn FramebufferTextureLayer(
|
||||
target: GLenum,
|
||||
attachment: GLenum,
|
||||
texture: GLuint,
|
||||
level: GLint,
|
||||
layer: GLint,
|
||||
);
|
||||
fn FramebufferRenderbuffer(
|
||||
target: GLenum,
|
||||
attachment: GLenum,
|
||||
|
@ -185,6 +145,31 @@ extern "C" {
|
|||
fn ClearColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat);
|
||||
fn ClearDepth(depth: GLdouble);
|
||||
fn Clear(mask: GLbitfield);
|
||||
fn ClearTexSubImage(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
zoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
format: GLenum,
|
||||
ty: GLenum,
|
||||
data: *const c_void,
|
||||
);
|
||||
fn ClearTexImage(target: GLenum, level: GLint, format: GLenum, ty: GLenum, data: *const c_void);
|
||||
fn ClearColorRect(
|
||||
fbo: GLuint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
r: GLfloat,
|
||||
g: GLfloat,
|
||||
b: GLfloat,
|
||||
a: GLfloat,
|
||||
);
|
||||
fn PixelStorei(name: GLenum, param: GLint);
|
||||
fn ReadPixels(
|
||||
x: GLint,
|
||||
|
@ -225,17 +210,6 @@ extern "C" {
|
|||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
);
|
||||
fn CopyTexSubImage3D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
zoffset: GLint,
|
||||
x: GLint,
|
||||
y: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
);
|
||||
fn BlitFramebuffer(
|
||||
src_x0: GLint,
|
||||
src_y0: GLint,
|
||||
|
@ -253,22 +227,33 @@ extern "C" {
|
|||
fn GetString(name: GLenum) -> *const c_char;
|
||||
fn GetStringi(name: GLenum, index: GLuint) -> *const c_char;
|
||||
fn GetError() -> GLenum;
|
||||
fn InitDefaultFramebuffer(width: i32, height: i32);
|
||||
fn InitDefaultFramebuffer(
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
buf: *mut c_void,
|
||||
);
|
||||
fn GetColorBuffer(
|
||||
fbo: GLuint,
|
||||
flush: GLboolean,
|
||||
width: *mut i32,
|
||||
height: *mut i32,
|
||||
stride: *mut i32,
|
||||
) -> *mut c_void;
|
||||
fn ResolveFramebuffer(fbo: GLuint);
|
||||
fn SetTextureBuffer(
|
||||
tex: GLuint,
|
||||
internal_format: GLenum,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
stride: GLsizei,
|
||||
buf: *mut c_void,
|
||||
min_width: GLsizei,
|
||||
min_height: GLsizei,
|
||||
);
|
||||
fn SetTextureParameter(tex: GLuint, pname: GLenum, param: GLint);
|
||||
fn DeleteTexture(n: GLuint);
|
||||
fn DeleteRenderbuffer(n: GLuint);
|
||||
fn DeleteFramebuffer(n: GLuint);
|
||||
|
@ -277,23 +262,64 @@ extern "C" {
|
|||
fn DeleteQuery(n: GLuint);
|
||||
fn DeleteShader(shader: GLuint);
|
||||
fn DeleteProgram(program: GLuint);
|
||||
fn LockFramebuffer(fbo: GLuint) -> *mut LockedTexture;
|
||||
fn LockTexture(tex: GLuint) -> *mut LockedTexture;
|
||||
fn LockResource(resource: *mut LockedTexture);
|
||||
fn UnlockResource(resource: *mut LockedTexture);
|
||||
fn GetResourceBuffer(
|
||||
resource: *mut LockedTexture,
|
||||
width: *mut i32,
|
||||
height: *mut i32,
|
||||
stride: *mut i32,
|
||||
) -> *mut c_void;
|
||||
fn Composite(
|
||||
src_id: GLuint,
|
||||
locked_dst: *mut LockedTexture,
|
||||
locked_src: *mut LockedTexture,
|
||||
src_x: GLint,
|
||||
src_y: GLint,
|
||||
src_width: GLsizei,
|
||||
src_height: GLsizei,
|
||||
dst_x: GLint,
|
||||
dst_y: GLint,
|
||||
dst_width: GLsizei,
|
||||
dst_height: GLsizei,
|
||||
opaque: GLboolean,
|
||||
flip: GLboolean,
|
||||
filter: GLenum,
|
||||
clip_x: GLint,
|
||||
clip_y: GLint,
|
||||
clip_width: GLsizei,
|
||||
clip_height: GLsizei,
|
||||
);
|
||||
fn CompositeYUV(
|
||||
locked_dst: *mut LockedTexture,
|
||||
locked_y: *mut LockedTexture,
|
||||
locked_u: *mut LockedTexture,
|
||||
locked_v: *mut LockedTexture,
|
||||
color_space: YUVColorSpace,
|
||||
color_depth: GLuint,
|
||||
src_x: GLint,
|
||||
src_y: GLint,
|
||||
src_width: GLsizei,
|
||||
src_height: GLsizei,
|
||||
dst_x: GLint,
|
||||
dst_y: GLint,
|
||||
dst_width: GLsizei,
|
||||
dst_height: GLsizei,
|
||||
flip: GLboolean,
|
||||
clip_x: GLint,
|
||||
clip_y: GLint,
|
||||
clip_width: GLsizei,
|
||||
clip_height: GLsizei,
|
||||
);
|
||||
fn CreateContext() -> *mut c_void;
|
||||
fn ReferenceContext(ctx: *mut c_void);
|
||||
fn DestroyContext(ctx: *mut c_void);
|
||||
fn MakeCurrent(ctx: *mut c_void);
|
||||
fn ReportMemory(size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Context(*mut c_void);
|
||||
|
||||
impl Context {
|
||||
|
@ -301,6 +327,12 @@ impl Context {
|
|||
Context(unsafe { CreateContext() })
|
||||
}
|
||||
|
||||
pub fn reference(&self) {
|
||||
unsafe {
|
||||
ReferenceContext(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(&self) {
|
||||
unsafe {
|
||||
DestroyContext(self.0);
|
||||
|
@ -313,18 +345,56 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_default_framebuffer(&self, width: i32, height: i32) {
|
||||
pub fn init_default_framebuffer(
|
||||
&self,
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
buf: *mut c_void,
|
||||
) {
|
||||
unsafe {
|
||||
InitDefaultFramebuffer(width, height);
|
||||
InitDefaultFramebuffer(x, y, width, height, stride, buf);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_color_buffer(&self, fbo: GLuint, flush: bool) -> (*mut c_void, i32, i32) {
|
||||
pub fn get_color_buffer(&self, fbo: GLuint, flush: bool) -> (*mut c_void, i32, i32, i32) {
|
||||
unsafe {
|
||||
let mut width: i32 = 0;
|
||||
let mut height: i32 = 0;
|
||||
let data_ptr = GetColorBuffer(fbo, flush as GLboolean, &mut width, &mut height);
|
||||
(data_ptr, width, height)
|
||||
let mut stride: i32 = 0;
|
||||
let data_ptr = GetColorBuffer(
|
||||
fbo,
|
||||
flush as GLboolean,
|
||||
&mut width,
|
||||
&mut height,
|
||||
&mut stride,
|
||||
);
|
||||
(data_ptr, width, height, stride)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_framebuffer(&self, fbo: GLuint) {
|
||||
unsafe {
|
||||
ResolveFramebuffer(fbo);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_color_rect(
|
||||
&self,
|
||||
fbo: GLuint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
r: f32,
|
||||
g: f32,
|
||||
b: f32,
|
||||
a: f32,
|
||||
) {
|
||||
unsafe {
|
||||
ClearColorRect(fbo, xoffset, yoffset, width, height, r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +404,7 @@ impl Context {
|
|||
internal_format: GLenum,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
stride: GLsizei,
|
||||
buf: *mut c_void,
|
||||
min_width: GLsizei,
|
||||
min_height: GLsizei,
|
||||
|
@ -344,6 +415,7 @@ impl Context {
|
|||
internal_format,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
buf,
|
||||
min_width,
|
||||
min_height,
|
||||
|
@ -351,32 +423,37 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn composite(
|
||||
&self,
|
||||
src_id: GLuint,
|
||||
src_x: GLint,
|
||||
src_y: GLint,
|
||||
src_width: GLsizei,
|
||||
src_height: GLint,
|
||||
dst_x: GLint,
|
||||
dst_y: GLint,
|
||||
opaque: bool,
|
||||
flip: bool,
|
||||
) {
|
||||
pub fn set_texture_parameter(&self, tex: GLuint, pname: GLenum, param: GLint) {
|
||||
unsafe {
|
||||
Composite(
|
||||
src_id,
|
||||
src_x,
|
||||
src_y,
|
||||
src_width,
|
||||
src_height,
|
||||
dst_x,
|
||||
dst_y,
|
||||
opaque as GLboolean,
|
||||
flip as GLboolean,
|
||||
);
|
||||
SetTextureParameter(tex, pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lock_framebuffer(&self, fbo: GLuint) -> Option<LockedResource> {
|
||||
unsafe {
|
||||
let resource = LockFramebuffer(fbo);
|
||||
if resource != ptr::null_mut() {
|
||||
Some(LockedResource(resource))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lock_texture(&self, tex: GLuint) -> Option<LockedResource> {
|
||||
unsafe {
|
||||
let resource = LockTexture(tex);
|
||||
if resource != ptr::null_mut() {
|
||||
Some(LockedResource(resource))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_memory(size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize {
|
||||
unsafe { ReportMemory(size_of_op) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<*mut c_void> for Context {
|
||||
|
@ -411,6 +488,7 @@ fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type:
|
|||
UNSIGNED_SHORT => 2,
|
||||
SHORT => 2,
|
||||
FLOAT => 4,
|
||||
UNSIGNED_INT_8_8_8_8_REV => 1,
|
||||
_ => panic!("unsupported pixel_type for read_pixels: {:?}", pixel_type),
|
||||
};
|
||||
|
||||
|
@ -485,8 +563,8 @@ impl Gl for Context {
|
|||
let u = str::from_utf8(s).unwrap();
|
||||
const PREFIX: &'static str = "// shader: ";
|
||||
if let Some(start) = u.find(PREFIX) {
|
||||
if let Some(end) = u[start ..].find('\n') {
|
||||
let name = u[start + PREFIX.len() .. start + end].trim();
|
||||
if let Some(end) = u[start..].find('\n') {
|
||||
let name = u[start + PREFIX.len()..start + end].trim();
|
||||
debug!("shader name: {}", name);
|
||||
unsafe {
|
||||
let c_string = CString::new(name).unwrap();
|
||||
|
@ -955,7 +1033,6 @@ impl Gl for Context {
|
|||
panic!();
|
||||
}
|
||||
|
||||
// FIXME: Does not verify buffer size -- unsafe!
|
||||
fn tex_image_3d(
|
||||
&self,
|
||||
target: GLenum,
|
||||
|
@ -969,24 +1046,7 @@ impl Gl for Context {
|
|||
ty: GLenum,
|
||||
opt_data: Option<&[u8]>,
|
||||
) {
|
||||
unsafe {
|
||||
let pdata = match opt_data {
|
||||
Some(data) => data.as_ptr() as *const GLvoid,
|
||||
None => ptr::null(),
|
||||
};
|
||||
TexImage3D(
|
||||
target,
|
||||
level,
|
||||
internal_format,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
border,
|
||||
format,
|
||||
ty,
|
||||
pdata,
|
||||
);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn copy_tex_image_2d(
|
||||
|
@ -1031,11 +1091,7 @@ impl Gl for Context {
|
|||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
) {
|
||||
unsafe {
|
||||
CopyTexSubImage3D(
|
||||
target, level, xoffset, yoffset, zoffset, x, y, width, height,
|
||||
);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn tex_sub_image_2d(
|
||||
|
@ -1117,22 +1173,7 @@ impl Gl for Context {
|
|||
data: &[u8],
|
||||
) {
|
||||
debug!("tex_sub_image_3d");
|
||||
//panic!();
|
||||
unsafe {
|
||||
TexSubImage3D(
|
||||
target,
|
||||
level,
|
||||
xoffset,
|
||||
yoffset,
|
||||
zoffset,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
format,
|
||||
ty,
|
||||
data.as_ptr() as *const c_void,
|
||||
);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn tex_sub_image_3d_pbo(
|
||||
|
@ -1149,21 +1190,7 @@ impl Gl for Context {
|
|||
ty: GLenum,
|
||||
offset: usize,
|
||||
) {
|
||||
unsafe {
|
||||
TexSubImage3D(
|
||||
target,
|
||||
level,
|
||||
xoffset,
|
||||
yoffset,
|
||||
zoffset,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
format,
|
||||
ty,
|
||||
offset as *const c_void,
|
||||
);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn tex_storage_2d(
|
||||
|
@ -1189,10 +1216,7 @@ impl Gl for Context {
|
|||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
) {
|
||||
//panic!();
|
||||
unsafe {
|
||||
TexStorage3D(target, levels, internal_format, width, height, depth);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn get_tex_image_into_buffer(
|
||||
|
@ -1352,10 +1376,7 @@ impl Gl for Context {
|
|||
"framebuffer_texture_layer {} {} {} {} {}",
|
||||
target, attachment, texture, level, layer
|
||||
);
|
||||
//panic!();
|
||||
unsafe {
|
||||
FramebufferTextureLayer(target, attachment, texture, level, layer);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn blit_framebuffer(
|
||||
|
@ -1477,7 +1498,9 @@ impl Gl for Context {
|
|||
}
|
||||
|
||||
fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) {
|
||||
panic!();
|
||||
unsafe {
|
||||
DrawElementsInstanced(mode, count, NONE, first as GLintptr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_arrays_instanced(
|
||||
|
@ -1487,7 +1510,9 @@ impl Gl for Context {
|
|||
count: GLsizei,
|
||||
primcount: GLsizei,
|
||||
) {
|
||||
panic!();
|
||||
unsafe {
|
||||
DrawElementsInstanced(mode, count, NONE, first as GLintptr, primcount);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_elements(
|
||||
|
@ -1503,13 +1528,7 @@ impl Gl for Context {
|
|||
);
|
||||
//panic!();
|
||||
unsafe {
|
||||
DrawElementsInstanced(
|
||||
mode,
|
||||
count,
|
||||
element_type,
|
||||
indices_offset as *const c_void,
|
||||
1,
|
||||
);
|
||||
DrawElementsInstanced(mode, count, element_type, indices_offset as GLintptr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1531,7 +1550,7 @@ impl Gl for Context {
|
|||
mode,
|
||||
count,
|
||||
element_type,
|
||||
indices_offset as *const c_void,
|
||||
indices_offset as GLintptr,
|
||||
primcount,
|
||||
);
|
||||
}
|
||||
|
@ -1824,8 +1843,8 @@ impl Gl for Context {
|
|||
}
|
||||
|
||||
fn get_program_info_log(&self, program: GLuint) -> String {
|
||||
panic!();
|
||||
//String::new()
|
||||
debug!("get_program_info_log {}", program);
|
||||
String::new()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1835,7 +1854,7 @@ impl Gl for Context {
|
|||
assert!(!result.is_empty());
|
||||
//#define GL_LINK_STATUS 0x8B82
|
||||
if pname == 0x8b82 {
|
||||
result[0] = 1;
|
||||
result[0] = GetLinkStatus(program);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2099,7 +2118,7 @@ impl Gl for Context {
|
|||
//ptr::null()
|
||||
}
|
||||
|
||||
fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) {
|
||||
fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum {
|
||||
panic!();
|
||||
}
|
||||
|
||||
|
@ -2172,7 +2191,7 @@ impl Gl for Context {
|
|||
|
||||
// GL_KHR_blend_equation_advanced
|
||||
fn blend_barrier_khr(&self) {
|
||||
panic!();
|
||||
// No barrier required, so nothing to do
|
||||
}
|
||||
|
||||
// GL_CHROMIUM_copy_texture
|
||||
|
@ -2250,4 +2269,158 @@ impl Gl for Context {
|
|||
) {
|
||||
unimplemented!("Not supported by SWGL");
|
||||
}
|
||||
|
||||
fn buffer_storage(
|
||||
&self,
|
||||
target: GLenum,
|
||||
size: GLsizeiptr,
|
||||
data: *const GLvoid,
|
||||
flags: GLbitfield,
|
||||
) {
|
||||
unimplemented!("Not supported by SWGL");
|
||||
}
|
||||
|
||||
fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr) {
|
||||
unimplemented!("Not supported by SWGL");
|
||||
}
|
||||
}
|
||||
|
||||
/// A resource that is intended for sharing between threads.
|
||||
/// Locked resources such as textures or framebuffers will
|
||||
/// not allow any further modifications while it remains
|
||||
/// locked. The resource will be unlocked when LockedResource
|
||||
/// is dropped.
|
||||
pub struct LockedResource(*mut LockedTexture);
|
||||
|
||||
unsafe impl Send for LockedResource {}
|
||||
unsafe impl Sync for LockedResource {}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum YUVColorSpace {
|
||||
Rec601 = 0,
|
||||
Rec709,
|
||||
Rec2020,
|
||||
Identity,
|
||||
}
|
||||
|
||||
impl LockedResource {
|
||||
/// Composites from a locked resource to another locked resource. The band
|
||||
/// offset and height are relative to the destination rectangle and specify
|
||||
/// how to clip the composition into appropriate range for this band.
|
||||
pub fn composite(
|
||||
&self,
|
||||
locked_src: &LockedResource,
|
||||
src_x: GLint,
|
||||
src_y: GLint,
|
||||
src_width: GLsizei,
|
||||
src_height: GLsizei,
|
||||
dst_x: GLint,
|
||||
dst_y: GLint,
|
||||
dst_width: GLsizei,
|
||||
dst_height: GLsizei,
|
||||
opaque: bool,
|
||||
flip: bool,
|
||||
filter: GLenum,
|
||||
clip_x: GLint,
|
||||
clip_y: GLint,
|
||||
clip_width: GLsizei,
|
||||
clip_height: GLsizei,
|
||||
) {
|
||||
unsafe {
|
||||
Composite(
|
||||
self.0,
|
||||
locked_src.0,
|
||||
src_x,
|
||||
src_y,
|
||||
src_width,
|
||||
src_height,
|
||||
dst_x,
|
||||
dst_y,
|
||||
dst_width,
|
||||
dst_height,
|
||||
opaque as GLboolean,
|
||||
flip as GLboolean,
|
||||
filter,
|
||||
clip_x,
|
||||
clip_y,
|
||||
clip_width,
|
||||
clip_height,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Composites from locked resources representing YUV planes
|
||||
pub fn composite_yuv(
|
||||
&self,
|
||||
locked_y: &LockedResource,
|
||||
locked_u: &LockedResource,
|
||||
locked_v: &LockedResource,
|
||||
color_space: YUVColorSpace,
|
||||
color_depth: GLuint,
|
||||
src_x: GLint,
|
||||
src_y: GLint,
|
||||
src_width: GLsizei,
|
||||
src_height: GLsizei,
|
||||
dst_x: GLint,
|
||||
dst_y: GLint,
|
||||
dst_width: GLsizei,
|
||||
dst_height: GLsizei,
|
||||
flip: bool,
|
||||
clip_x: GLint,
|
||||
clip_y: GLint,
|
||||
clip_width: GLsizei,
|
||||
clip_height: GLsizei,
|
||||
) {
|
||||
unsafe {
|
||||
CompositeYUV(
|
||||
self.0,
|
||||
locked_y.0,
|
||||
locked_u.0,
|
||||
locked_v.0,
|
||||
color_space,
|
||||
color_depth,
|
||||
src_x,
|
||||
src_y,
|
||||
src_width,
|
||||
src_height,
|
||||
dst_x,
|
||||
dst_y,
|
||||
dst_width,
|
||||
dst_height,
|
||||
flip as GLboolean,
|
||||
clip_x,
|
||||
clip_y,
|
||||
clip_width,
|
||||
clip_height,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the underlying buffer for a locked resource
|
||||
pub fn get_buffer(&self) -> (*mut c_void, i32, i32, i32) {
|
||||
unsafe {
|
||||
let mut width: i32 = 0;
|
||||
let mut height: i32 = 0;
|
||||
let mut stride: i32 = 0;
|
||||
let data_ptr = GetResourceBuffer(self.0, &mut width, &mut height, &mut stride);
|
||||
(data_ptr, width, height, stride)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for LockedResource {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
LockResource(self.0);
|
||||
}
|
||||
LockedResource(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LockedResource {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
UnlockResource(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1158
third_party/webrender/swgl/src/texture.h
vendored
1158
third_party/webrender/swgl/src/texture.h
vendored
File diff suppressed because it is too large
Load diff
87
third_party/webrender/swgl/src/vector_type.h
vendored
87
third_party/webrender/swgl/src/vector_type.h
vendored
|
@ -38,6 +38,16 @@ SI VectorType<T, 16> combine(VectorType<T, 8> a, VectorType<T, 8> b) {
|
|||
13, 14, 15);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SI VectorType<T, 2> lowHalf(VectorType<T, 4> a) {
|
||||
return __builtin_shufflevector(a, a, 0, 1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SI VectorType<T, 2> highHalf(VectorType<T, 4> a) {
|
||||
return __builtin_shufflevector(a, a, 2, 3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SI VectorType<T, 4> lowHalf(VectorType<T, 8> a) {
|
||||
return __builtin_shufflevector(a, a, 0, 1, 2, 3);
|
||||
|
@ -104,7 +114,7 @@ struct VectorType {
|
|||
};
|
||||
};
|
||||
|
||||
VectorType() : data{0} { }
|
||||
VectorType() : data{0} {}
|
||||
|
||||
constexpr VectorType(const VectorType& rhs) : data(rhs.data) {}
|
||||
// GCC vector extensions only support broadcasting scalars on arithmetic ops,
|
||||
|
@ -305,10 +315,27 @@ struct VectorType {
|
|||
return VectorType<T, N * 2>::wrap(data, high.data);
|
||||
}
|
||||
|
||||
# define xxxx swizzle(0, 0, 0, 0)
|
||||
# define yyyy swizzle(1, 1, 1, 1)
|
||||
# define zzzz swizzle(2, 2, 2, 2)
|
||||
# define wwww swizzle(3, 3, 3, 3)
|
||||
# define xxyy swizzle(0, 0, 1, 1)
|
||||
# define xxzz swizzle(0, 0, 2, 2)
|
||||
# define yyww swizzle(1, 1, 3, 3)
|
||||
# define zzww swizzle(2, 2, 3, 3)
|
||||
# define xyxy swizzle(0, 1, 0, 1)
|
||||
# define xzxz swizzle(0, 2, 0, 2)
|
||||
# define ywyw swizzle(1, 3, 1, 3)
|
||||
# define zwzw swizzle(2, 3, 2, 3)
|
||||
# define zwxy swizzle(2, 3, 0, 1)
|
||||
# define zyxw swizzle(2, 1, 0, 3)
|
||||
# define xxyz swizzle(0, 0, 1, 2)
|
||||
# define xyyz swizzle(0, 1, 1, 2)
|
||||
# define xyzz swizzle(0, 1, 2, 2)
|
||||
# define xzyw swizzle(0, 2, 1, 3)
|
||||
# define yzwx swizzle(1, 2, 3, 0)
|
||||
# define wxyz swizzle(3, 0, 1, 2)
|
||||
# define wzyx swizzle(3, 2, 1, 0)
|
||||
# define xxxxyyyy XXXXYYYY()
|
||||
VectorType<T, 8> XXXXYYYY() const {
|
||||
return swizzle(0, 0, 0, 0).combine(swizzle(1, 1, 1, 1));
|
||||
|
@ -331,6 +358,10 @@ struct VectorType {
|
|||
VectorType<T, 8> XXYYZZWW() const {
|
||||
return swizzle(0, 0, 1, 1).combine(swizzle(2, 2, 3, 3));
|
||||
}
|
||||
# define xxxxyyyyzzzzwwww XXXXYYYYZZZZWWWW()
|
||||
VectorType<T, 16> XXXXYYYYZZZZWWWW() {
|
||||
return XXXXYYYY().combine(ZZZZWWWW());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -343,6 +374,17 @@ struct VectorType<T, 2> {
|
|||
};
|
||||
T elements[2];
|
||||
};
|
||||
|
||||
SI VectorType wrap(const data_type& data) {
|
||||
VectorType v;
|
||||
v.data = data;
|
||||
return v;
|
||||
}
|
||||
|
||||
VectorType operator&(VectorType x) const { return wrap(data & x.data); }
|
||||
VectorType operator&(T x) const { return wrap(data & x); }
|
||||
VectorType operator|(VectorType x) const { return wrap(data | x.data); }
|
||||
VectorType operator|(T x) const { return wrap(data | x); }
|
||||
};
|
||||
|
||||
# define CONVERT(vector, type) ((type)(vector))
|
||||
|
@ -369,6 +411,32 @@ SI VectorType<T, N * 2> expand(VectorType<T, N> a) {
|
|||
}
|
||||
#endif
|
||||
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N * 4> combine(VectorType<T, N> a, VectorType<T, N> b,
|
||||
VectorType<T, N> c, VectorType<T, N> d) {
|
||||
return combine(combine(a, b), combine(c, d));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N> combineLow(VectorType<T, N> a, VectorType<T, N> b) {
|
||||
return combine(lowHalf(a), lowHalf(b));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N> combineHigh(VectorType<T, N> a, VectorType<T, N> b) {
|
||||
return combine(highHalf(a), highHalf(b));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N * 2> repeat2(VectorType<T, N> a) {
|
||||
return combine(a, a);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N * 4> repeat4(VectorType<T, N> a) {
|
||||
return combine(a, a, a, a);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SI VectorType<T, 4> zipLow(VectorType<T, 4> a, VectorType<T, 4> b) {
|
||||
return SHUFFLE(a, b, 0, 4, 1, 5);
|
||||
|
@ -410,6 +478,23 @@ SI VectorType<T, 8> zip2High(VectorType<T, 8> a, VectorType<T, 8> b) {
|
|||
return SHUFFLE(a, b, 4, 5, 12, 13, 6, 7, 14, 15);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
template <typename T>
|
||||
SI VectorType<T, 8> zip(VectorType<T, 4> a, VectorType<T, 4> b) {
|
||||
return SHUFFLE(a, b, 0, 4, 1, 5, 2, 6, 3, 7);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SI VectorType<T, 16> zip(VectorType<T, 8> a, VectorType<T, 8> b) {
|
||||
return SHUFFLE(a, b, 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15);
|
||||
}
|
||||
#else
|
||||
template <typename T, int N>
|
||||
SI VectorType<T, N * 2> zip(VectorType<T, N> a, VectorType<T, N> b) {
|
||||
return combine(zipLow(a, b), zipHigh(a, b));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct Unaligned {
|
||||
template <typename P>
|
||||
|
|
4
third_party/webrender/tileview/Cargo.toml
vendored
4
third_party/webrender/tileview/Cargo.toml
vendored
|
@ -8,8 +8,8 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ron = "0.5"
|
||||
ron = "0.6.2"
|
||||
serde = {version = "1.0.88", features = ["derive"] }
|
||||
webrender = {path = "../webrender", features=["capture","replay","debugger","png","profiler","no_static_freetype", "leak_checks"]}
|
||||
webrender = {path = "../webrender", features=["capture","replay","png","profiler","no_static_freetype", "leak_checks"]}
|
||||
webrender_api = {path = "../webrender_api", features=["serialize","deserialize"]}
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
|
|
5
third_party/webrender/tileview/src/main.rs
vendored
5
third_party/webrender/tileview/src/main.rs
vendored
|
@ -36,7 +36,8 @@ use std::io::prelude::*;
|
|||
use std::path::Path;
|
||||
use std::ffi::OsString;
|
||||
use std::collections::HashMap;
|
||||
use webrender::api::{enumerate_interners, ColorF};
|
||||
use webrender::enumerate_interners;
|
||||
use webrender::api::ColorF;
|
||||
use euclid::{Rect, Transform3D};
|
||||
use webrender_api::units::{PicturePoint, PictureSize, PicturePixel, WorldPixel};
|
||||
|
||||
|
@ -59,6 +60,7 @@ static CSS_PRIM_COUNT: &str = "fill:#40f0f0;fill-opacity:0.1;";
|
|||
static CSS_CONTENT: &str = "fill:#f04040;fill-opacity:0.1;";
|
||||
static CSS_COMPOSITOR_KIND_CHANGED: &str = "fill:#f0c070;fill-opacity:0.1;";
|
||||
static CSS_VALID_RECT_CHANGED: &str = "fill:#ff00ff;fill-opacity:0.1;";
|
||||
static CSS_SCALE_CHANGED: &str = "fill:#ff80ff;fill-opacity:0.1;";
|
||||
|
||||
// parameters to tweak the SVG generation
|
||||
struct SvgSettings {
|
||||
|
@ -111,6 +113,7 @@ fn tile_to_svg(key: TileOffset,
|
|||
Some(InvalidationReason::CompositorKindChanged) => CSS_COMPOSITOR_KIND_CHANGED.to_string(),
|
||||
Some(InvalidationReason::Content { .. } ) => CSS_CONTENT.to_string(),
|
||||
Some(InvalidationReason::ValidRectChanged) => CSS_VALID_RECT_CHANGED.to_string(),
|
||||
Some(InvalidationReason::ScaleChanged) => CSS_SCALE_CHANGED.to_string(),
|
||||
None => {
|
||||
let mut background = tile.background_color;
|
||||
if background.is_none() {
|
||||
|
|
35
third_party/webrender/webrender/Cargo.toml
vendored
35
third_party/webrender/webrender/Cargo.toml
vendored
|
@ -12,30 +12,28 @@ edition = "2018"
|
|||
default = ["freetype-lib"]
|
||||
freetype-lib = ["freetype/freetype-sys"]
|
||||
profiler = ["tracy-rs/enable_profiler"]
|
||||
debugger = ["ws", "serde_json", "serde", "image_loader", "base64"]
|
||||
capture = ["api/serialize", "ron", "serde", "smallvec/serde"]
|
||||
replay = ["api/deserialize", "ron", "serde", "smallvec/serde"]
|
||||
capture = ["api/serialize", "ron", "serde", "smallvec/serde", "etagere/serialization"]
|
||||
replay = ["api/deserialize", "ron", "serde", "smallvec/serde", "etagere/serialization"]
|
||||
display_list_stats = ["api/display_list_stats"]
|
||||
serialize_program = ["serde", "webrender_build/serialize_program"]
|
||||
no_static_freetype = []
|
||||
leak_checks = []
|
||||
gecko = []
|
||||
sw_compositor = ["swgl"]
|
||||
|
||||
[build-dependencies]
|
||||
build-parallel = "0.1.1"
|
||||
glslopt = "0.1.2"
|
||||
build-parallel = "0.1.2"
|
||||
glslopt = "0.1.9"
|
||||
webrender_build = { version = "0.0.1", path = "../webrender_build" }
|
||||
|
||||
[dependencies]
|
||||
base64 = { optional = true, version = "0.10" }
|
||||
bincode = "1.0"
|
||||
bitflags = "1.2"
|
||||
byteorder = "1.0"
|
||||
cfg-if = "0.1.2"
|
||||
cstr = "0.1.2"
|
||||
cstr = "0.2"
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
fxhash = "0.2.1"
|
||||
gleam = "0.12.1"
|
||||
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||
gleam = "0.15"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
malloc_size_of_derive = "0.1"
|
||||
|
@ -43,27 +41,23 @@ num-traits = "0.2"
|
|||
plane-split = "0.17"
|
||||
png = { optional = true, version = "0.16" }
|
||||
rayon = "1"
|
||||
ron = { optional = true, version = "0.5" }
|
||||
ron = { optional = true, version = "0.6.2" }
|
||||
serde = { optional = true, version = "1.0", features = ["serde_derive"] }
|
||||
serde_json = { optional = true, version = "1.0" }
|
||||
smallvec = "1"
|
||||
time = "0.1"
|
||||
api = { version = "0.61.0", path = "../webrender_api", package = "webrender_api" }
|
||||
webrender_build = { version = "0.0.1", path = "../webrender_build" }
|
||||
malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "wr_malloc_size_of" }
|
||||
ws = { optional = true, version = "0.9" }
|
||||
svg_fmt = "0.4"
|
||||
tracy-rs = { version = "0.1" }
|
||||
tracy-rs = "0.1.2"
|
||||
derive_more = "0.99"
|
||||
etagere = "0.2.4"
|
||||
swgl = { path = "../swgl", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
mozangle = "0.3.1"
|
||||
mozangle = "0.3.3"
|
||||
rand = "0.4"
|
||||
|
||||
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.build-dependencies]
|
||||
backtrace = "0.3"
|
||||
sig = "1.0"
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||
freetype = { version = "0.7", default-features = false }
|
||||
libc = "0.2"
|
||||
|
@ -75,3 +69,4 @@ dwrote = "0.11"
|
|||
core-foundation = "0.9"
|
||||
core-graphics = "0.22"
|
||||
core-text = { version = "19", default-features = false }
|
||||
objc = "0.2"
|
||||
|
|
103
third_party/webrender/webrender/backtrace.rs
vendored
103
third_party/webrender/webrender/backtrace.rs
vendored
|
@ -1,103 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Similar to `println!("{:?}", Backtrace::new())`, but doesn’t allocate.
|
||||
//!
|
||||
//! Seems to fix some deadlocks: https://github.com/servo/servo/issues/24881
|
||||
//!
|
||||
//! FIXME: if/when a future version of the `backtrace` crate has
|
||||
//! https://github.com/rust-lang/backtrace-rs/pull/265, use that instead.
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use backtrace::{BytesOrWideString, PrintFmt};
|
||||
|
||||
#[inline(never)]
|
||||
pub(crate) fn print(w: &mut dyn std::io::Write) -> Result<(), std::io::Error> {
|
||||
write!(w, "{:?}", Print {
|
||||
print_fn_address: print as usize,
|
||||
})
|
||||
}
|
||||
|
||||
struct Print {
|
||||
print_fn_address: usize,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Print {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Safety: we’re in a signal handler that is about to call `libc::_exit`.
|
||||
// Potential data races from using `*_unsynchronized` functions are perhaps
|
||||
// less bad than potential deadlocks?
|
||||
unsafe {
|
||||
let mut print_fn_frame = 0;
|
||||
let mut frame_count = 0;
|
||||
backtrace::trace_unsynchronized(|frame| {
|
||||
let found = frame.symbol_address() as usize == self.print_fn_address;
|
||||
if found {
|
||||
print_fn_frame = frame_count;
|
||||
}
|
||||
frame_count += 1;
|
||||
!found
|
||||
});
|
||||
|
||||
let mode = PrintFmt::Short;
|
||||
let mut p = print_path;
|
||||
let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
|
||||
f.add_context()?;
|
||||
let mut result = Ok(());
|
||||
let mut frame_count = 0;
|
||||
backtrace::trace_unsynchronized(|frame| {
|
||||
let skip = frame_count < print_fn_frame;
|
||||
frame_count += 1;
|
||||
if skip {
|
||||
return true
|
||||
}
|
||||
|
||||
let mut frame_fmt = f.frame();
|
||||
let mut any_symbol = false;
|
||||
backtrace::resolve_frame_unsynchronized(frame, |symbol| {
|
||||
any_symbol = true;
|
||||
if let Err(e) = frame_fmt.symbol(frame, symbol) {
|
||||
result = Err(e)
|
||||
}
|
||||
});
|
||||
if !any_symbol {
|
||||
if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
|
||||
result = Err(e)
|
||||
}
|
||||
}
|
||||
result.is_ok()
|
||||
});
|
||||
result?;
|
||||
f.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result {
|
||||
match path {
|
||||
BytesOrWideString::Bytes(mut bytes) => {
|
||||
loop {
|
||||
match std::str::from_utf8(bytes) {
|
||||
Ok(s) => {
|
||||
fmt.write_str(s)?;
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
fmt.write_char(std::char::REPLACEMENT_CHARACTER)?;
|
||||
match err.error_len() {
|
||||
Some(len) => bytes = &bytes[err.valid_up_to() + len..],
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BytesOrWideString::Wide(wide) => {
|
||||
for c in std::char::decode_utf16(wide.iter().cloned()) {
|
||||
fmt.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
90
third_party/webrender/webrender/build.rs
vendored
90
third_party/webrender/webrender/build.rs
vendored
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use webrender_build;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::fs::{canonicalize, read_dir, File};
|
||||
|
@ -14,6 +12,12 @@ use std::hash::Hasher;
|
|||
use webrender_build::shader::*;
|
||||
use webrender_build::shader_features::{ShaderFeatureFlags, get_shader_features};
|
||||
|
||||
// glsopt is known to leak, but we don't particularly care.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __lsan_default_options() -> *const u8 {
|
||||
b"detect_leaks=0\0".as_ptr()
|
||||
}
|
||||
|
||||
/// Compute the shader path for insertion into the include_str!() macro.
|
||||
/// This makes for more compact generated code than inserting the literal
|
||||
/// shader source into the generated file.
|
||||
|
@ -94,6 +98,16 @@ struct ShaderOptimizationError {
|
|||
message: String,
|
||||
}
|
||||
|
||||
fn print_shader_source(shader_src: &str) {
|
||||
// For some reason the glsl-opt errors are offset by 1 compared
|
||||
// to the provided shader source string.
|
||||
println!("0\t|");
|
||||
for (n, line) in shader_src.split('\n').enumerate() {
|
||||
let line_number = n + 1;
|
||||
println!("{}\t|{}", line_number, line);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &str) -> Result<(), std::io::Error> {
|
||||
writeln!(
|
||||
shader_file,
|
||||
|
@ -119,8 +133,10 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
|||
flags.remove(ShaderFeatureFlags::GLES);
|
||||
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL);
|
||||
}
|
||||
if !matches!(env::var("CARGO_CFG_TARGET_OS").as_ref().map(|s| &**s), Ok("android")) {
|
||||
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1);
|
||||
}
|
||||
flags.remove(ShaderFeatureFlags::DITHERING);
|
||||
flags.remove(ShaderFeatureFlags::PIXEL_LOCAL_STORAGE);
|
||||
|
||||
for (shader_name, configs) in get_shader_features(flags) {
|
||||
for config in configs {
|
||||
|
@ -156,15 +172,17 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
|||
format!("{}_{}", shader.shader_name, shader.config.replace(",", "_"))
|
||||
};
|
||||
|
||||
let vert = glslopt_ctx.optimize(glslopt::ShaderType::Vertex, vert_src);
|
||||
let vert = glslopt_ctx.optimize(glslopt::ShaderType::Vertex, vert_src.clone());
|
||||
if !vert.get_status() {
|
||||
print_shader_source(&vert_src);
|
||||
return Err(ShaderOptimizationError {
|
||||
shader: shader.clone(),
|
||||
message: vert.get_log().to_string(),
|
||||
});
|
||||
}
|
||||
let frag = glslopt_ctx.optimize(glslopt::ShaderType::Fragment, frag_src);
|
||||
let frag = glslopt_ctx.optimize(glslopt::ShaderType::Fragment, frag_src.clone());
|
||||
if !frag.get_status() {
|
||||
print_shader_source(&frag_src);
|
||||
return Err(ShaderOptimizationError {
|
||||
shader: shader.clone(),
|
||||
message: frag.get_log().to_string(),
|
||||
|
@ -178,17 +196,15 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
|||
// as a literal alongside the source string so that we don't need
|
||||
// to hash large strings at runtime.
|
||||
let mut hasher = DefaultHasher::new();
|
||||
hasher.write(vert_source.as_bytes());
|
||||
hasher.write(frag_source.as_bytes());
|
||||
let digest: ProgramSourceDigest = hasher.into();
|
||||
|
||||
let vert_file_path = Path::new(out_dir)
|
||||
.join(format!("{}_{:?}.vert", full_shader_name, shader.gl_version));
|
||||
let mut vert_file = File::create(&vert_file_path).unwrap();
|
||||
vert_file.write_all(vert_source.as_bytes()).unwrap();
|
||||
write_optimized_shader_file(&vert_file_path, vert_source, &shader.shader_name, &features, &mut hasher);
|
||||
|
||||
let frag_file_path = vert_file_path.with_extension("frag");
|
||||
let mut frag_file = File::create(&frag_file_path).unwrap();
|
||||
frag_file.write_all(frag_source.as_bytes()).unwrap();
|
||||
write_optimized_shader_file(&frag_file_path, frag_source, &shader.shader_name, &features, &mut hasher);
|
||||
|
||||
let digest: ProgramSourceDigest = hasher.into();
|
||||
|
||||
println!("Finished optimizing shader {:?}", shader);
|
||||
|
||||
|
@ -244,37 +260,35 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
mod backtrace;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
extern "C" fn handler(sig: i32) {
|
||||
use std::sync::atomic;
|
||||
static BEEN_HERE_BEFORE: atomic::AtomicBool = atomic::AtomicBool::new(false);
|
||||
if !BEEN_HERE_BEFORE.swap(true, atomic::Ordering::SeqCst) {
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
let _ = write!(&mut stdout, "Stack trace");
|
||||
if let Some(name) = std::thread::current().name() {
|
||||
let _ = write!(&mut stdout, " for thread \"{}\"", name);
|
||||
fn write_optimized_shader_file(
|
||||
path: &Path,
|
||||
source: &str,
|
||||
shader_name: &str,
|
||||
features: &[&str],
|
||||
hasher: &mut DefaultHasher,
|
||||
) {
|
||||
let mut file = File::create(&path).unwrap();
|
||||
for (line_number, line) in source.lines().enumerate() {
|
||||
// We embed the shader name and features as a comment in the
|
||||
// source to make debugging easier.
|
||||
// The #version directive must be on the first line so we insert
|
||||
// the extra information on the next line.
|
||||
if line_number == 1 {
|
||||
let prelude = format!(
|
||||
"// {}\n// features: {:?}\n\n",
|
||||
shader_name, features
|
||||
);
|
||||
file.write_all(prelude.as_bytes()).unwrap();
|
||||
hasher.write(prelude.as_bytes());
|
||||
}
|
||||
let _ = write!(&mut stdout, "\n");
|
||||
let _ = backtrace::print(&mut stdout);
|
||||
}
|
||||
unsafe {
|
||||
libc::_exit(sig);
|
||||
file.write_all(line.as_bytes()).unwrap();
|
||||
file.write_all("\n".as_bytes()).unwrap();
|
||||
hasher.write(line.as_bytes());
|
||||
hasher.write("\n".as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
{
|
||||
sig::signal!(sig::ffi::Sig::SEGV, handler); // handle segfaults
|
||||
sig::signal!(sig::ffi::Sig::ILL, handler); // handle stack overflow and unsupported CPUs
|
||||
sig::signal!(sig::ffi::Sig::IOT, handler); // handle double panics
|
||||
sig::signal!(sig::ffi::Sig::BUS, handler); // handle invalid memory access
|
||||
}
|
||||
|
||||
let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());
|
||||
|
||||
let shaders_file_path = Path::new(&out_dir).join("shaders.rs");
|
||||
|
|
35
third_party/webrender/webrender/res/base.glsl
vendored
35
third_party/webrender/webrender/res/base.glsl
vendored
|
@ -4,12 +4,6 @@
|
|||
|
||||
#if defined(GL_ES)
|
||||
#if GL_ES == 1
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp sampler2DArray;
|
||||
#else
|
||||
precision mediump sampler2DArray;
|
||||
#endif
|
||||
|
||||
// Sampler default precision is lowp on mobile GPUs.
|
||||
// This causes RGBA32F texture data to be clamped to 16 bit floats on some GPUs (e.g. Mali-T880).
|
||||
// Define highp precision macro to allow lossless FLOAT texture sampling.
|
||||
|
@ -32,7 +26,20 @@
|
|||
#else
|
||||
#define HIGHP_SAMPLER_FLOAT
|
||||
#define HIGHP_FS_ADDRESS
|
||||
#define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
|
||||
#if defined(PLATFORM_MACOS) && !defined(SWGL)
|
||||
// texelFetchOffset introduces a variety of shader compilation bugs on macOS Intel so avoid it.
|
||||
#define TEXEL_FETCH(sampler, position, lod, offset) texelFetch(sampler, position + offset, lod)
|
||||
#else
|
||||
#define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SWGL
|
||||
#define SWGL_DRAW_SPAN
|
||||
#define SWGL_CLIP_MASK
|
||||
#define SWGL_ANTIALIAS
|
||||
#define SWGL_BLEND
|
||||
#define SWGL_CLIP_DIST
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
@ -44,10 +51,20 @@
|
|||
#define PER_INSTANCE
|
||||
#endif
|
||||
|
||||
#define varying out
|
||||
#if __VERSION__ != 100
|
||||
#define varying out
|
||||
#define attribute in
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
precision highp float;
|
||||
#define varying in
|
||||
#if __VERSION__ != 100
|
||||
#define varying in
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Flat interpolation is not supported on ESSL 1
|
||||
#if __VERSION__ == 100
|
||||
#define flat
|
||||
#endif
|
||||
|
|
233
third_party/webrender/webrender/res/blend.glsl
vendored
Normal file
233
third_party/webrender/webrender/res/blend.glsl
vendored
Normal file
|
@ -0,0 +1,233 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define COMPONENT_TRANSFER_IDENTITY 0
|
||||
#define COMPONENT_TRANSFER_TABLE 1
|
||||
#define COMPONENT_TRANSFER_DISCRETE 2
|
||||
#define COMPONENT_TRANSFER_LINEAR 3
|
||||
#define COMPONENT_TRANSFER_GAMMA 4
|
||||
|
||||
// Must be kept in sync with `Filter::as_int` in internal_types.rs
|
||||
// Not all filters are defined here because some filter use different shaders.
|
||||
#define FILTER_CONTRAST 0
|
||||
#define FILTER_GRAYSCALE 1
|
||||
#define FILTER_HUE_ROTATE 2
|
||||
#define FILTER_INVERT 3
|
||||
#define FILTER_SATURATE 4
|
||||
#define FILTER_SEPIA 5
|
||||
#define FILTER_BRIGHTNESS 6
|
||||
#define FILTER_COLOR_MATRIX 7
|
||||
#define FILTER_SRGB_TO_LINEAR 8
|
||||
#define FILTER_LINEAR_TO_SRGB 9
|
||||
#define FILTER_FLOOD 10
|
||||
#define FILTER_COMPONENT_TRANSFER 11
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
void SetupFilterParams(
|
||||
int op,
|
||||
float amount,
|
||||
int gpu_data_address,
|
||||
out vec4 color_offset,
|
||||
out mat4 color_mat,
|
||||
out int table_address
|
||||
) {
|
||||
float lumR = 0.2126;
|
||||
float lumG = 0.7152;
|
||||
float lumB = 0.0722;
|
||||
float oneMinusLumR = 1.0 - lumR;
|
||||
float oneMinusLumG = 1.0 - lumG;
|
||||
float oneMinusLumB = 1.0 - lumB;
|
||||
float invAmount = 1.0 - amount;
|
||||
|
||||
if (op == FILTER_GRAYSCALE) {
|
||||
color_mat = mat4(
|
||||
vec4(lumR + oneMinusLumR * invAmount, lumR - lumR * invAmount, lumR - lumR * invAmount, 0.0),
|
||||
vec4(lumG - lumG * invAmount, lumG + oneMinusLumG * invAmount, lumG - lumG * invAmount, 0.0),
|
||||
vec4(lumB - lumB * invAmount, lumB - lumB * invAmount, lumB + oneMinusLumB * invAmount, 0.0),
|
||||
vec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
color_offset = vec4(0.0);
|
||||
} else if (op == FILTER_HUE_ROTATE) {
|
||||
float c = cos(amount);
|
||||
float s = sin(amount);
|
||||
color_mat = mat4(
|
||||
vec4(lumR + oneMinusLumR * c - lumR * s, lumR - lumR * c + 0.143 * s, lumR - lumR * c - oneMinusLumR * s, 0.0),
|
||||
vec4(lumG - lumG * c - lumG * s, lumG + oneMinusLumG * c + 0.140 * s, lumG - lumG * c + lumG * s, 0.0),
|
||||
vec4(lumB - lumB * c + oneMinusLumB * s, lumB - lumB * c - 0.283 * s, lumB + oneMinusLumB * c + lumB * s, 0.0),
|
||||
vec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
color_offset = vec4(0.0);
|
||||
} else if (op == FILTER_SATURATE) {
|
||||
color_mat = mat4(
|
||||
vec4(invAmount * lumR + amount, invAmount * lumR, invAmount * lumR, 0.0),
|
||||
vec4(invAmount * lumG, invAmount * lumG + amount, invAmount * lumG, 0.0),
|
||||
vec4(invAmount * lumB, invAmount * lumB, invAmount * lumB + amount, 0.0),
|
||||
vec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
color_offset = vec4(0.0);
|
||||
} else if (op == FILTER_SEPIA) {
|
||||
color_mat = mat4(
|
||||
vec4(0.393 + 0.607 * invAmount, 0.349 - 0.349 * invAmount, 0.272 - 0.272 * invAmount, 0.0),
|
||||
vec4(0.769 - 0.769 * invAmount, 0.686 + 0.314 * invAmount, 0.534 - 0.534 * invAmount, 0.0),
|
||||
vec4(0.189 - 0.189 * invAmount, 0.168 - 0.168 * invAmount, 0.131 + 0.869 * invAmount, 0.0),
|
||||
vec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
color_offset = vec4(0.0);
|
||||
} else if (op == FILTER_COLOR_MATRIX) {
|
||||
vec4 mat_data[4] = fetch_from_gpu_cache_4(gpu_data_address);
|
||||
vec4 offset_data = fetch_from_gpu_cache_1(gpu_data_address + 4);
|
||||
color_mat = mat4(mat_data[0], mat_data[1], mat_data[2], mat_data[3]);
|
||||
color_offset = offset_data;
|
||||
} else if (op == FILTER_COMPONENT_TRANSFER) {
|
||||
table_address = gpu_data_address;
|
||||
} else if (op == FILTER_FLOOD) {
|
||||
color_offset = fetch_from_gpu_cache_1(gpu_data_address);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
vec3 Contrast(vec3 Cs, float amount) {
|
||||
return clamp(Cs.rgb * amount - 0.5 * amount + 0.5, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 Invert(vec3 Cs, float amount) {
|
||||
return mix(Cs.rgb, vec3(1.0) - Cs.rgb, amount);
|
||||
}
|
||||
|
||||
vec3 Brightness(vec3 Cs, float amount) {
|
||||
// Apply the brightness factor.
|
||||
// Resulting color needs to be clamped to output range
|
||||
// since we are pre-multiplying alpha in the shader.
|
||||
return clamp(Cs.rgb * amount, vec3(0.0), vec3(1.0));
|
||||
}
|
||||
|
||||
// Based on the Gecko's implementation in
|
||||
// https://hg.mozilla.org/mozilla-central/file/91b4c3687d75/gfx/src/FilterSupport.cpp#l24
|
||||
// These could be made faster by sampling a lookup table stored in a float texture
|
||||
// with linear interpolation.
|
||||
|
||||
vec3 SrgbToLinear(vec3 color) {
|
||||
vec3 c1 = color / 12.92;
|
||||
vec3 c2 = pow(color / 1.055 + vec3(0.055 / 1.055), vec3(2.4));
|
||||
return if_then_else(lessThanEqual(color, vec3(0.04045)), c1, c2);
|
||||
}
|
||||
|
||||
vec3 LinearToSrgb(vec3 color) {
|
||||
vec3 c1 = color * 12.92;
|
||||
vec3 c2 = vec3(1.055) * pow(color, vec3(1.0 / 2.4)) - vec3(0.055);
|
||||
return if_then_else(lessThanEqual(color, vec3(0.0031308)), c1, c2);
|
||||
}
|
||||
|
||||
// This function has to be factored out due to the following issue:
|
||||
// https://github.com/servo/webrender/wiki/Driver-issues#bug-1532245---switch-statement-inside-control-flow-inside-switch-statement-fails-to-compile-on-some-android-phones
|
||||
// (and now the words "default: default:" so angle_shader_validation.rs passes)
|
||||
vec4 ComponentTransfer(vec4 colora, ivec4 vfuncs, int table_address) {
|
||||
// We push a different amount of data to the gpu cache depending on the
|
||||
// function type.
|
||||
// Identity => 0 blocks
|
||||
// Table/Discrete => 64 blocks (256 values)
|
||||
// Linear => 1 block (2 values)
|
||||
// Gamma => 1 block (3 values)
|
||||
// We loop through the color components and increment the offset (for the
|
||||
// next color component) into the gpu cache based on how many blocks that
|
||||
// function type put into the gpu cache.
|
||||
// Table/Discrete use a 256 entry look up table.
|
||||
// Linear/Gamma are a simple calculation.
|
||||
int offset = 0;
|
||||
vec4 texel;
|
||||
int k;
|
||||
|
||||
// Dynamically indexing a vector is buggy on some platforms, so use a temporary array
|
||||
int[4] funcs = int[4](vfuncs.r, vfuncs.g, vfuncs.b, vfuncs.a);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
switch (funcs[i]) {
|
||||
case COMPONENT_TRANSFER_IDENTITY:
|
||||
break;
|
||||
case COMPONENT_TRANSFER_TABLE:
|
||||
case COMPONENT_TRANSFER_DISCRETE: {
|
||||
// fetch value from lookup table
|
||||
k = int(floor(colora[i]*255.0));
|
||||
texel = fetch_from_gpu_cache_1(table_address + offset + k/4);
|
||||
colora[i] = clamp(texel[k % 4], 0.0, 1.0);
|
||||
// offset plus 256/4 blocks
|
||||
offset = offset + 64;
|
||||
break;
|
||||
}
|
||||
case COMPONENT_TRANSFER_LINEAR: {
|
||||
// fetch the two values for use in the linear equation
|
||||
texel = fetch_from_gpu_cache_1(table_address + offset);
|
||||
colora[i] = clamp(texel[0] * colora[i] + texel[1], 0.0, 1.0);
|
||||
// offset plus 1 block
|
||||
offset = offset + 1;
|
||||
break;
|
||||
}
|
||||
case COMPONENT_TRANSFER_GAMMA: {
|
||||
// fetch the three values for use in the gamma equation
|
||||
texel = fetch_from_gpu_cache_1(table_address + offset);
|
||||
colora[i] = clamp(texel[0] * pow(colora[i], texel[1]) + texel[2], 0.0, 1.0);
|
||||
// offset plus 1 block
|
||||
offset = offset + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// shouldn't happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
return colora;
|
||||
}
|
||||
|
||||
void CalculateFilter(
|
||||
vec4 Cs,
|
||||
int op,
|
||||
float amount,
|
||||
int table_address,
|
||||
vec4 color_offset,
|
||||
mat4 color_mat,
|
||||
ivec4 v_funcs,
|
||||
out vec3 color,
|
||||
out float alpha
|
||||
) {
|
||||
// Un-premultiply the input.
|
||||
alpha = Cs.a;
|
||||
color = alpha != 0.0 ? Cs.rgb / alpha : Cs.rgb;
|
||||
|
||||
switch (op) {
|
||||
case FILTER_CONTRAST:
|
||||
color = Contrast(color, amount);
|
||||
break;
|
||||
case FILTER_INVERT:
|
||||
color = Invert(color, amount);
|
||||
break;
|
||||
case FILTER_BRIGHTNESS:
|
||||
color = Brightness(color, amount);
|
||||
break;
|
||||
case FILTER_SRGB_TO_LINEAR:
|
||||
color = SrgbToLinear(color);
|
||||
break;
|
||||
case FILTER_LINEAR_TO_SRGB:
|
||||
color = LinearToSrgb(color);
|
||||
break;
|
||||
case FILTER_COMPONENT_TRANSFER: {
|
||||
// Get the unpremultiplied color with alpha.
|
||||
vec4 colora = vec4(color, alpha);
|
||||
colora = ComponentTransfer(colora, v_funcs, table_address);
|
||||
color = colora.rgb;
|
||||
alpha = colora.a;
|
||||
break;
|
||||
}
|
||||
case FILTER_FLOOD:
|
||||
color = color_offset.rgb;
|
||||
alpha = color_offset.a;
|
||||
break;
|
||||
default:
|
||||
// Color matrix type filters (sepia, hue-rotate, etc...)
|
||||
vec4 result = color_mat * vec4(color, alpha) + color_offset;
|
||||
result = clamp(result, vec4(0.0), vec4(1.0));
|
||||
color = result.rgb;
|
||||
alpha = result.a;
|
||||
}
|
||||
}
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue