aboutsummaryrefslogtreecommitdiffstats
path: root/components/webrender_traits/lib.rs
diff options
context:
space:
mode:
authorFernando Jiménez Moreno <ferjmoreno@gmail.com>2019-06-25 19:42:47 +0200
committerFernando Jiménez Moreno <ferjmoreno@gmail.com>2019-07-04 10:26:47 +0200
commitba9cf85fb3c1697998abab92488a0ab7ecdf431d (patch)
treedb5d5a66e9272469a446d7fd49e886e24c3074b2 /components/webrender_traits/lib.rs
parent7d589ed4f5762ee185b60a34a76bb59cdf05a536 (diff)
downloadservo-ba9cf85fb3c1697998abab92488a0ab7ecdf431d.tar.gz
servo-ba9cf85fb3c1697998abab92488a0ab7ecdf431d.zip
Webrender external image handler demux
Diffstat (limited to 'components/webrender_traits/lib.rs')
-rw-r--r--components/webrender_traits/lib.rs108
1 files changed, 108 insertions, 0 deletions
diff --git a/components/webrender_traits/lib.rs b/components/webrender_traits/lib.rs
new file mode 100644
index 00000000000..7a2f3b4b69b
--- /dev/null
+++ b/components/webrender_traits/lib.rs
@@ -0,0 +1,108 @@
+/* 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/. */
+
+#![crate_name = "webrender_traits"]
+#![crate_type = "rlib"]
+#![deny(unsafe_code)]
+
+use euclid::Size2D;
+use std::collections::HashMap;
+
+/// This trait is used as a bridge between the different GL clients
+/// in Servo that handles WebRender ExternalImages and the WebRender
+/// ExternalImageHandler API.
+//
+/// This trait is used to notify lock/unlock messages and get the
+/// required info that WR needs.
+pub trait WebrenderExternalImageApi {
+ fn lock(&mut self, id: u64) -> (u32, Size2D<i32>);
+ fn unlock(&mut self, id: u64);
+}
+
+/// Type of Webrender External Image Handler.
+pub enum WebrenderImageHandlerType {
+ WebGL,
+ Media,
+}
+
+/// WebRender External Image Handler implementation.
+pub struct WebrenderExternalImageHandler {
+ webgl_handler: Option<Box<dyn WebrenderExternalImageApi>>,
+ media_handler: Option<Box<dyn WebrenderExternalImageApi>>,
+ //XXX(ferjm) register external images.
+ external_images: HashMap<webrender_api::ExternalImageId, WebrenderImageHandlerType>,
+}
+
+impl WebrenderExternalImageHandler {
+ pub fn new() -> Self {
+ Self {
+ webgl_handler: None,
+ media_handler: None,
+ external_images: HashMap::new(),
+ }
+ }
+
+ pub fn set_handler(
+ &mut self,
+ handler: Box<dyn WebrenderExternalImageApi>,
+ handler_type: WebrenderImageHandlerType,
+ ) {
+ match handler_type {
+ WebrenderImageHandlerType::WebGL => self.webgl_handler = Some(handler),
+ WebrenderImageHandlerType::Media => self.media_handler = Some(handler),
+ }
+ }
+}
+
+impl webrender::ExternalImageHandler for WebrenderExternalImageHandler {
+ /// Lock the external image. Then, WR could start to read the
+ /// image content.
+ /// The WR client should not change the image content until the
+ /// unlock() call.
+ fn lock(
+ &mut self,
+ key: webrender_api::ExternalImageId,
+ _channel_index: u8,
+ _rendering: webrender_api::ImageRendering,
+ ) -> webrender::ExternalImage {
+ if let Some(handler_type) = self.external_images.get(&key) {
+ // It is safe to unwrap the handlers here because we forbid registration
+ // for specific types that has no handler set.
+ // XXX(ferjm) make this ^ true.
+ let (texture_id, size) = match handler_type {
+ WebrenderImageHandlerType::WebGL => {
+ self.webgl_handler.as_mut().unwrap().lock(key.0)
+ },
+ WebrenderImageHandlerType::Media => {
+ self.media_handler.as_mut().unwrap().lock(key.0)
+ },
+ };
+ webrender::ExternalImage {
+ uv: webrender_api::TexelRect::new(0.0, 0.0, size.width as f32, size.height as f32),
+ source: webrender::ExternalImageSource::NativeTexture(texture_id),
+ }
+ } else {
+ unreachable!()
+ }
+ }
+
+ /// Unlock the external image. The WR should not read the image
+ /// content after this call.
+ fn unlock(&mut self, key: webrender_api::ExternalImageId, _channel_index: u8) {
+ if let Some(handler_type) = self.external_images.get(&key) {
+ // It is safe to unwrap the handlers here because we forbid registration
+ // for specific types that has no handler set.
+ match handler_type {
+ WebrenderImageHandlerType::WebGL => {
+ self.webgl_handler.as_mut().unwrap().unlock(key.0)
+ },
+ WebrenderImageHandlerType::Media => {
+ self.media_handler.as_mut().unwrap().unlock(key.0)
+ },
+ };
+ } else {
+ unreachable!();
+ }
+ }
+}