Bug 1610738 - Add primitive flag to specify a compositor surface is preferred r=sotaro
authorGlenn Watson <gw@intuitionlibrary.com>
Wed, 22 Jan 2020 08:31:19 +0000
changeset 511208 71ed65a465d2bcfcf8e02ab8779c6700754ccdb2
parent 511207 01462d73b41ae9986c4a88b47729c19a37afe67b
child 511209 b6199c60bb46bea6369dfdaf2a2fa3b67486fc85
push id37047
push usermalexandru@mozilla.com
push dateThu, 23 Jan 2020 09:54:33 +0000
treeherdermozilla-central@a1669b599097 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1610738
milestone74.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1610738 - Add primitive flag to specify a compositor surface is preferred r=sotaro This allows calling code to specify whether a primitive would prefer to be promoted to a compositor surface and/or picture cache slice. This is a performance hint that can be used for large external primitives, such as videos and canvas elements. Differential Revision: https://phabricator.services.mozilla.com/D60637
gfx/webrender_bindings/src/bindings.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender_api/src/display_item.rs
gfx/wr/webrender_api/src/image.rs
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -346,31 +346,28 @@ impl<'a> MutByteSlice<'a> {
 #[repr(C)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct WrImageDescriptor {
     pub format: ImageFormat,
     pub width: i32,
     pub height: i32,
     pub stride: i32,
     pub opacity: OpacityType,
+    // TODO(gw): Remove this flag (use prim flags instead).
     pub prefer_compositor_surface: bool,
 }
 
 impl<'a> Into<ImageDescriptor> for &'a WrImageDescriptor {
     fn into(self) -> ImageDescriptor {
         let mut flags = ImageDescriptorFlags::empty();
 
         if self.opacity == OpacityType::Opaque {
             flags |= ImageDescriptorFlags::IS_OPAQUE;
         }
 
-        if self.prefer_compositor_surface {
-            flags |= ImageDescriptorFlags::PREFER_COMPOSITOR_SURFACE;
-        }
-
         ImageDescriptor {
             size: DeviceIntSize::new(self.width, self.height),
             stride: if self.stride != 0 {
                 Some(self.stride)
             } else {
                 None
             },
             format: self.format,
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -2980,16 +2980,20 @@ bitflags! {
         /// Force creation of a picture caching slice before this cluster.
         const CREATE_PICTURE_CACHE_PRE = 16;
         /// Force creation of a picture caching slice after this cluster.
         const CREATE_PICTURE_CACHE_POST = 32;
         /// If set, this cluster represents a scroll bar container.
         const SCROLLBAR_CONTAINER = 64;
         /// If set, this cluster contains clear rectangle primitives.
         const IS_CLEAR_PRIMITIVE = 128;
+        /// This is used as a performance hint - this primitive may be promoted to a native
+        /// compositor surface under certain (implementation specific) conditions. This
+        /// is typically used for large videos, and canvas elements.
+        const PREFER_COMPOSITOR_SURFACE = 256;
     }
 }
 
 /// Descriptor for a cluster of primitives. For now, this is quite basic but will be
 /// extended to handle more spatial clustering of primitives.
 #[cfg_attr(feature = "capture", derive(Serialize))]
 pub struct PrimitiveCluster {
     /// The positioning node for this cluster.
@@ -3107,16 +3111,20 @@ impl PrimitiveList {
         if prim_flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE) {
             flags.insert(ClusterFlags::IS_BACKFACE_VISIBLE);
         }
 
         if prim_flags.contains(PrimitiveFlags::IS_SCROLLBAR_CONTAINER) {
             flags.insert(ClusterFlags::SCROLLBAR_CONTAINER);
         }
 
+        if prim_flags.contains(PrimitiveFlags::PREFER_COMPOSITOR_SURFACE) {
+            flags.insert(ClusterFlags::PREFER_COMPOSITOR_SURFACE);
+        }
+
         // Insert the primitive into the first or last cluster as required
         match insert_position {
             PrimitiveListPosition::Begin => {
                 let mut cluster = PrimitiveCluster::new(
                     spatial_node_index,
                     flags,
                 );
                 cluster.push(prim_instance, prim_size);
--- a/gfx/wr/webrender_api/src/display_item.rs
+++ b/gfx/wr/webrender_api/src/display_item.rs
@@ -38,16 +38,20 @@ bitflags! {
     #[derive(Deserialize, MallocSizeOf, Serialize, PeekPoke)]
     pub struct PrimitiveFlags: u8 {
         /// The CSS backface-visibility property (yes, it can be really granular)
         const IS_BACKFACE_VISIBLE = 1 << 0;
         /// If set, this primitive represents a scroll bar container
         const IS_SCROLLBAR_CONTAINER = 1 << 1;
         /// If set, this primitive represents a scroll bar thumb
         const IS_SCROLLBAR_THUMB = 1 << 2;
+        /// This is used as a performance hint - this primitive may be promoted to a native
+        /// compositor surface under certain (implementation specific) conditions. This
+        /// is typically used for large videos, and canvas elements.
+        const PREFER_COMPOSITOR_SURFACE = 1 << 3;
     }
 }
 
 impl Default for PrimitiveFlags {
     fn default() -> Self {
         PrimitiveFlags::IS_BACKFACE_VISIBLE
     }
 }
--- a/gfx/wr/webrender_api/src/image.rs
+++ b/gfx/wr/webrender_api/src/image.rs
@@ -246,20 +246,16 @@ bitflags! {
         /// for opaque surfaces is an important optimization.
         const IS_OPAQUE = 1;
         /// Whether to allow the driver to automatically generate mipmaps. If images
         /// are already downscaled appropriately, mipmap generation can be wasted
         /// work, and cause performance problems on some cards/drivers.
         ///
         /// See https://github.com/servo/webrender/pull/2555/
         const ALLOW_MIPMAPS = 2;
-        /// This is used as a performance hint - this image may be promoted to a native
-        /// compositor surface under certain (implementation specific) conditions. This
-        /// is typically used for large videos, and canvas elements.
-        const PREFER_COMPOSITOR_SURFACE = 4;
     }
 }
 
 /// Metadata (but not storage) describing an image In WebRender.
 #[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
 pub struct ImageDescriptor {
     /// Format of the image data.
     pub format: ImageFormat,
@@ -320,22 +316,16 @@ impl ImageDescriptor {
     pub fn is_opaque(&self) -> bool {
         self.flags.contains(ImageDescriptorFlags::IS_OPAQUE)
     }
 
     /// Returns true if this descriptor allows mipmaps
     pub fn allow_mipmaps(&self) -> bool {
         self.flags.contains(ImageDescriptorFlags::ALLOW_MIPMAPS)
     }
-
-    /// Returns true if this descriptor wants to be drawn as a native
-    /// compositor surface.
-    pub fn prefer_compositor_surface(&self) -> bool {
-        self.flags.contains(ImageDescriptorFlags::PREFER_COMPOSITOR_SURFACE)
-    }
 }
 
 /// Represents the backing store of an arbitrary series of pixels for display by
 /// WebRender. This storage can take several forms.
 #[derive(Clone, Debug, Serialize, Deserialize)]
 pub enum ImageData {
     /// A simple series of bytes, provided by the embedding and owned by WebRender.
     /// The format is stored out-of-band, currently in ImageDescriptor.