зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central a=merge
This commit is contained in:
Коммит
d2a8e14b56
|
@ -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,
|
||||
);
|
||||
|
|
Двоичные данные
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.png
Двоичные данные
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 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);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче