mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Vendor the current version of WebRender
This is a step toward upgrading WebRender, which will be upgraded and patched in the `third_party` directory. This change vendors the current private branch of WebRender that we use and adds a `patches` directory which tracks the changes on top of the upstream WebRender commit described by third_party/webrender/patches/head.
This commit is contained in:
parent
c19eb800de
commit
49277f5c3f
1215 changed files with 185677 additions and 34 deletions
27
third_party/webrender/.gitignore
vendored
Normal file
27
third_party/webrender/.gitignore
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
target/
|
||||
*~
|
||||
*#
|
||||
|
||||
# WR internals
|
||||
captures
|
||||
wrench/json_frames
|
||||
wrench/ron_frames
|
||||
|
||||
# Editors
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
|
||||
# VSCode
|
||||
.vscode
|
||||
.vs
|
||||
|
||||
# System
|
||||
.fuse_hidden*
|
176
third_party/webrender/.taskcluster.yml
vendored
Normal file
176
third_party/webrender/.taskcluster.yml
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
# This file specifies the configuration needed to test WebRender using the
|
||||
# Taskcluster infrastructure. Most of this should be relatively
|
||||
# self-explanatory; this file was originally generated by using the
|
||||
# Taskcluster-GitHub integration quickstart tool which no longer exists.
|
||||
#
|
||||
# See https://community-tc.services.mozilla.com/docs
|
||||
version: 1
|
||||
policy:
|
||||
pullRequests: public
|
||||
|
||||
# This file triggers a set of tasks; the ones targeting Linux are run in a docker
|
||||
# container using docker-worker (which is a worker type provided by TaskCluster).
|
||||
# The OS X ones are run in a custom worker type, for which we have worker
|
||||
# instances configured and running.
|
||||
tasks:
|
||||
$if: 'tasks_for in ["github-push", "github-pull-request"]'
|
||||
then:
|
||||
$let:
|
||||
should_run:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
# for pushes, run on any branch but master
|
||||
then: {$eval: 'event.ref != "refs/heads/master"'}
|
||||
# for PRs, run for opened and synchronized events
|
||||
else: {$eval: 'event.action in ["opened", "synchronize"]'}
|
||||
repo_url:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then: ${event.repository.clone_url}
|
||||
else: ${event.pull_request.head.repo.clone_url}
|
||||
sha:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then: ${event.after}
|
||||
else: ${event.pull_request.head.sha}
|
||||
login: ${event.sender.login}
|
||||
branch:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then:
|
||||
$if: 'event.ref[:11] == "refs/heads/"'
|
||||
then: ${event.ref[11:]}
|
||||
else: ${event.ref}
|
||||
else: ${event.pull_request.head.ref}
|
||||
in:
|
||||
$if: should_run
|
||||
then:
|
||||
# For the docker-worker tasks, the Docker image used
|
||||
# (staktrace/webrender-test:debian-v6) was created using the Dockerfile in
|
||||
# ci-scripts/docker-image.
|
||||
#
|
||||
# The docker image may need to be updated over time if the set of required
|
||||
# packages increases. Note in particular that rust/cargo are not part of the
|
||||
# docker image, and are re-installed using rustup on each CI run. This ensures
|
||||
# the latest stable rust compiler is always used.
|
||||
# CI runs will be triggered on opening PRs, updating PRs, and pushes to the
|
||||
# repository.
|
||||
- metadata:
|
||||
name: Linux release tests
|
||||
description: Runs release-mode WebRender CI stuff on a Linux TC worker
|
||||
owner: noreply@mozilla.com
|
||||
source: ${repo_url}
|
||||
provisionerId: proj-webrender
|
||||
workerType: ci-linux
|
||||
deadline: {$fromNow: '1 day'}
|
||||
payload:
|
||||
maxRunTime: 7200
|
||||
image: 'staktrace/webrender-test:debian-v6'
|
||||
env:
|
||||
RUST_BACKTRACE: 'full'
|
||||
RUSTFLAGS: '--deny warnings'
|
||||
command:
|
||||
- /bin/bash
|
||||
- '--login'
|
||||
- '-c'
|
||||
- >-
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y &&
|
||||
source $HOME/.cargo/env &&
|
||||
git clone ${repo_url} webrender && cd webrender &&
|
||||
git checkout ${sha} &&
|
||||
servo-tidy &&
|
||||
ci-scripts/linux-release-tests.sh
|
||||
routes:
|
||||
- "index.project.webrender.ci.${login}.${branch}.linux-release"
|
||||
- metadata:
|
||||
name: Linux debug tests
|
||||
description: Runs debug-mode WebRender CI stuff on a Linux TC worker
|
||||
owner: noreply@mozilla.com
|
||||
source: ${repo_url}
|
||||
provisionerId: proj-webrender
|
||||
workerType: ci-linux
|
||||
deadline: {$fromNow: '1 day'}
|
||||
payload:
|
||||
maxRunTime: 7200
|
||||
image: 'staktrace/webrender-test:debian-v6'
|
||||
env:
|
||||
RUST_BACKTRACE: 'full'
|
||||
RUSTFLAGS: '--deny warnings'
|
||||
command:
|
||||
- /bin/bash
|
||||
- '--login'
|
||||
- '-c'
|
||||
- >-
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y &&
|
||||
source $HOME/.cargo/env &&
|
||||
git clone ${repo_url} webrender && cd webrender &&
|
||||
git checkout ${sha} &&
|
||||
servo-tidy &&
|
||||
ci-scripts/linux-debug-tests.sh
|
||||
routes:
|
||||
- "index.project.webrender.ci.${login}.${branch}.linux-debug"
|
||||
# For the OS X jobs we use a pool of machines that we are managing, because
|
||||
# Mozilla releng doesn't have any spare OS X machines for us at this time.
|
||||
# Talk to :kats or :jrmuizel if you need more details about this. The machines
|
||||
# are hooked up to taskcluster using taskcluster-worker; they use a workerpool
|
||||
# of proj-webrender/ci-macos. They are set up with all the dependencies needed
|
||||
# to build and test webrender, including Rust (currently 1.41.1), servo-tidy,
|
||||
# mako, zlib, etc. Note that unlike the docker-worker used for Linux, these
|
||||
# machines WILL persist state from one run to the next, so any cleanup needs
|
||||
# to be handled explicitly.
|
||||
|
||||
# macOS tasks currently disabled, see bug 1639217.
|
||||
# - metadata:
|
||||
# name: OS X release tests
|
||||
# description: Runs release-mode WebRender CI stuff on a OS X TC worker
|
||||
# owner: noreply@mozilla.com
|
||||
# source: ${repo_url}
|
||||
# provisionerId: 'proj-webrender'
|
||||
# workerType: 'ci-macos'
|
||||
# deadline: {$fromNow: '1 day'}
|
||||
# payload:
|
||||
# maxRunTime: 3600
|
||||
# command:
|
||||
# - - /bin/bash
|
||||
# - '--login'
|
||||
# - '-vec'
|
||||
# - |
|
||||
# git clone ${repo_url} webrender
|
||||
# cd webrender
|
||||
# git checkout ${sha}
|
||||
# source $HOME/servotidy-venv/bin/activate
|
||||
# servo-tidy
|
||||
# export RUST_BACKTRACE=full
|
||||
# export RUSTFLAGS='--deny warnings'
|
||||
# export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
# echo 'exec make -j1 "$@"' > $HOME/make # See #2638
|
||||
# chmod +x $HOME/make
|
||||
# export MAKE="$HOME/make"
|
||||
# ci-scripts/macos-release-tests.sh
|
||||
# routes:
|
||||
# - "index.project.webrender.ci.${login}.${branch}.osx-release"
|
||||
# - metadata:
|
||||
# name: OS X debug tests
|
||||
# description: Runs debug-mode WebRender CI stuff on a OS X TC worker
|
||||
# owner: noreply@mozilla.com
|
||||
# source: ${repo_url}
|
||||
# provisionerId: 'proj-webrender'
|
||||
# workerType: 'ci-macos'
|
||||
# deadline: {$fromNow: '1 day'}
|
||||
# payload:
|
||||
# maxRunTime: 3600
|
||||
# command:
|
||||
# - - /bin/bash
|
||||
# - '--login'
|
||||
# - '-vec'
|
||||
# - |
|
||||
# git clone ${repo_url} webrender
|
||||
# cd webrender
|
||||
# git checkout ${sha}
|
||||
# source $HOME/servotidy-venv/bin/activate
|
||||
# servo-tidy
|
||||
# export RUST_BACKTRACE=full
|
||||
# export RUSTFLAGS='--deny warnings'
|
||||
# export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
# echo 'exec make -j1 "$@"' > $HOME/make # See #2638
|
||||
# chmod +x $HOME/make
|
||||
# export MAKE="$HOME/make"
|
||||
# ci-scripts/macos-debug-tests.sh
|
||||
# routes:
|
||||
# - "index.project.webrender.ci.${login}.${branch}.osx-debug"
|
2267
third_party/webrender/Cargo.lock
generated
vendored
Normal file
2267
third_party/webrender/Cargo.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
25
third_party/webrender/Cargo.toml
vendored
Normal file
25
third_party/webrender/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"direct-composition",
|
||||
"examples",
|
||||
"webrender",
|
||||
"webrender_api",
|
||||
"wrench",
|
||||
"example-compositor/compositor",
|
||||
"tileview",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
panic = "abort"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
# 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.
|
||||
# See https://github.com/rust-windowing/android-rs-glue/issues/239.
|
||||
# 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" }
|
374
third_party/webrender/LICENSE
vendored
Normal file
374
third_party/webrender/LICENSE
vendored
Normal file
|
@ -0,0 +1,374 @@
|
|||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
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/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
53
third_party/webrender/README.md
vendored
Normal file
53
third_party/webrender/README.md
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
# WebRender
|
||||
|
||||
[](https://crates.io/crates/webrender)
|
||||
|
||||
WebRender is a GPU-based 2D rendering engine written in [Rust](https://www.rust-lang.org/). [Firefox](https://www.mozilla.org/firefox), the research web browser [Servo](https://github.com/servo/servo), and other GUI frameworks draw with it. It currently uses the OpenGL API internally.
|
||||
|
||||
Note that the canonical home for this code is in gfx/wr folder of the
|
||||
mozilla-central repository at https://hg.mozilla.org/mozilla-central. The
|
||||
Github repository at https://github.com/servo/webrender should be considered
|
||||
a downstream mirror, although it contains additional metadata (such as Github
|
||||
wiki pages) that do not exist in mozilla-central. Pull requests against the
|
||||
Github repository are still being accepted, although once reviewed, they will
|
||||
be landed on mozilla-central first and then mirrored back. If you are familiar
|
||||
with the mozilla-central contribution workflow, filing bugs in
|
||||
[Bugzilla](https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Graphics%3A%20WebRender)
|
||||
and submitting patches there would be preferred.
|
||||
|
||||
## Update as a Dependency
|
||||
After updating shaders in WebRender, go to servo and:
|
||||
|
||||
* Go to the servo directory and do ./mach update-cargo -p webrender
|
||||
* Create a pull request to servo
|
||||
|
||||
|
||||
## Use WebRender with Servo
|
||||
To use a local copy of WebRender with servo, go to your servo build directory and:
|
||||
|
||||
* Edit Cargo.toml
|
||||
* Add at the end of the file:
|
||||
|
||||
```
|
||||
[patch."https://github.com/servo/webrender"]
|
||||
"webrender" = { path = "<path>/webrender" }
|
||||
"webrender_api" = { path = "<path>/webrender_api" }
|
||||
```
|
||||
|
||||
where `<path>` is the path to your local copy of WebRender.
|
||||
|
||||
* Build as normal
|
||||
|
||||
## Documentation
|
||||
|
||||
The Wiki has a [few pages](https://github.com/servo/webrender/wiki/) describing the internals and conventions of WebRender.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests run using OSMesa to get consistent rendering across platforms.
|
||||
|
||||
Still there may be differences depending on font libraries on your system, for
|
||||
example.
|
||||
|
||||
See [this gist](https://gist.github.com/finalfantasia/129cae811e02bf4551ac) for
|
||||
how to make the text tests useful in Fedora, for example.
|
12
third_party/webrender/ci-scripts/docker-image/Dockerfile
vendored
Normal file
12
third_party/webrender/ci-scripts/docker-image/Dockerfile
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
FROM debian:buster-20200422
|
||||
|
||||
# Debian 10 doesn't have openjdk-8, so add the Debian 9 repository, which contains it.
|
||||
RUN sed s/buster/stretch/ /etc/apt/sources.list | tee /etc/apt/sources.list.d/stretch.list
|
||||
|
||||
COPY setup.sh /root
|
||||
RUN cd /root && ./setup.sh
|
||||
|
||||
RUN useradd -d /home/worker -s /bin/bash -m worker
|
||||
USER worker
|
||||
WORKDIR /home/worker
|
||||
CMD /bin/bash
|
37
third_party/webrender/ci-scripts/docker-image/setup.sh
vendored
Executable file
37
third_party/webrender/ci-scripts/docker-image/setup.sh
vendored
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/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/. */
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
test "$(whoami)" == 'root'
|
||||
|
||||
# Install stuff we need
|
||||
apt-get -y update
|
||||
apt-get install -y \
|
||||
bzip2 \
|
||||
cmake \
|
||||
curl \
|
||||
gcc \
|
||||
git \
|
||||
g++ \
|
||||
libfontconfig1-dev \
|
||||
libgl1-mesa-dev \
|
||||
libx11-dev \
|
||||
openjdk-8-jdk \
|
||||
pkg-config \
|
||||
python \
|
||||
python-mako \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
python-voluptuous \
|
||||
python-yaml \
|
||||
software-properties-common
|
||||
|
||||
# Other stuff we need
|
||||
pip install servo-tidy==0.3.0
|
36
third_party/webrender/ci-scripts/linux-debug-tests.sh
vendored
Executable file
36
third_party/webrender/ci-scripts/linux-debug-tests.sh
vendored
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/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 must be run from the root webrender directory!
|
||||
# Users may set the CARGOFLAGS environment variable to pass
|
||||
# additional flags to cargo if desired.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
CARGOFLAGS=${CARGOFLAGS:-"--verbose"} # default to --verbose if not set
|
||||
|
||||
pushd webrender
|
||||
cargo build ${CARGOFLAGS} --no-default-features
|
||||
cargo build ${CARGOFLAGS} --no-default-features --features capture
|
||||
cargo build ${CARGOFLAGS} --features capture,profiler
|
||||
cargo build ${CARGOFLAGS} --features replay
|
||||
popd
|
||||
|
||||
pushd wrench
|
||||
cargo build ${CARGOFLAGS} --features env_logger
|
||||
OPTIMIZED=0 python script/headless.py reftest
|
||||
popd
|
||||
|
||||
pushd examples
|
||||
cargo build ${CARGOFLAGS}
|
||||
popd
|
||||
|
||||
cargo test ${CARGOFLAGS} \
|
||||
--all --exclude compositor-windows --exclude compositor \
|
||||
--exclude glsl-to-cxx --exclude swgl
|
22
third_party/webrender/ci-scripts/linux-release-tests.sh
vendored
Executable file
22
third_party/webrender/ci-scripts/linux-release-tests.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 must be run from the root webrender directory!
|
||||
# Users may set the CARGOFLAGS environment variable to pass
|
||||
# additional flags to cargo if desired.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
||||
|
||||
pushd wrench
|
||||
python script/headless.py reftest
|
||||
python script/headless.py rawtest
|
||||
cargo build ${CARGOFLAGS} --release
|
||||
popd
|
42
third_party/webrender/ci-scripts/macos-debug-tests.sh
vendored
Executable file
42
third_party/webrender/ci-scripts/macos-debug-tests.sh
vendored
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/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 must be run from the root webrender directory!
|
||||
# Users may set the CARGOFLAGS environment variable to pass
|
||||
# additional flags to cargo if desired.
|
||||
|
||||
# Note that this script is run in a special cross-compiling configuration,
|
||||
# where CARGOTESTFLAGS includes `--no-run`, and the binaries produced by
|
||||
# `cargo test` are run on a different machine. When making changes to this
|
||||
# file, please ensure any such binaries produced by `cargo test` are not
|
||||
# deleted, or they may not get run as expected.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
CARGOFLAGS=${CARGOFLAGS:-"--verbose"} # default to --verbose if not set
|
||||
CARGOTESTFLAGS=${CARGOTESTFLAGS:-""}
|
||||
|
||||
pushd webrender
|
||||
cargo check ${CARGOFLAGS} --no-default-features
|
||||
cargo check ${CARGOFLAGS} --no-default-features --features capture
|
||||
cargo check ${CARGOFLAGS} --features capture,profiler
|
||||
cargo check ${CARGOFLAGS} --features replay
|
||||
popd
|
||||
|
||||
pushd wrench
|
||||
cargo check ${CARGOFLAGS} --features env_logger
|
||||
popd
|
||||
|
||||
pushd examples
|
||||
cargo check ${CARGOFLAGS}
|
||||
popd
|
||||
|
||||
cargo test ${CARGOFLAGS} ${CARGOTESTFLAGS} \
|
||||
--all --exclude compositor-windows --exclude compositor \
|
||||
--exclude glsl-to-cxx --exclude swgl
|
29
third_party/webrender/ci-scripts/macos-release-tests.sh
vendored
Executable file
29
third_party/webrender/ci-scripts/macos-release-tests.sh
vendored
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/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 must be run from the root webrender directory!
|
||||
# Users may set the CARGOFLAGS environment variable to pass
|
||||
# additional flags to cargo if desired.
|
||||
# The WRENCH_BINARY environment variable, if set, is used to run
|
||||
# the precached reftest.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
||||
WRENCH_BINARY=${WRENCH_BINARY:-""}
|
||||
|
||||
pushd wrench
|
||||
python script/headless.py reftest
|
||||
if [[ -z "${WRENCH_BINARY}" ]]; then
|
||||
cargo build ${CARGOFLAGS} --release
|
||||
WRENCH_BINARY="../target/release/wrench"
|
||||
fi
|
||||
"${WRENCH_BINARY}" --precache \
|
||||
reftest reftests/clip/fixed-position-clipping.yaml
|
||||
popd
|
124
third_party/webrender/ci-scripts/set-screenresolution.ps1
vendored
Normal file
124
third_party/webrender/ci-scripts/set-screenresolution.ps1
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
# http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/07/hey-scripting-guy-how-can-i-change-my-desktop-monitor-resolution-via-windows-powershell.aspx
|
||||
|
||||
Function Set-ScreenResolution {
|
||||
param (
|
||||
[Parameter(Mandatory=$true,
|
||||
Position = 0)]
|
||||
[int]
|
||||
$Width,
|
||||
[Parameter(Mandatory=$true,
|
||||
Position = 1)]
|
||||
[int]
|
||||
$Height
|
||||
)
|
||||
$pinvokeCode = @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
namespace Resolution
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DEVMODE1
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmDeviceName;
|
||||
public short dmSpecVersion;
|
||||
public short dmDriverVersion;
|
||||
public short dmSize;
|
||||
public short dmDriverExtra;
|
||||
public int dmFields;
|
||||
public short dmOrientation;
|
||||
public short dmPaperSize;
|
||||
public short dmPaperLength;
|
||||
public short dmPaperWidth;
|
||||
public short dmScale;
|
||||
public short dmCopies;
|
||||
public short dmDefaultSource;
|
||||
public short dmPrintQuality;
|
||||
public short dmColor;
|
||||
public short dmDuplex;
|
||||
public short dmYResolution;
|
||||
public short dmTTOption;
|
||||
public short dmCollate;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string dmFormName;
|
||||
public short dmLogPixels;
|
||||
public short dmBitsPerPel;
|
||||
public int dmPelsWidth;
|
||||
public int dmPelsHeight;
|
||||
public int dmDisplayFlags;
|
||||
public int dmDisplayFrequency;
|
||||
public int dmICMMethod;
|
||||
public int dmICMIntent;
|
||||
public int dmMediaType;
|
||||
public int dmDitherType;
|
||||
public int dmReserved1;
|
||||
public int dmReserved2;
|
||||
public int dmPanningWidth;
|
||||
public int dmPanningHeight;
|
||||
};
|
||||
class User_32
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
public const int CDS_UPDATEREGISTRY = 0x01;
|
||||
public const int CDS_TEST = 0x02;
|
||||
public const int DISP_CHANGE_SUCCESSFUL = 0;
|
||||
public const int DISP_CHANGE_RESTART = 1;
|
||||
public const int DISP_CHANGE_FAILED = -1;
|
||||
}
|
||||
public class PrmaryScreenResolution
|
||||
{
|
||||
static public string ChangeResolution(int width, int height)
|
||||
{
|
||||
DEVMODE1 dm = GetDevMode1();
|
||||
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
|
||||
{
|
||||
dm.dmPelsWidth = width;
|
||||
dm.dmPelsHeight = height;
|
||||
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
|
||||
if (iRet == User_32.DISP_CHANGE_FAILED)
|
||||
{
|
||||
return "Unable To Process Your Request. Sorry For This Inconvenience.";
|
||||
}
|
||||
else
|
||||
{
|
||||
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
|
||||
switch (iRet)
|
||||
{
|
||||
case User_32.DISP_CHANGE_SUCCESSFUL:
|
||||
{
|
||||
return "Success";
|
||||
}
|
||||
case User_32.DISP_CHANGE_RESTART:
|
||||
{
|
||||
return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
|
||||
}
|
||||
default:
|
||||
{
|
||||
return "Failed To Change The Resolution";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Failed To Change The Resolution.";
|
||||
}
|
||||
}
|
||||
private static DEVMODE1 GetDevMode1()
|
||||
{
|
||||
DEVMODE1 dm = new DEVMODE1();
|
||||
dm.dmDeviceName = new String(new char[32]);
|
||||
dm.dmFormName = new String(new char[32]);
|
||||
dm.dmSize = (short)Marshal.SizeOf(dm);
|
||||
return dm;
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
Add-Type $pinvokeCode -ErrorAction SilentlyContinue
|
||||
[Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height)
|
||||
}
|
36
third_party/webrender/ci-scripts/windows-tests.cmd
vendored
Executable file
36
third_party/webrender/ci-scripts/windows-tests.cmd
vendored
Executable file
|
@ -0,0 +1,36 @@
|
|||
:: 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 must be run from the root webrender directory!
|
||||
:: Users may set the CARGOFLAGS environment variable to pass
|
||||
:: additional flags to cargo if desired.
|
||||
|
||||
if NOT DEFINED CARGOFLAGS SET CARGOFLAGS=--verbose
|
||||
|
||||
pushd webrender_api
|
||||
cargo test %CARGOFLAGS%
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
||||
pushd webrender
|
||||
cargo test %CARGOFLAGS%
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
||||
pushd wrench
|
||||
cargo test --verbose
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
cargo run --release -- --angle reftest
|
||||
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||
popd
|
||||
|
||||
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
Normal file
6
third_party/webrender/debugger/.babelrc
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"presets": [
|
||||
["env", { "modules": false }],
|
||||
"stage-3"
|
||||
]
|
||||
}
|
11
third_party/webrender/debugger/.gitignore
vendored
Normal file
11
third_party/webrender/debugger/.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
.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
Normal file
23
third_party/webrender/debugger/README.md
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# 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
Normal file
13
third_party/webrender/debugger/dist/build.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
third_party/webrender/debugger/dist/build.js.map
vendored
Normal file
1
third_party/webrender/debugger/dist/build.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11
third_party/webrender/debugger/index.html
vendored
Normal file
11
third_party/webrender/debugger/index.html
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!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
Normal file
7606
third_party/webrender/debugger/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
36
third_party/webrender/debugger/package.json
vendored
Normal file
36
third_party/webrender/debugger/package.json
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"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
Normal file
55
third_party/webrender/debugger/src/App.vue
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
<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>
|
37
third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<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>
|
37
third_party/webrender/debugger/src/components/DocumentViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/DocumentViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<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>
|
41
third_party/webrender/debugger/src/components/NavBar.vue
vendored
Normal file
41
third_party/webrender/debugger/src/components/NavBar.vue
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<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>
|
33
third_party/webrender/debugger/src/components/NavMenu.vue
vendored
Normal file
33
third_party/webrender/debugger/src/components/NavMenu.vue
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<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>
|
162
third_party/webrender/debugger/src/components/OptionsPage.vue
vendored
Normal file
162
third_party/webrender/debugger/src/components/OptionsPage.vue
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
<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>
|
37
third_party/webrender/debugger/src/components/PassViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/PassViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<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>
|
37
third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<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>
|
32
third_party/webrender/debugger/src/components/ScreenshotPage.vue
vendored
Normal file
32
third_party/webrender/debugger/src/components/ScreenshotPage.vue
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<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>
|
40
third_party/webrender/debugger/src/components/TreeView.vue
vendored
Normal file
40
third_party/webrender/debugger/src/components/TreeView.vue
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
<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
Normal file
14
third_party/webrender/debugger/src/main.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
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
Normal file
105
third_party/webrender/debugger/src/store/index.js
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
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
Normal file
81
third_party/webrender/debugger/webpack.config.js
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
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
|
||||
})
|
||||
])
|
||||
}
|
14
third_party/webrender/direct-composition/Cargo.toml
vendored
Normal file
14
third_party/webrender/direct-composition/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
[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
Normal file
112
third_party/webrender/direct-composition/src/com.rs
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* 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
Normal file
174
third_party/webrender/direct-composition/src/egl.rs
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
/* 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
Normal file
179
third_party/webrender/direct-composition/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* 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)]
|
||||
|
||||
extern crate gleam;
|
||||
extern crate mozangle;
|
||||
extern crate 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()
|
||||
}
|
||||
}
|
||||
}
|
11
third_party/webrender/direct-composition/src/main.rs
vendored
Normal file
11
third_party/webrender/direct-composition/src/main.rs
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* 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(not(windows))]
|
||||
fn main() {
|
||||
println!("This demo only runs on Windows.");
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
include!("main_windows.rs");
|
212
third_party/webrender/direct-composition/src/main_windows.rs
vendored
Normal file
212
third_party/webrender/direct-composition/src/main_windows.rs
vendored
Normal file
|
@ -0,0 +1,212 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate direct_composition;
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate webrender;
|
||||
extern crate 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();
|
||||
}
|
||||
}
|
9
third_party/webrender/example-compositor/compositor-windows/Cargo.toml
vendored
Normal file
9
third_party/webrender/example-compositor/compositor-windows/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "compositor-windows"
|
||||
version = "0.1.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
edition = "2018"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
25
third_party/webrender/example-compositor/compositor-windows/build.rs
vendored
Normal file
25
third_party/webrender/example-compositor/compositor-windows/build.rs
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* 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/. */
|
||||
|
||||
fn main() {
|
||||
// HACK - This build script relies on Gecko having been built, so that the ANGLE libraries
|
||||
// have already been compiled. It also assumes they are being built with an in-tree
|
||||
// x86_64 object directory.
|
||||
|
||||
cc::Build::new()
|
||||
.file("src/lib.cpp")
|
||||
.include("../../../angle/checkout/include")
|
||||
.compile("windows");
|
||||
|
||||
// Set up linker paths for ANGLE that is built by Gecko
|
||||
println!("cargo:rustc-link-search=../../obj-x86_64-pc-mingw32/gfx/angle/targets/libEGL");
|
||||
println!("cargo:rustc-link-search=../../obj-x86_64-pc-mingw32/gfx/angle/targets/libGLESv2");
|
||||
|
||||
// Link to libEGL and libGLESv2 (ANGLE) and D3D11 + DirectComposition
|
||||
println!("cargo:rustc-link-lib=libEGL");
|
||||
println!("cargo:rustc-link-lib=libGLESv2");
|
||||
println!("cargo:rustc-link-lib=dcomp");
|
||||
println!("cargo:rustc-link-lib=d3d11");
|
||||
println!("cargo:rustc-link-lib=dwmapi");
|
||||
}
|
802
third_party/webrender/example-compositor/compositor-windows/src/lib.cpp
vendored
Normal file
802
third_party/webrender/example-compositor/compositor-windows/src/lib.cpp
vendored
Normal file
|
@ -0,0 +1,802 @@
|
|||
/* 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 <windows.h>
|
||||
#include <math.h>
|
||||
#include <dcomp.h>
|
||||
#include <d3d11.h>
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <dwmapi.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#define EGL_EGL_PROTOTYPES 1
|
||||
#define EGL_EGLEXT_PROTOTYPES 1
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
#include "EGL/eglext_angle.h"
|
||||
#include "GL/gl.h"
|
||||
#include "GLES/gl.h"
|
||||
#include "GLES/glext.h"
|
||||
#include "GLES3/gl3.h"
|
||||
|
||||
#define NUM_QUERIES 2
|
||||
|
||||
#define USE_VIRTUAL_SURFACES
|
||||
#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 {
|
||||
#ifndef USE_VIRTUAL_SURFACES
|
||||
// Represents the underlying DirectComposition surface texture that gets drawn into.
|
||||
IDCompositionSurface *pSurface;
|
||||
// Represents the node in the visual tree that defines the properties of this tile (clip, position etc).
|
||||
IDCompositionVisual2 *pVisual;
|
||||
#endif
|
||||
};
|
||||
|
||||
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 {
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
bool is_opaque;
|
||||
std::unordered_map<TileKey, Tile, TileKeyHasher> tiles;
|
||||
IDCompositionVisual2 *pVisual;
|
||||
#ifdef USE_VIRTUAL_SURFACES
|
||||
IDCompositionVirtualSurface *pVirtualSurface;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct CachedFrameBuffer {
|
||||
int width;
|
||||
int height;
|
||||
GLuint fboId;
|
||||
GLuint depthRboId;
|
||||
};
|
||||
|
||||
struct Window {
|
||||
// Win32 window details
|
||||
HWND hWnd;
|
||||
HINSTANCE hInstance;
|
||||
bool enable_compositor;
|
||||
RECT client_rect;
|
||||
SyncMode sync_mode;
|
||||
|
||||
// Main interfaces to D3D11 and DirectComposition
|
||||
ID3D11Device *pD3D11Device;
|
||||
IDCompositionDesktopDevice *pDCompDevice;
|
||||
IDCompositionTarget *pDCompTarget;
|
||||
IDXGIDevice *pDXGIDevice;
|
||||
ID3D11Query *pQueries[NUM_QUERIES];
|
||||
int current_query;
|
||||
|
||||
// ANGLE interfaces that wrap the D3D device
|
||||
EGLDeviceEXT EGLDevice;
|
||||
EGLDisplay EGLDisplay;
|
||||
EGLContext EGLContext;
|
||||
EGLConfig config;
|
||||
// Framebuffer surface for debug mode when we are not using DC
|
||||
EGLSurface fb_surface;
|
||||
|
||||
// The currently bound surface, valid during bind() and unbind()
|
||||
IDCompositionSurface *pCurrentSurface;
|
||||
EGLImage mEGLImage;
|
||||
GLuint mColorRBO;
|
||||
|
||||
// The root of the DC visual tree. Nothing is drawn on this, but
|
||||
// all child tiles are parented to here.
|
||||
IDCompositionVisual2 *pRoot;
|
||||
IDCompositionVisualDebug *pVisualDebug;
|
||||
std::vector<CachedFrameBuffer> mFrameBuffers;
|
||||
|
||||
// Maintain list of layer state between frames to avoid visual tree rebuild.
|
||||
std::vector<uint64_t> mCurrentLayers;
|
||||
std::vector<uint64_t> mPrevLayers;
|
||||
|
||||
// Maps WR surface IDs to each OS surface
|
||||
std::unordered_map<uint64_t, Surface> surfaces;
|
||||
};
|
||||
|
||||
static const wchar_t *CLASS_NAME = L"WR DirectComposite";
|
||||
|
||||
static GLuint GetOrCreateFbo(Window *window, int aWidth, int aHeight) {
|
||||
GLuint fboId = 0;
|
||||
|
||||
// Check if we have a cached FBO with matching dimensions
|
||||
for (auto it = window->mFrameBuffers.begin(); it != window->mFrameBuffers.end(); ++it) {
|
||||
if (it->width == aWidth && it->height == aHeight) {
|
||||
fboId = it->fboId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not, create a new FBO with attached depth buffer
|
||||
if (fboId == 0) {
|
||||
// Create the depth buffer
|
||||
GLuint depthRboId;
|
||||
glGenRenderbuffers(1, &depthRboId);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthRboId);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
|
||||
aWidth, aHeight);
|
||||
|
||||
// Create the framebuffer and attach the depth buffer to it
|
||||
glGenFramebuffers(1, &fboId);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, depthRboId);
|
||||
|
||||
// Store this in the cache for future calls.
|
||||
CachedFrameBuffer frame_buffer_info;
|
||||
frame_buffer_info.width = aWidth;
|
||||
frame_buffer_info.height = aHeight;
|
||||
frame_buffer_info.fboId = fboId;
|
||||
frame_buffer_info.depthRboId = depthRboId;
|
||||
window->mFrameBuffers.push_back(frame_buffer_info);
|
||||
}
|
||||
|
||||
return fboId;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
) {
|
||||
switch (message) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
Window *com_dc_create_window(int width, int height, bool enable_compositor, SyncMode sync_mode) {
|
||||
// Create a simple Win32 window
|
||||
Window *window = new Window;
|
||||
window->hInstance = GetModuleHandle(NULL);
|
||||
window->enable_compositor = enable_compositor;
|
||||
window->mEGLImage = EGL_NO_IMAGE;
|
||||
window->sync_mode = sync_mode;
|
||||
|
||||
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = window->hInstance;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);;
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.lpszClassName = CLASS_NAME;
|
||||
RegisterClassEx(&wcex);
|
||||
|
||||
int dpiX = 0;
|
||||
int dpiY = 0;
|
||||
HDC hdc = GetDC(NULL);
|
||||
if (hdc) {
|
||||
dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
ReleaseDC(NULL, hdc);
|
||||
}
|
||||
|
||||
RECT window_rect = { 0, 0, width, height };
|
||||
AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
UINT window_width = static_cast<UINT>(ceil(float(window_rect.right - window_rect.left) * dpiX / 96.f));
|
||||
UINT window_height = static_cast<UINT>(ceil(float(window_rect.bottom - window_rect.top) * dpiY / 96.f));
|
||||
|
||||
LPCWSTR name;
|
||||
DWORD style;
|
||||
if (enable_compositor) {
|
||||
name = L"example-compositor (DirectComposition)";
|
||||
style = WS_EX_NOREDIRECTIONBITMAP;
|
||||
} else {
|
||||
name = L"example-compositor (Simple)";
|
||||
style = 0;
|
||||
}
|
||||
|
||||
window->hWnd = CreateWindowEx(
|
||||
style,
|
||||
CLASS_NAME,
|
||||
name,
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
window_width,
|
||||
window_height,
|
||||
NULL,
|
||||
NULL,
|
||||
window->hInstance,
|
||||
NULL
|
||||
);
|
||||
|
||||
ShowWindow(window->hWnd, SW_SHOWNORMAL);
|
||||
UpdateWindow(window->hWnd);
|
||||
GetClientRect(window->hWnd, &window->client_rect);
|
||||
|
||||
// Create a D3D11 device
|
||||
D3D_FEATURE_LEVEL featureLevelSupported;
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
||||
NULL,
|
||||
0,
|
||||
D3D11_SDK_VERSION,
|
||||
&window->pD3D11Device,
|
||||
&featureLevelSupported,
|
||||
nullptr
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
memset(&query_desc, 0, sizeof(query_desc));
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
for (int i=0 ; i < NUM_QUERIES ; ++i) {
|
||||
hr = window->pD3D11Device->CreateQuery(&query_desc, &window->pQueries[i]);
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
window->current_query = 0;
|
||||
|
||||
hr = window->pD3D11Device->QueryInterface(&window->pDXGIDevice);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Create a DirectComposition device
|
||||
hr = DCompositionCreateDevice2(
|
||||
window->pDXGIDevice,
|
||||
__uuidof(IDCompositionDesktopDevice),
|
||||
(void **) &window->pDCompDevice
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Create a DirectComposition target for a Win32 window handle
|
||||
hr = window->pDCompDevice->CreateTargetForHwnd(
|
||||
window->hWnd,
|
||||
TRUE,
|
||||
&window->pDCompTarget
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Create an ANGLE EGL device that wraps D3D11
|
||||
window->EGLDevice = eglCreateDeviceANGLE(
|
||||
EGL_D3D11_DEVICE_ANGLE,
|
||||
window->pD3D11Device,
|
||||
nullptr
|
||||
);
|
||||
|
||||
EGLint display_attribs[] = {
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
window->EGLDisplay = eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_DEVICE_EXT,
|
||||
window->EGLDevice,
|
||||
display_attribs
|
||||
);
|
||||
|
||||
eglInitialize(
|
||||
window->EGLDisplay,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
|
||||
EGLint num_configs = 0;
|
||||
EGLint cfg_attribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_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];
|
||||
|
||||
if (window->enable_compositor) {
|
||||
window->fb_surface = EGL_NO_SURFACE;
|
||||
} else {
|
||||
window->fb_surface = eglCreateWindowSurface(
|
||||
window->EGLDisplay,
|
||||
window->config,
|
||||
window->hWnd,
|
||||
NULL
|
||||
);
|
||||
assert(window->fb_surface != EGL_NO_SURFACE);
|
||||
}
|
||||
|
||||
EGLint ctx_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// Create an EGL context that can be used for drawing
|
||||
window->EGLContext = eglCreateContext(
|
||||
window->EGLDisplay,
|
||||
window->config,
|
||||
EGL_NO_CONTEXT,
|
||||
ctx_attribs
|
||||
);
|
||||
|
||||
// Create the root of the DirectComposition visual tree
|
||||
hr = window->pDCompDevice->CreateVisual(&window->pRoot);
|
||||
assert(SUCCEEDED(hr));
|
||||
hr = window->pDCompTarget->SetRoot(window->pRoot);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
hr = window->pRoot->QueryInterface(
|
||||
__uuidof(IDCompositionVisualDebug),
|
||||
(void **) &window->pVisualDebug
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Uncomment this to see redraw regions during composite
|
||||
// window->pVisualDebug->EnableRedrawRegions();
|
||||
|
||||
EGLBoolean ok = eglMakeCurrent(
|
||||
window->EGLDisplay,
|
||||
window->fb_surface,
|
||||
window->fb_surface,
|
||||
window->EGLContext
|
||||
);
|
||||
assert(ok);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void com_dc_destroy_window(Window *window) {
|
||||
for (auto surface_it=window->surfaces.begin() ; surface_it != window->surfaces.end() ; ++surface_it) {
|
||||
Surface &surface = surface_it->second;
|
||||
|
||||
#ifndef USE_VIRTUAL_SURFACES
|
||||
for (auto tile_it=surface.tiles.begin() ; tile_it != surface.tiles.end() ; ++tile_it) {
|
||||
tile_it->second.pSurface->Release();
|
||||
tile_it->second.pVisual->Release();
|
||||
}
|
||||
#endif
|
||||
|
||||
surface.pVisual->Release();
|
||||
}
|
||||
|
||||
if (window->fb_surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(window->EGLDisplay, window->fb_surface);
|
||||
}
|
||||
eglDestroyContext(window->EGLDisplay, window->EGLContext);
|
||||
eglTerminate(window->EGLDisplay);
|
||||
eglReleaseDeviceANGLE(window->EGLDevice);
|
||||
|
||||
for (int i=0 ; i < NUM_QUERIES ; ++i) {
|
||||
window->pQueries[i]->Release();
|
||||
}
|
||||
window->pRoot->Release();
|
||||
window->pVisualDebug->Release();
|
||||
window->pD3D11Device->Release();
|
||||
window->pDXGIDevice->Release();
|
||||
window->pDCompDevice->Release();
|
||||
window->pDCompTarget->Release();
|
||||
|
||||
CloseWindow(window->hWnd);
|
||||
UnregisterClass(CLASS_NAME, window->hInstance);
|
||||
|
||||
delete window;
|
||||
}
|
||||
|
||||
bool com_dc_tick(Window *) {
|
||||
// Check and dispatch the windows event loop
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void com_dc_swap_buffers(Window *window) {
|
||||
// If not using DC mode, then do a normal EGL swap buffers.
|
||||
if (window->fb_surface != EGL_NO_SURFACE) {
|
||||
switch (window->sync_mode) {
|
||||
case SyncMode::None:
|
||||
eglSwapInterval(window->EGLDisplay, 0);
|
||||
break;
|
||||
case SyncMode::Swap:
|
||||
eglSwapInterval(window->EGLDisplay, 1);
|
||||
break;
|
||||
default:
|
||||
assert(false); // unexpected vsync mode for simple compositor.
|
||||
break;
|
||||
}
|
||||
|
||||
eglSwapBuffers(window->EGLDisplay, window->fb_surface);
|
||||
} else {
|
||||
switch (window->sync_mode) {
|
||||
case SyncMode::None:
|
||||
break;
|
||||
case SyncMode::Commit:
|
||||
window->pDCompDevice->WaitForCommitCompletion();
|
||||
break;
|
||||
case SyncMode::Flush:
|
||||
DwmFlush();
|
||||
break;
|
||||
case SyncMode::Query:
|
||||
// todo!!!!
|
||||
break;
|
||||
default:
|
||||
assert(false); // unexpected vsync mode for native compositor
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new DC surface
|
||||
void com_dc_create_surface(
|
||||
Window *window,
|
||||
uint64_t id,
|
||||
int tile_width,
|
||||
int tile_height,
|
||||
bool is_opaque
|
||||
) {
|
||||
assert(window->surfaces.count(id) == 0);
|
||||
|
||||
Surface surface;
|
||||
surface.tile_width = tile_width;
|
||||
surface.tile_height = tile_height;
|
||||
surface.is_opaque = is_opaque;
|
||||
|
||||
// Create the visual node in the DC tree that stores properties
|
||||
HRESULT hr = window->pDCompDevice->CreateVisual(&surface.pVisual);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
#ifdef USE_VIRTUAL_SURFACES
|
||||
DXGI_ALPHA_MODE alpha_mode = surface.is_opaque ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||
|
||||
hr = window->pDCompDevice->CreateVirtualSurface(
|
||||
VIRTUAL_OFFSET * 2,
|
||||
VIRTUAL_OFFSET * 2,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
alpha_mode,
|
||||
&surface.pVirtualSurface
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Bind the surface memory to this visual
|
||||
hr = surface.pVisual->SetContent(surface.pVirtualSurface);
|
||||
assert(SUCCEEDED(hr));
|
||||
#endif
|
||||
|
||||
window->surfaces[id] = surface;
|
||||
}
|
||||
|
||||
void com_dc_create_tile(
|
||||
Window *window,
|
||||
uint64_t id,
|
||||
int x,
|
||||
int y
|
||||
) {
|
||||
assert(window->surfaces.count(id) == 1);
|
||||
Surface &surface = window->surfaces[id];
|
||||
|
||||
TileKey key(x, y);
|
||||
assert(surface.tiles.count(key) == 0);
|
||||
|
||||
Tile tile;
|
||||
|
||||
#ifndef USE_VIRTUAL_SURFACES
|
||||
// Create the video memory surface.
|
||||
DXGI_ALPHA_MODE alpha_mode = surface.is_opaque ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||
HRESULT hr = window->pDCompDevice->CreateSurface(
|
||||
surface.tile_width,
|
||||
surface.tile_height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
alpha_mode,
|
||||
&tile.pSurface
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Create the visual node in the DC tree that stores properties
|
||||
hr = window->pDCompDevice->CreateVisual(&tile.pVisual);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Bind the surface memory to this visual
|
||||
hr = tile.pVisual->SetContent(tile.pSurface);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
// Place the visual in local-space of this surface
|
||||
float offset_x = (float) (x * surface.tile_width);
|
||||
float offset_y = (float) (y * surface.tile_height);
|
||||
tile.pVisual->SetOffsetX(offset_x);
|
||||
tile.pVisual->SetOffsetY(offset_y);
|
||||
|
||||
surface.pVisual->AddVisual(
|
||||
tile.pVisual,
|
||||
FALSE,
|
||||
NULL
|
||||
);
|
||||
#endif
|
||||
|
||||
surface.tiles[key] = tile;
|
||||
}
|
||||
|
||||
void com_dc_destroy_tile(
|
||||
Window *window,
|
||||
uint64_t id,
|
||||
int x,
|
||||
int y
|
||||
) {
|
||||
assert(window->surfaces.count(id) == 1);
|
||||
Surface &surface = window->surfaces[id];
|
||||
|
||||
TileKey key(x, y);
|
||||
assert(surface.tiles.count(key) == 1);
|
||||
Tile &tile = surface.tiles[key];
|
||||
|
||||
#ifndef USE_VIRTUAL_SURFACES
|
||||
surface.pVisual->RemoveVisual(tile.pVisual);
|
||||
|
||||
tile.pVisual->Release();
|
||||
tile.pSurface->Release();
|
||||
#endif
|
||||
|
||||
surface.tiles.erase(key);
|
||||
}
|
||||
|
||||
void com_dc_destroy_surface(
|
||||
Window *window,
|
||||
uint64_t id
|
||||
) {
|
||||
assert(window->surfaces.count(id) == 1);
|
||||
Surface &surface = window->surfaces[id];
|
||||
|
||||
window->pRoot->RemoveVisual(surface.pVisual);
|
||||
|
||||
#ifdef USE_VIRTUAL_SURFACES
|
||||
surface.pVirtualSurface->Release();
|
||||
#else
|
||||
// Release the video memory and visual in the tree
|
||||
for (auto tile_it=surface.tiles.begin() ; tile_it != surface.tiles.end() ; ++tile_it) {
|
||||
tile_it->second.pSurface->Release();
|
||||
tile_it->second.pVisual->Release();
|
||||
}
|
||||
#endif
|
||||
|
||||
surface.pVisual->Release();
|
||||
window->surfaces.erase(id);
|
||||
}
|
||||
|
||||
// Bind a DC surface to allow issuing GL commands to it
|
||||
GLuint com_dc_bind_surface(
|
||||
Window *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
|
||||
) {
|
||||
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];
|
||||
|
||||
// Inform DC that we want to draw on this surface. DC uses texture
|
||||
// atlases when the tiles are small. It returns an offset where the
|
||||
// client code must draw into this surface when this happens.
|
||||
RECT update_rect;
|
||||
update_rect.left = dirty_x0;
|
||||
update_rect.top = dirty_y0;
|
||||
update_rect.right = dirty_x0 + dirty_width;
|
||||
update_rect.bottom = dirty_y0 + dirty_height;
|
||||
POINT offset;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ID3D11Texture2D *pTexture;
|
||||
HRESULT hr;
|
||||
|
||||
// Store the current surface for unbinding later
|
||||
#ifdef USE_VIRTUAL_SURFACES
|
||||
LONG tile_offset_x = VIRTUAL_OFFSET + tile_x * surface.tile_width;
|
||||
LONG tile_offset_y = VIRTUAL_OFFSET + tile_y * surface.tile_height;
|
||||
|
||||
update_rect.left += tile_offset_x;
|
||||
update_rect.top += tile_offset_y;
|
||||
update_rect.right += tile_offset_x;
|
||||
update_rect.bottom += tile_offset_y;
|
||||
|
||||
hr = surface.pVirtualSurface->BeginDraw(
|
||||
&update_rect,
|
||||
__uuidof(ID3D11Texture2D),
|
||||
(void **) &pTexture,
|
||||
&offset
|
||||
);
|
||||
window->pCurrentSurface = surface.pVirtualSurface;
|
||||
#else
|
||||
hr = tile.pSurface->BeginDraw(
|
||||
&update_rect,
|
||||
__uuidof(ID3D11Texture2D),
|
||||
(void **) &pTexture,
|
||||
&offset
|
||||
);
|
||||
window->pCurrentSurface = tile.pSurface;
|
||||
#endif
|
||||
|
||||
// DC includes the origin of the dirty / update rect in the draw offset,
|
||||
// undo that here since WR expects it to be an absolute offset.
|
||||
assert(SUCCEEDED(hr));
|
||||
offset.x -= dirty_x0;
|
||||
offset.y -= dirty_y0;
|
||||
pTexture->GetDesc(&desc);
|
||||
*x_offset = offset.x;
|
||||
*y_offset = offset.y;
|
||||
|
||||
// Construct an EGLImage wrapper around the D3D texture for ANGLE.
|
||||
const EGLAttrib attribs[] = { EGL_NONE };
|
||||
window->mEGLImage = eglCreateImage(
|
||||
window->EGLDisplay,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_D3D11_TEXTURE_ANGLE,
|
||||
static_cast<EGLClientBuffer>(pTexture),
|
||||
attribs
|
||||
);
|
||||
|
||||
// Get the current FBO and RBO id, so we can restore them later
|
||||
GLint currentFboId, currentRboId;
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFboId);
|
||||
glGetIntegerv(GL_RENDERBUFFER_BINDING, ¤tRboId);
|
||||
|
||||
// Create a render buffer object that is backed by the EGL image.
|
||||
glGenRenderbuffers(1, &window->mColorRBO);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, window->mColorRBO);
|
||||
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, window->mEGLImage);
|
||||
|
||||
// Get or create an FBO for the specified dimensions
|
||||
GLuint fboId = GetOrCreateFbo(window, desc.Width, desc.Height);
|
||||
|
||||
// Attach the new renderbuffer to the FBO
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_RENDERBUFFER,
|
||||
window->mColorRBO);
|
||||
|
||||
// Restore previous FBO and RBO bindings
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFboId);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, currentRboId);
|
||||
|
||||
return fboId;
|
||||
}
|
||||
|
||||
// Unbind a currently bound DC surface
|
||||
void com_dc_unbind_surface(Window *window) {
|
||||
HRESULT hr = window->pCurrentSurface->EndDraw();
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
glDeleteRenderbuffers(1, &window->mColorRBO);
|
||||
window->mColorRBO = 0;
|
||||
|
||||
eglDestroyImage(window->EGLDisplay, window->mEGLImage);
|
||||
window->mEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
|
||||
void com_dc_begin_transaction(Window *) {
|
||||
}
|
||||
|
||||
// Add a DC surface to the visual tree. Called per-frame to build the composition.
|
||||
void com_dc_add_surface(
|
||||
Window *window,
|
||||
uint64_t id,
|
||||
int x,
|
||||
int y,
|
||||
int clip_x,
|
||||
int clip_y,
|
||||
int clip_w,
|
||||
int clip_h
|
||||
) {
|
||||
Surface surface = window->surfaces[id];
|
||||
window->mCurrentLayers.push_back(id);
|
||||
|
||||
// Place the visual - this changes frame to frame based on scroll position
|
||||
// of the slice.
|
||||
float offset_x = (float) (x + window->client_rect.left);
|
||||
float offset_y = (float) (y + window->client_rect.top);
|
||||
#ifdef USE_VIRTUAL_SURFACES
|
||||
offset_x -= VIRTUAL_OFFSET;
|
||||
offset_y -= VIRTUAL_OFFSET;
|
||||
#endif
|
||||
surface.pVisual->SetOffsetX(offset_x);
|
||||
surface.pVisual->SetOffsetY(offset_y);
|
||||
|
||||
// Set the clip rect - converting from world space to the pre-offset space
|
||||
// that DC requires for rectangle clips.
|
||||
D2D_RECT_F clip_rect;
|
||||
clip_rect.left = clip_x - offset_x;
|
||||
clip_rect.top = clip_y - offset_y;
|
||||
clip_rect.right = clip_rect.left + clip_w;
|
||||
clip_rect.bottom = clip_rect.top + clip_h;
|
||||
surface.pVisual->SetClip(clip_rect);
|
||||
}
|
||||
|
||||
// Finish the composition transaction, telling DC to composite
|
||||
void com_dc_end_transaction(Window *window) {
|
||||
bool same = window->mPrevLayers == window->mCurrentLayers;
|
||||
|
||||
if (!same) {
|
||||
HRESULT hr = window->pRoot->RemoveAllVisuals();
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
for (auto it = window->mCurrentLayers.begin(); it != window->mCurrentLayers.end(); ++it) {
|
||||
Surface &surface = window->surfaces[*it];
|
||||
|
||||
// Add this visual as the last element in the visual tree (z-order is implicit,
|
||||
// based on the order tiles are added).
|
||||
hr = window->pRoot->AddVisual(
|
||||
surface.pVisual,
|
||||
FALSE,
|
||||
NULL
|
||||
);
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
}
|
||||
|
||||
window->mPrevLayers.swap(window->mCurrentLayers);
|
||||
window->mCurrentLayers.clear();
|
||||
|
||||
HRESULT hr = window->pDCompDevice->Commit();
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
// Get a pointer to an EGL symbol
|
||||
void *com_dc_get_proc_address(const char *name) {
|
||||
return eglGetProcAddress(name);
|
||||
}
|
||||
}
|
261
third_party/webrender/example-compositor/compositor-windows/src/lib.rs
vendored
Normal file
261
third_party/webrender/example-compositor/compositor-windows/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
/* 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 DirectComposite / D3D11 / ANGLE
|
||||
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_dc_create_window(
|
||||
width: i32,
|
||||
height: i32,
|
||||
enable_compositor: bool,
|
||||
sync_mode: i32,
|
||||
) -> *mut Window;
|
||||
fn com_dc_destroy_window(window: *mut Window);
|
||||
fn com_dc_tick(window: *mut Window) -> bool;
|
||||
fn com_dc_get_proc_address(name: *const c_char) -> *const c_void;
|
||||
fn com_dc_swap_buffers(window: *mut Window);
|
||||
|
||||
fn com_dc_create_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
tile_width: i32,
|
||||
tile_height: i32,
|
||||
is_opaque: bool,
|
||||
);
|
||||
|
||||
fn com_dc_create_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
);
|
||||
|
||||
fn com_dc_destroy_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
);
|
||||
|
||||
fn com_dc_destroy_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
);
|
||||
|
||||
fn com_dc_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_dc_unbind_surface(window: *mut Window);
|
||||
|
||||
fn com_dc_begin_transaction(window: *mut Window);
|
||||
|
||||
fn com_dc_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_dc_end_transaction(window: *mut Window);
|
||||
}
|
||||
|
||||
pub fn create_window(
|
||||
width: i32,
|
||||
height: i32,
|
||||
enable_compositor: bool,
|
||||
sync_mode: i32,
|
||||
) -> *mut Window {
|
||||
unsafe {
|
||||
com_dc_create_window(width, height, enable_compositor, sync_mode)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_window(window: *mut Window) {
|
||||
unsafe {
|
||||
com_dc_destroy_window(window);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(window: *mut Window) -> bool {
|
||||
unsafe {
|
||||
com_dc_tick(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_proc_address(name: *const c_char) -> *const c_void {
|
||||
unsafe {
|
||||
com_dc_get_proc_address(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
tile_width: i32,
|
||||
tile_height: i32,
|
||||
is_opaque: bool,
|
||||
) {
|
||||
unsafe {
|
||||
com_dc_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_dc_create_tile(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_tile(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) {
|
||||
unsafe {
|
||||
com_dc_destroy_tile(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy_surface(
|
||||
window: *mut Window,
|
||||
id: u64,
|
||||
) {
|
||||
unsafe {
|
||||
com_dc_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_dc_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_dc_add_surface(
|
||||
window,
|
||||
id,
|
||||
x,
|
||||
y,
|
||||
clip_x,
|
||||
clip_y,
|
||||
clip_w,
|
||||
clip_h,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_transaction(window: *mut Window) {
|
||||
unsafe {
|
||||
com_dc_begin_transaction(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unbind_surface(window: *mut Window) {
|
||||
unsafe {
|
||||
com_dc_unbind_surface(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_transaction(window: *mut Window) {
|
||||
unsafe {
|
||||
com_dc_end_transaction(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn swap_buffers(window: *mut Window) {
|
||||
unsafe {
|
||||
com_dc_swap_buffers(window);
|
||||
}
|
||||
}
|
13
third_party/webrender/example-compositor/compositor/Cargo.toml
vendored
Normal file
13
third_party/webrender/example-compositor/compositor/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "compositor"
|
||||
version = "0.1.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
edition = "2018"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
webrender = { path = "../../webrender" }
|
||||
gleam = "0.12.0"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
compositor-windows = { path = "../compositor-windows" }
|
484
third_party/webrender/example-compositor/compositor/src/main.rs
vendored
Normal file
484
third_party/webrender/example-compositor/compositor/src/main.rs
vendored
Normal file
|
@ -0,0 +1,484 @@
|
|||
/* 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/. */
|
||||
|
||||
/*
|
||||
|
||||
An example of how to implement the Compositor trait that
|
||||
allows picture caching surfaces to be composited by the operating
|
||||
system.
|
||||
|
||||
The current example supports DirectComposite on Windows only.
|
||||
|
||||
*/
|
||||
|
||||
use euclid::Angle;
|
||||
use gleam::gl;
|
||||
use std::ffi::CString;
|
||||
use std::sync::mpsc;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
#[cfg(target_os = "windows")]
|
||||
use compositor_windows as compositor;
|
||||
use std::{env, f32, process};
|
||||
|
||||
// A very hacky integration with DirectComposite. It proxies calls from the compositor
|
||||
// interface to a simple C99 library which does the DirectComposition / D3D11 / ANGLE
|
||||
// interfacing. This is a very unsafe impl due to the way the window pointer is passed
|
||||
// around!
|
||||
struct DirectCompositeInterface {
|
||||
window: *mut compositor::Window,
|
||||
}
|
||||
|
||||
impl DirectCompositeInterface {
|
||||
fn new(window: *mut compositor::Window) -> Self {
|
||||
DirectCompositeInterface {
|
||||
window,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl webrender::Compositor for DirectCompositeInterface {
|
||||
fn create_surface(
|
||||
&mut self,
|
||||
id: webrender::NativeSurfaceId,
|
||||
tile_size: DeviceIntSize,
|
||||
is_opaque: bool,
|
||||
) {
|
||||
compositor::create_surface(
|
||||
self.window,
|
||||
id.0,
|
||||
tile_size.width,
|
||||
tile_size.height,
|
||||
is_opaque,
|
||||
);
|
||||
}
|
||||
|
||||
fn destroy_surface(
|
||||
&mut self,
|
||||
id: webrender::NativeSurfaceId,
|
||||
) {
|
||||
compositor::destroy_surface(self.window, id.0);
|
||||
}
|
||||
|
||||
fn create_tile(
|
||||
&mut self,
|
||||
id: webrender::NativeTileId,
|
||||
) {
|
||||
compositor::create_tile(
|
||||
self.window,
|
||||
id.surface_id.0,
|
||||
id.x,
|
||||
id.y,
|
||||
);
|
||||
}
|
||||
|
||||
fn destroy_tile(
|
||||
&mut self,
|
||||
id: webrender::NativeTileId,
|
||||
) {
|
||||
compositor::destroy_tile(
|
||||
self.window,
|
||||
id.surface_id.0,
|
||||
id.x,
|
||||
id.y,
|
||||
);
|
||||
}
|
||||
|
||||
fn bind(
|
||||
&mut self,
|
||||
id: webrender::NativeTileId,
|
||||
dirty_rect: DeviceIntRect,
|
||||
) -> webrender::NativeSurfaceInfo {
|
||||
let (fbo_id, x, y) = compositor::bind_surface(
|
||||
self.window,
|
||||
id.surface_id.0,
|
||||
id.x,
|
||||
id.y,
|
||||
dirty_rect.origin.x,
|
||||
dirty_rect.origin.y,
|
||||
dirty_rect.size.width,
|
||||
dirty_rect.size.height,
|
||||
);
|
||||
|
||||
webrender::NativeSurfaceInfo {
|
||||
origin: DeviceIntPoint::new(x, y),
|
||||
fbo_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn unbind(&mut self) {
|
||||
compositor::unbind_surface(self.window);
|
||||
}
|
||||
|
||||
fn begin_frame(&mut self) {
|
||||
compositor::begin_transaction(self.window);
|
||||
}
|
||||
|
||||
fn add_surface(
|
||||
&mut self,
|
||||
id: webrender::NativeSurfaceId,
|
||||
position: DeviceIntPoint,
|
||||
clip_rect: DeviceIntRect,
|
||||
) {
|
||||
compositor::add_surface(
|
||||
self.window,
|
||||
id.0,
|
||||
position.x,
|
||||
position.y,
|
||||
clip_rect.origin.x,
|
||||
clip_rect.origin.y,
|
||||
clip_rect.size.width,
|
||||
clip_rect.size.height,
|
||||
);
|
||||
}
|
||||
|
||||
fn end_frame(&mut self) {
|
||||
compositor::end_transaction(self.window);
|
||||
}
|
||||
}
|
||||
|
||||
// Simplisitic implementation of the WR notifier interface to know when a frame
|
||||
// has been prepared and can be rendered.
|
||||
struct Notifier {
|
||||
tx: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
impl Notifier {
|
||||
fn new(tx: mpsc::Sender<()>) -> Self {
|
||||
Notifier {
|
||||
tx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderNotifier for Notifier {
|
||||
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||
Box::new(Notifier {
|
||||
tx: self.tx.clone()
|
||||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
}
|
||||
|
||||
fn new_frame_ready(&self,
|
||||
_: DocumentId,
|
||||
_scrolled: bool,
|
||||
_composite_needed: bool,
|
||||
_render_time: Option<u64>) {
|
||||
self.tx.send(()).ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn push_rotated_rect(
|
||||
builder: &mut DisplayListBuilder,
|
||||
rect: LayoutRect,
|
||||
color: ColorF,
|
||||
spatial_id: SpatialId,
|
||||
root_pipeline_id: PipelineId,
|
||||
angle: f32,
|
||||
time: f32,
|
||||
) {
|
||||
let color = color.scale_rgb(time);
|
||||
let rotation = LayoutTransform::create_rotation(
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
Angle::radians(2.0 * std::f32::consts::PI * angle),
|
||||
);
|
||||
let transform_origin = LayoutVector3D::new(
|
||||
rect.origin.x + rect.size.width * 0.5,
|
||||
rect.origin.y + rect.size.height * 0.5,
|
||||
0.0,
|
||||
);
|
||||
let transform = rotation
|
||||
.pre_translate(-transform_origin)
|
||||
.post_translate(transform_origin);
|
||||
let spatial_id = builder.push_reference_frame(
|
||||
LayoutPoint::zero(),
|
||||
spatial_id,
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Value(transform),
|
||||
ReferenceFrameKind::Transform,
|
||||
);
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
rect,
|
||||
SpaceAndClipInfo {
|
||||
spatial_id,
|
||||
clip_id: ClipId::root(root_pipeline_id),
|
||||
},
|
||||
),
|
||||
rect,
|
||||
color,
|
||||
);
|
||||
}
|
||||
|
||||
fn build_display_list(
|
||||
builder: &mut DisplayListBuilder,
|
||||
scroll_id: ExternalScrollId,
|
||||
root_pipeline_id: PipelineId,
|
||||
layout_size: LayoutSize,
|
||||
time: f32,
|
||||
invalidations: Invalidations,
|
||||
) {
|
||||
let size_factor = match invalidations {
|
||||
Invalidations::Small => 0.1,
|
||||
Invalidations::Large | Invalidations::Scrolling => 1.0,
|
||||
};
|
||||
|
||||
let fixed_space_info = SpaceAndClipInfo {
|
||||
spatial_id: SpatialId::root_scroll_node(root_pipeline_id),
|
||||
clip_id: ClipId::root(root_pipeline_id),
|
||||
};
|
||||
|
||||
let scroll_space_info = builder.define_scroll_frame(
|
||||
&fixed_space_info,
|
||||
Some(scroll_id),
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||
ScrollSensitivity::Script,
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size).inflate(-10.0, -10.0),
|
||||
fixed_space_info,
|
||||
),
|
||||
LayoutRect::new(LayoutPoint::zero(), layout_size).inflate(-10.0, -10.0),
|
||||
ColorF::new(0.8, 0.8, 0.8, 1.0),
|
||||
);
|
||||
|
||||
push_rotated_rect(
|
||||
builder,
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(100.0, 100.0),
|
||||
LayoutSize::new(size_factor * 400.0, size_factor * 400.0),
|
||||
),
|
||||
ColorF::new(1.0, 0.0, 0.0, 1.0),
|
||||
scroll_space_info.spatial_id,
|
||||
root_pipeline_id,
|
||||
time,
|
||||
time,
|
||||
);
|
||||
|
||||
push_rotated_rect(
|
||||
builder,
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(800.0, 100.0),
|
||||
LayoutSize::new(size_factor * 100.0, size_factor * 600.0),
|
||||
),
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||
fixed_space_info.spatial_id,
|
||||
root_pipeline_id,
|
||||
0.2,
|
||||
time,
|
||||
);
|
||||
|
||||
push_rotated_rect(
|
||||
builder,
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(700.0, 200.0),
|
||||
LayoutSize::new(size_factor * 300.0, size_factor * 300.0),
|
||||
),
|
||||
ColorF::new(0.0, 0.0, 1.0, 1.0),
|
||||
scroll_space_info.spatial_id,
|
||||
root_pipeline_id,
|
||||
0.1,
|
||||
time,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum Invalidations {
|
||||
Large,
|
||||
Small,
|
||||
Scrolling,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum Sync {
|
||||
None = 0,
|
||||
Swap = 1,
|
||||
Commit = 2,
|
||||
Flush = 3,
|
||||
Query = 4,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
if args.len() != 6 {
|
||||
println!("USAGE: compositor [native|none] [small|large|scroll] [none|swap|commit|flush|query] width height");
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
let enable_compositor = match args[1].parse::<String>().unwrap().as_str() {
|
||||
"native" => true,
|
||||
"none" => false,
|
||||
_ => panic!("invalid compositor [native, none]"),
|
||||
};
|
||||
|
||||
let inv_mode = match args[2].parse::<String>().unwrap().as_str() {
|
||||
"small" => Invalidations::Small,
|
||||
"large" => Invalidations::Large,
|
||||
"scroll" => Invalidations::Scrolling,
|
||||
_ => panic!("invalid invalidations [small, large, scroll]"),
|
||||
};
|
||||
|
||||
let sync_mode = match args[3].parse::<String>().unwrap().as_str() {
|
||||
"none" => Sync::None,
|
||||
"swap" => Sync::Swap,
|
||||
"commit" => Sync::Commit,
|
||||
"flush" => Sync::Flush,
|
||||
"query" => Sync::Query,
|
||||
_ => panic!("invalid sync mode [none, swap, commit, flush, query]"),
|
||||
};
|
||||
|
||||
let width = args[4].parse().unwrap();
|
||||
let height = args[5].parse().unwrap();
|
||||
let device_size = DeviceIntSize::new(width, height);
|
||||
|
||||
// Load GL, construct WR and the native compositor interface.
|
||||
let window = compositor::create_window(
|
||||
device_size.width,
|
||||
device_size.height,
|
||||
enable_compositor,
|
||||
sync_mode as i32,
|
||||
);
|
||||
let debug_flags = DebugFlags::empty();
|
||||
let compositor_config = if enable_compositor {
|
||||
webrender::CompositorConfig::Native {
|
||||
max_update_rects: 1,
|
||||
compositor: Box::new(DirectCompositeInterface::new(window)),
|
||||
}
|
||||
} else {
|
||||
webrender::CompositorConfig::Draw {
|
||||
max_partial_present_rects: 0,
|
||||
}
|
||||
};
|
||||
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,
|
||||
..webrender::RendererOptions::default()
|
||||
};
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let notifier = Box::new(Notifier::new(tx));
|
||||
let gl = unsafe {
|
||||
gl::GlesFns::load_with(
|
||||
|symbol| {
|
||||
let symbol = CString::new(symbol).unwrap();
|
||||
let ptr = compositor::get_proc_address(symbol.as_ptr());
|
||||
ptr
|
||||
}
|
||||
)
|
||||
};
|
||||
let (mut renderer, sender) = webrender::Renderer::new(
|
||||
gl.clone(),
|
||||
notifier,
|
||||
opts,
|
||||
None,
|
||||
device_size,
|
||||
).unwrap();
|
||||
let api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
let device_pixel_ratio = 1.0;
|
||||
let mut current_epoch = Epoch(0);
|
||||
let root_pipeline_id = PipelineId(0, 0);
|
||||
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||
let mut time = 0.0;
|
||||
let scroll_id = ExternalScrollId(3, root_pipeline_id);
|
||||
|
||||
// Kick off first transaction which will mean we get a notify below to build the DL and render.
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_root_pipeline(root_pipeline_id);
|
||||
|
||||
if let Invalidations::Scrolling = inv_mode {
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||
|
||||
build_display_list(
|
||||
&mut root_builder,
|
||||
scroll_id,
|
||||
root_pipeline_id,
|
||||
layout_size,
|
||||
1.0,
|
||||
inv_mode,
|
||||
);
|
||||
|
||||
txn.set_display_list(
|
||||
current_epoch,
|
||||
None,
|
||||
layout_size,
|
||||
root_builder.finalize(),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
// Tick the compositor (in this sample, we don't block on UI events)
|
||||
while compositor::tick(window) {
|
||||
// If there is a new frame ready to draw
|
||||
if let Ok(..) = rx.try_recv() {
|
||||
// Update and render. This will invoke the native compositor interface implemented above
|
||||
// as required.
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
let _ = renderer.flush_pipeline_info();
|
||||
|
||||
// Construct a simple display list that can be drawn and composited by DC.
|
||||
let mut txn = Transaction::new();
|
||||
|
||||
match inv_mode {
|
||||
Invalidations::Small | Invalidations::Large => {
|
||||
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||
|
||||
build_display_list(
|
||||
&mut root_builder,
|
||||
scroll_id,
|
||||
root_pipeline_id,
|
||||
layout_size,
|
||||
time,
|
||||
inv_mode,
|
||||
);
|
||||
|
||||
txn.set_display_list(
|
||||
current_epoch,
|
||||
None,
|
||||
layout_size,
|
||||
root_builder.finalize(),
|
||||
true,
|
||||
);
|
||||
}
|
||||
Invalidations::Scrolling => {
|
||||
let d = 0.5 - 0.5 * (2.0 * f32::consts::PI * 5.0 * time).cos();
|
||||
txn.scroll_node_with_id(
|
||||
LayoutPoint::new(0.0, (d * 100.0).round()),
|
||||
scroll_id,
|
||||
ScrollClamping::NoClamping,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
current_epoch.0 += 1;
|
||||
time += 0.001;
|
||||
if time > 1.0 {
|
||||
time = 0.0;
|
||||
}
|
||||
|
||||
// This does nothing when native compositor is enabled
|
||||
compositor::swap_buffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
renderer.deinit();
|
||||
compositor::destroy_window(window);
|
||||
}
|
71
third_party/webrender/examples/Cargo.toml
vendored
Normal file
71
third_party/webrender/examples/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
[package]
|
||||
name = "webrender-examples"
|
||||
version = "0.1.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/webrender"
|
||||
edition = "2018"
|
||||
|
||||
[[bin]]
|
||||
name = "alpha_perf"
|
||||
path = "alpha_perf.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "animation"
|
||||
path = "animation.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "basic"
|
||||
path = "basic.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "blob"
|
||||
path = "blob.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "document"
|
||||
path = "document.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "frame_output"
|
||||
path = "frame_output.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "iframe"
|
||||
path = "iframe.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "image_resize"
|
||||
path = "image_resize.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "multiwindow"
|
||||
path = "multiwindow.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "scrolling"
|
||||
path = "scrolling.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "texture_cache_stress"
|
||||
path = "texture_cache_stress.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "yuv"
|
||||
path = "yuv.rs"
|
||||
|
||||
[features]
|
||||
debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||
|
||||
[dependencies]
|
||||
app_units = "0.7"
|
||||
env_logger = "0.5"
|
||||
euclid = "0.22"
|
||||
gleam = "0.12"
|
||||
glutin = "0.21"
|
||||
rayon = "1"
|
||||
webrender = { path = "../webrender" }
|
||||
winit = "0.19"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation = "0.7"
|
8
third_party/webrender/examples/README.md
vendored
Normal file
8
third_party/webrender/examples/README.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Examples
|
||||
|
||||
This directory contains a collection of examples which uses the WebRender API.
|
||||
|
||||
To run an example e.g. `basic`, try:
|
||||
```
|
||||
cargo run --bin basic
|
||||
```
|
93
third_party/webrender/examples/alpha_perf.rs
vendored
Normal file
93
third_party/webrender/examples/alpha_perf.rs
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use std::cmp;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::DeviceIntSize;
|
||||
|
||||
|
||||
struct App {
|
||||
rect_count: usize,
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
let bounds = (0, 0).to(1920, 1080);
|
||||
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,
|
||||
);
|
||||
|
||||
for _ in 0 .. self.rect_count {
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(bounds, space_and_clip),
|
||||
bounds,
|
||||
ColorF::new(1.0, 1.0, 1.0, 0.05)
|
||||
);
|
||||
}
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event: winit::WindowEvent,
|
||||
_api: &mut RenderApi,
|
||||
_document_id: DocumentId
|
||||
) -> bool {
|
||||
match event {
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
match key {
|
||||
winit::VirtualKeyCode::Right => {
|
||||
self.rect_count += 1;
|
||||
println!("rects = {}", self.rect_count);
|
||||
}
|
||||
winit::VirtualKeyCode::Left => {
|
||||
self.rect_count = cmp::max(self.rect_count, 1) - 1;
|
||||
println!("rects = {}", self.rect_count);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
rect_count: 1,
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
219
third_party/webrender/examples/animation.rs
vendored
Normal file
219
third_party/webrender/examples/animation.rs
vendored
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* 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 example creates a 200x200 white rect and allows the user to move it
|
||||
//! around by using the arrow keys and rotate with '<'/'>'.
|
||||
//! It does this by using the animation API.
|
||||
|
||||
//! The example also features seamless opaque/transparent split of a
|
||||
//! 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;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::Angle;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
struct App {
|
||||
property_key0: PropertyBindingKey<LayoutTransform>,
|
||||
property_key1: PropertyBindingKey<LayoutTransform>,
|
||||
property_key2: PropertyBindingKey<LayoutTransform>,
|
||||
opacity_key: PropertyBindingKey<f32>,
|
||||
opacity: f32,
|
||||
angle0: f32,
|
||||
angle1: f32,
|
||||
angle2: f32,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn add_rounded_rect(
|
||||
&mut self,
|
||||
bounds: LayoutRect,
|
||||
color: ColorF,
|
||||
builder: &mut DisplayListBuilder,
|
||||
pipeline_id: PipelineId,
|
||||
property_key: PropertyBindingKey<LayoutTransform>,
|
||||
opacity_key: Option<PropertyBindingKey<f32>>,
|
||||
) {
|
||||
let filters = match opacity_key {
|
||||
Some(opacity_key) => {
|
||||
vec![
|
||||
FilterOp::Opacity(PropertyBinding::Binding(opacity_key, self.opacity), self.opacity),
|
||||
]
|
||||
}
|
||||
None => {
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
|
||||
let spatial_id = builder.push_reference_frame(
|
||||
bounds.origin,
|
||||
SpatialId::root_scroll_node(pipeline_id),
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Binding(property_key, LayoutTransform::identity()),
|
||||
ReferenceFrameKind::Transform,
|
||||
);
|
||||
|
||||
builder.push_simple_stacking_context_with_filters(
|
||||
LayoutPoint::zero(),
|
||||
spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
&filters,
|
||||
&[],
|
||||
&[]
|
||||
);
|
||||
|
||||
let space_and_clip = SpaceAndClipInfo {
|
||||
spatial_id,
|
||||
clip_id: ClipId::root(pipeline_id),
|
||||
};
|
||||
let clip_bounds = LayoutRect::new(LayoutPoint::zero(), bounds.size);
|
||||
let complex_clip = ComplexClipRegion {
|
||||
rect: clip_bounds,
|
||||
radii: BorderRadius::uniform(30.0),
|
||||
mode: ClipMode::Clip,
|
||||
};
|
||||
let clip_id = builder.define_clip_rounded_rect(
|
||||
&space_and_clip,
|
||||
complex_clip,
|
||||
);
|
||||
|
||||
// Fill it with a white rect
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::zero(), bounds.size),
|
||||
SpaceAndClipInfo {
|
||||
spatial_id,
|
||||
clip_id,
|
||||
}
|
||||
),
|
||||
LayoutRect::new(LayoutPoint::zero(), bounds.size),
|
||||
color,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
builder.pop_reference_frame();
|
||||
}
|
||||
}
|
||||
|
||||
impl Example for App {
|
||||
const WIDTH: u32 = 2048;
|
||||
const HEIGHT: u32 = 1536;
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
_api: &mut RenderApi,
|
||||
builder: &mut DisplayListBuilder,
|
||||
_txn: &mut Transaction,
|
||||
_device_size: DeviceIntSize,
|
||||
pipeline_id: PipelineId,
|
||||
_document_id: DocumentId,
|
||||
) {
|
||||
let opacity_key = self.opacity_key;
|
||||
|
||||
let bounds = (150, 150).to(250, 250);
|
||||
let key0 = self.property_key0;
|
||||
self.add_rounded_rect(bounds, ColorF::new(1.0, 0.0, 0.0, 0.5), builder, pipeline_id, key0, Some(opacity_key));
|
||||
|
||||
let bounds = (400, 400).to(600, 600);
|
||||
let key1 = self.property_key1;
|
||||
self.add_rounded_rect(bounds, ColorF::new(0.0, 1.0, 0.0, 0.5), builder, pipeline_id, key1, None);
|
||||
|
||||
let bounds = (200, 500).to(350, 580);
|
||||
let key2 = self.property_key2;
|
||||
self.add_rounded_rect(bounds, ColorF::new(0.0, 0.0, 1.0, 0.5), builder, pipeline_id, key2, None);
|
||||
}
|
||||
|
||||
fn on_event(&mut self, win_event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||
let mut rebuild_display_list = false;
|
||||
|
||||
match win_event {
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let (delta_angle, delta_opacity) = match key {
|
||||
winit::VirtualKeyCode::Down => (0.0, -0.1),
|
||||
winit::VirtualKeyCode::Up => (0.0, 0.1),
|
||||
winit::VirtualKeyCode::Right => (1.0, 0.0),
|
||||
winit::VirtualKeyCode::Left => (-1.0, 0.0),
|
||||
winit::VirtualKeyCode::R => {
|
||||
rebuild_display_list = true;
|
||||
(0.0, 0.0)
|
||||
}
|
||||
_ => return false,
|
||||
};
|
||||
// Update the transform based on the keyboard input and push it to
|
||||
// webrender using the generate_frame API. This will recomposite with
|
||||
// the updated transform.
|
||||
self.opacity += delta_opacity;
|
||||
self.angle0 += delta_angle * 0.1;
|
||||
self.angle1 += delta_angle * 0.2;
|
||||
self.angle2 -= delta_angle * 0.15;
|
||||
let xf0 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle0));
|
||||
let xf1 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle1));
|
||||
let xf2 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle2));
|
||||
let mut txn = Transaction::new();
|
||||
txn.update_dynamic_properties(
|
||||
DynamicProperties {
|
||||
transforms: vec![
|
||||
PropertyValue {
|
||||
key: self.property_key0,
|
||||
value: xf0,
|
||||
},
|
||||
PropertyValue {
|
||||
key: self.property_key1,
|
||||
value: xf1,
|
||||
},
|
||||
PropertyValue {
|
||||
key: self.property_key2,
|
||||
value: xf2,
|
||||
},
|
||||
],
|
||||
floats: vec![
|
||||
PropertyValue {
|
||||
key: self.opacity_key,
|
||||
value: self.opacity,
|
||||
}
|
||||
],
|
||||
colors: vec![],
|
||||
},
|
||||
);
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
rebuild_display_list
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
property_key0: PropertyBindingKey::new(42), // arbitrary magic number
|
||||
property_key1: PropertyBindingKey::new(44), // arbitrary magic number
|
||||
property_key2: PropertyBindingKey::new(45), // arbitrary magic number
|
||||
opacity_key: PropertyBindingKey::new(43),
|
||||
opacity: 0.5,
|
||||
angle0: 0.0,
|
||||
angle1: 0.0,
|
||||
angle2: 0.0,
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
321
third_party/webrender/examples/basic.rs
vendored
Normal file
321
third_party/webrender/examples/basic.rs
vendored
Normal file
|
@ -0,0 +1,321 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::vec2;
|
||||
use winit::TouchPhase;
|
||||
use std::collections::HashMap;
|
||||
use webrender::ShaderPrecacheFlags;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Gesture {
|
||||
None,
|
||||
Pan,
|
||||
Zoom,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Touch {
|
||||
id: u64,
|
||||
start_x: f32,
|
||||
start_y: f32,
|
||||
current_x: f32,
|
||||
current_y: f32,
|
||||
}
|
||||
|
||||
fn dist(x0: f32, y0: f32, x1: f32, y1: f32) -> f32 {
|
||||
let dx = x0 - x1;
|
||||
let dy = y0 - y1;
|
||||
((dx * dx) + (dy * dy)).sqrt()
|
||||
}
|
||||
|
||||
impl Touch {
|
||||
fn distance_from_start(&self) -> f32 {
|
||||
dist(self.start_x, self.start_y, self.current_x, self.current_y)
|
||||
}
|
||||
|
||||
fn initial_distance_from_other(&self, other: &Touch) -> f32 {
|
||||
dist(self.start_x, self.start_y, other.start_x, other.start_y)
|
||||
}
|
||||
|
||||
fn current_distance_from_other(&self, other: &Touch) -> f32 {
|
||||
dist(
|
||||
self.current_x,
|
||||
self.current_y,
|
||||
other.current_x,
|
||||
other.current_y,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct TouchState {
|
||||
active_touches: HashMap<u64, Touch>,
|
||||
current_gesture: Gesture,
|
||||
start_zoom: f32,
|
||||
current_zoom: f32,
|
||||
start_pan: DeviceIntPoint,
|
||||
current_pan: DeviceIntPoint,
|
||||
}
|
||||
|
||||
enum TouchResult {
|
||||
None,
|
||||
Pan(DeviceIntPoint),
|
||||
Zoom(f32),
|
||||
}
|
||||
|
||||
impl TouchState {
|
||||
fn new() -> TouchState {
|
||||
TouchState {
|
||||
active_touches: HashMap::new(),
|
||||
current_gesture: Gesture::None,
|
||||
start_zoom: 1.0,
|
||||
current_zoom: 1.0,
|
||||
start_pan: DeviceIntPoint::zero(),
|
||||
current_pan: DeviceIntPoint::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, touch: winit::Touch) -> TouchResult {
|
||||
match touch.phase {
|
||||
TouchPhase::Started => {
|
||||
debug_assert!(!self.active_touches.contains_key(&touch.id));
|
||||
self.active_touches.insert(
|
||||
touch.id,
|
||||
Touch {
|
||||
id: touch.id,
|
||||
start_x: touch.location.x as f32,
|
||||
start_y: touch.location.y as f32,
|
||||
current_x: touch.location.x as f32,
|
||||
current_y: touch.location.y as f32,
|
||||
},
|
||||
);
|
||||
self.current_gesture = Gesture::None;
|
||||
}
|
||||
TouchPhase::Moved => {
|
||||
match self.active_touches.get_mut(&touch.id) {
|
||||
Some(active_touch) => {
|
||||
active_touch.current_x = touch.location.x as f32;
|
||||
active_touch.current_y = touch.location.y as f32;
|
||||
}
|
||||
None => panic!("move touch event with unknown touch id!"),
|
||||
}
|
||||
|
||||
match self.current_gesture {
|
||||
Gesture::None => {
|
||||
let mut over_threshold_count = 0;
|
||||
let active_touch_count = self.active_touches.len();
|
||||
|
||||
for (_, touch) in &self.active_touches {
|
||||
if touch.distance_from_start() > 8.0 {
|
||||
over_threshold_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if active_touch_count == over_threshold_count {
|
||||
if active_touch_count == 1 {
|
||||
self.start_pan = self.current_pan;
|
||||
self.current_gesture = Gesture::Pan;
|
||||
} else if active_touch_count == 2 {
|
||||
self.start_zoom = self.current_zoom;
|
||||
self.current_gesture = Gesture::Zoom;
|
||||
}
|
||||
}
|
||||
}
|
||||
Gesture::Pan => {
|
||||
let keys: Vec<u64> = self.active_touches.keys().cloned().collect();
|
||||
debug_assert!(keys.len() == 1);
|
||||
let active_touch = &self.active_touches[&keys[0]];
|
||||
let x = active_touch.current_x - active_touch.start_x;
|
||||
let y = active_touch.current_y - active_touch.start_y;
|
||||
self.current_pan.x = self.start_pan.x + x.round() as i32;
|
||||
self.current_pan.y = self.start_pan.y + y.round() as i32;
|
||||
return TouchResult::Pan(self.current_pan);
|
||||
}
|
||||
Gesture::Zoom => {
|
||||
let keys: Vec<u64> = self.active_touches.keys().cloned().collect();
|
||||
debug_assert!(keys.len() == 2);
|
||||
let touch0 = &self.active_touches[&keys[0]];
|
||||
let touch1 = &self.active_touches[&keys[1]];
|
||||
let initial_distance = touch0.initial_distance_from_other(touch1);
|
||||
let current_distance = touch0.current_distance_from_other(touch1);
|
||||
self.current_zoom = self.start_zoom * current_distance / initial_distance;
|
||||
return TouchResult::Zoom(self.current_zoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
TouchPhase::Ended | TouchPhase::Cancelled => {
|
||||
self.active_touches.remove(&touch.id).unwrap();
|
||||
self.current_gesture = Gesture::None;
|
||||
}
|
||||
}
|
||||
|
||||
TouchResult::None
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
touch_state: TouchState::new(),
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
||||
|
||||
struct App {
|
||||
touch_state: TouchState,
|
||||
}
|
||||
|
||||
impl Example for App {
|
||||
// Make this the only example to test all shaders for compile errors.
|
||||
const PRECACHE_SHADER_FLAGS: ShaderPrecacheFlags = ShaderPrecacheFlags::FULL_COMPILE;
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
builder: &mut DisplayListBuilder,
|
||||
txn: &mut Transaction,
|
||||
_: DeviceIntSize,
|
||||
pipeline_id: PipelineId,
|
||||
_document_id: DocumentId,
|
||||
) {
|
||||
let content_bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
let spatial_id = root_space_and_clip.spatial_id;
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
content_bounds.origin,
|
||||
spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
let image_mask_key = api.generate_image_key();
|
||||
txn.add_image(
|
||||
image_mask_key,
|
||||
ImageDescriptor::new(2, 2, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(vec![0, 80, 180, 255]),
|
||||
None,
|
||||
);
|
||||
let mask = ImageMask {
|
||||
image: image_mask_key,
|
||||
rect: (75, 75).by(100, 100),
|
||||
repeat: false,
|
||||
};
|
||||
let complex = ComplexClipRegion::new(
|
||||
(50, 50).to(150, 150),
|
||||
BorderRadius::uniform(20.0),
|
||||
ClipMode::Clip
|
||||
);
|
||||
let mask_clip_id = builder.define_clip_image_mask(
|
||||
&root_space_and_clip,
|
||||
mask,
|
||||
);
|
||||
let clip_id = builder.define_clip_rounded_rect(
|
||||
&SpaceAndClipInfo {
|
||||
spatial_id: root_space_and_clip.spatial_id,
|
||||
clip_id: mask_clip_id,
|
||||
},
|
||||
complex,
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
(100, 100).to(200, 200),
|
||||
SpaceAndClipInfo { spatial_id, clip_id },
|
||||
),
|
||||
(100, 100).to(200, 200),
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
(250, 100).to(350, 200),
|
||||
SpaceAndClipInfo { spatial_id, clip_id },
|
||||
),
|
||||
(250, 100).to(350, 200),
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||
);
|
||||
let border_side = BorderSide {
|
||||
color: ColorF::new(0.0, 0.0, 1.0, 1.0),
|
||||
style: BorderStyle::Groove,
|
||||
};
|
||||
let border_widths = LayoutSideOffsets::new_all_same(10.0);
|
||||
let border_details = BorderDetails::Normal(NormalBorder {
|
||||
top: border_side,
|
||||
right: border_side,
|
||||
bottom: border_side,
|
||||
left: border_side,
|
||||
radius: BorderRadius::uniform(20.0),
|
||||
do_aa: true,
|
||||
});
|
||||
|
||||
let bounds = (100, 100).to(200, 200);
|
||||
builder.push_border(
|
||||
&CommonItemProperties::new(
|
||||
bounds,
|
||||
SpaceAndClipInfo { spatial_id, clip_id },
|
||||
),
|
||||
bounds,
|
||||
border_widths,
|
||||
border_details,
|
||||
);
|
||||
|
||||
if false {
|
||||
// draw box shadow?
|
||||
let simple_box_bounds = (20, 200).by(50, 50);
|
||||
let offset = vec2(10.0, 10.0);
|
||||
let color = ColorF::new(1.0, 1.0, 1.0, 1.0);
|
||||
let blur_radius = 0.0;
|
||||
let spread_radius = 0.0;
|
||||
let simple_border_radius = 8.0;
|
||||
let box_shadow_type = BoxShadowClipMode::Inset;
|
||||
|
||||
builder.push_box_shadow(
|
||||
&CommonItemProperties::new(content_bounds, root_space_and_clip),
|
||||
simple_box_bounds,
|
||||
offset,
|
||||
color,
|
||||
blur_radius,
|
||||
spread_radius,
|
||||
BorderRadius::uniform(simple_border_radius),
|
||||
box_shadow_type,
|
||||
);
|
||||
}
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||
let mut txn = Transaction::new();
|
||||
match event {
|
||||
winit::WindowEvent::Touch(touch) => match self.touch_state.handle_event(touch) {
|
||||
TouchResult::Pan(pan) => {
|
||||
txn.set_pan(pan);
|
||||
}
|
||||
TouchResult::Zoom(zoom) => {
|
||||
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||
}
|
||||
TouchResult::None => {}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if !txn.is_empty() {
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
289
third_party/webrender/examples/blob.rs
vendored
Normal file
289
third_party/webrender/examples/blob.rs
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate rayon;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
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::{ColorF, CommonItemProperties, SpaceAndClipInfo, ImageDescriptorFlags};
|
||||
use webrender::api::units::*;
|
||||
use webrender::euclid::size2;
|
||||
|
||||
// This example shows how to implement a very basic BlobImageHandler that can only render
|
||||
// a checkerboard pattern.
|
||||
|
||||
// The deserialized command list internally used by this example is just a color.
|
||||
type ImageRenderingCommands = api::ColorU;
|
||||
|
||||
// Serialize/deserialize the blob.
|
||||
// For real usecases you should probably use serde rather than doing it by hand.
|
||||
|
||||
fn serialize_blob(color: api::ColorU) -> Arc<Vec<u8>> {
|
||||
Arc::new(vec![color.r, color.g, color.b, color.a])
|
||||
}
|
||||
|
||||
fn deserialize_blob(blob: &[u8]) -> Result<ImageRenderingCommands, ()> {
|
||||
let mut iter = blob.iter();
|
||||
return match (iter.next(), iter.next(), iter.next(), iter.next()) {
|
||||
(Some(&r), Some(&g), Some(&b), Some(&a)) => Ok(api::ColorU::new(r, g, b, a)),
|
||||
(Some(&a), None, None, None) => Ok(api::ColorU::new(a, a, a, a)),
|
||||
_ => Err(()),
|
||||
};
|
||||
}
|
||||
|
||||
// This is the function that applies the deserialized drawing commands and generates
|
||||
// actual image data.
|
||||
fn render_blob(
|
||||
commands: Arc<ImageRenderingCommands>,
|
||||
descriptor: &api::BlobImageDescriptor,
|
||||
tile: TileOffset,
|
||||
) -> api::BlobImageResult {
|
||||
let color = *commands;
|
||||
|
||||
// Note: This implementation ignores the dirty rect which isn't incorrect
|
||||
// but is a missed optimization.
|
||||
|
||||
// Allocate storage for the result. Right now the resource cache expects the
|
||||
// tiles to have have no stride or offset.
|
||||
let bpp = 4;
|
||||
let mut texels = Vec::with_capacity((descriptor.rect.size.area() * bpp) as usize);
|
||||
|
||||
// Generate a per-tile pattern to see it in the demo. For a real use case it would not
|
||||
// make sense for the rendered content to depend on its tile.
|
||||
let tile_checker = (tile.x % 2 == 0) != (tile.y % 2 == 0);
|
||||
|
||||
let [w, h] = descriptor.rect.size.to_array();
|
||||
let offset = descriptor.rect.origin;
|
||||
|
||||
for y in 0..h {
|
||||
for x in 0..w {
|
||||
// Apply the tile's offset. This is important: all drawing commands should be
|
||||
// translated by this offset to give correct results with tiled blob images.
|
||||
let x2 = x + offset.x;
|
||||
let y2 = y + offset.y;
|
||||
|
||||
// Render a simple checkerboard pattern
|
||||
let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
// ..nested in the per-tile checkerboard pattern
|
||||
let tc = if tile_checker { 0 } else { (1 - checker) * 40 };
|
||||
|
||||
match descriptor.format {
|
||||
api::ImageFormat::BGRA8 => {
|
||||
texels.push(color.b * checker + tc);
|
||||
texels.push(color.g * checker + tc);
|
||||
texels.push(color.r * checker + tc);
|
||||
texels.push(color.a * checker + tc);
|
||||
}
|
||||
api::ImageFormat::R8 => {
|
||||
texels.push(color.a * checker + tc);
|
||||
}
|
||||
_ => {
|
||||
return Err(api::BlobImageError::Other(
|
||||
format!("Unsupported image format"),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(api::RasterizedBlobImage {
|
||||
data: Arc::new(texels),
|
||||
rasterized_rect: size2(w, h).into(),
|
||||
})
|
||||
}
|
||||
|
||||
struct CheckerboardRenderer {
|
||||
// We are going to defer the rendering work to worker threads.
|
||||
// Using a pre-built Arc<ThreadPool> rather than creating our own threads
|
||||
// makes it possible to share the same thread pool as the glyph renderer (if we
|
||||
// want to).
|
||||
workers: Arc<ThreadPool>,
|
||||
|
||||
// The deserialized drawing commands.
|
||||
// In this example we store them in Arcs. This isn't necessary since in this simplified
|
||||
// case the command list is a simple 32 bits value and would be cheap to clone before sending
|
||||
// to the workers. But in a more realistic scenario the commands would typically be bigger
|
||||
// and more expensive to clone, so let's pretend it is also the case here.
|
||||
image_cmds: HashMap<api::BlobImageKey, Arc<ImageRenderingCommands>>,
|
||||
}
|
||||
|
||||
impl CheckerboardRenderer {
|
||||
fn new(workers: Arc<ThreadPool>) -> Self {
|
||||
CheckerboardRenderer {
|
||||
image_cmds: HashMap::new(),
|
||||
workers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl api::BlobImageHandler for CheckerboardRenderer {
|
||||
fn create_similar(&self) -> Box<dyn api::BlobImageHandler> {
|
||||
Box::new(CheckerboardRenderer::new(Arc::clone(&self.workers)))
|
||||
}
|
||||
|
||||
fn add(&mut self, key: api::BlobImageKey, cmds: Arc<api::BlobImageData>,
|
||||
_visible_rect: &DeviceIntRect, _: api::TileSize) {
|
||||
self.image_cmds
|
||||
.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
|
||||
}
|
||||
|
||||
fn update(&mut self, key: api::BlobImageKey, cmds: Arc<api::BlobImageData>,
|
||||
_visible_rect: &DeviceIntRect, _dirty_rect: &BlobDirtyRect) {
|
||||
// Here, updating is just replacing the current version of the commands with
|
||||
// the new one (no incremental updates).
|
||||
self.image_cmds
|
||||
.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
|
||||
}
|
||||
|
||||
fn delete(&mut self, key: api::BlobImageKey) {
|
||||
self.image_cmds.remove(&key);
|
||||
}
|
||||
|
||||
fn prepare_resources(
|
||||
&mut self,
|
||||
_services: &dyn api::BlobImageResources,
|
||||
_requests: &[api::BlobImageParams],
|
||||
) {}
|
||||
|
||||
fn enable_multithreading(&mut self, _: bool) {}
|
||||
fn delete_font(&mut self, _font: api::FontKey) {}
|
||||
fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) {}
|
||||
fn clear_namespace(&mut self, _namespace: api::IdNamespace) {}
|
||||
fn create_blob_rasterizer(&mut self) -> Box<dyn api::AsyncBlobImageRasterizer> {
|
||||
Box::new(Rasterizer {
|
||||
workers: Arc::clone(&self.workers),
|
||||
image_cmds: self.image_cmds.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Rasterizer {
|
||||
workers: Arc<ThreadPool>,
|
||||
image_cmds: HashMap<api::BlobImageKey, Arc<ImageRenderingCommands>>,
|
||||
}
|
||||
|
||||
impl api::AsyncBlobImageRasterizer for Rasterizer {
|
||||
fn rasterize(
|
||||
&mut self,
|
||||
requests: &[api::BlobImageParams],
|
||||
_low_priority: bool
|
||||
) -> Vec<(api::BlobImageRequest, api::BlobImageResult)> {
|
||||
let requests: Vec<(&api::BlobImageParams, Arc<ImageRenderingCommands>)> = requests.into_iter().map(|params| {
|
||||
(params, Arc::clone(&self.image_cmds[¶ms.request.key]))
|
||||
}).collect();
|
||||
|
||||
self.workers.install(|| {
|
||||
requests.into_par_iter().map(|(params, commands)| {
|
||||
(params.request, render_blob(commands, ¶ms.descriptor, params.request.tile))
|
||||
}).collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct App {}
|
||||
|
||||
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,
|
||||
) {
|
||||
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
LayoutPoint::zero(),
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
let size1 = DeviceIntSize::new(500, 500);
|
||||
let blob_img1 = api.generate_blob_image_key();
|
||||
txn.add_blob_image(
|
||||
blob_img1,
|
||||
api::ImageDescriptor::new(
|
||||
size1.width,
|
||||
size1.height,
|
||||
api::ImageFormat::BGRA8,
|
||||
ImageDescriptorFlags::IS_OPAQUE,
|
||||
),
|
||||
serialize_blob(api::ColorU::new(50, 50, 150, 255)),
|
||||
size1.into(),
|
||||
Some(128),
|
||||
);
|
||||
let bounds = (30, 30).by(size1.width, size1.height);
|
||||
builder.push_image(
|
||||
&CommonItemProperties::new(bounds, space_and_clip),
|
||||
bounds,
|
||||
api::ImageRendering::Auto,
|
||||
api::AlphaType::PremultipliedAlpha,
|
||||
blob_img1.as_image(),
|
||||
ColorF::WHITE,
|
||||
);
|
||||
|
||||
let size2 = DeviceIntSize::new(256, 256);
|
||||
let blob_img2 = api.generate_blob_image_key();
|
||||
txn.add_blob_image(
|
||||
blob_img2,
|
||||
api::ImageDescriptor::new(
|
||||
size2.width,
|
||||
size2.height,
|
||||
api::ImageFormat::BGRA8,
|
||||
ImageDescriptorFlags::IS_OPAQUE,
|
||||
),
|
||||
serialize_blob(api::ColorU::new(50, 150, 50, 255)),
|
||||
size2.into(),
|
||||
None,
|
||||
);
|
||||
let bounds = (600, 600).by(size2.width, size2.height);
|
||||
builder.push_image(
|
||||
&CommonItemProperties::new(bounds, space_and_clip),
|
||||
bounds,
|
||||
api::ImageRendering::Auto,
|
||||
api::AlphaType::PremultipliedAlpha,
|
||||
blob_img2.as_image(),
|
||||
ColorF::WHITE,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let workers =
|
||||
ThreadPoolBuilder::new().thread_name(|idx| format!("WebRender:Worker#{}", idx))
|
||||
.build();
|
||||
|
||||
let workers = Arc::new(workers.unwrap());
|
||||
|
||||
let opts = webrender::RendererOptions {
|
||||
workers: Some(Arc::clone(&workers)),
|
||||
// Register our blob renderer, so that WebRender integrates it in the resource cache..
|
||||
// Share the same pool of worker threads between WebRender and our blob renderer.
|
||||
blob_image_handler: Some(Box::new(CheckerboardRenderer::new(Arc::clone(&workers)))),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut app = App {};
|
||||
|
||||
boilerplate::main_wrapper(&mut app, Some(opts));
|
||||
}
|
338
third_party/webrender/examples/common/boilerplate.rs
vendored
Normal file
338
third_party/webrender/examples/common/boilerplate.rs
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
/* 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 gleam::gl;
|
||||
use glutin;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use webrender;
|
||||
use winit;
|
||||
use webrender::{DebugFlags, ShaderPrecacheFlags};
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
struct Notifier {
|
||||
events_proxy: winit::EventsLoopProxy,
|
||||
}
|
||||
|
||||
impl Notifier {
|
||||
fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
|
||||
Notifier { events_proxy }
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderNotifier for Notifier {
|
||||
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||
Box::new(Notifier {
|
||||
events_proxy: self.events_proxy.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _ = self.events_proxy.wakeup();
|
||||
}
|
||||
|
||||
fn new_frame_ready(&self,
|
||||
_: DocumentId,
|
||||
_scrolled: bool,
|
||||
_composite_needed: bool,
|
||||
_render_time: Option<u64>) {
|
||||
self.wake_up();
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HandyDandyRectBuilder {
|
||||
fn to(&self, x2: i32, y2: i32) -> LayoutRect;
|
||||
fn by(&self, w: i32, h: i32) -> LayoutRect;
|
||||
}
|
||||
// Allows doing `(x, y).to(x2, y2)` or `(x, y).by(width, height)` with i32
|
||||
// values to build a f32 LayoutRect
|
||||
impl HandyDandyRectBuilder for (i32, i32) {
|
||||
fn to(&self, x2: i32, y2: i32) -> LayoutRect {
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(self.0 as f32, self.1 as f32),
|
||||
LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32),
|
||||
)
|
||||
}
|
||||
|
||||
fn by(&self, w: i32, h: i32) -> LayoutRect {
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(self.0 as f32, self.1 as f32),
|
||||
LayoutSize::new(w as f32, h as f32),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Example {
|
||||
const TITLE: &'static str = "WebRender Sample App";
|
||||
const PRECACHE_SHADER_FLAGS: ShaderPrecacheFlags = ShaderPrecacheFlags::EMPTY;
|
||||
const WIDTH: u32 = 1920;
|
||||
const HEIGHT: u32 = 1080;
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
builder: &mut DisplayListBuilder,
|
||||
txn: &mut Transaction,
|
||||
device_size: DeviceIntSize,
|
||||
pipeline_id: PipelineId,
|
||||
document_id: DocumentId,
|
||||
);
|
||||
fn on_event(
|
||||
&mut self,
|
||||
_: winit::WindowEvent,
|
||||
_: &mut RenderApi,
|
||||
_: DocumentId,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
fn get_image_handlers(
|
||||
&mut self,
|
||||
_gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
(None, None)
|
||||
}
|
||||
fn draw_custom(&mut self, _gl: &dyn gl::Gl) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_wrapper<E: Example>(
|
||||
example: &mut E,
|
||||
options: Option<webrender::RendererOptions>,
|
||||
) {
|
||||
env_logger::init();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use core_foundation::{self as cf, base::TCFType};
|
||||
let i = cf::bundle::CFBundle::main_bundle().info_dictionary();
|
||||
let mut i = unsafe { i.to_mutable() };
|
||||
i.set(
|
||||
cf::string::CFString::new("NSSupportsAutomaticGraphicsSwitching"),
|
||||
cf::boolean::CFBoolean::true_value().into_CFType(),
|
||||
);
|
||||
}
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let res_path = if args.len() > 1 {
|
||||
Some(PathBuf::from(&args[1]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let window_builder = winit::WindowBuilder::new()
|
||||
.with_title(E::TITLE)
|
||||
.with_multitouch()
|
||||
.with_dimensions(winit::dpi::LogicalSize::new(E::WIDTH as f64, E::HEIGHT as f64));
|
||||
let windowed_context = glutin::ContextBuilder::new()
|
||||
.with_gl(glutin::GlRequest::GlThenGles {
|
||||
opengl_version: (3, 2),
|
||||
opengles_version: (3, 0),
|
||||
})
|
||||
.build_windowed(window_builder, &events_loop)
|
||||
.unwrap();
|
||||
|
||||
let windowed_context = unsafe { windowed_context.make_current().unwrap() };
|
||||
|
||||
let gl = match windowed_context.get_api() {
|
||||
glutin::Api::OpenGl => unsafe {
|
||||
gl::GlFns::load_with(
|
||||
|symbol| windowed_context.get_proc_address(symbol) as *const _
|
||||
)
|
||||
},
|
||||
glutin::Api::OpenGlEs => unsafe {
|
||||
gl::GlesFns::load_with(
|
||||
|symbol| windowed_context.get_proc_address(symbol) as *const _
|
||||
)
|
||||
},
|
||||
glutin::Api::WebGl => unimplemented!(),
|
||||
};
|
||||
|
||||
println!("OpenGL version {}", gl.get_string(gl::VERSION));
|
||||
println!("Shader resource path: {:?}", res_path);
|
||||
let device_pixel_ratio = windowed_context.window().get_hidpi_factor() as f32;
|
||||
println!("Device pixel ratio: {}", device_pixel_ratio);
|
||||
|
||||
println!("Loading shaders...");
|
||||
let mut debug_flags = DebugFlags::ECHO_DRIVER_MESSAGES | DebugFlags::TEXTURE_CACHE_DBG;
|
||||
let opts = webrender::RendererOptions {
|
||||
resource_override_path: res_path,
|
||||
precache_flags: E::PRECACHE_SHADER_FLAGS,
|
||||
device_pixel_ratio,
|
||||
clear_color: Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||
debug_flags,
|
||||
//allow_texture_swizzling: false,
|
||||
..options.unwrap_or(webrender::RendererOptions::default())
|
||||
};
|
||||
|
||||
let device_size = {
|
||||
let size = windowed_context
|
||||
.window()
|
||||
.get_inner_size()
|
||||
.unwrap()
|
||||
.to_physical(device_pixel_ratio as f64);
|
||||
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||
};
|
||||
let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
|
||||
let (mut renderer, sender) = webrender::Renderer::new(
|
||||
gl.clone(),
|
||||
notifier,
|
||||
opts,
|
||||
None,
|
||||
device_size,
|
||||
).unwrap();
|
||||
let mut api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
|
||||
let (external, output) = example.get_image_handlers(&*gl);
|
||||
|
||||
if let Some(output_image_handler) = output {
|
||||
renderer.set_output_image_handler(output_image_handler);
|
||||
}
|
||||
|
||||
if let Some(external_image_handler) = external {
|
||||
renderer.set_external_image_handler(external_image_handler);
|
||||
}
|
||||
|
||||
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 txn = Transaction::new();
|
||||
|
||||
example.render(
|
||||
&mut api,
|
||||
&mut builder,
|
||||
&mut txn,
|
||||
device_size,
|
||||
pipeline_id,
|
||||
document_id,
|
||||
);
|
||||
txn.set_display_list(
|
||||
epoch,
|
||||
Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||
layout_size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.set_root_pipeline(pipeline_id);
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
println!("Entering event loop");
|
||||
events_loop.run_forever(|global_event| {
|
||||
let mut txn = Transaction::new();
|
||||
let mut custom_event = true;
|
||||
|
||||
let old_flags = debug_flags;
|
||||
let win_event = match global_event {
|
||||
winit::Event::WindowEvent { event, .. } => event,
|
||||
_ => return winit::ControlFlow::Continue,
|
||||
};
|
||||
match win_event {
|
||||
winit::WindowEvent::CloseRequested => return winit::ControlFlow::Break,
|
||||
winit::WindowEvent::AxisMotion { .. } |
|
||||
winit::WindowEvent::CursorMoved { .. } => {
|
||||
custom_event = example.on_event(
|
||||
win_event,
|
||||
&mut api,
|
||||
document_id,
|
||||
);
|
||||
// skip high-frequency events from triggering a frame draw.
|
||||
if !custom_event {
|
||||
return winit::ControlFlow::Continue;
|
||||
}
|
||||
},
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => match key {
|
||||
winit::VirtualKeyCode::Escape => return winit::ControlFlow::Break,
|
||||
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(),
|
||||
1.0
|
||||
),
|
||||
winit::VirtualKeyCode::Key2 => txn.set_document_view(
|
||||
device_size.into(),
|
||||
2.0
|
||||
),
|
||||
winit::VirtualKeyCode::M => api.notify_memory_pressure(),
|
||||
winit::VirtualKeyCode::C => {
|
||||
let path: PathBuf = "../captures/example".into();
|
||||
//TODO: switch between SCENE/FRAME capture types
|
||||
// based on "shift" modifier, when `glutin` is updated.
|
||||
let bits = CaptureBits::all();
|
||||
api.save_capture(path, bits);
|
||||
},
|
||||
_ => {
|
||||
custom_event = example.on_event(
|
||||
win_event,
|
||||
&mut api,
|
||||
document_id,
|
||||
)
|
||||
},
|
||||
},
|
||||
other => custom_event = example.on_event(
|
||||
other,
|
||||
&mut api,
|
||||
document_id,
|
||||
),
|
||||
};
|
||||
|
||||
if debug_flags != old_flags {
|
||||
api.send_debug_cmd(DebugCommand::SetFlags(debug_flags));
|
||||
}
|
||||
|
||||
if custom_event {
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
|
||||
|
||||
example.render(
|
||||
&mut api,
|
||||
&mut builder,
|
||||
&mut txn,
|
||||
device_size,
|
||||
pipeline_id,
|
||||
document_id,
|
||||
);
|
||||
txn.set_display_list(
|
||||
epoch,
|
||||
Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||
layout_size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
}
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
let _ = renderer.flush_pipeline_info();
|
||||
example.draw_custom(&*gl);
|
||||
windowed_context.swap_buffers().ok();
|
||||
|
||||
winit::ControlFlow::Continue
|
||||
});
|
||||
|
||||
renderer.deinit();
|
||||
}
|
19
third_party/webrender/examples/common/image_helper.rs
vendored
Normal file
19
third_party/webrender/examples/common/image_helper.rs
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* 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 webrender::api::{ImageData, ImageDescriptor, ImageFormat, ImageDescriptorFlags};
|
||||
|
||||
pub fn make_checkerboard(width: u32, height: u32) -> (ImageDescriptor, ImageData) {
|
||||
let mut image_data = Vec::new();
|
||||
for y in 0 .. height {
|
||||
for x in 0 .. width {
|
||||
let lum = 255 * (((x & 8) == 0) ^ ((y & 8) == 0)) as u8;
|
||||
image_data.extend_from_slice(&[lum, lum, lum, 0xff]);
|
||||
}
|
||||
}
|
||||
(
|
||||
ImageDescriptor::new(width as i32, height as i32, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(image_data)
|
||||
)
|
||||
}
|
149
third_party/webrender/examples/document.rs
vendored
Normal file
149
third_party/webrender/examples/document.rs
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::Example;
|
||||
use euclid::Scale;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
// This example creates multiple documents overlapping each other with
|
||||
// specified layer indices.
|
||||
|
||||
struct Document {
|
||||
id: DocumentId,
|
||||
pipeline_id: PipelineId,
|
||||
content_rect: LayoutRect,
|
||||
color: ColorF,
|
||||
}
|
||||
|
||||
struct App {
|
||||
documents: Vec<Document>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn init(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
device_pixel_ratio: f32,
|
||||
) {
|
||||
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 {
|
||||
let size = DeviceIntSize::new(250, 250);
|
||||
let bounds = DeviceIntRect::new(offset, size);
|
||||
|
||||
let document_id = api.add_document(size, layer);
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_document_view(bounds, device_pixel_ratio);
|
||||
txn.set_root_pipeline(pipeline_id);
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
self.documents.push(Document {
|
||||
id: document_id,
|
||||
pipeline_id,
|
||||
content_rect: LayoutRect::new(
|
||||
LayoutPoint::origin(),
|
||||
bounds.size.to_f32() / Scale::new(device_pixel_ratio),
|
||||
),
|
||||
color,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Example for App {
|
||||
fn render(
|
||||
&mut self,
|
||||
api: &mut RenderApi,
|
||||
base_builder: &mut DisplayListBuilder,
|
||||
_txn: &mut Transaction,
|
||||
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);
|
||||
}
|
||||
|
||||
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(),
|
||||
doc.content_rect.size,
|
||||
);
|
||||
|
||||
builder.push_simple_stacking_context(
|
||||
doc.content_rect.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(local_rect, space_and_clip),
|
||||
local_rect,
|
||||
doc.color,
|
||||
);
|
||||
builder.pop_stacking_context();
|
||||
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_display_list(
|
||||
Epoch(0),
|
||||
None,
|
||||
doc.content_rect.size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
api.send_transaction(doc.id, txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
documents: Vec::new(),
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
238
third_party/webrender/examples/frame_output.rs
vendored
Normal file
238
third_party/webrender/examples/frame_output.rs
vendored
Normal file
|
@ -0,0 +1,238 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate 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);
|
||||
}
|
95
third_party/webrender/examples/iframe.rs
vendored
Normal file
95
third_party/webrender/examples/iframe.rs
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* 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/. */
|
||||
|
||||
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::api::units::*;
|
||||
|
||||
// This example uses the push_iframe API to nest a second pipeline's displaylist
|
||||
// inside the root pipeline's display list. When it works, a green square is
|
||||
// shown. If it fails, a red square is shown.
|
||||
|
||||
struct App {}
|
||||
|
||||
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,
|
||||
) {
|
||||
// All the sub_* things are for the nested pipeline
|
||||
let sub_size = DeviceIntSize::new(100, 100);
|
||||
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 space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
|
||||
sub_builder.push_simple_stacking_context(
|
||||
sub_bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
// green rect visible == success
|
||||
sub_builder.push_rect(
|
||||
&CommonItemProperties::new(sub_bounds, space_and_clip),
|
||||
sub_bounds,
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0)
|
||||
);
|
||||
sub_builder.pop_stacking_context();
|
||||
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_display_list(
|
||||
Epoch(0),
|
||||
None,
|
||||
sub_bounds.size,
|
||||
sub_builder.finalize(),
|
||||
true,
|
||||
);
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
space_and_clip.spatial_id = builder.push_reference_frame(
|
||||
sub_bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
TransformStyle::Flat,
|
||||
PropertyBinding::Binding(PropertyBindingKey::new(42), LayoutTransform::identity()),
|
||||
ReferenceFrameKind::Transform,
|
||||
);
|
||||
|
||||
// And this is for the root pipeline
|
||||
builder.push_simple_stacking_context(
|
||||
sub_bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
// red rect under the iframe: if this is visible, things have gone wrong
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(sub_bounds, space_and_clip),
|
||||
sub_bounds,
|
||||
ColorF::new(1.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
builder.push_iframe(sub_bounds, sub_bounds, &space_and_clip, sub_pipeline_id, false);
|
||||
builder.pop_stacking_context();
|
||||
builder.pop_reference_frame();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
121
third_party/webrender/examples/image_resize.rs
vendored
Normal file
121
third_party/webrender/examples/image_resize.rs
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
#[path = "common/image_helper.rs"]
|
||||
mod image_helper;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
struct App {
|
||||
image_key: ImageKey,
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
let (image_descriptor, image_data) = image_helper::make_checkerboard(32, 32);
|
||||
txn.add_image(
|
||||
self.image_key,
|
||||
image_descriptor,
|
||||
image_data,
|
||||
None,
|
||||
);
|
||||
|
||||
let bounds = (0, 0).to(512, 512);
|
||||
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,
|
||||
);
|
||||
|
||||
let image_size = LayoutSize::new(100.0, 100.0);
|
||||
|
||||
builder.push_image(
|
||||
&CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
|
||||
space_and_clip,
|
||||
),
|
||||
bounds,
|
||||
ImageRendering::Auto,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
self.image_key,
|
||||
ColorF::WHITE,
|
||||
);
|
||||
|
||||
builder.push_image(
|
||||
&CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
|
||||
space_and_clip,
|
||||
),
|
||||
bounds,
|
||||
ImageRendering::Pixelated,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
self.image_key,
|
||||
ColorF::WHITE,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||
match event {
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(winit::VirtualKeyCode::Space),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let mut image_data = Vec::new();
|
||||
for y in 0 .. 64 {
|
||||
for x in 0 .. 64 {
|
||||
let r = 255 * ((y & 32) == 0) as u8;
|
||||
let g = 255 * ((x & 32) == 0) as u8;
|
||||
image_data.extend_from_slice(&[0, g, r, 0xff]);
|
||||
}
|
||||
}
|
||||
|
||||
let mut txn = Transaction::new();
|
||||
txn.update_image(
|
||||
self.image_key,
|
||||
ImageDescriptor::new(64, 64, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(image_data),
|
||||
&DirtyRect::All,
|
||||
);
|
||||
let mut txn = Transaction::new();
|
||||
txn.generate_frame();
|
||||
api.send_transaction(document_id, txn);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
image_key: ImageKey(IdNamespace(0), 0),
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
326
third_party/webrender/examples/multiwindow.rs
vendored
Normal file
326
third_party/webrender/examples/multiwindow.rs
vendored
Normal file
|
@ -0,0 +1,326 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
use gleam::gl;
|
||||
use glutin::NotCurrent;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
use webrender::DebugFlags;
|
||||
use winit::dpi::LogicalSize;
|
||||
|
||||
struct Notifier {
|
||||
events_proxy: winit::EventsLoopProxy,
|
||||
}
|
||||
|
||||
impl Notifier {
|
||||
fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
|
||||
Notifier { events_proxy }
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderNotifier for Notifier {
|
||||
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||
Box::new(Notifier {
|
||||
events_proxy: self.events_proxy.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn wake_up(&self) {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _ = self.events_proxy.wakeup();
|
||||
}
|
||||
|
||||
fn new_frame_ready(&self,
|
||||
_: DocumentId,
|
||||
_scrolled: bool,
|
||||
_composite_needed: bool,
|
||||
_render_time: Option<u64>) {
|
||||
self.wake_up();
|
||||
}
|
||||
}
|
||||
|
||||
struct Window {
|
||||
events_loop: winit::EventsLoop, //TODO: share events loop?
|
||||
context: Option<glutin::WindowedContext<NotCurrent>>,
|
||||
renderer: webrender::Renderer,
|
||||
name: &'static str,
|
||||
pipeline_id: PipelineId,
|
||||
document_id: DocumentId,
|
||||
epoch: Epoch,
|
||||
api: RenderApi,
|
||||
font_instance_key: FontInstanceKey,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
fn new(name: &'static str, clear_color: ColorF) -> Self {
|
||||
let events_loop = winit::EventsLoop::new();
|
||||
let window_builder = winit::WindowBuilder::new()
|
||||
.with_title(name)
|
||||
.with_multitouch()
|
||||
.with_dimensions(LogicalSize::new(800., 600.));
|
||||
let context = glutin::ContextBuilder::new()
|
||||
.with_gl(glutin::GlRequest::GlThenGles {
|
||||
opengl_version: (3, 2),
|
||||
opengles_version: (3, 0),
|
||||
})
|
||||
.build_windowed(window_builder, &events_loop)
|
||||
.unwrap();
|
||||
|
||||
let context = unsafe { context.make_current().unwrap() };
|
||||
|
||||
let gl = match context.get_api() {
|
||||
glutin::Api::OpenGl => unsafe {
|
||||
gl::GlFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
||||
},
|
||||
glutin::Api::OpenGlEs => unsafe {
|
||||
gl::GlesFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
||||
},
|
||||
glutin::Api::WebGl => unimplemented!(),
|
||||
};
|
||||
|
||||
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
||||
|
||||
let opts = webrender::RendererOptions {
|
||||
device_pixel_ratio,
|
||||
clear_color: Some(clear_color),
|
||||
..webrender::RendererOptions::default()
|
||||
};
|
||||
|
||||
let device_size = {
|
||||
let size = context
|
||||
.window()
|
||||
.get_inner_size()
|
||||
.unwrap()
|
||||
.to_physical(device_pixel_ratio as f64);
|
||||
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 mut api = sender.create_api();
|
||||
let document_id = api.add_document(device_size, 0);
|
||||
|
||||
let epoch = Epoch(0);
|
||||
let pipeline_id = PipelineId(0, 0);
|
||||
let mut txn = Transaction::new();
|
||||
|
||||
let font_key = api.generate_font_key();
|
||||
let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
|
||||
txn.add_raw_font(font_key, font_bytes, 0);
|
||||
|
||||
let font_instance_key = api.generate_font_instance_key();
|
||||
txn.add_font_instance(font_instance_key, font_key, 32.0, None, None, Vec::new());
|
||||
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
Window {
|
||||
events_loop,
|
||||
context: Some(unsafe { context.make_not_current().unwrap() }),
|
||||
renderer,
|
||||
name,
|
||||
epoch,
|
||||
pipeline_id,
|
||||
document_id,
|
||||
api,
|
||||
font_instance_key,
|
||||
}
|
||||
}
|
||||
|
||||
fn tick(&mut self) -> bool {
|
||||
let mut do_exit = false;
|
||||
let my_name = &self.name;
|
||||
let renderer = &mut self.renderer;
|
||||
let api = &mut self.api;
|
||||
|
||||
self.events_loop.poll_events(|global_event| match global_event {
|
||||
winit::Event::WindowEvent { event, .. } => match event {
|
||||
winit::WindowEvent::CloseRequested |
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
virtual_keycode: Some(winit::VirtualKeyCode::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
do_exit = true
|
||||
}
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(winit::VirtualKeyCode::P),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
println!("set flags {}", my_name);
|
||||
api.send_debug_cmd(DebugCommand::SetFlags(DebugFlags::PROFILER_DBG))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
if do_exit {
|
||||
return true
|
||||
}
|
||||
|
||||
let context = unsafe { self.context.take().unwrap().make_current().unwrap() };
|
||||
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
||||
let device_size = {
|
||||
let size = context
|
||||
.window()
|
||||
.get_inner_size()
|
||||
.unwrap()
|
||||
.to_physical(device_pixel_ratio as f64);
|
||||
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||
};
|
||||
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 space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
|
||||
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
builder.push_simple_stacking_context(
|
||||
bounds.origin,
|
||||
space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
builder.push_rect(
|
||||
&CommonItemProperties::new(
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(100.0, 200.0),
|
||||
LayoutSize::new(100.0, 200.0),
|
||||
),
|
||||
space_and_clip,
|
||||
),
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(100.0, 200.0),
|
||||
LayoutSize::new(100.0, 200.0),
|
||||
),
|
||||
ColorF::new(0.0, 1.0, 0.0, 1.0));
|
||||
|
||||
let text_bounds = LayoutRect::new(
|
||||
LayoutPoint::new(100.0, 50.0),
|
||||
LayoutSize::new(700.0, 200.0)
|
||||
);
|
||||
let glyphs = vec![
|
||||
GlyphInstance {
|
||||
index: 48,
|
||||
point: LayoutPoint::new(100.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 68,
|
||||
point: LayoutPoint::new(150.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 80,
|
||||
point: LayoutPoint::new(200.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 82,
|
||||
point: LayoutPoint::new(250.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 81,
|
||||
point: LayoutPoint::new(300.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 3,
|
||||
point: LayoutPoint::new(350.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 86,
|
||||
point: LayoutPoint::new(400.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 79,
|
||||
point: LayoutPoint::new(450.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 72,
|
||||
point: LayoutPoint::new(500.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 83,
|
||||
point: LayoutPoint::new(550.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 87,
|
||||
point: LayoutPoint::new(600.0, 100.0),
|
||||
},
|
||||
GlyphInstance {
|
||||
index: 17,
|
||||
point: LayoutPoint::new(650.0, 100.0),
|
||||
},
|
||||
];
|
||||
|
||||
builder.push_text(
|
||||
&CommonItemProperties::new(
|
||||
text_bounds,
|
||||
space_and_clip,
|
||||
),
|
||||
text_bounds,
|
||||
&glyphs,
|
||||
self.font_instance_key,
|
||||
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
||||
None,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
|
||||
txn.set_display_list(
|
||||
self.epoch,
|
||||
None,
|
||||
layout_size,
|
||||
builder.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.set_root_pipeline(self.pipeline_id);
|
||||
txn.generate_frame();
|
||||
api.send_transaction(self.document_id, txn);
|
||||
|
||||
renderer.update();
|
||||
renderer.render(device_size).unwrap();
|
||||
context.swap_buffers().ok();
|
||||
|
||||
self.context = Some(unsafe { context.make_not_current().unwrap() });
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn deinit(self) {
|
||||
self.renderer.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
|
||||
let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));
|
||||
|
||||
loop {
|
||||
if win1.tick() {
|
||||
break;
|
||||
}
|
||||
if win2.tick() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
win1.deinit();
|
||||
win2.deinit();
|
||||
}
|
||||
|
||||
fn load_file(name: &str) -> Vec<u8> {
|
||||
let mut file = File::open(name).unwrap();
|
||||
let mut buffer = vec![];
|
||||
file.read_to_end(&mut buffer).unwrap();
|
||||
buffer
|
||||
}
|
231
third_party/webrender/examples/scrolling.rs
vendored
Normal file
231
third_party/webrender/examples/scrolling.rs
vendored
Normal file
|
@ -0,0 +1,231 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate euclid;
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use euclid::SideOffsets2D;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
use winit::dpi::LogicalPosition;
|
||||
|
||||
|
||||
struct App {
|
||||
cursor_position: WorldPoint,
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||
builder.push_simple_stacking_context(
|
||||
LayoutPoint::zero(),
|
||||
root_space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
|
||||
if true {
|
||||
// scrolling and clips stuff
|
||||
// let's make a scrollbox
|
||||
let scrollbox = (0, 0).to(300, 400);
|
||||
builder.push_simple_stacking_context(
|
||||
LayoutPoint::new(10., 10.),
|
||||
root_space_and_clip.spatial_id,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
// set the scrolling clip
|
||||
let space_and_clip1 = builder.define_scroll_frame(
|
||||
&root_space_and_clip,
|
||||
None,
|
||||
(0, 0).by(1000, 1000),
|
||||
scrollbox,
|
||||
ScrollSensitivity::ScriptAndInputEvents,
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
// 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));
|
||||
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));
|
||||
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(
|
||||
(50, 0).to(100, 50).intersection(&(60, 10).to(110, 60)).unwrap(),
|
||||
space_and_clip1,
|
||||
);
|
||||
info.hit_info = Some((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
|
||||
// the same stacking context, so note that the rects passed in need to
|
||||
// be relative to the stacking context.
|
||||
let space_and_clip2 = builder.define_scroll_frame(
|
||||
&space_and_clip1,
|
||||
None,
|
||||
(0, 100).to(300, 1000),
|
||||
(0, 100).to(200, 300),
|
||||
ScrollSensitivity::ScriptAndInputEvents,
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
// give it a giant gray background just to distinguish it and to easily
|
||||
// visually identify the nested scrollbox
|
||||
let mut info = CommonItemProperties::new(
|
||||
(-1000, -1000).to(5000, 5000),
|
||||
space_and_clip2,
|
||||
);
|
||||
info.hit_info = Some((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));
|
||||
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
|
||||
// at a margin of 10px from the bottom, for 40 pixels of scrolling,
|
||||
// and once at a margin of 10px from the top, for 60 pixels of
|
||||
// scrolling.
|
||||
let sticky_id = builder.define_sticky_frame(
|
||||
space_and_clip2.spatial_id,
|
||||
(50, 350).by(50, 50),
|
||||
SideOffsets2D::new(Some(10.0), None, Some(10.0), None),
|
||||
StickyOffsetBounds::new(-40.0, 60.0),
|
||||
StickyOffsetBounds::new(0.0, 0.0),
|
||||
LayoutVector2D::new(0.0, 0.0)
|
||||
);
|
||||
|
||||
let mut 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_rect(
|
||||
&info,
|
||||
info.clip_rect,
|
||||
ColorF::new(0.5, 0.5, 1.0, 1.0),
|
||||
);
|
||||
|
||||
// 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(
|
||||
(250, 350).to(300, 400),
|
||||
space_and_clip2,
|
||||
);
|
||||
info.hit_info = Some((0, 7));
|
||||
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 1.0, 1.0));
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||
let mut txn = Transaction::new();
|
||||
match event {
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
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)),
|
||||
_ => None,
|
||||
};
|
||||
let zoom = match key {
|
||||
winit::VirtualKeyCode::Key0 => Some(1.0),
|
||||
winit::VirtualKeyCode::Minus => Some(0.8),
|
||||
winit::VirtualKeyCode::Equals => Some(1.25),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(offset) = offset {
|
||||
txn.scroll(
|
||||
ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
|
||||
self.cursor_position,
|
||||
);
|
||||
txn.generate_frame();
|
||||
}
|
||||
if let Some(zoom) = zoom {
|
||||
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||
txn.generate_frame();
|
||||
}
|
||||
}
|
||||
winit::WindowEvent::CursorMoved { position: LogicalPosition { x, y }, .. } => {
|
||||
self.cursor_position = WorldPoint::new(x as f32, y as f32);
|
||||
}
|
||||
winit::WindowEvent::MouseWheel { delta, .. } => {
|
||||
const LINE_HEIGHT: f32 = 38.0;
|
||||
let (dx, dy) = match delta {
|
||||
winit::MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT),
|
||||
winit::MouseScrollDelta::PixelDelta(pos) => (pos.x as f32, pos.y as f32),
|
||||
};
|
||||
|
||||
txn.scroll(
|
||||
ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
|
||||
self.cursor_position,
|
||||
);
|
||||
txn.generate_frame();
|
||||
}
|
||||
winit::WindowEvent::MouseInput { .. } => {
|
||||
let results = api.hit_test(
|
||||
document_id,
|
||||
None,
|
||||
self.cursor_position,
|
||||
HitTestFlags::FIND_ALL
|
||||
);
|
||||
|
||||
println!("Hit test results:");
|
||||
for item in &results.items {
|
||||
println!(" • {:?}", item);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
api.send_transaction(document_id, txn);
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
cursor_position: WorldPoint::zero(),
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
322
third_party/webrender/examples/texture_cache_stress.rs
vendored
Normal file
322
third_party/webrender/examples/texture_cache_stress.rs
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||
use gleam::gl;
|
||||
use std::mem;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
struct ImageGenerator {
|
||||
patterns: [[u8; 3]; 6],
|
||||
next_pattern: usize,
|
||||
current_image: Vec<u8>,
|
||||
}
|
||||
|
||||
impl ImageGenerator {
|
||||
fn new() -> Self {
|
||||
ImageGenerator {
|
||||
next_pattern: 0,
|
||||
patterns: [
|
||||
[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
[1, 0, 1],
|
||||
],
|
||||
current_image: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_image(&mut self, size: i32) {
|
||||
let pattern = &self.patterns[self.next_pattern];
|
||||
self.current_image.clear();
|
||||
for y in 0 .. size {
|
||||
for x in 0 .. size {
|
||||
let lum = 255 * (1 - (((x & 8) == 0) ^ ((y & 8) == 0)) as u8);
|
||||
self.current_image.extend_from_slice(&[
|
||||
lum * pattern[0],
|
||||
lum * pattern[1],
|
||||
lum * pattern[2],
|
||||
0xff,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
self.next_pattern = (self.next_pattern + 1) % self.patterns.len();
|
||||
}
|
||||
|
||||
fn take(&mut self) -> Vec<u8> {
|
||||
mem::replace(&mut self.current_image, Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalImageHandler for ImageGenerator {
|
||||
fn lock(
|
||||
&mut self,
|
||||
_key: ExternalImageId,
|
||||
channel_index: u8,
|
||||
_rendering: ImageRendering
|
||||
) -> ExternalImage {
|
||||
self.generate_image(channel_index as i32);
|
||||
ExternalImage {
|
||||
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||
source: ExternalImageSource::RawData(&self.current_image),
|
||||
}
|
||||
}
|
||||
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
|
||||
}
|
||||
|
||||
struct App {
|
||||
stress_keys: Vec<ImageKey>,
|
||||
image_key: Option<ImageKey>,
|
||||
image_generator: ImageGenerator,
|
||||
swap_keys: Vec<ImageKey>,
|
||||
swap_index: usize,
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
let bounds = (0, 0).to(512, 512);
|
||||
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,
|
||||
);
|
||||
|
||||
let x0 = 50.0;
|
||||
let y0 = 50.0;
|
||||
let image_size = LayoutSize::new(4.0, 4.0);
|
||||
|
||||
if self.swap_keys.is_empty() {
|
||||
let key0 = api.generate_image_key();
|
||||
let key1 = api.generate_image_key();
|
||||
|
||||
self.image_generator.generate_image(128);
|
||||
txn.add_image(
|
||||
key0,
|
||||
ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(self.image_generator.take()),
|
||||
None,
|
||||
);
|
||||
|
||||
self.image_generator.generate_image(128);
|
||||
txn.add_image(
|
||||
key1,
|
||||
ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(self.image_generator.take()),
|
||||
None,
|
||||
);
|
||||
|
||||
self.swap_keys.push(key0);
|
||||
self.swap_keys.push(key1);
|
||||
}
|
||||
|
||||
for (i, key) in self.stress_keys.iter().enumerate() {
|
||||
let x = (i % 128) as f32;
|
||||
let y = (i / 128) as f32;
|
||||
let info = CommonItemProperties::new(
|
||||
LayoutRect::new(
|
||||
LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y),
|
||||
image_size,
|
||||
),
|
||||
space_and_clip,
|
||||
);
|
||||
|
||||
builder.push_image(
|
||||
&info,
|
||||
bounds,
|
||||
ImageRendering::Auto,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
*key,
|
||||
ColorF::WHITE,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(image_key) = self.image_key {
|
||||
let image_size = LayoutSize::new(100.0, 100.0);
|
||||
let info = CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
|
||||
space_and_clip,
|
||||
);
|
||||
builder.push_image(
|
||||
&info,
|
||||
bounds,
|
||||
ImageRendering::Auto,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
image_key,
|
||||
ColorF::WHITE,
|
||||
);
|
||||
}
|
||||
|
||||
let swap_key = self.swap_keys[self.swap_index];
|
||||
let image_size = LayoutSize::new(64.0, 64.0);
|
||||
let info = CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size),
|
||||
space_and_clip,
|
||||
);
|
||||
builder.push_image(
|
||||
&info,
|
||||
bounds,
|
||||
ImageRendering::Auto,
|
||||
AlphaType::PremultipliedAlpha,
|
||||
swap_key,
|
||||
ColorF::WHITE,
|
||||
);
|
||||
self.swap_index = 1 - self.swap_index;
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event: winit::WindowEvent,
|
||||
api: &mut RenderApi,
|
||||
document_id: DocumentId,
|
||||
) -> bool {
|
||||
match event {
|
||||
winit::WindowEvent::KeyboardInput {
|
||||
input: winit::KeyboardInput {
|
||||
state: winit::ElementState::Pressed,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let mut txn = Transaction::new();
|
||||
|
||||
match key {
|
||||
winit::VirtualKeyCode::S => {
|
||||
self.stress_keys.clear();
|
||||
|
||||
for _ in 0 .. 16 {
|
||||
for _ in 0 .. 16 {
|
||||
let size = 4;
|
||||
|
||||
let image_key = api.generate_image_key();
|
||||
|
||||
self.image_generator.generate_image(size);
|
||||
|
||||
txn.add_image(
|
||||
image_key,
|
||||
ImageDescriptor::new(
|
||||
size,
|
||||
size,
|
||||
ImageFormat::BGRA8,
|
||||
ImageDescriptorFlags::IS_OPAQUE,
|
||||
),
|
||||
ImageData::new(self.image_generator.take()),
|
||||
None,
|
||||
);
|
||||
|
||||
self.stress_keys.push(image_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
winit::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() {
|
||||
txn.delete_image(image_key);
|
||||
},
|
||||
winit::VirtualKeyCode::U => if let Some(image_key) = self.image_key {
|
||||
let size = 128;
|
||||
self.image_generator.generate_image(size);
|
||||
|
||||
txn.update_image(
|
||||
image_key,
|
||||
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(self.image_generator.take()),
|
||||
&DirtyRect::All,
|
||||
);
|
||||
},
|
||||
winit::VirtualKeyCode::E => {
|
||||
if let Some(image_key) = self.image_key.take() {
|
||||
txn.delete_image(image_key);
|
||||
}
|
||||
|
||||
let size = 32;
|
||||
let image_key = api.generate_image_key();
|
||||
|
||||
let image_data = ExternalImageData {
|
||||
id: ExternalImageId(0),
|
||||
channel_index: size as u8,
|
||||
image_type: ExternalImageType::Buffer,
|
||||
};
|
||||
|
||||
txn.add_image(
|
||||
image_key,
|
||||
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(image_data),
|
||||
None,
|
||||
);
|
||||
|
||||
self.image_key = Some(image_key);
|
||||
}
|
||||
winit::VirtualKeyCode::R => {
|
||||
if let Some(image_key) = self.image_key.take() {
|
||||
txn.delete_image(image_key);
|
||||
}
|
||||
|
||||
let image_key = api.generate_image_key();
|
||||
let size = 32;
|
||||
self.image_generator.generate_image(size);
|
||||
|
||||
txn.add_image(
|
||||
image_key,
|
||||
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::new(self.image_generator.take()),
|
||||
None,
|
||||
);
|
||||
|
||||
self.image_key = Some(image_key);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
api.send_transaction(document_id, txn);
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn get_image_handlers(
|
||||
&mut self,
|
||||
_gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
(Some(Box::new(ImageGenerator::new())), None)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
image_key: None,
|
||||
stress_keys: Vec::new(),
|
||||
image_generator: ImageGenerator::new(),
|
||||
swap_keys: Vec::new(),
|
||||
swap_index: 0,
|
||||
};
|
||||
boilerplate::main_wrapper(&mut app, None);
|
||||
}
|
226
third_party/webrender/examples/yuv.rs
vendored
Normal file
226
third_party/webrender/examples/yuv.rs
vendored
Normal file
|
@ -0,0 +1,226 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate gleam;
|
||||
extern crate glutin;
|
||||
extern crate webrender;
|
||||
extern crate winit;
|
||||
|
||||
#[path = "common/boilerplate.rs"]
|
||||
mod boilerplate;
|
||||
|
||||
use crate::boilerplate::Example;
|
||||
use gleam::gl;
|
||||
use webrender::api::*;
|
||||
use webrender::api::units::*;
|
||||
|
||||
|
||||
fn init_gl_texture(
|
||||
id: gl::GLuint,
|
||||
internal: gl::GLenum,
|
||||
external: gl::GLenum,
|
||||
bytes: &[u8],
|
||||
gl: &dyn gl::Gl,
|
||||
) {
|
||||
gl.bind_texture(gl::TEXTURE_2D, 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,
|
||||
internal as gl::GLint,
|
||||
100,
|
||||
100,
|
||||
0,
|
||||
external,
|
||||
gl::UNSIGNED_BYTE,
|
||||
Some(bytes),
|
||||
);
|
||||
gl.bind_texture(gl::TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
struct YuvImageProvider {
|
||||
texture_ids: Vec<gl::GLuint>,
|
||||
}
|
||||
|
||||
impl YuvImageProvider {
|
||||
fn new(gl: &dyn gl::Gl) -> Self {
|
||||
let texture_ids = gl.gen_textures(4);
|
||||
|
||||
init_gl_texture(texture_ids[0], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||
init_gl_texture(texture_ids[1], gl::RG8, gl::RG, &[0; 100 * 100 * 2], gl);
|
||||
init_gl_texture(texture_ids[2], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||
init_gl_texture(texture_ids[3], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||
|
||||
YuvImageProvider {
|
||||
texture_ids
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalImageHandler for YuvImageProvider {
|
||||
fn lock(
|
||||
&mut self,
|
||||
key: ExternalImageId,
|
||||
_channel_index: u8,
|
||||
_rendering: ImageRendering
|
||||
) -> ExternalImage {
|
||||
let id = self.texture_ids[key.0 as usize];
|
||||
ExternalImage {
|
||||
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||
source: ExternalImageSource::NativeTexture(id),
|
||||
}
|
||||
}
|
||||
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {
|
||||
}
|
||||
}
|
||||
|
||||
struct App {
|
||||
texture_id: gl::GLuint,
|
||||
current_value: u8,
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||
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,
|
||||
);
|
||||
|
||||
let yuv_chanel1 = api.generate_image_key();
|
||||
let yuv_chanel2 = api.generate_image_key();
|
||||
let yuv_chanel2_1 = api.generate_image_key();
|
||||
let yuv_chanel3 = api.generate_image_key();
|
||||
txn.add_image(
|
||||
yuv_chanel1,
|
||||
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(0),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
);
|
||||
txn.add_image(
|
||||
yuv_chanel2,
|
||||
ImageDescriptor::new(100, 100, ImageFormat::RG8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(1),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
);
|
||||
txn.add_image(
|
||||
yuv_chanel2_1,
|
||||
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(2),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
);
|
||||
txn.add_image(
|
||||
yuv_chanel3,
|
||||
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||
ImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(3),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
);
|
||||
|
||||
let info = CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
|
||||
space_and_clip,
|
||||
);
|
||||
builder.push_yuv_image(
|
||||
&info,
|
||||
bounds,
|
||||
YuvData::NV12(yuv_chanel1, yuv_chanel2),
|
||||
ColorDepth::Color8,
|
||||
YuvColorSpace::Rec601,
|
||||
ColorRange::Limited,
|
||||
ImageRendering::Auto,
|
||||
);
|
||||
|
||||
let info = CommonItemProperties::new(
|
||||
LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
|
||||
space_and_clip,
|
||||
);
|
||||
builder.push_yuv_image(
|
||||
&info,
|
||||
bounds,
|
||||
YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
|
||||
ColorDepth::Color8,
|
||||
YuvColorSpace::Rec601,
|
||||
ColorRange::Limited,
|
||||
ImageRendering::Auto,
|
||||
);
|
||||
|
||||
builder.pop_stacking_context();
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
_event: winit::WindowEvent,
|
||||
_api: &mut RenderApi,
|
||||
_document_id: DocumentId,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_image_handlers(
|
||||
&mut self,
|
||||
gl: &dyn gl::Gl,
|
||||
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||
Option<Box<dyn OutputImageHandler>>) {
|
||||
let provider = YuvImageProvider::new(gl);
|
||||
self.texture_id = provider.texture_ids[0];
|
||||
(Some(Box::new(provider)), None)
|
||||
}
|
||||
|
||||
fn draw_custom(&mut self, gl: &dyn gl::Gl) {
|
||||
init_gl_texture(self.texture_id, gl::RED, gl::RED, &[self.current_value; 100 * 100], gl);
|
||||
self.current_value = self.current_value.wrapping_add(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App {
|
||||
texture_id: 0,
|
||||
current_value: 0,
|
||||
};
|
||||
|
||||
let opts = webrender::RendererOptions {
|
||||
debug_flags: webrender::DebugFlags::NEW_FRAME_INDICATOR | webrender::DebugFlags::NEW_SCENE_INDICATOR,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
boilerplate::main_wrapper(&mut app, Some(opts));
|
||||
}
|
11
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
Normal file
11
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "glsl-to-cxx"
|
||||
version = "0.1.0"
|
||||
license = "MPL-2.0"
|
||||
authors = ["The Mozilla Project Developers"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
glsl = "4.0"
|
3
third_party/webrender/glsl-to-cxx/README.md
vendored
Normal file
3
third_party/webrender/glsl-to-cxx/README.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
A GLSL to C++ translator.
|
||||
|
||||
Translates GLSL to vectorized C++. Intended for use with WebRender software backend.
|
3856
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
Normal file
3856
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
3706
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
Normal file
3706
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
third_party/webrender/glsl-to-cxx/src/main.rs
vendored
Normal file
8
third_party/webrender/glsl-to-cxx/src/main.rs
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* 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 glsl_to_cxx::translate;
|
||||
fn main() {
|
||||
println!("{}", translate(&mut std::env::args()));
|
||||
}
|
226
third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
vendored
Normal file
226
third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
vendored
Normal file
|
@ -0,0 +1,226 @@
|
|||
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
|
||||
|
174
third_party/webrender/patches/0002-Bug-1646741-Update-gleam-to-0.12.-r-kvark.patch
vendored
Normal file
174
third_party/webrender/patches/0002-Bug-1646741-Update-gleam-to-0.12.-r-kvark.patch
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
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
|
||||
|
107
third_party/webrender/patches/0003-Bug-1651889.-Update-to-gleam-0.12.1.-r-kvark.patch
vendored
Normal file
107
third_party/webrender/patches/0003-Bug-1651889.-Update-to-gleam-0.12.1.-r-kvark.patch
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
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
|
||||
|
328
third_party/webrender/patches/0004-Bug-1654699.-Update-core-foundation-core-graphics.-r.patch
vendored
Normal file
328
third_party/webrender/patches/0004-Bug-1654699.-Update-core-foundation-core-graphics.-r.patch
vendored
Normal file
|
@ -0,0 +1,328 @@
|
|||
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
|
||||
|
9059
third_party/webrender/patches/0005-Bug-1656236-Update-to-euclid-0.22.-r-kvark.patch
vendored
Normal file
9059
third_party/webrender/patches/0005-Bug-1656236-Update-to-euclid-0.22.-r-kvark.patch
vendored
Normal file
File diff suppressed because it is too large
Load diff
53
third_party/webrender/patches/0006-Bump-procedural-masquerade-to-0.1.7.patch
vendored
Normal file
53
third_party/webrender/patches/0006-Bump-procedural-masquerade-to-0.1.7.patch
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
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
third_party/webrender/patches/head
vendored
Normal file
1
third_party/webrender/patches/head
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
1175acad2d4f49fa712e105c84149ac7f394261d
|
6
third_party/webrender/patches/series
vendored
Normal file
6
third_party/webrender/patches/series
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
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
|
17
third_party/webrender/peek-poke/Cargo.toml
vendored
Normal file
17
third_party/webrender/peek-poke/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "peek-poke"
|
||||
version = "0.2.0"
|
||||
authors = ["Dan Glastonbury <dan.glastonbury@gmail.com>"]
|
||||
repository = "https://github.com/servo/webrender"
|
||||
description = "A mechanism for serializing and deserializing data into/from byte buffers, for use in WebRender."
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
euclid = { version = "0.22.0", optional = true }
|
||||
peek-poke-derive = { version = "0.2", path = "./peek-poke-derive", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["derive"]
|
||||
derive = ["peek-poke-derive"]
|
||||
extras = ["derive", "euclid"]
|
201
third_party/webrender/peek-poke/LICENSE-APACHE
vendored
Normal file
201
third_party/webrender/peek-poke/LICENSE-APACHE
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
44
third_party/webrender/peek-poke/LICENSE-MIT
vendored
Normal file
44
third_party/webrender/peek-poke/LICENSE-MIT
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Daniel Glastonbury
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This work incorporates work covered by the following copyright and permission
|
||||
notice:
|
||||
|
||||
Copyright (c) 2019 Devashish Dixit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
54
third_party/webrender/peek-poke/README.md
vendored
Normal file
54
third_party/webrender/peek-poke/README.md
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Peeks, Pokes, and Pointers
|
||||
|
||||
Peek from and poke structures into byte slices.
|
||||
|
||||
## Benchmark
|
||||
|
||||
Below are the benchmark results of comparison between `peek-poke` and `bincode` serializing and deserializing same `struct`:
|
||||
```
|
||||
struct MyPeekPokeStruct {
|
||||
a: u8,
|
||||
b: u16,
|
||||
c: MyPeekPokeEnum,
|
||||
d: Option<usize>,
|
||||
}
|
||||
|
||||
enum MyPeekPokeEnum {
|
||||
Variant1,
|
||||
Variant2(u16),
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
Benchmarking struct::serialize/peek_poke::poke_into: Collecting 100 samples in struct::serialize/peek_poke::poke_into
|
||||
time: [2.7267 ns 2.7321 ns 2.7380 ns]
|
||||
|
||||
Benchmarking struct::serialize/bincode::serialize: Collecting 100 samples in est struct::serialize/bincode::serialize
|
||||
time: [31.264 ns 31.326 ns 31.389 ns]
|
||||
|
||||
Benchmarking struct::deserialize/peek_poke::peek_from: Collecting 100 samples struct::deserialize/peek_poke::peek_from
|
||||
time: [5.3544 ns 5.3672 ns 5.3817 ns]
|
||||
|
||||
Benchmarking struct::deserialize/bincode::deserialize: Collecting 100 samples in struct::deserialize/bincode::deserialize
|
||||
time: [25.155 ns 26.439 ns 27.661 ns]
|
||||
```
|
||||
|
||||
You can run benchmarks by running following command:
|
||||
```
|
||||
cargo bench
|
||||
```
|
||||
|
||||
## License
|
||||
[license]: #license
|
||||
|
||||
Licensed under either of
|
||||
- Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
- MIT license (http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
see [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT) for details.
|
||||
|
||||
## Contribution
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as
|
||||
defined in the Apache-2.0 license, shall be dual licensed as about, without any additional terms or conditions.
|
19
third_party/webrender/peek-poke/peek-poke-derive/Cargo.toml
vendored
Normal file
19
third_party/webrender/peek-poke/peek-poke-derive/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "peek-poke-derive"
|
||||
version = "0.2.1"
|
||||
authors = ["Dan Glastonbury <dan.glastonbury@gmail.com>"]
|
||||
repository = "https://github.com/servo/webrender"
|
||||
description = "Derive macro for peek-poke."
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = "1"
|
||||
synstructure = "0.12"
|
||||
unicode-xid = "0.2"
|
201
third_party/webrender/peek-poke/peek-poke-derive/LICENSE-APACHE
vendored
Normal file
201
third_party/webrender/peek-poke/peek-poke-derive/LICENSE-APACHE
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
44
third_party/webrender/peek-poke/peek-poke-derive/LICENSE-MIT
vendored
Normal file
44
third_party/webrender/peek-poke/peek-poke-derive/LICENSE-MIT
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Daniel Glastonbury
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This work incorporates work covered by the following copyright and permission
|
||||
notice:
|
||||
|
||||
Copyright (c) 2019 Devashish Dixit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
54
third_party/webrender/peek-poke/peek-poke-derive/README.md
vendored
Normal file
54
third_party/webrender/peek-poke/peek-poke-derive/README.md
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Peeks, Pokes, and Pointers
|
||||
|
||||
Peek from and poke structures into byte slices.
|
||||
|
||||
## Benchmark
|
||||
|
||||
Below are the benchmark results of comparison between `peek-poke` and `bincode` serializing and deserializing same `struct`:
|
||||
```
|
||||
struct MyPeekPokeStruct {
|
||||
a: u8,
|
||||
b: u16,
|
||||
c: MyPeekPokeEnum,
|
||||
d: Option<usize>,
|
||||
}
|
||||
|
||||
enum MyPeekPokeEnum {
|
||||
Variant1,
|
||||
Variant2(u16),
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
Benchmarking struct::serialize/peek_poke::poke_into: Collecting 100 samples in struct::serialize/peek_poke::poke_into
|
||||
time: [2.7267 ns 2.7321 ns 2.7380 ns]
|
||||
|
||||
Benchmarking struct::serialize/bincode::serialize: Collecting 100 samples in est struct::serialize/bincode::serialize
|
||||
time: [31.264 ns 31.326 ns 31.389 ns]
|
||||
|
||||
Benchmarking struct::deserialize/peek_poke::peek_from: Collecting 100 samples struct::deserialize/peek_poke::peek_from
|
||||
time: [5.3544 ns 5.3672 ns 5.3817 ns]
|
||||
|
||||
Benchmarking struct::deserialize/bincode::deserialize: Collecting 100 samples in struct::deserialize/bincode::deserialize
|
||||
time: [25.155 ns 26.439 ns 27.661 ns]
|
||||
```
|
||||
|
||||
You can run benchmarks by running following command:
|
||||
```
|
||||
cargo bench
|
||||
```
|
||||
|
||||
## License
|
||||
[license]: #license
|
||||
|
||||
Licensed under either of
|
||||
- Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
- MIT license (http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
see [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT) for details.
|
||||
|
||||
## Contribution
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as
|
||||
defined in the Apache-2.0 license, shall be dual licensed as about, without any additional terms or conditions.
|
266
third_party/webrender/peek-poke/peek-poke-derive/src/lib.rs
vendored
Normal file
266
third_party/webrender/peek-poke/peek-poke-derive/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{Ident, Index, TraitBound};
|
||||
use synstructure::{decl_derive, Structure, BindStyle, AddBounds};
|
||||
use unicode_xid::UnicodeXID;
|
||||
|
||||
// Internal method for sanitizing an identifier for hygiene purposes.
|
||||
fn sanitize_ident(s: &str) -> Ident {
|
||||
let mut res = String::with_capacity(s.len());
|
||||
for mut c in s.chars() {
|
||||
if !UnicodeXID::is_xid_continue(c) {
|
||||
c = '_'
|
||||
}
|
||||
// Deduplicate consecutive _ characters.
|
||||
if res.ends_with('_') && c == '_' {
|
||||
continue;
|
||||
}
|
||||
res.push(c);
|
||||
}
|
||||
Ident::new(&res, Span::call_site())
|
||||
}
|
||||
|
||||
/// Calculates size type for number of variants (used for enums)
|
||||
fn get_discriminant_size_type(len: usize) -> TokenStream {
|
||||
if len <= <u8>::max_value() as usize {
|
||||
quote! { u8 }
|
||||
} else if len <= <u16>::max_value() as usize {
|
||||
quote! { u16 }
|
||||
} else {
|
||||
quote! { u32 }
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn derive_max_size(s: &Structure) -> TokenStream {
|
||||
let max_size = s.variants().iter().fold(quote!(0), |acc, vi| {
|
||||
let variant_size = vi.bindings().iter().fold(quote!(0), |acc, bi| {
|
||||
// compute size of each variant by summing the sizes of its bindings
|
||||
let ty = &bi.ast().ty;
|
||||
quote!(#acc + <#ty>::max_size())
|
||||
});
|
||||
|
||||
// find the maximum of each variant
|
||||
quote! {
|
||||
max(#acc, #variant_size)
|
||||
}
|
||||
});
|
||||
|
||||
let body = if is_struct(s) {
|
||||
max_size
|
||||
} else {
|
||||
let discriminant_size_type = get_discriminant_size_type(s.variants().len());
|
||||
quote! {
|
||||
#discriminant_size_type ::max_size() + #max_size
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
use std::cmp::max;
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn derive_peek_from_for_enum(s: &mut Structure) -> TokenStream {
|
||||
assert!(!is_struct(s));
|
||||
s.bind_with(|_| BindStyle::Move);
|
||||
|
||||
let num_variants = s.variants().len();
|
||||
let discriminant_size_type = get_discriminant_size_type(num_variants);
|
||||
let body = s
|
||||
.variants()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(quote!(), |acc, (i, vi)| {
|
||||
let bindings = vi
|
||||
.bindings()
|
||||
.iter()
|
||||
.map(|bi| quote!(#bi))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let variant_pat = Index::from(i);
|
||||
let poke_exprs = bindings.iter().fold(quote!(), |acc, bi| {
|
||||
quote! {
|
||||
#acc
|
||||
let (#bi, bytes) = peek_poke::peek_from_default(bytes);
|
||||
}
|
||||
});
|
||||
let construct = vi.construct(|_, i| {
|
||||
let bi = &bindings[i];
|
||||
quote!(#bi)
|
||||
});
|
||||
|
||||
quote! {
|
||||
#acc
|
||||
#variant_pat => {
|
||||
#poke_exprs
|
||||
*output = #construct;
|
||||
bytes
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let type_name = s.ast().ident.to_string();
|
||||
let max_tag_value = num_variants - 1;
|
||||
|
||||
quote! {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let (variant, bytes) = peek_poke::peek_from_default::<#discriminant_size_type>(bytes);
|
||||
match variant {
|
||||
#body
|
||||
out_of_range_tag => {
|
||||
panic!("WRDL: memory corruption detected while parsing {} - enum tag should be <= {}, but was {}",
|
||||
#type_name, #max_tag_value, out_of_range_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn derive_peek_from_for_struct(s: &mut Structure) -> TokenStream {
|
||||
assert!(is_struct(&s));
|
||||
|
||||
s.variants_mut()[0].bind_with(|_| BindStyle::RefMut);
|
||||
let pat = s.variants()[0].pat();
|
||||
let peek_exprs = s.variants()[0].bindings().iter().fold(quote!(), |acc, bi| {
|
||||
let ty = &bi.ast().ty;
|
||||
quote! {
|
||||
#acc
|
||||
let bytes = <#ty>::peek_from(bytes, #bi);
|
||||
}
|
||||
});
|
||||
|
||||
let body = quote! {
|
||||
#pat => {
|
||||
#peek_exprs
|
||||
bytes
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
match &mut (*output) {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn derive_poke_into(s: &Structure) -> TokenStream {
|
||||
let is_struct = is_struct(&s);
|
||||
let discriminant_size_type = get_discriminant_size_type(s.variants().len());
|
||||
let body = s
|
||||
.variants()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(quote!(), |acc, (i, vi)| {
|
||||
let init = if !is_struct {
|
||||
let index = Index::from(i);
|
||||
quote! {
|
||||
let bytes = #discriminant_size_type::poke_into(&#index, bytes);
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let variant_pat = vi.pat();
|
||||
let poke_exprs = vi.bindings().iter().fold(init, |acc, bi| {
|
||||
quote! {
|
||||
#acc
|
||||
let bytes = #bi.poke_into(bytes);
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#acc
|
||||
#variant_pat => {
|
||||
#poke_exprs
|
||||
bytes
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
match &*self {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn peek_poke_derive(mut s: Structure) -> TokenStream {
|
||||
s.binding_name(|_, i| Ident::new(&format!("__self_{}", i), Span::call_site()));
|
||||
|
||||
let max_size_fn = derive_max_size(&s);
|
||||
let poke_into_fn = derive_poke_into(&s);
|
||||
let peek_from_fn = if is_struct(&s) {
|
||||
derive_peek_from_for_struct(&mut s)
|
||||
} else {
|
||||
derive_peek_from_for_enum(&mut s)
|
||||
};
|
||||
|
||||
let poke_impl = s.gen_impl(quote! {
|
||||
extern crate peek_poke;
|
||||
|
||||
gen unsafe impl peek_poke::Poke for @Self {
|
||||
#max_size_fn
|
||||
#poke_into_fn
|
||||
}
|
||||
});
|
||||
|
||||
// To implement `fn peek_from` we require that types implement `Default`
|
||||
// trait to create temporary values. This code does the addition all
|
||||
// manually until https://github.com/mystor/synstructure/issues/24 is fixed.
|
||||
let default_trait = syn::parse_str::<TraitBound>("::std::default::Default").unwrap();
|
||||
let peek_trait = syn::parse_str::<TraitBound>("peek_poke::Peek").unwrap();
|
||||
|
||||
let ast = s.ast();
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
let mut where_clause = where_clause.cloned();
|
||||
s.add_trait_bounds(&default_trait, &mut where_clause, AddBounds::Generics);
|
||||
s.add_trait_bounds(&peek_trait, &mut where_clause, AddBounds::Generics);
|
||||
|
||||
let dummy_const: Ident = sanitize_ident(&format!("_DERIVE_peek_poke_Peek_FOR_{}", name));
|
||||
|
||||
let peek_impl = quote! {
|
||||
#[allow(non_upper_case_globals)]
|
||||
const #dummy_const: () = {
|
||||
extern crate peek_poke;
|
||||
|
||||
impl #impl_generics peek_poke::Peek for #name #ty_generics #where_clause {
|
||||
#peek_from_fn
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
quote! {
|
||||
#poke_impl
|
||||
#peek_impl
|
||||
}
|
||||
}
|
||||
|
||||
decl_derive!([PeekPoke] => peek_poke_derive);
|
170
third_party/webrender/peek-poke/src/euclid.rs
vendored
Normal file
170
third_party/webrender/peek-poke/src/euclid.rs
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::{Peek, Poke};
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, Vector2D};
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Point2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
2 * T::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.x.poke_into(bytes);
|
||||
let bytes = self.y.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for Point2D<T, U> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = T::peek_from(bytes, &mut (*output).x);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).y);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Rect<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
Point2D::<T, U>::max_size() + Size2D::<T, U>::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.origin.poke_into(bytes);
|
||||
let bytes = self.size.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for Rect<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).origin);
|
||||
let bytes = Size2D::<T, U>::peek_from(bytes, &mut (*output).size);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for SideOffsets2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
4 * T::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.top.poke_into(bytes);
|
||||
let bytes = self.right.poke_into(bytes);
|
||||
let bytes = self.bottom.poke_into(bytes);
|
||||
let bytes = self.left.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for SideOffsets2D<T, U> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = T::peek_from(bytes, &mut (*output).top);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).right);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).bottom);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).left);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Size2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
2 * T::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.width.poke_into(bytes);
|
||||
let bytes = self.height.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for Size2D<T, U> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = T::peek_from(bytes, &mut (*output).width);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).height);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, S, D> Poke for Transform3D<T, S, D> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
16 * T::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.m11.poke_into(bytes);
|
||||
let bytes = self.m12.poke_into(bytes);
|
||||
let bytes = self.m13.poke_into(bytes);
|
||||
let bytes = self.m14.poke_into(bytes);
|
||||
let bytes = self.m21.poke_into(bytes);
|
||||
let bytes = self.m22.poke_into(bytes);
|
||||
let bytes = self.m23.poke_into(bytes);
|
||||
let bytes = self.m24.poke_into(bytes);
|
||||
let bytes = self.m31.poke_into(bytes);
|
||||
let bytes = self.m32.poke_into(bytes);
|
||||
let bytes = self.m33.poke_into(bytes);
|
||||
let bytes = self.m34.poke_into(bytes);
|
||||
let bytes = self.m41.poke_into(bytes);
|
||||
let bytes = self.m42.poke_into(bytes);
|
||||
let bytes = self.m43.poke_into(bytes);
|
||||
let bytes = self.m44.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, S, D> Peek for Transform3D<T, S, D> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m11);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m12);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m13);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m14);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m21);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m22);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m23);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m24);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m31);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m32);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m33);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m34);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m41);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m42);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m43);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).m44);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke, U> Poke for Vector2D<T, U> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
2 * T::max_size()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
let bytes = self.x.poke_into(bytes);
|
||||
let bytes = self.y.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<T: Peek, U> Peek for Vector2D<T, U> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let bytes = T::peek_from(bytes, &mut (*output).x);
|
||||
let bytes = T::peek_from(bytes, &mut (*output).y);
|
||||
bytes
|
||||
}
|
||||
}
|
427
third_party/webrender/peek-poke/src/lib.rs
vendored
Normal file
427
third_party/webrender/peek-poke/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,427 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Fast binary serialization and deserialization for types with a known maximum size.
|
||||
//!
|
||||
//! ## Binary Encoding Scheme
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! ## Comparison to bincode
|
||||
|
||||
#[cfg(feature = "derive")]
|
||||
pub use peek_poke_derive::*;
|
||||
|
||||
use core::{marker::PhantomData, mem::size_of, slice};
|
||||
use crate::{slice_ext::*, vec_ext::*};
|
||||
|
||||
mod slice_ext;
|
||||
mod vec_ext;
|
||||
|
||||
union MaybeUninitShim<T: Copy> {
|
||||
uninit: (),
|
||||
init: T,
|
||||
}
|
||||
|
||||
/// Peek helper for constructing a `T` by `Copy`ing into an uninitialized stack
|
||||
/// allocation.
|
||||
pub unsafe fn peek_from_uninit<T: Copy + Peek>(bytes: *const u8) -> (T, *const u8) {
|
||||
let mut val = MaybeUninitShim { uninit: () };
|
||||
let bytes = <T>::peek_from(bytes, &mut val.init);
|
||||
(val.init, bytes)
|
||||
}
|
||||
|
||||
/// Peek helper for constructing a `T` by `Default` initialized stack
|
||||
/// allocation.
|
||||
pub unsafe fn peek_from_default<T: Default + Peek>(bytes: *const u8) -> (T, *const u8) {
|
||||
let mut val = T::default();
|
||||
let bytes = <T>::peek_from(bytes, &mut val);
|
||||
(val, bytes)
|
||||
}
|
||||
|
||||
/// Peek inplace a `T` from a slice of bytes, returning a slice of the remaining
|
||||
/// bytes. `src` must contain at least `T::max_size()` bytes.
|
||||
///
|
||||
/// [`ensure_red_zone`] can be used to add required padding.
|
||||
pub fn peek_from_slice<'a, T: Peek>(src: &'a [u8], dst: &mut T) -> &'a [u8] {
|
||||
unsafe {
|
||||
// If src.len() == T::max_size() then src is at the start of the red-zone.
|
||||
assert!(T::max_size() < src.len(), "WRDL: unexpected end of display list");
|
||||
let end_ptr = T::peek_from(src.as_ptr(), dst);
|
||||
let len = end_ptr as usize - src.as_ptr() as usize;
|
||||
// Did someone break the T::peek_from() can't read more than T::max_size()
|
||||
// bytes contract?
|
||||
assert!(len <= src.len(), "WRDL: Peek::max_size was wrong");
|
||||
slice::from_raw_parts(end_ptr, src.len() - len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Poke helper to insert a serialized version of `src` at the beginning for `dst`.
|
||||
pub fn poke_inplace_slice<T: Poke>(src: &T, dst: &mut [u8]) {
|
||||
assert!(T::max_size() <= dst.len(), "WRDL: buffer too small to write into");
|
||||
unsafe {
|
||||
src.poke_into(dst.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
/// Poke helper to append a serialized version of `src` to the end of `dst`.
|
||||
pub fn poke_into_vec<T: Poke>(src: &T, dst: &mut Vec<u8>) {
|
||||
dst.reserve(T::max_size());
|
||||
unsafe {
|
||||
let ptr = dst.as_end_mut_ptr();
|
||||
let end_ptr = src.poke_into(ptr);
|
||||
dst.set_end_ptr(end_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Is returning the len of the iterator of any practical use?
|
||||
pub fn poke_extend_vec<I>(src: I, dst: &mut Vec<u8>) -> usize
|
||||
where
|
||||
I: ExactSizeIterator,
|
||||
I::Item: Poke,
|
||||
{
|
||||
let len = src.len();
|
||||
let max_size = len * I::Item::max_size();
|
||||
dst.reserve(max_size);
|
||||
unsafe {
|
||||
let ptr = dst.as_end_mut_ptr();
|
||||
// Guard against the possibility of a misbehaved implementation of
|
||||
// ExactSizeIterator by writing at most `len` items.
|
||||
let end_ptr = src.take(len).fold(ptr, |ptr, item| item.poke_into(ptr));
|
||||
dst.set_end_ptr(end_ptr);
|
||||
}
|
||||
|
||||
len
|
||||
}
|
||||
|
||||
/// Add `T::max_size()` "red zone" (padding of zeroes) to the end of the vec of
|
||||
/// `bytes`. This allows deserialization to assert that at least `T::max_size()`
|
||||
/// bytes exist at all times.
|
||||
pub fn ensure_red_zone<T: Poke>(bytes: &mut Vec<u8>) {
|
||||
bytes.reserve(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.add(T::max_size()));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn read_verbatim<T>(src: *const u8, dst: *mut T) -> *const u8 {
|
||||
*dst = (src as *const T).read_unaligned();
|
||||
src.add(size_of::<T>())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn write_verbatim<T>(src: T, dst: *mut u8) -> *mut u8 {
|
||||
(dst as *mut T).write_unaligned(src);
|
||||
dst.add(size_of::<T>())
|
||||
}
|
||||
|
||||
#[cfg(feature = "extras")]
|
||||
mod euclid;
|
||||
|
||||
/// A trait for values that provide serialization into buffers of bytes.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use peek_poke::Poke;
|
||||
///
|
||||
/// struct Bar {
|
||||
/// a: u32,
|
||||
/// b: u8,
|
||||
/// c: i16,
|
||||
/// }
|
||||
///
|
||||
/// unsafe impl Poke for Bar {
|
||||
/// fn max_size() -> usize {
|
||||
/// <u32>::max_size() + <u8>::max_size() + <i16>::max_size()
|
||||
/// }
|
||||
/// unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
/// let bytes = self.a.poke_into(bytes);
|
||||
/// let bytes = self.b.poke_into(bytes);
|
||||
/// self.c.poke_into(bytes)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `Poke` trait is an `unsafe` trait for the reasons, and implementors must
|
||||
/// ensure that they adhere to these contracts:
|
||||
///
|
||||
/// * `max_size()` query and calculations in general must be correct. Callers
|
||||
/// of this trait are expected to rely on the contract defined on each
|
||||
/// method, and implementors must ensure such contracts remain true.
|
||||
pub unsafe trait Poke {
|
||||
/// Return the maximum number of bytes that the serialized version of `Self`
|
||||
/// will occupy.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Implementors of `Poke` guarantee to not write more than the result of
|
||||
/// calling `max_size()` into the buffer pointed to by `bytes` when
|
||||
/// `poke_into()` is called.
|
||||
fn max_size() -> usize;
|
||||
/// Serialize into the buffer pointed to by `bytes`.
|
||||
///
|
||||
/// Returns a pointer to the next byte after the serialized representation of `Self`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe because undefined behavior can result if the
|
||||
/// caller does not ensure all of the following:
|
||||
///
|
||||
/// * `bytes` must denote a valid pointer to a block of memory.
|
||||
///
|
||||
/// * `bytes` must pointer to at least the number of bytes returned by
|
||||
/// `max_size()`.
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8;
|
||||
}
|
||||
|
||||
/// A trait for values that provide deserialization from buffers of bytes.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// use peek_poke::Peek;
|
||||
///
|
||||
/// struct Bar {
|
||||
/// a: u32,
|
||||
/// b: u8,
|
||||
/// c: i16,
|
||||
/// }
|
||||
///
|
||||
/// ...
|
||||
///
|
||||
/// impl Peek for Bar {
|
||||
/// unsafe fn peek_from(&mut self, bytes: *const u8) -> *const u8 {
|
||||
/// let bytes = self.a.peek_from(bytes);
|
||||
/// let bytes = self.b.peek_from(bytes);
|
||||
/// self.c.peek_from(bytes)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `Peek` trait contains unsafe methods for the following reasons, and
|
||||
/// implementors must ensure that they adhere to these contracts:
|
||||
///
|
||||
/// * Callers of this trait are expected to rely on the contract defined on each
|
||||
/// method, and implementors must ensure that `peek_from()` doesn't read more
|
||||
/// bytes from `bytes` than is returned by `Peek::max_size()`.
|
||||
pub trait Peek: Poke {
|
||||
/// Deserialize from the buffer pointed to by `bytes`.
|
||||
///
|
||||
/// Returns a pointer to the next byte after the unconsumed bytes not used
|
||||
/// to deserialize the representation of `Self`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe because undefined behavior can result if the
|
||||
/// caller does not ensure all of the following:
|
||||
///
|
||||
/// * `bytes` must denote a valid pointer to a block of memory.
|
||||
///
|
||||
/// * `bytes` must pointer to at least the number of bytes returned by
|
||||
/// `Poke::max_size()`.
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8;
|
||||
}
|
||||
|
||||
macro_rules! impl_poke_for_deref {
|
||||
(<$($desc:tt)+) => {
|
||||
unsafe impl <$($desc)+ {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
<T>::max_size()
|
||||
}
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
(**self).poke_into(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_poke_for_deref!(<'a, T: Poke> Poke for &'a T);
|
||||
impl_poke_for_deref!(<'a, T: Poke> Poke for &'a mut T);
|
||||
|
||||
macro_rules! impl_for_primitive {
|
||||
($($ty:ty)+) => {
|
||||
$(unsafe impl Poke for $ty {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
size_of::<Self>()
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
write_verbatim(*self, bytes)
|
||||
}
|
||||
}
|
||||
impl Peek for $ty {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
read_verbatim(bytes, output)
|
||||
}
|
||||
})+
|
||||
};
|
||||
}
|
||||
|
||||
impl_for_primitive! {
|
||||
i8 i16 i32 i64 isize
|
||||
u8 u16 u32 u64 usize
|
||||
f32 f64
|
||||
}
|
||||
|
||||
unsafe impl Poke for bool {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
u8::max_size()
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
(*self as u8).poke_into(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl Peek for bool {
|
||||
#[inline]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let mut int_bool = 0u8;
|
||||
let ptr = <u8>::peek_from(bytes, &mut int_bool);
|
||||
*output = int_bool != 0;
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Poke for PhantomData<T> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
0
|
||||
}
|
||||
#[inline(always)]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Peek for PhantomData<T> {
|
||||
#[inline(always)]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
*output = PhantomData;
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Poke> Poke for Option<T> {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
u8::max_size() + T::max_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
match self {
|
||||
None => 0u8.poke_into(bytes),
|
||||
Some(ref v) => {
|
||||
let bytes = 1u8.poke_into(bytes);
|
||||
let bytes = v.poke_into(bytes);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Peek> Peek for Option<T> {
|
||||
#[inline]
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
let (variant, bytes) = peek_from_default::<u8>(bytes);
|
||||
match variant {
|
||||
0 => {
|
||||
*output = None;
|
||||
bytes
|
||||
}
|
||||
1 => {
|
||||
let (val, bytes) = peek_from_default(bytes);
|
||||
*output = Some(val);
|
||||
bytes
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_for_arrays {
|
||||
($($len:tt)+) => {
|
||||
$(unsafe impl<T: Poke> Poke for [T; $len] {
|
||||
fn max_size() -> usize {
|
||||
$len * T::max_size()
|
||||
}
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
self.iter().fold(bytes, |bytes, e| e.poke_into(bytes))
|
||||
}
|
||||
}
|
||||
impl<T: Peek> Peek for [T; $len] {
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
(&mut *output).iter_mut().fold(bytes, |bytes, e| <T>::peek_from(bytes, e))
|
||||
}
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
impl_for_arrays! {
|
||||
01 02 03 04 05 06 07 08 09 10
|
||||
11 12 13 14 15 16 17 18 19 20
|
||||
21 22 23 24 25 26 27 28 29 30
|
||||
31 32
|
||||
}
|
||||
|
||||
unsafe impl Poke for () {
|
||||
fn max_size() -> usize {
|
||||
0
|
||||
}
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl Peek for () {
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
*output = ();
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_for_tuple {
|
||||
($($n:tt: $ty:ident),+) => {
|
||||
unsafe impl<$($ty: Poke),+> Poke for ($($ty,)+) {
|
||||
#[inline(always)]
|
||||
fn max_size() -> usize {
|
||||
0 $(+ <$ty>::max_size())+
|
||||
}
|
||||
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
|
||||
$(let bytes = self.$n.poke_into(bytes);)+
|
||||
bytes
|
||||
}
|
||||
}
|
||||
impl<$($ty: Peek),+> Peek for ($($ty,)+) {
|
||||
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
|
||||
$(let bytes = $ty::peek_from(bytes, &mut (*output).$n);)+
|
||||
bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_for_tuple!(0: A);
|
||||
impl_for_tuple!(0: A, 1: B);
|
||||
impl_for_tuple!(0: A, 1: B, 2: C);
|
||||
impl_for_tuple!(0: A, 1: B, 2: C, 3: D);
|
||||
impl_for_tuple!(0: A, 1: B, 2: C, 3: D, 4: E);
|
19
third_party/webrender/peek-poke/src/slice_ext.rs
vendored
Normal file
19
third_party/webrender/peek-poke/src/slice_ext.rs
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub trait AsEndMutPtr<T> {
|
||||
fn as_end_mut_ptr(self) -> *mut T;
|
||||
}
|
||||
|
||||
impl<'a> AsEndMutPtr<u8> for &'a mut [u8] {
|
||||
fn as_end_mut_ptr(self) -> *mut u8 {
|
||||
unsafe { self.as_mut_ptr().add(self.len()) }
|
||||
}
|
||||
}
|
26
third_party/webrender/peek-poke/src/vec_ext.rs
vendored
Normal file
26
third_party/webrender/peek-poke/src/vec_ext.rs
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::vec::Vec;
|
||||
|
||||
pub trait VecExt {
|
||||
type Item;
|
||||
unsafe fn set_end_ptr(&mut self, end: *const Self::Item);
|
||||
}
|
||||
|
||||
impl<T> VecExt for Vec<T> {
|
||||
type Item = T;
|
||||
unsafe fn set_end_ptr(&mut self, end: *const T) {
|
||||
assert!(end as usize >= self.as_ptr() as usize);
|
||||
let new_len = end as usize - self.as_ptr() as usize;
|
||||
assert!(new_len <= self.capacity());
|
||||
self.set_len(new_len);
|
||||
}
|
||||
}
|
117
third_party/webrender/peek-poke/tests/max_size.rs
vendored
Normal file
117
third_party/webrender/peek-poke/tests/max_size.rs
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use peek_poke::{PeekPoke, Poke};
|
||||
use std::{marker::PhantomData, mem::size_of};
|
||||
|
||||
#[test]
|
||||
fn test_numbers() {
|
||||
assert_eq!(u8::max_size(), size_of::<u8>());
|
||||
assert_eq!(u16::max_size(), size_of::<u16>());
|
||||
assert_eq!(u32::max_size(), size_of::<u32>());
|
||||
assert_eq!(u64::max_size(), size_of::<u64>());
|
||||
assert_eq!(usize::max_size(), size_of::<usize>());
|
||||
assert_eq!(i8::max_size(), size_of::<i8>());
|
||||
assert_eq!(i16::max_size(), size_of::<i16>());
|
||||
assert_eq!(i32::max_size(), size_of::<i32>());
|
||||
assert_eq!(i64::max_size(), size_of::<i64>());
|
||||
assert_eq!(isize::max_size(), size_of::<isize>());
|
||||
// floating
|
||||
assert_eq!(f32::max_size(), size_of::<f32>());
|
||||
assert_eq!(f64::max_size(), size_of::<f64>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool() {
|
||||
assert_eq!(bool::max_size(), size_of::<u8>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option() {
|
||||
assert_eq!(
|
||||
Option::<usize>::max_size(),
|
||||
<u8>::max_size() + <usize>::max_size()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixed_size_array() {
|
||||
assert_eq!(<[u32; 32]>::max_size(), 32 * size_of::<u32>());
|
||||
assert_eq!(<[u64; 8]>::max_size(), 8 * size_of::<u64>());
|
||||
assert_eq!(<[u8; 19]>::max_size(), 19 * size_of::<u8>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple() {
|
||||
assert_eq!(<(isize, )>::max_size(), size_of::<isize>());
|
||||
assert_eq!(<(isize, isize, isize)>::max_size(), 3 * size_of::<isize>());
|
||||
assert_eq!(<(isize, ())>::max_size(), size_of::<isize>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_struct() {
|
||||
#[derive(Debug, PeekPoke)]
|
||||
struct Bar {
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
}
|
||||
|
||||
assert_eq!(<Bar>::max_size(), 3 * <u32>::max_size());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
#[derive(Clone, Copy, PeekPoke)]
|
||||
enum TestEnum {
|
||||
NoArg,
|
||||
OneArg(usize),
|
||||
Args(usize, usize),
|
||||
AnotherNoArg,
|
||||
StructLike { x: usize, y: f32 },
|
||||
}
|
||||
assert_eq!(
|
||||
TestEnum::max_size(),
|
||||
<u8>::max_size() + 2 * <usize>::max_size()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_cstyle() {
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, PeekPoke)]
|
||||
enum BorderStyle {
|
||||
None = 0,
|
||||
Solid = 1,
|
||||
Double = 2,
|
||||
Dotted = 3,
|
||||
Dashed = 4,
|
||||
Hidden = 5,
|
||||
Groove = 6,
|
||||
Ridge = 7,
|
||||
Inset = 8,
|
||||
Outset = 9,
|
||||
}
|
||||
assert_eq!(BorderStyle::max_size(), <u8>::max_size());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_phantom_data() {
|
||||
struct Bar;
|
||||
#[derive(PeekPoke)]
|
||||
struct Foo {
|
||||
x: u32,
|
||||
y: u32,
|
||||
_marker: PhantomData<Bar>,
|
||||
}
|
||||
assert_eq!(Foo::max_size(), 2 * size_of::<u32>())
|
||||
}
|
275
third_party/webrender/peek-poke/tests/round_trip.rs
vendored
Normal file
275
third_party/webrender/peek-poke/tests/round_trip.rs
vendored
Normal file
|
@ -0,0 +1,275 @@
|
|||
// Copyright 2019 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use peek_poke::{Peek, PeekPoke, Poke};
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
fn poke_into<V: Peek + Poke>(a: &V) -> Vec<u8> {
|
||||
let mut v = <Vec<u8>>::with_capacity(<V>::max_size());
|
||||
let end_ptr = unsafe { a.poke_into(v.as_mut_ptr()) };
|
||||
let new_size = end_ptr as usize - v.as_ptr() as usize;
|
||||
assert!(new_size <= v.capacity());
|
||||
unsafe {
|
||||
v.set_len(new_size);
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "option_copy"))]
|
||||
fn the_same<V>(a: V)
|
||||
where
|
||||
V: Debug + Default + PartialEq + Peek + Poke,
|
||||
{
|
||||
let v = poke_into(&a);
|
||||
let (b, end_ptr) = unsafe { peek_poke::peek_from_default(v.as_ptr()) };
|
||||
let size = end_ptr as usize - v.as_ptr() as usize;
|
||||
assert_eq!(size, v.len());
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[cfg(feature = "option_copy")]
|
||||
fn the_same<V>(a: V)
|
||||
where
|
||||
V: Copy + Debug + PartialEq + Peek + Poke,
|
||||
{
|
||||
let v = poke_into(&a);
|
||||
let mut b = a;
|
||||
let end_ptr = unsafe { b.peek_from(v.as_ptr()) };
|
||||
let size = end_ptr as usize - v.as_ptr() as usize;
|
||||
assert_eq!(size, v.len());
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numbers() {
|
||||
// unsigned positive
|
||||
the_same(5u8);
|
||||
the_same(5u16);
|
||||
the_same(5u32);
|
||||
the_same(5u64);
|
||||
the_same(5usize);
|
||||
// signed positive
|
||||
the_same(5i8);
|
||||
the_same(5i16);
|
||||
the_same(5i32);
|
||||
the_same(5i64);
|
||||
the_same(5isize);
|
||||
// signed negative
|
||||
the_same(-5i8);
|
||||
the_same(-5i16);
|
||||
the_same(-5i32);
|
||||
the_same(-5i64);
|
||||
the_same(-5isize);
|
||||
// floating
|
||||
the_same(-100f32);
|
||||
the_same(0f32);
|
||||
the_same(5f32);
|
||||
the_same(-100f64);
|
||||
the_same(5f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool() {
|
||||
the_same(true);
|
||||
the_same(false);
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "option_copy", feature = "option_default"))]
|
||||
#[test]
|
||||
fn test_option() {
|
||||
the_same(Some(5usize));
|
||||
//the_same(Some("foo bar".to_string()));
|
||||
the_same(None::<usize>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixed_size_array() {
|
||||
the_same([24u32; 32]);
|
||||
the_same([1u64, 2, 3, 4, 5, 6, 7, 8]);
|
||||
the_same([0u8; 19]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple() {
|
||||
the_same((1isize, ));
|
||||
the_same((1isize, 2isize, 3isize));
|
||||
the_same((1isize, ()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_struct() {
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, PeekPoke)]
|
||||
struct Bar {
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
#[cfg(any(feature = "option_copy", feature = "option_default"))]
|
||||
d: Option<u32>,
|
||||
}
|
||||
|
||||
the_same(Bar {
|
||||
a: 2,
|
||||
b: 4,
|
||||
c: 42,
|
||||
#[cfg(any(feature = "option_copy", feature = "option_default"))]
|
||||
d: None,
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PeekPoke)]
|
||||
enum TestEnum {
|
||||
NoArg,
|
||||
OneArg(usize),
|
||||
Args(usize, usize),
|
||||
AnotherNoArg,
|
||||
StructLike { x: usize, y: f32 },
|
||||
}
|
||||
|
||||
impl Default for TestEnum {
|
||||
fn default() -> Self {
|
||||
TestEnum::NoArg
|
||||
}
|
||||
}
|
||||
|
||||
the_same(TestEnum::NoArg);
|
||||
the_same(TestEnum::OneArg(4));
|
||||
the_same(TestEnum::Args(4, 5));
|
||||
the_same(TestEnum::AnotherNoArg);
|
||||
the_same(TestEnum::StructLike { x: 4, y: 3.14159 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_cstyle() {
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PeekPoke)]
|
||||
enum BorderStyle {
|
||||
None = 0,
|
||||
Solid = 1,
|
||||
Double = 2,
|
||||
Dotted = 3,
|
||||
Dashed = 4,
|
||||
Hidden = 5,
|
||||
Groove = 6,
|
||||
Ridge = 7,
|
||||
Inset = 8,
|
||||
Outset = 9,
|
||||
}
|
||||
|
||||
impl Default for BorderStyle {
|
||||
fn default() -> Self {
|
||||
BorderStyle::None
|
||||
}
|
||||
}
|
||||
|
||||
the_same(BorderStyle::None);
|
||||
the_same(BorderStyle::Solid);
|
||||
the_same(BorderStyle::Double);
|
||||
the_same(BorderStyle::Dotted);
|
||||
the_same(BorderStyle::Dashed);
|
||||
the_same(BorderStyle::Hidden);
|
||||
the_same(BorderStyle::Groove);
|
||||
the_same(BorderStyle::Ridge);
|
||||
the_same(BorderStyle::Inset);
|
||||
the_same(BorderStyle::Outset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_phantom_data() {
|
||||
struct Bar;
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)]
|
||||
struct Foo {
|
||||
x: u32,
|
||||
y: u32,
|
||||
_marker: PhantomData<Bar>,
|
||||
}
|
||||
the_same(Foo {
|
||||
x: 19,
|
||||
y: 42,
|
||||
_marker: PhantomData,
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic() {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)]
|
||||
struct Foo<T> {
|
||||
x: T,
|
||||
y: T,
|
||||
}
|
||||
the_same(Foo { x: 19.0, y: 42.0 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic_enum() {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, PeekPoke)]
|
||||
pub struct PropertyBindingKey<T> {
|
||||
pub id: usize,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PeekPoke)]
|
||||
pub enum PropertyBinding<T> {
|
||||
Value(T),
|
||||
Binding(PropertyBindingKey<T>, T),
|
||||
}
|
||||
|
||||
impl<T: Default> Default for PropertyBinding<T> {
|
||||
fn default() -> Self {
|
||||
PropertyBinding::Value(Default::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "extras", feature = "option_copy"))]
|
||||
mod extra_tests {
|
||||
use super::*;
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, Vector2D};
|
||||
use std::mem::size_of;
|
||||
|
||||
#[test]
|
||||
fn euclid_types() {
|
||||
the_same(Point2D::<f32>::new(1.0, 2.0));
|
||||
assert_eq!(Point2D::<f32>::max_size(), 2 * size_of::<f32>());
|
||||
|
||||
the_same(Rect::<f32>::new(
|
||||
Point2D::<f32>::new(0.0, 0.0),
|
||||
Size2D::<f32>::new(100.0, 80.0),
|
||||
));
|
||||
assert_eq!(Rect::<f32>::max_size(), 4 * size_of::<f32>());
|
||||
|
||||
the_same(SideOffsets2D::<f32>::new(0.0, 10.0, -1.0, -10.0));
|
||||
assert_eq!(SideOffsets2D::<f32>::max_size(), 4 * size_of::<f32>());
|
||||
|
||||
the_same(Transform3D::<f32>::identity());
|
||||
assert_eq!(Transform3D::<f32>::max_size(), 16 * size_of::<f32>());
|
||||
|
||||
the_same(Vector2D::<f32>::new(1.0, 2.0));
|
||||
assert_eq!(Vector2D::<f32>::max_size(), 2 * size_of::<f32>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn webrender_api_types() {
|
||||
type PipelineSourceId = i32;
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PeekPoke)]
|
||||
struct PipelineId(pub PipelineSourceId, pub u32);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PeekPoke)]
|
||||
struct ClipChainId(pub u64, pub PipelineId);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PeekPoke)]
|
||||
struct SpatialId(pub usize, pub PipelineId);
|
||||
|
||||
the_same(PipelineId(42, 2));
|
||||
the_same(ClipChainId(19u64, PipelineId(42, 2)));
|
||||
the_same(SpatialId(19usize, PipelineId(42, 2)));
|
||||
}
|
||||
}
|
6
third_party/webrender/rustfmt.toml
vendored
Normal file
6
third_party/webrender/rustfmt.toml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
reorder_imports = false
|
||||
reorder_imports_in_group = true
|
||||
reorder_imported_names = true
|
||||
error_on_line_overflow_comments = false
|
||||
max_width = 100
|
||||
spaces_around_ranges = true
|
39
third_party/webrender/servo-tidy.toml
vendored
Normal file
39
third_party/webrender/servo-tidy.toml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
[configs]
|
||||
skip-check-length = false
|
||||
skip-check-licenses = false
|
||||
check-alphabetical-order = false
|
||||
|
||||
[ignore]
|
||||
# Ignored packages with duplicated versions
|
||||
packages = [
|
||||
"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",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
# Files that are ignored for all tidy and lint checks.
|
||||
files = [
|
||||
"./wrench/src/egl.rs", # Copied from glutin
|
||||
]
|
||||
|
||||
# Many directories are currently ignored while we tidy things up
|
||||
# gradually.
|
||||
directories = [
|
||||
# Generated and upstream code combined with our own. Could use cleanup
|
||||
"./target",
|
||||
"./webrender/src",
|
||||
]
|
15
third_party/webrender/swgl/Cargo.toml
vendored
Normal file
15
third_party/webrender/swgl/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "swgl"
|
||||
version = "0.1.0"
|
||||
license = "MPL-2.0"
|
||||
authors = ["The Mozilla Project Developers"]
|
||||
build = "build.rs"
|
||||
description = "Software OpenGL implementation for WebRender."
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.46"
|
||||
glsl-to-cxx = { path = "../glsl-to-cxx" }
|
||||
webrender_build = { path = "../webrender_build" }
|
||||
|
||||
[dependencies]
|
||||
gleam = "0.12.0"
|
4
third_party/webrender/swgl/README.md
vendored
Normal file
4
third_party/webrender/swgl/README.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
swgl
|
||||
========
|
||||
|
||||
Software OpenGL implementation for WebRender
|
150
third_party/webrender/swgl/build.rs
vendored
Normal file
150
third_party/webrender/swgl/build.rs
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* 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/. */
|
||||
|
||||
extern crate cc;
|
||||
extern crate glsl_to_cxx;
|
||||
extern crate webrender_build;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
use webrender_build::shader::{ShaderFeatureFlags, get_shader_features};
|
||||
|
||||
// Shader key is in "name feature,feature" format.
|
||||
// File name needs to be formatted as "name_feature_feature".
|
||||
fn shader_file(shader_key: &str) -> String {
|
||||
shader_key.replace(' ', "_").replace(',', "_")
|
||||
}
|
||||
|
||||
fn write_load_shader(shader_keys: &[String]) {
|
||||
let mut load_shader = String::new();
|
||||
for s in shader_keys {
|
||||
let _ = write!(load_shader, "#include \"{}.h\"\n", shader_file(s));
|
||||
}
|
||||
load_shader.push_str("ProgramLoader load_shader(const char* name) {\n");
|
||||
for s in shader_keys {
|
||||
let _ = write!(load_shader, " if (!strcmp(name, \"{}\")) {{ return {}_program::loader; }}\n",
|
||||
s, shader_file(s));
|
||||
}
|
||||
load_shader.push_str(" return nullptr;\n}\n");
|
||||
std::fs::write(std::env::var("OUT_DIR").unwrap() + "/load_shader.h", load_shader).unwrap();
|
||||
}
|
||||
|
||||
fn process_imports(shader_dir: &str, shader: &str, included: &mut HashSet<String>, output: &mut String) {
|
||||
if !included.insert(shader.into()) {
|
||||
return;
|
||||
}
|
||||
println!("cargo:rerun-if-changed={}/{}.glsl", shader_dir, shader);
|
||||
let source = std::fs::read_to_string(format!("{}/{}.glsl", shader_dir, shader)).unwrap();
|
||||
for line in source.lines() {
|
||||
if line.starts_with("#include ") {
|
||||
let imports = line["#include ".len() ..].split(',');
|
||||
for import in imports {
|
||||
process_imports(shader_dir, import, included, output);
|
||||
}
|
||||
} else if line.starts_with("#version ") || line.starts_with("#extension ") {
|
||||
// ignore
|
||||
} else {
|
||||
output.push_str(line);
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_shader(shader_key: &str, shader_dir: &str) {
|
||||
let mut imported = String::from("#define SWGL 1\n");
|
||||
let _ = write!(imported, "#define WR_MAX_VERTEX_TEXTURE_WIDTH {}U\n",
|
||||
webrender_build::MAX_VERTEX_TEXTURE_WIDTH);
|
||||
|
||||
let (basename, features) =
|
||||
shader_key.split_at(shader_key.find(' ').unwrap_or(shader_key.len()));
|
||||
if !features.is_empty() {
|
||||
for feature in features.trim().split(',') {
|
||||
let _ = write!(imported, "#define WR_FEATURE_{}\n", feature);
|
||||
}
|
||||
}
|
||||
|
||||
process_imports(shader_dir, basename, &mut HashSet::new(), &mut imported);
|
||||
|
||||
let shader = shader_file(shader_key);
|
||||
|
||||
let out_dir = std::env::var("OUT_DIR").unwrap();
|
||||
let imp_name = format!("{}/{}.c", out_dir, shader);
|
||||
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.file(&imp_name);
|
||||
let vs = build.clone()
|
||||
.define("WR_VERTEX_SHADER", Some("1"))
|
||||
.expand();
|
||||
let fs = build.clone()
|
||||
.define("WR_FRAGMENT_SHADER", Some("1"))
|
||||
.expand();
|
||||
let vs_name = format!("{}/{}.vert", out_dir, shader);
|
||||
let fs_name = format!("{}/{}.frag", out_dir, shader);
|
||||
std::fs::write(&vs_name, vs).unwrap();
|
||||
std::fs::write(&fs_name, fs).unwrap();
|
||||
|
||||
let mut 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();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let shader_dir = match std::env::var("MOZ_SRC") {
|
||||
Ok(dir) => dir + "/gfx/wr/webrender/res",
|
||||
Err(_) => std::env::var("CARGO_MANIFEST_DIR").unwrap() + "/../webrender/res",
|
||||
};
|
||||
|
||||
let shader_flags =
|
||||
ShaderFeatureFlags::GL |
|
||||
ShaderFeatureFlags::DUAL_SOURCE_BLENDING;
|
||||
let mut shaders: Vec<String> = Vec::new();
|
||||
for (name, features) in get_shader_features(shader_flags) {
|
||||
shaders.extend(features.iter().map(|f| {
|
||||
if f.is_empty() { name.to_owned() } else { format!("{} {}", name, f) }
|
||||
}));
|
||||
}
|
||||
|
||||
shaders.sort();
|
||||
|
||||
for shader in &shaders {
|
||||
translate_shader(shader, &shader_dir);
|
||||
}
|
||||
|
||||
write_load_shader(&shaders);
|
||||
|
||||
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/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")
|
||||
.define("_GLIBCXX_USE_CXX11_ABI", Some("0"))
|
||||
.include(shader_dir)
|
||||
.include("src")
|
||||
.include(std::env::var("OUT_DIR").unwrap())
|
||||
.compile("gl_cc");
|
||||
}
|
4015
third_party/webrender/swgl/src/gl.cc
vendored
Normal file
4015
third_party/webrender/swgl/src/gl.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
176
third_party/webrender/swgl/src/gl_defs.h
vendored
Normal file
176
third_party/webrender/swgl/src/gl_defs.h
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* 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/. */
|
||||
|
||||
typedef int8_t GLbyte;
|
||||
typedef uint8_t GLubyte;
|
||||
typedef int16_t GLshort;
|
||||
typedef uint16_t GLushort;
|
||||
typedef int32_t GLint;
|
||||
typedef uint32_t GLuint;
|
||||
typedef int64_t GLint64;
|
||||
typedef uint64_t GLuint64;
|
||||
|
||||
typedef float GLfloat;
|
||||
typedef double GLdouble;
|
||||
|
||||
typedef uint32_t GLenum;
|
||||
typedef int32_t GLboolean;
|
||||
typedef uint32_t GLbitfield;
|
||||
|
||||
typedef int32_t GLsizei;
|
||||
typedef size_t GLsizeiptr;
|
||||
typedef intptr_t GLintptr;
|
||||
|
||||
#define GL_NO_ERROR 0
|
||||
|
||||
#define GL_RGBA32F 0x8814
|
||||
#define GL_RGBA8 0x8058
|
||||
#define GL_R8 0x8229
|
||||
#define GL_RGBA32I 0x8D82
|
||||
#define GL_BGRA8 0x93A1
|
||||
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
|
||||
#define GL_RED 0x1903
|
||||
#define GL_GREEN 0x1904
|
||||
#define GL_BLUE 0x1905
|
||||
#define GL_ALPHA 0x1906
|
||||
#define GL_RGB 0x1907
|
||||
#define GL_RGBA 0x1908
|
||||
#define GL_RGBA_INTEGER 0x8D99
|
||||
#define GL_BGRA 0x80E1
|
||||
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
#define GL_DEPTH_COMPONENT24 0x81A6
|
||||
#define GL_DEPTH_COMPONENT32 0x81A7
|
||||
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
|
||||
#define GL_READ_FRAMEBUFFER 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
|
||||
#define GL_RENDERBUFFER 0x8D41
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_DEPTH_ATTACHMENT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT 0x8D20
|
||||
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||
|
||||
#define GL_PIXEL_PACK_BUFFER 0x88EB
|
||||
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
|
||||
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
|
||||
#define GL_QUERY_RESULT 0x8866
|
||||
#define GL_QUERY_RESULT_AVAILABLE 0x8867
|
||||
#define GL_TIME_ELAPSED 0x88BF
|
||||
#define GL_SAMPLES_PASSED 0x8914
|
||||
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_TEXTURE_3D 0x806F
|
||||
#define GL_TEXTURE_2D_ARRAY 0x8C1A
|
||||
#define GL_TEXTURE_RECTANGLE 0x84F5
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
#define GL_TEXTURE2 0x84C2
|
||||
#define GL_TEXTURE3 0x84C3
|
||||
#define GL_TEXTURE4 0x84C4
|
||||
#define GL_TEXTURE5 0x84C5
|
||||
#define GL_TEXTURE6 0x84C6
|
||||
#define GL_TEXTURE7 0x84C7
|
||||
#define GL_TEXTURE8 0x84C8
|
||||
#define GL_TEXTURE9 0x84C9
|
||||
#define GL_TEXTURE10 0x84CA
|
||||
#define GL_TEXTURE11 0x84CB
|
||||
#define GL_TEXTURE12 0x84CC
|
||||
#define GL_TEXTURE13 0x84CD
|
||||
#define GL_TEXTURE14 0x84CE
|
||||
#define GL_TEXTURE15 0x84CF
|
||||
#define GL_MAX_TEXTURE_UNITS 0x84E2
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
|
||||
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_ZERO 0
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
#define GL_SRC1_ALPHA 0x8589
|
||||
#define GL_SRC1_COLOR 0x88F9
|
||||
#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
|
||||
#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
|
||||
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
#define GL_EQUAL 0x0202
|
||||
#define GL_LEQUAL 0x0203
|
||||
#define GL_GREATER 0x0204
|
||||
#define GL_NOTEQUAL 0x0205
|
||||
#define GL_GEQUAL 0x0206
|
||||
#define GL_ALWAYS 0x0207
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_DEPTH_WRITEMASK 0x0B72
|
||||
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
#define GL_LINE_LOOP 0x0002
|
||||
#define GL_LINE_STRIP 0x0003
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
#define GL_QUADS 0x0007
|
3240
third_party/webrender/swgl/src/glsl.h
vendored
Normal file
3240
third_party/webrender/swgl/src/glsl.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
12
third_party/webrender/swgl/src/lib.rs
vendored
Normal file
12
third_party/webrender/swgl/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* 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/. */
|
||||
|
||||
#![crate_name = "swgl"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern crate gleam;
|
||||
|
||||
mod swgl_fns;
|
||||
|
||||
pub use crate::swgl_fns::*;
|
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