Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an example app using the DirectComposition API #2458

Merged
merged 75 commits into from
Mar 12, 2018
Merged

Conversation

SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Feb 22, 2018

This PR is not intended to be merged, only to have a place to discuss while showing some code.

This is a standalone demo app that uses the winit crate to create a window, then uses COM APIs through the winapi crate to set up DirectComposition in this window with two "visuals", each a rectangle of a given size with its own Direct3D swap chain, render target, and context. One of the two visuals scrolls on MouseWheel events, without either of them being re-rendered.

For now ClearRenderTargetView is used to fill each rectangle with a solid RGBA color. This is intended to be replaced with rendering arbitrary Direct3D content.

A next step is probably integrating ANGLE so that separate OpenGL contexts can be created to render into respective visuals. I’m not sure where to start for this, though. ANGLE’s own documentation seems to be more about building than APIs.

Looking up directcomposition angle specifically does yield some interesting things. It looks like ANGLE itself has some explicit support for DirectComposition:

CC @jrmuizel @pcwalton @glennw


Update: the demo now renders with WebRender and ANGLE:

capture2


This change is Reviewable


impl<T> ops::DerefMut for ComPtr<T> where T: Interface {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not sound, right? ComPtr is shared, so I can effectively do:

let mut a: ComPtr<T> = something_that_returns_a_comptr();
let mut b = a.clone();

let mut a: &mut T = &mut *a;
let mut b: &mut T = &mut *b;

And get mutable aliasing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right. I added this hoping to use deref coercions to get *mut IUnknown, ended up doing something else (see the as_ptr function), and forgot to remove it. retep998 had already pointed out that even mem::replace would be enough to make Bad Things happen if DerefMut exists.

@jrmuizel
Copy link
Collaborator

The relevant code for hooking up ANGLE to DirectComposite exists in Chrome and Gecko in the following places:

https://cs.chromium.org/chromium/src/gpu/ipc/service/direct_composition_child_surface_win.cc?l=248&rcl=0a4de6f832840ebcd642c30b9e028d9853811af3

https://searchfox.org/mozilla-central/rev/9a8d3f8191b15cdca89a7ce044c7bea2dd0462dc/gfx/webrender_bindings/RenderCompositorANGLE.cpp#259

@sotaroikeda
Copy link
Contributor

sotaroikeda commented Feb 23, 2018

Bug 1191971 has wip patches to add DirectComposition support to RenderCompositorANGLE.cpp of gecko.

@sotaroikeda
Copy link
Contributor

sotaroikeda commented Feb 23, 2018

ANGLE's support for DirectComposition seemed to be added originally for chromium's video overlay support. But current chromiun seemed not use it now. Instead, DirectCompositionSurfaceWin and DirectCompositionChildSurfaceWin are used.

One tricky thing about video overlay is that we need to swith between video overlay rendering and normal WebRender video rendering depends on scene situation.

In chromium, overlay usage decision is done around DirectRenderer, OverlayProcessor and CompositorOverlayCandidateValidatorWin.
https://cs.chromium.org/chromium/src/components/viz/service/display/direct_renderer.cc
https://cs.chromium.org/chromium/src/components/viz/service/display/overlay_processor.cc
https://cs.chromium.org/chromium/src/components/viz/service/display_embedder/compositor_overlay_candidate_validator_win.cc

Actual DirectComposition layer is managed by DCLayerTree
https://cs.chromium.org/chromium/src/gpu/ipc/service/direct_composition_surface_win.cc?l=167

@SimonSapin
Copy link
Member Author

@jrmuizel In what form would you want to merge this? I intended this code as a stand-alone, it’s only in a branch of this repo because I didn’t bother creating a separate repo. If this is to become a library, what should be in scope for it? (For example, creating a D3D device? Creating a window?)

At first I tried having a single renderer with multiple documents, but as far as I can tell both documents ended up rendered in both visuals. I think that what would be needed is some API to tell WR to only render one document.

@SimonSapin
Copy link
Member Author

Also if we want this to be more than a demo we probably need to get full ANGLE packaged in a new crate, or expand https://github.com/servo/angle.

@SimonSapin
Copy link
Member Author

get full ANGLE packaged in a new crate

I did this at https://github.com/servo/mozangle, by reading importing gfx/angle from mozilla-central and reading the generated moz.build files.

This demo app should now build with just cargo build, no need to build ANGLE separately.

CC @jdashg @jrmuizel @emilio

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #2492) made this pull request unmergeable. Please resolve the merge conflicts.

@SimonSapin SimonSapin changed the title (Do not merge) Prototype with the DirectComposition API Add an example app using the DirectComposition API Mar 9, 2018
@SimonSapin
Copy link
Member Author

This hits rust-lang/cargo#4866 (comment) when .travis.yml runs cargo test --all, the Windows-only mozangle/egl feature ends up being selected even on non-Windows…

Perhaps I should make that Cargo feature be a no-op rather than a compile error, on platforms where it’s not supported?

@SimonSapin
Copy link
Member Author

I’ve also made AppVeyor (try to) build this app, but:

gfx/angle/checkout/src/common/platform.h:65:10: fatal error: d3d11_3.h: No such file or directory

@SimonSapin
Copy link
Member Author

Oh, appveyor.yml uses the x86_64-pc-windows-gnu toolchain, whereas I’m using MSVC on my machine.

@jrmuizel
Copy link
Collaborator

jrmuizel commented Mar 9, 2018

We should switch appveyor to to the msvc toolchain instead of gnu one. We don't use the gnu one in production

@SimonSapin
Copy link
Member Author

r? @glennw

@glennw
Copy link
Member

glennw commented Mar 12, 2018

@bors-servo r+

@bors-servo
Copy link
Contributor

📌 Commit c4a859d has been approved by glennw

@bors-servo
Copy link
Contributor

⌛ Testing commit c4a859d with merge 4ccaede...

bors-servo pushed a commit that referenced this pull request Mar 12, 2018
Add an example app using the DirectComposition API

~This PR is not intended to be merged, only to have a place to discuss while showing some code.~

<img src=https://user-images.githubusercontent.com/291359/36546140-e7a15da0-17ea-11e8-92fa-af320b32f4f2.PNG width=300>

This is a standalone demo app that uses the `winit` crate to create a window, then uses COM APIs through the `winapi` crate to set up DirectComposition in this window with two "visuals", each a rectangle of a given size with its own Direct3D swap chain, render target, and context. One of the two visuals scrolls on `MouseWheel` events, without either of them being re-rendered.

For now `ClearRenderTargetView` is used to fill each rectangle with a solid RGBA color. This is intended to be replaced with rendering arbitrary Direct3D content.

~A next step is probably integrating ANGLE so that separate OpenGL contexts can be created to render into respective visuals. I’m not sure where to start for this, though. ANGLE’s own documentation seems to be more about building than APIs.~

Looking up `directcomposition angle` specifically does yield some interesting things. It looks like ANGLE itself has some explicit support for DirectComposition:

* https://bugs.chromium.org/p/chromium/issues/detail?id=524838
* https://bugs.chromium.org/p/angleproject/issues/detail?id=1178
* https://github.com/google/angle/blob/master/extensions/EGL_ANGLE_direct_composition.txt

CC @jrmuizel @pcwalton @glennw

----

**Update:** the demo now renders with WebRender and ANGLE:

![capture2](https://user-images.githubusercontent.com/291359/36852686-a4fa993a-1d6c-11e8-8650-e245a2e62ace.PNG)

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/2458)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - status-appveyor, status-taskcluster, status-travis
Approved by: glennw
Pushing 4ccaede to master...

@bors-servo bors-servo merged commit c4a859d into master Mar 12, 2018
@SimonSapin SimonSapin deleted the directcomposition branch March 12, 2018 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants