Commit dbce0f38 authored by Connor Brewster's avatar Connor Brewster
Browse files

Bug 1178765 - Part 2: Implement backdrop-filter in WebRender r=gw

Differential Revision: https://phabricator.services.mozilla.com/D39098

--HG--
extra : moz-landing-system : lando
parent afa1fcba
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ bool gecko_profiler_thread_is_being_profiled();
  macro(radial_grad);                      \
  macro(picture);                          \
  macro(text_run);                         \
  macro(filterdata);
  macro(filterdata);                       \
  macro(backdrop);

// Prelude of types necessary before including webrender_ffi_generated.h
namespace mozilla {
+74 −2
Original line number Diff line number Diff line
@@ -1632,9 +1632,19 @@ impl BatchBuilder {
                                let uv_rect_address = render_tasks[cache_task_id]
                                    .get_texture_address(gpu_cache)
                                    .as_int();
                                let textures = match render_tasks[cache_task_id].saved_index {
                                    Some(saved_index) => BatchTextures {
                                        colors: [
                                            TextureSource::RenderTaskCache(saved_index, Swizzle::default()),
                                            TextureSource::PrevPassAlpha,
                                            TextureSource::Invalid,
                                        ]
                                    },
                                    None => BatchTextures::render_target_cache(),
                                };
                                let batch_params = BrushBatchParameters::shared(
                                    BrushBatchKind::Image(ImageBufferKind::Texture2DArray),
                                    BatchTextures::render_target_cache(),
                                    textures,
                                    [
                                        ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
                                        RasterizationSpace::Screen as i32,
@@ -2367,6 +2377,67 @@ impl BatchBuilder {
                    );
                }
            }
            PrimitiveInstanceKind::Backdrop { data_handle } => {
                let prim_data = &ctx.data_stores.backdrop[data_handle];
                let backdrop_pic_index = prim_data.kind.pic_index;
                let backdrop_surface_index = ctx.prim_store.pictures[backdrop_pic_index.0]
                    .raster_config
                    .as_ref()
                    .expect("backdrop surface should be alloc by now")
                    .surface_index;

                let backdrop_task_id = ctx.surfaces[backdrop_surface_index.0]
                    .render_tasks
                    .as_ref()
                    .expect("backdrop task not available")
                    .root;

                let backdrop_uv_rect_address = render_tasks[backdrop_task_id]
                    .get_texture_address(gpu_cache)
                    .as_int();

                let textures = BatchTextures::render_target_cache();
                let batch_key = BatchKey::new(
                    BatchKind::Brush(BrushBatchKind::Image(ImageBufferKind::Texture2DArray)),
                    BlendMode::PremultipliedAlpha,
                    textures,
                );

                let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
                let backdrop_picture = &ctx.prim_store.pictures[backdrop_pic_index.0];
                let prim_header = PrimitiveHeader {
                    local_rect: backdrop_picture.snapped_local_rect,
                    local_clip_rect: prim_info.combined_local_clip_rect,
                    transform_id,
                    snap_offsets,
                    specific_prim_address: prim_cache_address,
                };

                let prim_header_index = prim_headers.push(
                    &prim_header,
                    z_id,
                    [
                        ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
                        RasterizationSpace::Screen as i32,
                        get_shader_opacity(1.0),
                        0
                    ],
                );

                self.add_brush_instance_to_batches(
                    batch_key,
                    batch_features,
                    bounding_rect,
                    z_id,
                    INVALID_SEGMENT_INDEX,
                    EdgeAaSegmentMask::empty(),
                    OPAQUE_TASK_ADDRESS,
                    BrushFlags::empty(),
                    prim_header_index,
                    backdrop_uv_rect_address,
                    prim_vis_mask,
                );
            }
        }
    }

@@ -2695,7 +2766,8 @@ impl PrimitiveInstance {
            PrimitiveInstanceKind::RadialGradient { .. } |
            PrimitiveInstanceKind::PushClipChain |
            PrimitiveInstanceKind::PopClipChain |
            PrimitiveInstanceKind::Clear { .. } => {
            PrimitiveInstanceKind::Clear { .. } |
            PrimitiveInstanceKind::Backdrop { .. } => {
                return true;
            }
        };
+416 −164

File changed.

Preview size limit exceeded, changes collapsed.

+48 −33
Original line number Diff line number Diff line
@@ -1565,7 +1565,8 @@ impl TileCacheInstance {
            PrimitiveInstanceKind::Clear { .. } |
            PrimitiveInstanceKind::NormalBorder { .. } |
            PrimitiveInstanceKind::LinearGradient { .. } |
            PrimitiveInstanceKind::RadialGradient { .. } => {
            PrimitiveInstanceKind::RadialGradient { .. } |
            PrimitiveInstanceKind::Backdrop { .. } => {
                // These don't contribute dependencies
            }
        };
@@ -1891,6 +1892,8 @@ bitflags! {
        const CLIP = 2;
        /// Preserve-3D requires a surface for plane-splitting.
        const PRESERVE3D = 4;
        /// A backdrop that is reused which requires a surface.
        const BACKDROP = 8;
    }
}

@@ -2162,6 +2165,10 @@ impl PrimitiveList {
                    let data = &interners.yuv_image[data_handle];
                    (data.is_backface_visible, data.prim_size)
                }
                PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
                    let data = &interners.backdrop[data_handle];
                    (data.is_backface_visible, data.prim_size)
                }
                PrimitiveInstanceKind::PushClipChain |
                PrimitiveInstanceKind::PopClipChain => {
                    (true, LayoutSize::zero())
@@ -2303,7 +2310,7 @@ pub struct PicturePrimitive {
    pub tile_cache: Option<Box<TileCacheInstance>>,

    /// The config options for this picture.
    options: PictureOptions,
    pub options: PictureOptions,
}

impl PicturePrimitive {
@@ -2556,6 +2563,7 @@ impl PicturePrimitive {
                            blur_std_deviation * scale_factors.0,
                            blur_std_deviation * scale_factors.1
                        );
                        let device_rect = if self.options.inflate_if_required {
                            let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
                            let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil();

@@ -2589,6 +2597,11 @@ impl PicturePrimitive {
                                blur_std_deviation,
                            );

                            device_rect
                        } else {
                            clipped
                        };

                        let uv_rect_kind = calculate_uv_rect_kind(
                            &pic_rect,
                            &transform,
@@ -3325,7 +3338,9 @@ impl PicturePrimitive {
            let surface = state.current_surface_mut();
            // Inflate the local bounding rect if required by the filter effect.
            // This inflaction factor is to be applied to the surface itself.
            if self.options.inflate_if_required {
                surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor);
            }

            let mut surface_rect = surface.rect * Scale::new(1.0);

+105 −0
Original line number Diff line number Diff line
/* 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 api::units::*;
use crate::clip_scroll_tree::SpatialNodeIndex;
use crate::intern::{Internable, InternDebug, Handle as InternHandle};
use crate::internal_types::LayoutPrimitiveInfo;
use crate::prim_store::{
    InternablePrimitive, PictureIndex, PrimitiveInstanceKind, PrimKey, PrimKeyCommonData, PrimTemplate,
    PrimTemplateCommonData, PrimitiveStore, PrimitiveSceneData, RectangleKey,
};

#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, PartialEq, MallocSizeOf, Hash)]
pub struct Backdrop {
    pub pic_index: PictureIndex,
    pub spatial_node_index: SpatialNodeIndex,
    pub border_rect: RectangleKey,
}

impl From<Backdrop> for BackdropData {
    fn from(backdrop: Backdrop) -> Self {
        BackdropData {
            pic_index: backdrop.pic_index,
            spatial_node_index: backdrop.spatial_node_index,
            border_rect: backdrop.border_rect.into(),
        }
    }
}

pub type BackdropKey = PrimKey<Backdrop>;

impl BackdropKey {
    pub fn new(
        is_backface_visible: bool,
        prim_size: LayoutSize,
        backdrop: Backdrop,
    ) -> Self {
        BackdropKey {
            common: PrimKeyCommonData {
                is_backface_visible,
                prim_size: prim_size.into(),
            },
            kind: backdrop,
        }
    }
}

impl InternDebug for BackdropKey {}

#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, MallocSizeOf)]
pub struct BackdropData {
    pub pic_index: PictureIndex,
    pub spatial_node_index: SpatialNodeIndex,
    pub border_rect: LayoutRect,
}

pub type BackdropTemplate = PrimTemplate<BackdropData>;

impl From<BackdropKey> for BackdropTemplate {
    fn from(backdrop: BackdropKey) -> Self {
        let common = PrimTemplateCommonData::with_key_common(backdrop.common);

        BackdropTemplate {
            common,
            kind: backdrop.kind.into(),
        }
    }
}

pub type BackdropDataHandle = InternHandle<Backdrop>;

impl Internable for Backdrop {
    type Key = BackdropKey;
    type StoreData = BackdropTemplate;
    type InternData = PrimitiveSceneData;
}

impl InternablePrimitive for Backdrop {
    fn into_key(
        self,
        info: &LayoutPrimitiveInfo,
    ) -> BackdropKey {
        BackdropKey::new(
            info.is_backface_visible,
            info.rect.size,
            self
        )
    }

    fn make_instance_kind(
        _key: BackdropKey,
        data_handle: BackdropDataHandle,
        _prim_store: &mut PrimitiveStore,
        _reference_frame_relative_offset: LayoutVector2D,
    ) -> PrimitiveInstanceKind {
        PrimitiveInstanceKind::Backdrop {
            data_handle,
        }
    }
}
Loading