Merge autoland to mozilla-central a=merge

This commit is contained in:
Norisz Fay 2022-05-25 12:21:01 +03:00
Родитель 9d3026616c 8a61d1ea98
Коммит d2a8e14b56
27 изменённых файлов: 693 добавлений и 193 удалений

Просмотреть файл

@ -698,8 +698,19 @@ var gHistorySwipeAnimation = {
return;
}
let box = this._prevBox.style.opacity > 0 ? this._prevBox : this._nextBox;
if (box.style.opacity > 0) {
let prevOpacity = window
.getComputedStyle(this._prevBox)
.getPropertyValue("opacity");
let nextOpacity = window
.getComputedStyle(this._nextBox)
.getPropertyValue("opacity");
let box = null;
if (prevOpacity > 0) {
box = this._prevBox;
} else if (nextOpacity > 0) {
box = this._nextBox;
}
if (box != null) {
this._isStoppingAnimation = true;
box.style.transition = "opacity 0.2s cubic-bezier(.07,.95,0,1)";
box.addEventListener("transitionend", this, true);

Просмотреть файл

@ -90,6 +90,7 @@ function originQuery(where) {
OR (host BETWEEN 'www.' || :searchString AND 'www.' || :searchString || X'FFFF')
)
SELECT :query_type AS query_type,
:searchString AS search_string,
iif(instr(host, :searchString) = 1, host, fixed) || '/' AS host_fixed,
ifnull(:prefix, host_prefix) || host || '/' AS url
FROM origins
@ -106,6 +107,7 @@ function urlQuery(where1, where2) {
// types a key when the urlbar value looks like a URL with a path.
return `/* do not warn (bug no): cannot use an index to sort */
SELECT :query_type AS query_type,
:searchString AS search_string,
url,
:strippedURL AS stripped_url,
frecency,
@ -117,6 +119,7 @@ function urlQuery(where1, where2) {
${where1}
UNION ALL
SELECT :query_type AS query_type,
:searchString AS search_string,
url,
:strippedURL AS stripped_url,
frecency,
@ -295,10 +298,6 @@ class ProviderAutofill extends UrlbarProvider {
);
this._strippedPrefix = this._strippedPrefix.toLowerCase();
if (!this._searchString || !this._searchString.length) {
return false;
}
// Don't try to autofill if the search term includes any whitespace.
// This may confuse completeDefaultIndex cause the AUTOCOMPLETE_MATCH
// tokenizer ends up trimming the search string and returning a value
@ -525,6 +524,7 @@ class ProviderAutofill extends UrlbarProvider {
let opts = {
query_type: QUERYTYPE.AUTOFILL_URL,
searchString: this._searchString,
revHost,
strippedURL,
};
@ -588,6 +588,7 @@ class ProviderAutofill extends UrlbarProvider {
const query = `
SELECT
:queryType AS query_type,
:searchString AS search_string,
i.input AS input,
h.url AS url,
fixup_url(h.url) AS fixed_url,
@ -616,6 +617,7 @@ class ProviderAutofill extends UrlbarProvider {
*/
_processRow(row, queryContext) {
let queryType = row.getResultByName("query_type");
let searchString = row.getResultByName("search_string");
let autofilledValue, finalCompleteValue, autofilledType;
let adaptiveHistoryInput;
switch (queryType) {
@ -656,8 +658,11 @@ class ProviderAutofill extends UrlbarProvider {
autofilledType = "url";
break;
case QUERYTYPE.AUTOFILL_ADAPTIVE:
autofilledValue = row.getResultByName("fixed_url");
finalCompleteValue = row.getResultByName("url");
const isFixedUrlMatched = row.getResultByName("fixed_url_match");
autofilledValue = isFixedUrlMatched
? row.getResultByName("fixed_url")
: finalCompleteValue;
adaptiveHistoryInput = row.getResultByName("input");
autofilledType = "adaptive";
break;
@ -679,7 +684,7 @@ class ProviderAutofill extends UrlbarProvider {
);
autofilledValue =
queryContext.searchString +
autofilledValue.substring(this._searchString.length);
autofilledValue.substring(searchString.length);
result.autofill = {
adaptiveHistoryInput,
value: autofilledValue,
@ -771,6 +776,15 @@ class ProviderAutofill extends UrlbarProvider {
}
}
// The adaptive history query is passed queryContext.searchString (the full
// search string), but the origin and URL queries are passed the prefix
// (this._strippedPrefix) and the rest of the search string
// (this._searchString) separately. The user must specify a non-prefix part
// to trigger origin and URL autofill.
if (!this._searchString.length) {
return null;
}
// If search string looks like an origin, try to autofill against origins.
// Otherwise treat it as a possible URL. When the string has only one slash
// at the end, we still treat it as an URL.
@ -796,7 +810,10 @@ class ProviderAutofill extends UrlbarProvider {
}
async _matchSearchEngineDomain(queryContext) {
if (!UrlbarPrefs.get("autoFill.searchEngines")) {
if (
!UrlbarPrefs.get("autoFill.searchEngines") ||
!this._searchString.length
) {
return null;
}

Просмотреть файл

@ -584,6 +584,101 @@ const TEST_DATA = [
],
},
},
{
description: "Prefixed URL for input history and 'http' for user input",
pref: true,
visitHistory: ["http://example.com/test"],
inputHistory: [{ uri: "http://example.com/test", input: "http" }],
userInput: "http",
expected: {
autofilled: "http://example.com/test",
completed: "http://example.com/test",
results: [
context =>
makeVisitResult(context, {
uri: "http://example.com/test",
title: "example.com/test",
heuristic: true,
}),
],
},
},
{
description: "Prefixed URL for input history and 'http:' for user input",
pref: true,
visitHistory: ["http://example.com/test"],
inputHistory: [{ uri: "http://example.com/test", input: "http:" }],
userInput: "http:",
expected: {
autofilled: "http://example.com/test",
completed: "http://example.com/test",
results: [
context =>
makeVisitResult(context, {
uri: "http://example.com/test",
title: "example.com/test",
heuristic: true,
}),
],
},
},
{
description: "Prefixed URL for input history and 'http:/' for user input",
pref: true,
visitHistory: ["http://example.com/test"],
inputHistory: [{ uri: "http://example.com/test", input: "http:/" }],
userInput: "http:/",
expected: {
autofilled: "http://example.com/test",
completed: "http://example.com/test",
results: [
context =>
makeVisitResult(context, {
uri: "http://example.com/test",
title: "example.com/test",
heuristic: true,
}),
],
},
},
{
description: "Prefixed URL for input history and 'http://' for user input",
pref: true,
visitHistory: ["http://example.com/test"],
inputHistory: [{ uri: "http://example.com/test", input: "http://" }],
userInput: "http://",
expected: {
autofilled: "http://example.com/test",
completed: "http://example.com/test",
results: [
context =>
makeVisitResult(context, {
uri: "http://example.com/test",
title: "example.com/test",
heuristic: true,
}),
],
},
},
{
description: "Prefixed URL for input history and 'http://e' for user input",
pref: true,
visitHistory: ["http://example.com/test"],
inputHistory: [{ uri: "http://example.com/test", input: "http://e" }],
userInput: "http://e",
expected: {
autofilled: "http://example.com/test",
completed: "http://example.com/test",
results: [
context =>
makeVisitResult(context, {
uri: "http://example.com/test",
title: "example.com/test",
heuristic: true,
}),
],
},
},
{
description:
"Those that match with fixed URL take precedence over those that match prefixed URL",

Просмотреть файл

@ -912,7 +912,10 @@ D3D11DXVA2Manager::InitInternal(layers::KnowsCompositor* aKnowsCompositor,
mDevice = aDevice;
if (!mDevice) {
mDevice = gfx::DeviceManagerDx::Get()->CreateDecoderDevice();
bool useHardwareWebRender =
aKnowsCompositor && aKnowsCompositor->UsingHardwareWebRender();
mDevice =
gfx::DeviceManagerDx::Get()->CreateDecoderDevice(useHardwareWebRender);
if (!mDevice) {
aFailureReason.AssignLiteral("Failed to create D3D11 device for decoder");
return E_FAIL;

Просмотреть файл

@ -862,7 +862,8 @@ FeatureStatus DeviceManagerDx::CreateContentDevice() {
return FeatureStatus::Available;
}
RefPtr<ID3D11Device> DeviceManagerDx::CreateDecoderDevice() {
RefPtr<ID3D11Device> DeviceManagerDx::CreateDecoderDevice(
bool aHardwareWebRender) {
bool isAMD = false;
{
MutexAutoLock lock(mDeviceLock);
@ -884,8 +885,9 @@ RefPtr<ID3D11Device> DeviceManagerDx::CreateDecoderDevice() {
}
if (reuseDevice) {
if (mCompositorDevice && mCompositorDeviceSupportsVideo &&
!mDecoderDevice) {
// Use mCompositorDevice for decoder device only for hardware WebRender.
if (aHardwareWebRender && mCompositorDevice &&
mCompositorDeviceSupportsVideo && !mDecoderDevice) {
mDecoderDevice = mCompositorDevice;
RefPtr<ID3D10Multithread> multi;

Просмотреть файл

@ -61,7 +61,7 @@ class DeviceManagerDx final {
RefPtr<ID3D11Device> GetImageDevice();
RefPtr<IDCompositionDevice2> GetDirectCompositionDevice();
RefPtr<ID3D11Device> GetVRDevice();
RefPtr<ID3D11Device> CreateDecoderDevice();
RefPtr<ID3D11Device> CreateDecoderDevice(bool aHardwareWebRender);
IDirectDraw7* GetDirectDraw();
unsigned GetCompositorFeatureLevel() const;

Просмотреть файл

@ -86,6 +86,10 @@
using namespace mozilla;
using namespace mozilla::gfx;
// Determine whether to add the deprecated names to the list, depending on build-time SDK options.
#define USE_DEPRECATED_FONT_FAMILY_NAMES !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15)
#if USE_DEPRECATED_FONT_FAMILY_NAMES
// List generated by diffing the arrays returned by CTFontManagerCopyAvailableFontFamilyNames()
// when built with MACOSX_DEPLOYMENT_TARGET=10.12 vs 11.0, to identify the font family names
// that Core Text is treating as "deprecated" and hiding from the app on newer systems.
@ -246,9 +250,7 @@ constexpr nsLiteralCString kDeprecatedFontFamilies[] = {
"Superclarendon"_ns,
"Times"_ns,
};
// Determine whether to add the deprecated names to the list, depending on build-time SDK options.
#define USE_DEPRECATED_FONT_FAMILY_NAMES !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15)
#endif // USE_DEPRECATED_FONT_FAMILY_NAMES
// indexes into the NSArray objects that the Cocoa font manager returns
// as the available members of a family

Просмотреть файл

@ -48,7 +48,8 @@ bool gecko_profiler_thread_is_being_profiled();
macro(picture); \
macro(text_run); \
macro(filterdata); \
macro(backdrop); \
macro(backdrop_capture); \
macro(backdrop_render); \
macro(polyon);
// Prelude of types necessary before including webrender_ffi_generated.h

Просмотреть файл

@ -16,14 +16,14 @@ use crate::gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId
use crate::gpu_types::{ImageBrushData, get_shader_opacity, BoxShadowData};
use crate::gpu_types::{ClipMaskInstanceCommon, ClipMaskInstanceImage, ClipMaskInstanceRect, ClipMaskInstanceBoxShadow};
use crate::internal_types::{FastHashMap, Swizzle, TextureSource, Filter};
use crate::picture::{Picture3DContext, PictureCompositeMode, TileKey};
use crate::picture::{Picture3DContext, PictureCompositeMode, TileKey, calculate_screen_uv};
use crate::prim_store::{PrimitiveInstanceKind, ClipData, PrimitiveInstanceIndex};
use crate::prim_store::{PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
use crate::prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex};
use crate::prim_store::VECS_PER_SEGMENT;
use crate::render_target::RenderTargetContext;
use crate::render_task_graph::{RenderTaskId, RenderTaskGraph};
use crate::render_task::RenderTaskAddress;
use crate::render_task::{RenderTaskAddress, RenderTaskKind};
use crate::renderer::{BlendMode, ShaderColorMode};
use crate::renderer::MAX_VERTEX_TEXTURE_WIDTH;
use crate::resource_cache::{GlyphFetchResult, ImageProperties, ImageRequest};
@ -1420,6 +1420,11 @@ impl BatchBuilder {
// be encountered during batching. Consider making TileCache
// a standalone type, not a picture.
}
PictureCompositeMode::IntermediateSurface { .. } => {
// TODO(gw): As an optimization, support making this a pass-through
// and/or drawing directly from here when possible
// (e.g. if not wrapped by filters / different spatial node).
}
PictureCompositeMode::Filter(ref filter) => {
assert!(filter.is_visible());
match filter {
@ -2931,7 +2936,111 @@ impl BatchBuilder {
}
}
}
PrimitiveInstanceKind::Backdrop { .. } => {}
PrimitiveInstanceKind::BackdropCapture { .. } => {}
PrimitiveInstanceKind::BackdropRender { pic_index, .. } => {
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
let blend_mode = BlendMode::PremultipliedAlpha;
let pic_task_id = ctx.prim_store.pictures[pic_index.0].primary_render_task_id;
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
specific_prim_address: prim_cache_address,
transform_id,
};
let (clip_task_address, clip_mask_texture_id) = ctx.get_prim_clip_task_and_texture(
prim_info.clip_task_index,
render_tasks,
).unwrap();
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2D)
);
let (_, texture) = render_tasks.resolve_location(
pic_task_id,
gpu_cache,
).unwrap();
let textures = BatchTextures::prim_textured(
texture,
clip_mask_texture_id,
);
let key = BatchKey::new(
kind,
blend_mode,
textures,
);
let prim_header_index = prim_headers.push(
&prim_header,
z_id,
ImageBrushData {
color_mode: ShaderColorMode::Image,
alpha_type: AlphaType::PremultipliedAlpha,
raster_space: RasterizationSpace::Screen,
opacity: 1.0,
}.encode(),
);
let pic_task = &render_tasks[pic_task_id.unwrap()];
let pic_info = match pic_task.kind {
RenderTaskKind::Picture(ref info) => info,
_ => panic!("bug: not a picture"),
};
let target_rect = pic_task.get_target_rect();
let backdrop_rect = DeviceRect::from_origin_and_size(
pic_info.content_origin,
target_rect.size().to_f32(),
);
let map_prim_to_backdrop = SpaceMapper::new_with_target(
pic_info.surface_spatial_node_index,
prim_spatial_node_index,
WorldRect::max_rect(),
ctx.spatial_tree,
);
let top_left = map_prim_to_backdrop.map_point(prim_rect.top_left()).unwrap();
let top_right = map_prim_to_backdrop.map_point(prim_rect.top_right()).unwrap();
let bottom_left = map_prim_to_backdrop.map_point(prim_rect.bottom_left()).unwrap();
let bottom_right = map_prim_to_backdrop.map_point(prim_rect.bottom_right()).unwrap();
let top_left = calculate_screen_uv(top_left * pic_info.device_pixel_scale, backdrop_rect);
let top_right = calculate_screen_uv(top_right * pic_info.device_pixel_scale, backdrop_rect);
let bottom_left = calculate_screen_uv(bottom_left * pic_info.device_pixel_scale, backdrop_rect);
let bottom_right = calculate_screen_uv(bottom_right * pic_info.device_pixel_scale, backdrop_rect);
// TODO (gw): This is a hack that provides the GPU cache blocks for an
// ImageSource. We should update the GPU cache interfaces to
// allow pushing per-frame blocks via a request interface.
let gpu_blocks = &[
GpuBlockData::from([
target_rect.min.x as f32,
target_rect.min.y as f32,
target_rect.max.x as f32,
target_rect.max.y as f32,
]),
GpuBlockData::from([0.0; 4]),
GpuBlockData::from(top_left),
GpuBlockData::from(top_right),
GpuBlockData::from(bottom_left),
GpuBlockData::from(bottom_right),
];
let uv_rect_handle = gpu_cache.push_per_frame_blocks(gpu_blocks);
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
EdgeAaSegmentMask::all(),
clip_task_address,
brush_flags,
prim_header_index,
uv_rect_handle.as_int(gpu_cache),
);
}
}
}
@ -3850,10 +3959,6 @@ pub struct CommandBufferBuilder {
/// List of render tasks that depend on the task that will be created for this builder
pub extra_dependencies: Vec<RenderTaskId>,
/// If true, this represents a surface that wraps a sub-graph, and we need to look
/// higher in the surface hierarchy for the resolve surface.
pub wraps_sub_graph: bool,
}
impl CommandBufferBuilder {
@ -3863,7 +3968,6 @@ impl CommandBufferBuilder {
establishes_sub_graph: false,
resolve_source: None,
extra_dependencies: Vec::new(),
wraps_sub_graph: false,
}
}
@ -3878,7 +3982,6 @@ impl CommandBufferBuilder {
establishes_sub_graph: false,
resolve_source: None,
extra_dependencies: Vec::new(),
wraps_sub_graph: false,
}
}
@ -3887,7 +3990,6 @@ impl CommandBufferBuilder {
render_task_id: RenderTaskId,
establishes_sub_graph: bool,
root_task_id: Option<RenderTaskId>,
wraps_sub_graph: bool,
) -> Self {
CommandBufferBuilder {
kind: CommandBufferBuilderKind::Simple {
@ -3897,7 +3999,6 @@ impl CommandBufferBuilder {
establishes_sub_graph,
resolve_source: None,
extra_dependencies: Vec::new(),
wraps_sub_graph,
}
}
}

Просмотреть файл

@ -394,7 +394,8 @@ macro_rules! enumerate_interners {
picture: Picture,
text_run: TextRun,
filter_data: FilterDataIntern,
backdrop: Backdrop,
backdrop_capture: BackdropCapture,
backdrop_render: BackdropRender,
polygon: PolygonIntern,
}
}

Просмотреть файл

@ -2945,6 +2945,7 @@ impl TileCacheInstance {
surface_stack: &[(PictureIndex, SurfaceIndex)],
composite_state: &mut CompositeState,
gpu_cache: &mut GpuCache,
scratch: &mut PrimitiveScratchBuffer,
is_root_tile_cache: bool,
surfaces: &mut [SurfaceInfo],
) {
@ -3308,7 +3309,12 @@ impl TileCacheInstance {
});
}
}
PrimitiveInstanceKind::Backdrop { .. } => {
PrimitiveInstanceKind::BackdropCapture { .. } => {}
PrimitiveInstanceKind::BackdropRender { pic_index, .. } => {
// Mark that we need the sub-graph this render depends on so that
// we don't skip it during the prepare pass
scratch.required_sub_graphs.insert(pic_index);
// If this is a sub-graph, register the bounds on any affected tiles
// so we know how much to expand the content tile by.
@ -3982,6 +3988,8 @@ pub enum PictureCompositeMode {
},
/// Apply an SVG filter
SvgFilter(Vec<FilterPrimitive>, Vec<SFilterData>),
/// A surface that is used as an input to another primitive
IntermediateSurface,
}
impl PictureCompositeMode {
@ -4392,10 +4400,8 @@ bitflags! {
/// This picture establishes a sub-graph, which affects how SurfaceBuilder will
/// set up dependencies in the render task graph
const IS_SUB_GRAPH = 1 << 1;
/// This picture wraps a sub-graph, but is not the resolve source itself
const WRAPS_SUB_GRAPH = 1 << 2;
/// If set, this picture should not apply snapping via changing the raster root
const DISABLE_SNAPPING = 1 << 3;
const DISABLE_SNAPPING = 1 << 2;
}
}
@ -4488,6 +4494,7 @@ impl PicturePrimitive {
Some(RasterConfig { composite_mode: PictureCompositeMode::ComponentTransferFilter(..), .. }) |
Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) |
Some(RasterConfig { composite_mode: PictureCompositeMode::SvgFilter(..), .. }) |
Some(RasterConfig { composite_mode: PictureCompositeMode::IntermediateSurface, .. }) |
None => {
false
}
@ -5131,7 +5138,6 @@ impl PicturePrimitive {
frame_state.surface_builder.push_surface(
surface_index,
false,
false,
surface_local_dirty_rect,
descriptor,
frame_state.surfaces,
@ -5524,6 +5530,41 @@ impl PicturePrimitive {
surface_rects.clipped_local,
);
}
PictureCompositeMode::IntermediateSurface => {
if !scratch.required_sub_graphs.contains(&pic_index) {
return None;
}
// TODO(gw): Remove all the mostly duplicated code in each of these
// match cases (they used to be quite different).
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
let render_task_id = frame_state.rg_builder.add().init(
RenderTask::new_dynamic(
surface_rects.task_size,
RenderTaskKind::new_picture(
surface_rects.task_size,
surface_rects.needs_scissor_rect,
surface_rects.clipped.min,
surface_spatial_node_index,
raster_spatial_node_index,
device_pixel_scale,
None,
None,
None,
cmd_buffer_index,
can_use_shared_surface,
)
).with_uv_rect_kind(surface_rects.uv_rect_kind)
);
primary_render_task_id = render_task_id;
surface_descriptor = SurfaceDescriptor::new_simple(
render_task_id,
surface_rects.clipped_local,
);
}
PictureCompositeMode::SvgFilter(ref primitives, ref filter_datas) => {
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
@ -5567,12 +5608,10 @@ impl PicturePrimitive {
}
let is_sub_graph = self.flags.contains(PictureFlags::IS_SUB_GRAPH);
let wraps_sub_graph = self.flags.contains(PictureFlags::WRAPS_SUB_GRAPH);
frame_state.surface_builder.push_surface(
raster_config.surface_index,
is_sub_graph,
wraps_sub_graph,
surface_rects.clipped_local,
surface_descriptor,
frame_state.surfaces,
@ -5611,6 +5650,7 @@ impl PicturePrimitive {
PictureCompositeMode::ComponentTransferFilter(..) |
PictureCompositeMode::Filter(..) |
PictureCompositeMode::MixBlend(..) |
PictureCompositeMode::IntermediateSurface |
PictureCompositeMode::SvgFilter(..) => {
// TODO(gw): We can take advantage of the same logic that
// exists in the opaque rect detection for tile
@ -6211,6 +6251,7 @@ impl PicturePrimitive {
}
PictureCompositeMode::MixBlend(..) |
PictureCompositeMode::Blit(_) |
PictureCompositeMode::IntermediateSurface |
PictureCompositeMode::SvgFilter(..) => {}
}
@ -6931,7 +6972,7 @@ fn get_relative_scale_offset(
scale_offset
}
fn calculate_screen_uv(
pub fn calculate_screen_uv(
p: DevicePoint,
clipped: DeviceRect,
) -> DeviceHomogeneousVector {

Просмотреть файл

@ -800,11 +800,23 @@ fn prepare_interned_prim_for_render(
prim_instance.clear_visibility();
}
}
PrimitiveInstanceKind::Backdrop { .. } => {
PrimitiveInstanceKind::BackdropCapture { .. } => {
// Register the owner picture of this backdrop primitive as the
// target for resolve of the sub-graph
frame_state.surface_builder.register_resolve_source();
}
PrimitiveInstanceKind::BackdropRender { .. } => {
let sub_graph_output_id = frame_state
.surface_builder
.sub_graph_output_stack
.pop()
.expect("bug: no sub-graph output");
frame_state.surface_builder.add_child_render_task(
sub_graph_output_id,
frame_state.rg_builder,
);
}
};
}
@ -912,7 +924,8 @@ fn update_clip_task_for_brush(
PrimitiveInstanceKind::TextRun { .. } |
PrimitiveInstanceKind::Clear { .. } |
PrimitiveInstanceKind::LineDecoration { .. } |
PrimitiveInstanceKind::Backdrop { .. } => {
PrimitiveInstanceKind::BackdropCapture { .. } |
PrimitiveInstanceKind::BackdropRender { .. } => {
return None;
}
PrimitiveInstanceKind::Image { image_instance_index, .. } => {
@ -1380,7 +1393,8 @@ fn build_segments_if_needed(
PrimitiveInstanceKind::RadialGradient { .. } |
PrimitiveInstanceKind::ConicGradient { .. } |
PrimitiveInstanceKind::LineDecoration { .. } |
PrimitiveInstanceKind::Backdrop { .. } => {
PrimitiveInstanceKind::BackdropCapture { .. } |
PrimitiveInstanceKind::BackdropRender { .. } => {
// These primitives don't support / need segments.
return;
}

Просмотреть файл

@ -7,88 +7,168 @@ use crate::intern::{Internable, InternDebug, Handle as InternHandle};
use crate::internal_types::LayoutPrimitiveInfo;
use crate::prim_store::{
InternablePrimitive, PrimitiveInstanceKind, PrimKey, PrimTemplate,
PrimTemplateCommonData, PrimitiveStore,
PrimTemplateCommonData, PrimitiveStore, PictureIndex,
};
use crate::scene_building::IsVisible;
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, PartialEq, MallocSizeOf, Hash)]
pub struct Backdrop {
pub struct BackdropCapture {
}
impl From<Backdrop> for BackdropData {
fn from(_backdrop: Backdrop) -> Self {
BackdropData {
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, PartialEq, MallocSizeOf, Hash)]
pub struct BackdropRender {
}
impl From<BackdropCapture> for BackdropCaptureData {
fn from(_backdrop: BackdropCapture) -> Self {
BackdropCaptureData {
}
}
}
pub type BackdropKey = PrimKey<Backdrop>;
impl From<BackdropRender> for BackdropRenderData {
fn from(_backdrop: BackdropRender) -> Self {
BackdropRenderData {
}
}
}
impl BackdropKey {
pub type BackdropCaptureKey = PrimKey<BackdropCapture>;
pub type BackdropRenderKey = PrimKey<BackdropRender>;
impl BackdropCaptureKey {
pub fn new(
info: &LayoutPrimitiveInfo,
backdrop: Backdrop,
backdrop_capture: BackdropCapture,
) -> Self {
BackdropKey {
BackdropCaptureKey {
common: info.into(),
kind: backdrop,
kind: backdrop_capture,
}
}
}
impl InternDebug for BackdropKey {}
impl BackdropRenderKey {
pub fn new(
info: &LayoutPrimitiveInfo,
backdrop_render: BackdropRender,
) -> Self {
BackdropRenderKey {
common: info.into(),
kind: backdrop_render,
}
}
}
impl InternDebug for BackdropCaptureKey {}
impl InternDebug for BackdropRenderKey {}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, MallocSizeOf)]
pub struct BackdropData {
pub struct BackdropCaptureData {
}
pub type BackdropTemplate = PrimTemplate<BackdropData>;
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, MallocSizeOf)]
pub struct BackdropRenderData {
}
impl From<BackdropKey> for BackdropTemplate {
fn from(backdrop: BackdropKey) -> Self {
pub type BackdropCaptureTemplate = PrimTemplate<BackdropCaptureData>;
pub type BackdropRenderTemplate = PrimTemplate<BackdropRenderData>;
impl From<BackdropCaptureKey> for BackdropCaptureTemplate {
fn from(backdrop: BackdropCaptureKey) -> Self {
let common = PrimTemplateCommonData::with_key_common(backdrop.common);
BackdropTemplate {
BackdropCaptureTemplate {
common,
kind: backdrop.kind.into(),
}
}
}
pub type BackdropDataHandle = InternHandle<Backdrop>;
impl From<BackdropRenderKey> for BackdropRenderTemplate {
fn from(backdrop: BackdropRenderKey) -> Self {
let common = PrimTemplateCommonData::with_key_common(backdrop.common);
impl Internable for Backdrop {
type Key = BackdropKey;
type StoreData = BackdropTemplate;
type InternData = ();
const PROFILE_COUNTER: usize = crate::profiler::INTERNED_BACKDROPS;
BackdropRenderTemplate {
common,
kind: backdrop.kind.into(),
}
}
}
impl InternablePrimitive for Backdrop {
pub type BackdropCaptureDataHandle = InternHandle<BackdropCapture>;
pub type BackdropRenderDataHandle = InternHandle<BackdropRender>;
impl Internable for BackdropCapture {
type Key = BackdropCaptureKey;
type StoreData = BackdropCaptureTemplate;
type InternData = ();
const PROFILE_COUNTER: usize = crate::profiler::INTERNED_BACKDROP_CAPTURES;
}
impl Internable for BackdropRender {
type Key = BackdropRenderKey;
type StoreData = BackdropRenderTemplate;
type InternData = ();
const PROFILE_COUNTER: usize = crate::profiler::INTERNED_BACKDROP_RENDERS;
}
impl InternablePrimitive for BackdropCapture {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> BackdropKey {
BackdropKey::new(info, self)
) -> BackdropCaptureKey {
BackdropCaptureKey::new(info, self)
}
fn make_instance_kind(
_key: BackdropKey,
data_handle: BackdropDataHandle,
_key: BackdropCaptureKey,
data_handle: BackdropCaptureDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::Backdrop {
PrimitiveInstanceKind::BackdropCapture {
data_handle,
}
}
}
impl IsVisible for Backdrop {
impl InternablePrimitive for BackdropRender {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> BackdropRenderKey {
BackdropRenderKey::new(info, self)
}
fn make_instance_kind(
_key: BackdropRenderKey,
data_handle: BackdropRenderDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::BackdropRender {
data_handle,
pic_index: PictureIndex::INVALID,
}
}
}
impl IsVisible for BackdropCapture {
fn is_visible(&self) -> bool {
true
}
}
impl IsVisible for BackdropRender {
fn is_visible(&self) -> bool {
true
}

Просмотреть файл

@ -4,7 +4,7 @@
// list of all interned primitives to match enumerate_interners!
pub use crate::prim_store::backdrop::Backdrop;
pub use crate::prim_store::backdrop::{BackdropCapture, BackdropRender};
pub use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
pub use crate::prim_store::image::{Image, YuvImage};
pub use crate::prim_store::line_dec::{LineDecoration};

Просмотреть файл

@ -28,7 +28,7 @@ use std::{hash, ops, u32, usize};
#[cfg(debug_assertions)]
use std::sync::atomic::{AtomicUsize, Ordering};
use crate::util::Recycler;
use crate::internal_types::LayoutPrimitiveInfo;
use crate::internal_types::{FastHashSet, LayoutPrimitiveInfo};
#[cfg(debug_assertions)]
use crate::internal_types::FrameId;
use crate::visibility::PrimitiveVisibility;
@ -44,7 +44,7 @@ pub mod interned;
mod storage;
use backdrop::BackdropDataHandle;
use backdrop::{BackdropCaptureDataHandle, BackdropRenderDataHandle};
use borders::{ImageBorderDataHandle, NormalBorderDataHandle};
use gradient::{LinearGradientPrimitive, LinearGradientDataHandle, RadialGradientDataHandle, ConicGradientDataHandle};
use image::{ImageDataHandle, ImageInstance, YuvImageDataHandle};
@ -124,6 +124,10 @@ impl ClipTaskIndex {
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PictureIndex(pub usize);
impl PictureIndex {
pub const INVALID: PictureIndex = PictureIndex(!0);
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Copy, Debug, Clone, MallocSizeOf, PartialEq)]
@ -1060,8 +1064,12 @@ pub enum PrimitiveInstanceKind {
data_handle: PrimitiveDataHandle,
},
/// Render a portion of a specified backdrop.
Backdrop {
data_handle: BackdropDataHandle,
BackdropCapture {
data_handle: BackdropCaptureDataHandle,
},
BackdropRender {
data_handle: BackdropRenderDataHandle,
pic_index: PictureIndex,
},
}
@ -1192,7 +1200,10 @@ impl PrimitiveInstance {
PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
data_handle.uid()
}
PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
PrimitiveInstanceKind::BackdropCapture { data_handle, .. } => {
data_handle.uid()
}
PrimitiveInstanceKind::BackdropRender { data_handle, .. } => {
data_handle.uid()
}
}
@ -1257,6 +1268,9 @@ pub struct PrimitiveScratchBuffer {
/// List of current debug messages to log on screen
messages: Vec<DebugMessage>,
/// Set of sub-graphs that are required, determined during visibility pass
pub required_sub_graphs: FastHashSet<PictureIndex>,
}
impl Default for PrimitiveScratchBuffer {
@ -1270,6 +1284,7 @@ impl Default for PrimitiveScratchBuffer {
gradient_tiles: GradientTileStorage::new(0),
debug_items: Vec::new(),
messages: Vec::new(),
required_sub_graphs: FastHashSet::default(),
}
}
}
@ -1300,6 +1315,8 @@ impl PrimitiveScratchBuffer {
// should fix this in the future to retain handles.
self.gradient_tiles.clear();
self.required_sub_graphs.clear();
self.debug_items.clear();
}

Просмотреть файл

@ -224,6 +224,7 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
}
Some(PictureCompositeMode::Blit(_)) |
Some(PictureCompositeMode::TileCache { .. }) |
Some(PictureCompositeMode::IntermediateSurface) |
None => {
PictureCompositeKey::Identity
}

Просмотреть файл

@ -225,33 +225,34 @@ pub const INTERNED_RADIAL_GRADIENTS: usize = 94;
pub const INTERNED_CONIC_GRADIENTS: usize = 95;
pub const INTERNED_PICTURES: usize = 96;
pub const INTERNED_FILTER_DATA: usize = 97;
pub const INTERNED_BACKDROPS: usize = 98;
pub const INTERNED_POLYGONS: usize = 99;
pub const INTERNED_BACKDROP_CAPTURES: usize = 98;
pub const INTERNED_BACKDROP_RENDERS: usize = 99;
pub const INTERNED_POLYGONS: usize = 100;
pub const DEPTH_TARGETS_MEM: usize = 100;
pub const DEPTH_TARGETS_MEM: usize = 101;
pub const SHADER_BUILD_TIME: usize = 101;
pub const SHADER_BUILD_TIME: usize = 102;
pub const RENDER_REASON_FIRST: usize = 102;
pub const RENDER_REASON_SCENE: usize = 102;
pub const RENDER_REASON_ANIMATED_PROPERTY: usize = 103;
pub const RENDER_REASON_RESOURCE_UPDATE: usize = 104;
pub const RENDER_REASON_ASYNC_IMAGE: usize = 105;
pub const RENDER_REASON_CLEAR_RESOURCES: usize = 106;
pub const RENDER_REASON_APZ: usize = 107;
pub const RENDER_REASON_RESIZE: usize = 108;
pub const RENDER_REASON_WIDGET: usize = 109;
pub const RENDER_REASON_TEXTURE_CACHE_FLUSH: usize = 110;
pub const RENDER_REASON_SNAPSHOT: usize = 111;
pub const RENDER_REASON_POST_RESOURCE_UPDATE_HOOKS: usize = 112;
pub const RENDER_REASON_CONFIG_CHANGE: usize = 113;
pub const RENDER_REASON_CONTENT_SYNC: usize = 114;
pub const RENDER_REASON_FLUSH: usize = 115;
pub const RENDER_REASON_TESTING: usize = 116;
pub const RENDER_REASON_OTHER: usize = 117;
pub const RENDER_REASON_VSYNC: usize = 118;
pub const RENDER_REASON_FIRST: usize = 103;
pub const RENDER_REASON_SCENE: usize = 103;
pub const RENDER_REASON_ANIMATED_PROPERTY: usize = 104;
pub const RENDER_REASON_RESOURCE_UPDATE: usize = 105;
pub const RENDER_REASON_ASYNC_IMAGE: usize = 106;
pub const RENDER_REASON_CLEAR_RESOURCES: usize = 107;
pub const RENDER_REASON_APZ: usize = 108;
pub const RENDER_REASON_RESIZE: usize = 109;
pub const RENDER_REASON_WIDGET: usize = 110;
pub const RENDER_REASON_TEXTURE_CACHE_FLUSH: usize = 111;
pub const RENDER_REASON_SNAPSHOT: usize = 112;
pub const RENDER_REASON_POST_RESOURCE_UPDATE_HOOKS: usize = 113;
pub const RENDER_REASON_CONFIG_CHANGE: usize = 114;
pub const RENDER_REASON_CONTENT_SYNC: usize = 115;
pub const RENDER_REASON_FLUSH: usize = 116;
pub const RENDER_REASON_TESTING: usize = 117;
pub const RENDER_REASON_OTHER: usize = 118;
pub const RENDER_REASON_VSYNC: usize = 119;
pub const NUM_PROFILER_EVENTS: usize = 119;
pub const NUM_PROFILER_EVENTS: usize = 120;
pub struct Profiler {
counters: Vec<Counter>,
@ -401,7 +402,8 @@ impl Profiler {
int("Interned conic gradients", "", INTERNED_CONIC_GRADIENTS, Expected::none()),
int("Interned pictures", "", INTERNED_PICTURES, Expected::none()),
int("Interned filter data", "", INTERNED_FILTER_DATA, Expected::none()),
int("Interned backdrops", "", INTERNED_BACKDROPS, Expected::none()),
int("Interned backdrop captures", "", INTERNED_BACKDROP_CAPTURES, Expected::none()),
int("Interned backdrop renders", "", INTERNED_BACKDROP_RENDERS, Expected::none()),
int("Interned polygons", "", INTERNED_POLYGONS, Expected::none()),
float("Depth targets mem", "MB", DEPTH_TARGETS_MEM, Expected::none()),

Просмотреть файл

@ -258,8 +258,12 @@ impl DataStores {
let prim_data = &self.yuv_image[data_handle];
&prim_data.common
}
PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
let prim_data = &self.backdrop[data_handle];
PrimitiveInstanceKind::BackdropCapture { data_handle, .. } => {
let prim_data = &self.backdrop_capture[data_handle];
&prim_data.common
}
PrimitiveInstanceKind::BackdropRender { data_handle, .. } => {
let prim_data = &self.backdrop_render[data_handle];
&prim_data.common
}
}

Просмотреть файл

@ -19,7 +19,7 @@ use crate::glyph_rasterizer::SharedFontResources;
use crate::intern::{Internable, Interner, UpdateList};
use crate::internal_types::{FastHashMap, FastHashSet};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use crate::prim_store::backdrop::Backdrop;
use crate::prim_store::backdrop::{BackdropCapture, BackdropRender};
use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
use crate::prim_store::gradient::{LinearGradient, RadialGradient, ConicGradient};
use crate::prim_store::image::{Image, YuvImage};

Просмотреть файл

@ -64,7 +64,7 @@ use crate::prim_store::{PrimitiveInstance, register_prim_chase_id};
use crate::prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore};
use crate::prim_store::{InternablePrimitive, SegmentInstanceIndex, PictureIndex};
use crate::prim_store::{PolygonKey};
use crate::prim_store::backdrop::Backdrop;
use crate::prim_store::backdrop::{BackdropCapture, BackdropRender};
use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
use crate::prim_store::gradient::{
GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams, ConicGradient,
@ -287,7 +287,6 @@ impl PictureChainBuilder {
interners: &mut Interners,
prim_store: &mut PrimitiveStore,
prim_instances: &mut Vec<PrimitiveInstance>,
extra_pic_flags: PictureFlags,
) -> PictureChainBuilder {
let prim_list = match self.current {
PictureSource::PrimitiveList { prim_list } => {
@ -308,14 +307,12 @@ impl PictureChainBuilder {
}
};
let mut flags = if self.set_resolve_target {
let flags = if self.set_resolve_target {
PictureFlags::IS_RESOLVE_TARGET
} else {
PictureFlags::empty()
};
flags |= extra_pic_flags;
let pic_index = PictureIndex(prim_store.pictures
.alloc()
.init(PicturePrimitive::new_image(
@ -645,8 +642,8 @@ impl<'a> SceneBuilder<'a> {
// If we're a surface, use that spatial node, otherwise the parent
let spatial_node_index = match pic.composite_mode {
Some(_) if !pic.flags.contains(PictureFlags::WRAPS_SUB_GRAPH) => pic.spatial_node_index,
Some(_) | None => parent_spatial_node_index.expect("bug: no parent"),
Some(_) => pic.spatial_node_index,
None => parent_spatial_node_index.expect("bug: no parent"),
};
(
@ -1993,12 +1990,20 @@ impl<'a> SceneBuilder<'a> {
}
fn make_current_slice_atomic_if_required(&mut self) {
if self.sc_stack.is_empty() {
// Shadows can only exist within a stacking context
assert!(self.pending_shadow_items.is_empty());
let has_non_wrapping_sc = self.sc_stack
.iter()
.position(|sc| {
!sc.flags.contains(StackingContextFlags::WRAPS_BACKDROP_FILTER)
})
.is_some();
self.tile_cache_builder.make_current_slice_atomic();
if has_non_wrapping_sc {
return;
}
// Shadows can only exist within a stacking context
assert!(self.pending_shadow_items.is_empty());
self.tile_cache_builder.make_current_slice_atomic();
}
/// If no stacking contexts are present (i.e. we are adding prims to a tile
@ -2283,12 +2288,6 @@ impl<'a> SceneBuilder<'a> {
None => true,
};
let pic_flags = if stacking_context.flags.contains(StackingContextFlags::WRAPS_BACKDROP_FILTER) {
PictureFlags::WRAPS_SUB_GRAPH
} else {
PictureFlags::empty()
};
let mut source = match stacking_context.context_3d {
// TODO(gw): For now, as soon as this picture is in
// a 3D context, we draw it to an intermediate
@ -2313,7 +2312,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.prim_list,
stacking_context.spatial_node_index,
stacking_context.raster_space,
pic_flags,
PictureFlags::empty(),
))
);
@ -2357,7 +2356,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.prim_list,
stacking_context.spatial_node_index,
stacking_context.raster_space,
pic_flags,
PictureFlags::empty(),
))
);
@ -2487,7 +2486,6 @@ impl<'a> SceneBuilder<'a> {
stacking_context.composite_ops.filter_primitives,
stacking_context.composite_ops.filter_datas,
None,
pic_flags,
);
// Same for mix-blend-mode, except we can skip if this primitive is the first in the parent
@ -2516,7 +2514,6 @@ impl<'a> SceneBuilder<'a> {
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
PictureFlags::empty(),
);
} else {
// If we have a mix-blend-mode, the stacking context needs to be isolated
@ -3619,11 +3616,11 @@ impl<'a> SceneBuilder<'a> {
// Create the backdrop prim - this is a placeholder which sets the size of resolve
// picture that reads from the backdrop root
let backdrop_instance = self.create_primitive(
let backdrop_capture_instance = self.create_primitive(
info,
spatial_node_index,
clip_chain_id,
Backdrop {
ClipChainId::NONE,
BackdropCapture {
},
);
@ -3631,7 +3628,7 @@ impl<'a> SceneBuilder<'a> {
// is needed for the call to `wrap_prim_with_filters` below
let mut prim_list = PrimitiveList::empty();
prim_list.add_prim(
backdrop_instance,
backdrop_capture_instance,
info.rect,
spatial_node_index,
info.flags,
@ -3654,41 +3651,86 @@ impl<'a> SceneBuilder<'a> {
filter_primitives,
filter_datas,
Some(false),
PictureFlags::empty(),
);
// Clip the backdrop filter to the outline of the backdrop-filter prim. If this is
// axis-aligned with the backdrop root, no clip mask will be produced. Otherwise,
// it will result in a clip-mask matching the primitive shape that is used to mask
// the final backdrop-filter output
let filter_clips = vec![
ClipItemKey {
kind: ClipItemKeyKind::rectangle(
info.rect,
ClipMode::Clip,
),
spatial_node_index,
},
];
let filter_clip_chain_id = self.build_clip_chain(
filter_clips,
clip_chain_id,
);
// If all the filters were no-ops (e.g. opacity(0)) then we don't get a picture here
// and we can skip adding the backdrop-filter.
if source.has_picture() {
source = source.add_picture(
PictureCompositeMode::IntermediateSurface,
Picture3DContext::Out,
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
);
let filtered_instance = source.finalize(
filter_clip_chain_id,
ClipChainId::NONE,
&mut self.interners,
&mut self.prim_store,
);
// Extract the pic index for the intermediate surface. We need to
// supply this to the capture prim below.
let output_pic_index = match filtered_instance.kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => pic_index,
_ => panic!("bug: not a picture"),
};
// Find which stacking context (or root tile cache) to add the
// backdrop-filter chain to
let sc_index = self.sc_stack.iter().rposition(|sc| {
!sc.flags.contains(StackingContextFlags::WRAPS_BACKDROP_FILTER)
});
match sc_index {
Some(sc_index) => {
self.sc_stack[sc_index].prim_list.add_prim(
filtered_instance,
info.rect,
filter_spatial_node_index,
info.flags,
&mut self.prim_instances,
);
}
None => {
self.tile_cache_builder.add_prim(
filtered_instance,
info.rect,
filter_spatial_node_index,
info.flags,
self.spatial_tree,
&self.clip_store,
self.interners,
&self.quality_settings,
&mut self.prim_instances,
);
}
}
// Add the prim that renders the result of the backdrop filter chain
let mut backdrop_render_instance = self.create_primitive(
info,
spatial_node_index,
clip_chain_id,
BackdropRender {
},
);
// Set up the picture index for the backdrop-filter output in the prim
// that will draw it
match backdrop_render_instance.kind {
PrimitiveInstanceKind::BackdropRender { ref mut pic_index, .. } => {
assert_eq!(*pic_index, PictureIndex::INVALID);
*pic_index = output_pic_index;
}
_ => panic!("bug: unexpected prim kind"),
}
self.add_primitive_to_draw_list(
filtered_instance,
backdrop_render_instance,
info.rect,
filter_spatial_node_index,
spatial_node_index,
info.flags,
);
}
@ -3702,7 +3744,6 @@ impl<'a> SceneBuilder<'a> {
mut filter_primitives: Vec<FilterPrimitive>,
filter_datas: Vec<FilterData>,
should_inflate_override: Option<bool>,
extra_pic_flags: PictureFlags,
) -> PictureChainBuilder {
// TODO(cbrewster): Currently CSS and SVG filters live side by side in WebRender, but unexpected results will
// happen if they are used simulataneously. Gecko only provides either filter ops or filter primitives.
@ -3768,7 +3809,6 @@ impl<'a> SceneBuilder<'a> {
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
extra_pic_flags,
);
}
@ -3805,7 +3845,6 @@ impl<'a> SceneBuilder<'a> {
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
extra_pic_flags,
);
}

Просмотреть файл

@ -207,6 +207,9 @@ pub struct SurfaceBuilder {
builder_stack: Vec<CommandBufferBuilder>,
// Dirty rect stack used to reject adding primitives
dirty_rect_stack: Vec<Vec<PictureRect>>,
// A stack of the output render tasks from any sub-graphs that haven't
// been consumed by BackdropRender prims yet
pub sub_graph_output_stack: Vec<RenderTaskId>,
}
impl SurfaceBuilder {
@ -215,6 +218,7 @@ impl SurfaceBuilder {
current_cmd_buffers: CommandBufferTargets::Tiled { tiles: FastHashMap::default() },
builder_stack: Vec::new(),
dirty_rect_stack: Vec::new(),
sub_graph_output_stack: Vec::new(),
}
}
@ -245,7 +249,6 @@ impl SurfaceBuilder {
&mut self,
surface_index: SurfaceIndex,
is_sub_graph: bool,
wraps_sub_graph: bool,
clipping_rect: PictureRect,
descriptor: SurfaceDescriptor,
surfaces: &mut [SurfaceInfo],
@ -267,7 +270,6 @@ impl SurfaceBuilder {
render_task_id,
is_sub_graph,
None,
wraps_sub_graph,
)
}
SurfaceDescriptorKind::Chained { render_task_id, root_task_id } => {
@ -275,7 +277,6 @@ impl SurfaceBuilder {
render_task_id,
is_sub_graph,
Some(root_task_id),
wraps_sub_graph,
)
}
};
@ -403,6 +404,9 @@ impl SurfaceBuilder {
let resolve_task_id = builder.resolve_source.expect("bug: no resolve set");
let mut src_task_ids = Vec::new();
// Make the output of the sub-graph a dependency of the new replacement tile task
self.sub_graph_output_stack.push(child_root_task_id.unwrap_or(child_render_task_id));
// Set up dependencies for the sub-graph. The basic concepts below are the same, but for
// tiled surfaces are a little more complex as there are multiple tasks to set up.
// (a) Set up new task(s) on parent surface that write to the same location
@ -410,26 +414,7 @@ impl SurfaceBuilder {
// (c) Make the old parent surface tasks input dependencies of the resolve target
// (d) Make the sub-graph output an input dependency of the new task(s).
// If this surface wraps a sub-graph, we need to look up in the hierarchy to find where
// the resource source actually is. This may happen in cases where a clip-mask applies to
// a backdrop-filter and child content in the associated stacking context.
let sub_graph_source_index = self.builder_stack
.iter()
.rposition(|builder| {
!builder.wraps_sub_graph
})
.expect("bug: no parent that is not a sub graph wrapper");
let sub_graph_parent = if sub_graph_source_index == self.builder_stack.len() - 1 {
None
} else {
match self.builder_stack.last().unwrap().kind {
CommandBufferBuilderKind::Simple { render_task_id, .. } => Some(render_task_id),
_ => panic!("bug: should not occur on tiled surfaces"),
}
};
match self.builder_stack[sub_graph_source_index].kind {
match self.builder_stack.last_mut().unwrap().kind {
CommandBufferBuilderKind::Tiled { ref mut tiles } => {
let keys: Vec<TileKey> = tiles.keys().cloned().collect();
@ -474,12 +459,6 @@ impl SurfaceBuilder {
),
);
// Make the output of the sub-graph a dependency of the new replacement tile task
rg_builder.add_dependency(
sub_graph_parent.unwrap_or(new_task_id),
child_root_task_id.unwrap_or(child_render_task_id),
);
// Update the surface builder with the now current target for future primitives
tiles.insert(
key,
@ -538,12 +517,6 @@ impl SurfaceBuilder {
),
);
// Make the output of the sub-graph a dependency of the new replacement tile task
rg_builder.add_dependency(
sub_graph_parent.unwrap_or(new_task_id),
child_root_task_id.unwrap_or(child_render_task_id),
);
// Update the surface builder with the now current target for future primitives
*parent_task_id = new_task_id;
}

Просмотреть файл

@ -360,6 +360,7 @@ pub fn update_prim_visibility(
&frame_state.surface_stack,
&mut frame_state.composite_state,
&mut frame_state.gpu_cache,
&mut frame_state.scratch.primitive,
is_root_tile_cache,
surfaces,
);

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 59 KiB

После

Ширина:  |  Высота:  |  Размер: 59 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.6 KiB

Просмотреть файл

@ -0,0 +1,17 @@
---
root:
items:
- type: rect
color: red
bounds: 0 0 200 200
- image: checkerboard(2,14,14,14,14)
bounds: 0 0 200 200
- type: stacking-context
transform: rotate(45)
transform-origin: 100 100
filters: identity
wraps-backdrop-filter: true
items:
- type: backdrop-filter
bounds: 50 50 100 100
filters: invert(1)

Просмотреть файл

@ -73,6 +73,7 @@ platform(linux,mac) == backdrop-filter-blur-across-tiles.yaml backdrop-filter-bl
#platform(linux,mac) == backdrop-filter-drop-shadow.yaml backdrop-filter-drop-shadow.png
== backdrop-filter-blur-edge-mode.yaml backdrop-filter-blur-edge-mode-ref.yaml
== backdrop-filter-half-opacity.yaml backdrop-filter-half-opacity-ref.yaml
platform(linux,mac) == backdrop-filter-transformed-filter.yaml backdrop-filter-transformed-filter.png
platform(linux,max) == svg-filter-offset.yaml svg-filter-offset-ref.yaml
skip_on(android,device) == fuzzy(1,100) svg-filter-composite.yaml svg-filter-composite-ref.yaml
skip_on(android,device) == filter-mix-blend-scaling.yaml filter-mix-blend-scaling-ref.yaml

Просмотреть файл

@ -89,11 +89,12 @@ async function panRightToLeft(aElement, aX, aY, aMultiplier) {
}
async function panLeftToRight(aElement, aX, aY, aMultiplier) {
await panLeftToRightBeginAndUpdate(aElement, aX, aY, aMultiplier);
await panLeftToRightBegin(aElement, aX, aY, aMultiplier);
await panLeftToRightUpdate(aElement, aX, aY, aMultiplier);
await panLeftToRightEnd(aElement, aX, aY, aMultiplier);
}
async function panLeftToRightBeginAndUpdate(aElement, aX, aY, aMultiplier) {
async function panLeftToRightBegin(aElement, aX, aY, aMultiplier) {
await NativePanHandler.promiseNativePanEvent(
aElement,
aX,
@ -102,6 +103,9 @@ async function panLeftToRightBeginAndUpdate(aElement, aX, aY, aMultiplier) {
0,
NativePanHandler.beginPhase
);
}
async function panLeftToRightUpdate(aElement, aX, aY, aMultiplier) {
await NativePanHandler.promiseNativePanEvent(
aElement,
aX,
@ -284,7 +288,8 @@ add_task(async () => {
// anything. Don't send the pan end because we want to check the opacity
// before the MSD animation in SwipeTracker starts which can temporarily put
// us at 1 opacity.
await panLeftToRightBeginAndUpdate(tab.linkedBrowser, 100, 100, 0.9);
await panLeftToRightBegin(tab.linkedBrowser, 100, 100, 0.9);
await panLeftToRightUpdate(tab.linkedBrowser, 100, 100, 0.9);
// Check both getComputedStyle instead of element.style.opacity because we use a transition on the opacity.
let computedOpacity = window
@ -382,7 +387,8 @@ add_task(async () => {
// anything. Don't send the pan end because we want to check the opacity
// before the MSD animation in SwipeTracker starts which can temporarily put
// us at 1 opacity.
await panLeftToRightBeginAndUpdate(tab.linkedBrowser, 100, 100, 1.8);
await panLeftToRightBegin(tab.linkedBrowser, 100, 100, 1.8);
await panLeftToRightUpdate(tab.linkedBrowser, 100, 100, 1.8);
// Check both getComputedStyle instead of element.style.opacity because we use a transition on the opacity.
let computedOpacity = window
@ -621,3 +627,74 @@ add_task(async () => {
BrowserTestUtils.removeTab(tab);
});
add_task(async () => {
// success-velocity-contribution is very high and whole-page-pixel-size is
// very low so that one swipe goes over the threshold asap.
await SpecialPowers.pushPrefEnv({
set: [
["browser.gesture.swipe.left", "Browser:BackOrBackDuplicate"],
["browser.gesture.swipe.eight", "Browser:ForwardOrForwardDuplicate"],
["widget.disable-swipe-tracker", false],
["widget.swipe.velocity-twitch-tolerance", 0.0000001],
["widget.swipe.success-velocity-contribution", 999999.0],
["widget.swipe.whole-page-pixel-size", 1.0],
],
});
const firstPage = "about:about";
const secondPage = "about:mozilla";
const tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
firstPage,
true /* waitForLoad */
);
BrowserTestUtils.loadURI(tab.linkedBrowser, secondPage);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, secondPage);
// Make sure we can go back to the previous page.
ok(gBrowser.webNavigation.canGoBack);
// and we cannot go forward to the next page.
ok(!gBrowser.webNavigation.canGoForward);
// Navigate backward.
let startLoadingPromise = BrowserTestUtils.browserStarted(
tab.linkedBrowser,
firstPage
);
let stoppedLoadingPromise = BrowserTestUtils.browserStopped(
tab.linkedBrowser,
firstPage
);
await panLeftToRightBegin(tab.linkedBrowser, 100, 100, 100);
ok(gHistorySwipeAnimation._prevBox != null, "should have prevbox");
let transitionPromise = new Promise(resolve => {
gHistorySwipeAnimation._prevBox.addEventListener(
"transitionstart",
resolve,
{ once: true }
);
});
await panLeftToRightUpdate(tab.linkedBrowser, 100, 100, 100);
await panLeftToRightEnd(tab.linkedBrowser, 100, 100, 100);
// Make sure the gesture triggered going back to the previous page.
await Promise.all([startLoadingPromise, stoppedLoadingPromise]);
ok(gBrowser.webNavigation.canGoForward);
await transitionPromise;
await TestUtils.waitForCondition(() => {
return (
gHistorySwipeAnimation._prevBox == null &&
gHistorySwipeAnimation._nextBox == null
);
});
BrowserTestUtils.removeTab(tab);
});