diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-08-15 16:00:10 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-15 16:00:10 -0500 |
commit | 90f55ea4580e2a15f7d70d0491444f18b972d450 (patch) | |
tree | c85f3cb5d55babab03d56dac8b0d10d588b0a0f9 /components/canvas/webgl_mode | |
parent | 2e60b27a2186a8cba4b952960155dfcf3f47d7db (diff) | |
parent | 703962fe61d673536eb982b45795ae13748f0f6a (diff) | |
download | servo-90f55ea4580e2a15f7d70d0491444f18b972d450.tar.gz servo-90f55ea4580e2a15f7d70d0491444f18b972d450.zip |
Auto merge of #17891 - MortimerGoro:webgl_move, r=glennw,emilio
Improved WebGL architecture
<!-- Please describe your changes on the following line: -->
Info about the big picture and the goals of the WebGL refactor in this thread: https://groups.google.com/forum/#!topic/mozilla.dev.servo/0WMGz60kKzQ
I tried to reduce this PR as much as possible as requested in the thread. I'll do separate PRs for other features (e.g.: Batch messages or use shared memory to improve frame times) or fixes.
Some tips to ease the review process:
- Most changes in DOM objects follow the same pattern (remove CanvasMsg wrapper and use the new sender method).
- WebGLCommands are the same ones as before (moved from webrender_api). So those lines are already reviewed.
- See WebGL traits in [components/canvas_traits/webgl.rs](https://github.com/servo/servo/pull/17891/files#diff-8701045d01505418701d0631d4d45562)
- See WebGLThread and WR External Image bridge in [components/canvas/webgl_thread.rs](https://github.com/servo/servo/pull/17891/files#diff-281554879f39a2a041f7a69d442a5d2e)
- The implementation submitted in this PR creates a single `WebGLThread` for all ScriptThread/Pipelines. See that in [components/canvas/webgl_mode/inprocess.rs](https://github.com/servo/servo/pull/17891/files#diff-250070c6c5a38c7f9fa0f5b3c101f68b)
The conformance tests will help to guarantee that we don't miss anything.
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17891)
<!-- Reviewable:end -->
Diffstat (limited to 'components/canvas/webgl_mode')
-rw-r--r-- | components/canvas/webgl_mode/inprocess.rs | 95 | ||||
-rw-r--r-- | components/canvas/webgl_mode/mod.rs | 6 |
2 files changed, 101 insertions, 0 deletions
diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs new file mode 100644 index 00000000000..257f1395545 --- /dev/null +++ b/components/canvas/webgl_mode/inprocess.rs @@ -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/. */ + +use ::gl_context::GLContextFactory; +use ::webgl_thread::{WebGLExternalImageApi, WebGLExternalImageHandler, WebGLThreadObserver, WebGLThread}; +use canvas_traits::webgl::{WebGLChan, WebGLContextId, WebGLMsg, WebGLPipeline, WebGLReceiver}; +use canvas_traits::webgl::{WebGLSender, WebVRCommand, WebVRRenderHandler}; +use canvas_traits::webgl::webgl_channel; +use euclid::Size2D; +use std::marker::PhantomData; +use webrender; +use webrender_api; + +/// WebGL Threading API entry point that lives in the constellation. +pub struct WebGLThreads(WebGLSender<WebGLMsg>); + +impl WebGLThreads { + /// Creates a new WebGLThreads object + pub fn new(gl_factory: GLContextFactory, + webrender_api_sender: webrender_api::RenderApiSender, + webvr_compositor: Option<Box<WebVRRenderHandler>>) + -> (WebGLThreads, Box<webrender::ExternalImageHandler>) { + // This implementation creates a single `WebGLThread` for all the pipelines. + let channel = WebGLThread::start(gl_factory, + webrender_api_sender, + webvr_compositor.map(|c| WebVRRenderWrapper(c)), + PhantomData); + let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(channel.clone())); + (WebGLThreads(channel), Box::new(external)) + } + + /// Gets the WebGLThread handle for each script pipeline. + pub fn pipeline(&self) -> WebGLPipeline { + // This mode creates a single thread, so the existing WebGLChan is just cloned. + WebGLPipeline(WebGLChan(self.0.clone())) + } + + /// Sends a exit message to close the WebGLThreads and release all WebGLContexts. + pub fn exit(&self) -> Result<(), &'static str> { + self.0.send(WebGLMsg::Exit).map_err(|_| "Failed to send Exit message") + } +} + +/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads. +struct WebGLExternalImages { + webgl_channel: WebGLSender<WebGLMsg>, + // Used to avoid creating a new channel on each received WebRender request. + lock_channel: (WebGLSender<(u32, Size2D<i32>)>, WebGLReceiver<(u32, Size2D<i32>)>), +} + +impl WebGLExternalImages { + fn new(channel: WebGLSender<WebGLMsg>) -> Self { + Self { + webgl_channel: channel, + lock_channel: webgl_channel().unwrap(), + } + } +} + +impl WebGLExternalImageApi for WebGLExternalImages { + fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) { + self.webgl_channel.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())).unwrap(); + self.lock_channel.1.recv().unwrap() + } + + fn unlock(&mut self, ctx_id: WebGLContextId) { + self.webgl_channel.send(WebGLMsg::Unlock(ctx_id)).unwrap(); + } +} + +/// Custom observer used in a `WebGLThread`. +impl WebGLThreadObserver for PhantomData<()> { + fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) { + debug!("WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); + } + + fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) { + debug!("WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); + } + + fn on_context_delete(&mut self, ctx_id: WebGLContextId) { + debug!("WebGLContext deleted (ctx_id: {:?})", ctx_id); + } +} + + +/// Wrapper to send WebVR commands used in `WebGLThread`. +struct WebVRRenderWrapper(Box<WebVRRenderHandler>); + +impl WebVRRenderHandler for WebVRRenderWrapper { + fn handle(&mut self, command: WebVRCommand, texture: Option<(u32, Size2D<i32>)>) { + self.0.handle(command, texture); + } +} diff --git a/components/canvas/webgl_mode/mod.rs b/components/canvas/webgl_mode/mod.rs new file mode 100644 index 00000000000..660818fb096 --- /dev/null +++ b/components/canvas/webgl_mode/mod.rs @@ -0,0 +1,6 @@ +/* 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/. */ + +mod inprocess; +pub use self::inprocess::WebGLThreads; |