Commit 16db5bad authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Don't create dummy display item for filter on empty contents

Only reference filters can create visual effect on empty contents.
As we now support empty paint chunks, we can avoid the dummy display
item for a filter on empty contents. Instead, we emit filter paint
operation for the filter with correct bounds and visual rect in
PaintChunksToCcLayer.

Change-Id: I709858a236aefa0403d35f591928f25875560f9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2093915
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748800}
parent 14c902e6
...@@ -53,14 +53,11 @@ TEST_P(BoxPainterTest, EmptyDecorationBackground) { ...@@ -53,14 +53,11 @@ TEST_P(BoxPainterTest, EmptyDecorationBackground) {
kDocumentBackgroundType), kDocumentBackgroundType),
GetLayoutView().FirstFragment().ContentsProperties(), GetLayoutView().FirstFragment().ContentsProperties(),
nullptr, IntRect(0, 0, 800, 600)), nullptr, IntRect(0, 0, 800, 600)),
IsPaintChunk( // Empty backgrounds contribute to bounds of paint chunks.
1, 3, PaintChunk::Id(*body->Layer(), DisplayItem::kLayerChunk), IsPaintChunk(1, 3,
body->FirstFragment().LocalBorderBoxProperties(), nullptr, PaintChunk::Id(*body->Layer(), DisplayItem::kLayerChunk),
// In CompositeAfterPaint, empty backgrounds contribute body->FirstFragment().LocalBorderBoxProperties(),
// to bounds of paint chunks. nullptr, IntRect(-2, 0, 202, 350))));
RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
? IntRect(-2, 0, 202, 350)
: IntRect(-2, 0, 104, 202))));
} }
TEST_P(BoxPainterTest, ScrollHitTestOrderWithScrollBackgroundAttachment) { TEST_P(BoxPainterTest, ScrollHitTestOrderWithScrollBackgroundAttachment) {
......
...@@ -442,9 +442,6 @@ PaintResult PaintLayerPainter::PaintLayerContents( ...@@ -442,9 +442,6 @@ PaintResult PaintLayerPainter::PaintLayerContents(
local_painting_info.GetGlobalPaintFlags() & kGlobalPaintSelectionOnly; local_painting_info.GetGlobalPaintFlags() & kGlobalPaintSelectionOnly;
{ // Begin block for the lifetime of any filter. { // Begin block for the lifetime of any filter.
size_t display_item_list_size_before_painting =
context.GetPaintController().NewDisplayItemList().size();
bool is_painting_root_layer = (&paint_layer_) == painting_info.root_layer; bool is_painting_root_layer = (&paint_layer_) == painting_info.root_layer;
bool should_paint_background = bool should_paint_background =
should_paint_content && !selection_only && should_paint_content && !selection_only &&
...@@ -521,19 +518,6 @@ PaintResult PaintLayerPainter::PaintLayerContents( ...@@ -521,19 +518,6 @@ PaintResult PaintLayerPainter::PaintLayerContents(
PaintSelfOutlineForFragments(layer_fragments, context, PaintSelfOutlineForFragments(layer_fragments, context,
local_painting_info, paint_flags); local_painting_info, paint_flags);
} }
if (!is_painting_overlay_overflow_controls) {
// For filters, if the layer painted nothing, we need to issue a no-op
// display item to ensure the filters won't be ignored. For backdrop
// filters, we issue the display item regardless of other paintings to
// ensure correct bounds of the composited layer for the backdrop filter.
if ((paint_layer_.PaintsWithFilters() &&
display_item_list_size_before_painting ==
context.GetPaintController().NewDisplayItemList().size()) ||
paint_layer_.GetLayoutObject().HasBackdropFilter()) {
PaintEmptyContentForFilters(context);
}
}
} // FilterPainter block } // FilterPainter block
bool should_paint_mask = is_painting_mask && should_paint_content && bool should_paint_mask = is_painting_mask && should_paint_content &&
...@@ -853,21 +837,4 @@ void PaintLayerPainter::FillMaskingFragment(GraphicsContext& context, ...@@ -853,21 +837,4 @@ void PaintLayerPainter::FillMaskingFragment(GraphicsContext& context,
context.FillRect(snapped_clip_rect, Color::kBlack); context.FillRect(snapped_clip_rect, Color::kBlack);
} }
// Generate a no-op DrawingDisplayItem to ensure a non-empty chunk for the
// filter without content.
void PaintLayerPainter::PaintEmptyContentForFilters(GraphicsContext& context) {
DCHECK(paint_layer_.PaintsWithFilters() ||
paint_layer_.GetLayoutObject().HasBackdropFilter());
ScopedPaintChunkProperties paint_chunk_properties(
context.GetPaintController(),
paint_layer_.GetLayoutObject().FirstFragment().LocalBorderBoxProperties(),
paint_layer_, DisplayItem::kEmptyContentForFilters);
if (DrawingRecorder::UseCachedDrawingIfPossible(
context, paint_layer_, DisplayItem::kEmptyContentForFilters))
return;
DrawingRecorder recorder(context, paint_layer_,
DisplayItem::kEmptyContentForFilters);
}
} // namespace blink } // namespace blink
...@@ -106,8 +106,6 @@ class CORE_EXPORT PaintLayerPainter { ...@@ -106,8 +106,6 @@ class CORE_EXPORT PaintLayerPainter {
const ClipRect&, const ClipRect&,
const DisplayItemClient&); const DisplayItemClient&);
void PaintEmptyContentForFilters(GraphicsContext&);
void AdjustForPaintProperties(const GraphicsContext&, void AdjustForPaintProperties(const GraphicsContext&,
PaintLayerPaintingInfo&, PaintLayerPaintingInfo&,
PaintLayerFlags&); PaintLayerFlags&);
......
...@@ -277,6 +277,7 @@ void ConversionContext::TranslateForLayerOffsetOnce() { ...@@ -277,6 +277,7 @@ void ConversionContext::TranslateForLayerOffsetOnce() {
} }
void ConversionContext::SwitchToChunkState(const PaintChunk& chunk) { void ConversionContext::SwitchToChunkState(const PaintChunk& chunk) {
TranslateForLayerOffsetOnce();
chunk_to_layer_mapper_.SwitchToChunk(chunk); chunk_to_layer_mapper_.SwitchToChunk(chunk);
const auto& chunk_state = chunk.properties; const auto& chunk_state = chunk.properties;
...@@ -591,6 +592,19 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) { ...@@ -591,6 +592,19 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
EffectBoundsInfo{save_layer_id, current_transform_}); EffectBoundsInfo{save_layer_id, current_transform_});
current_clip_ = input_clip; current_clip_ = input_clip;
current_effect_ = &effect; current_effect_ = &effect;
if (effect.Filter().HasReferenceFilter()) {
auto reference_box = effect.Filter().ReferenceBox();
reference_box.MoveBy(effect.FiltersOrigin());
effect_bounds_stack_.back().bounds = reference_box;
if (current_effect_->Filter().HasReferenceFilter()) {
// Emit an empty paint operation to add the filter's source bounds (mapped
// to layer space) to the visual rect of the filter's SaveLayerOp.
cc_list_.StartPaint();
cc_list_.EndPaintOfUnpaired(chunk_to_layer_mapper_.MapVisualRect(
EnclosingIntRect(reference_box)));
}
}
} }
void ConversionContext::UpdateEffectBounds( void ConversionContext::UpdateEffectBounds(
...@@ -727,17 +741,16 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks, ...@@ -727,17 +741,16 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
else else
continue; continue;
// If we have an empty paint record, then we would prefer not to draw it. // If we have an empty paint record, then we would prefer ignoring it.
// However, if we also have a non-root effect, it means that the filter // However, if we also have a non-root effect, the empty paint record
// applied might draw something even if the record is empty. We need to // might be for a mask with empty content which should make the masked
// "draw" this record in order to ensure that the effect has correct // content fully invisible. We need to "draw" this record to ensure that
// visual rects. // the effect has correct visual rect.
if ((!record || record->size() == 0) && if ((!record || record->size() == 0) &&
&chunk_state.Effect() == &EffectPaintPropertyNode::Root()) { &chunk_state.Effect() == &EffectPaintPropertyNode::Root()) {
continue; continue;
} }
TranslateForLayerOffsetOnce();
if (!switched_to_chunk_state) { if (!switched_to_chunk_state) {
SwitchToChunkState(chunk); SwitchToChunkState(chunk);
switched_to_chunk_state = true; switched_to_chunk_state = true;
...@@ -749,7 +762,18 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks, ...@@ -749,7 +762,18 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
cc_list_.EndPaintOfUnpaired( cc_list_.EndPaintOfUnpaired(
chunk_to_layer_mapper_.MapVisualRect(item.VisualRect())); chunk_to_layer_mapper_.MapVisualRect(item.VisualRect()));
} }
UpdateEffectBounds(FloatRect(chunk.bounds), chunk_state.Transform());
// If we have an empty paint chunk, then we would prefer ignoring it.
// However, a reference filter can generate visible effect from invisible
// source, and we need to emit paint operations for it.
if (!switched_to_chunk_state && &chunk_state.Effect() != current_effect_)
SwitchToChunkState(chunk);
// Most effects apply to drawable contents only. Reference filters are
// exceptions, for which we have already added the reference box to the
// bounds of the effect in StartEffect().
UpdateEffectBounds(FloatRect(chunk.drawable_bounds),
chunk_state.Transform());
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <initializer_list> #include <initializer_list>
#include "cc/paint/display_item_list.h" #include "cc/paint/display_item_list.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_flags.h" #include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer.h" #include "cc/paint/paint_op_buffer.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -160,26 +161,43 @@ struct TestChunks { ...@@ -160,26 +161,43 @@ struct TestChunks {
DisplayItemList items = DisplayItemList(0); DisplayItemList items = DisplayItemList(0);
// Add a paint chunk with a non-empty paint record and given property nodes. // Add a paint chunk with a non-empty paint record and given property nodes.
void AddChunk(const TransformPaintPropertyNode& t, void AddChunk(
const ClipPaintPropertyNode& c, const TransformPaintPropertyNode& t,
const EffectPaintPropertyNode& e, const ClipPaintPropertyNode& c,
const IntRect& bounds = IntRect(0, 0, 100, 100)) { const EffectPaintPropertyNode& e,
const IntRect& bounds = IntRect(0, 0, 100, 100),
const base::Optional<IntRect>& drawable_bounds = base::nullopt) {
auto record = sk_make_sp<PaintRecord>(); auto record = sk_make_sp<PaintRecord>();
record->push<cc::DrawRectOp>(bounds, cc::PaintFlags()); record->push<cc::DrawRectOp>(drawable_bounds ? *drawable_bounds : bounds,
AddChunk(std::move(record), t, c, e, bounds); cc::PaintFlags());
AddChunk(std::move(record), t, c, e, bounds, drawable_bounds);
} }
// Add a paint chunk with a given paint record and property nodes. // Add a paint chunk with a given paint record and property nodes.
void AddChunk(sk_sp<PaintRecord> record, void AddChunk(
const TransformPaintPropertyNode& t, sk_sp<PaintRecord> record,
const ClipPaintPropertyNode& c, const TransformPaintPropertyNode& t,
const EffectPaintPropertyNode& e, const ClipPaintPropertyNode& c,
const IntRect& bounds = IntRect(0, 0, 100, 100)) { const EffectPaintPropertyNode& e,
const IntRect& bounds = IntRect(0, 0, 100, 100),
const base::Optional<IntRect>& drawable_bounds = base::nullopt) {
auto i = items.size(); auto i = items.size();
items.AllocateAndConstruct<DrawingDisplayItem>( items.AllocateAndConstruct<DrawingDisplayItem>(
DefaultId().client, DefaultId().type, std::move(record)); DefaultId().client, DefaultId().type, std::move(record));
if (drawable_bounds)
items.Last().SetVisualRectForTesting(*drawable_bounds);
chunks.emplace_back(i, i + 1, DefaultId(), PropertyTreeState(t, c, e)); chunks.emplace_back(i, i + 1, DefaultId(), PropertyTreeState(t, c, e));
chunks.back().bounds = bounds; chunks.back().bounds = bounds;
chunks.back().drawable_bounds = drawable_bounds ? *drawable_bounds : bounds;
}
void AddEmptyChunk(const TransformPaintPropertyNode& t,
const ClipPaintPropertyNode& c,
const EffectPaintPropertyNode& e,
const IntRect& bounds = IntRect(0, 0, 100, 100)) {
auto i = items.size();
chunks.emplace_back(i, i, DefaultId(), PropertyTreeState(t, c, e));
chunks.back().bounds = bounds;
} }
}; };
...@@ -1330,5 +1348,88 @@ TEST_P(PaintChunksToCcLayerTest, EmptyChunkRect) { ...@@ -1330,5 +1348,88 @@ TEST_P(PaintChunksToCcLayerTest, EmptyChunkRect) {
EXPECT_EFFECT_BOUNDS(0, 0, 0, 0, *output, 0); EXPECT_EFFECT_BOUNDS(0, 0, 0, 0, *output, 0);
} }
TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnEmptyChunk) {
CompositorFilterOperations filter;
filter.AppendReferenceFilter(sk_make_sp<cc::RecordPaintFilter>(
sk_make_sp<cc::PaintOpBuffer>(), SkRect::MakeIWH(100, 100)));
filter.SetReferenceBox(FloatRect(11, 22, 33, 44));
ASSERT_TRUE(filter.HasReferenceFilter());
auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(10, 20));
TestChunks chunks;
chunks.AddEmptyChunk(t0(), c0(), *e1, IntRect(0, 0, 200, 300));
auto cc_list = base::MakeRefCounted<cc::DisplayItemList>(
cc::DisplayItemList::kTopLevelDisplayItemList);
PaintChunksToCcLayer::ConvertInto(chunks.chunks, PropertyTreeState::Root(),
gfx::Vector2dF(5, 10), FloatSize(),
chunks.items, *cc_list);
ASSERT_EQ(9u, cc_list->TotalOpCount());
// (16 32) is (11, 22) + filter_offset - layer_offset.
gfx::Rect expected_visual_rect(16, 32, 33, 44);
for (size_t i = 0; i < cc_list->TotalOpCount(); i++) {
SCOPED_TRACE(testing::Message() << "Visual rect of op " << i);
EXPECT_EQ(expected_visual_rect, cc_list->VisualRectForTesting(i));
}
auto output = cc_list->ReleaseAsRecord();
EXPECT_THAT(*output,
PaintRecordMatcher::Make(
{cc::PaintOpType::Save,
cc::PaintOpType::Translate, // layer offset
cc::PaintOpType::Save, // <e1>
cc::PaintOpType::Translate, cc::PaintOpType::SaveLayer,
cc::PaintOpType::Translate, cc::PaintOpType::Restore,
cc::PaintOpType::Restore, // </e1>
cc::PaintOpType::Restore}));
EXPECT_EFFECT_BOUNDS(11, 22, 33, 44, *output, 4);
}
TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
CompositorFilterOperations filter;
filter.AppendReferenceFilter(sk_make_sp<cc::RecordPaintFilter>(
sk_make_sp<cc::PaintOpBuffer>(), SkRect::MakeIWH(100, 100)));
filter.SetReferenceBox(FloatRect(11, 22, 33, 44));
ASSERT_TRUE(filter.HasReferenceFilter());
auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(10, 20));
TestChunks chunks;
chunks.AddChunk(t0(), c0(), *e1, IntRect(5, 10, 200, 300),
IntRect(10, 15, 20, 30));
auto cc_list = base::MakeRefCounted<cc::DisplayItemList>(
cc::DisplayItemList::kTopLevelDisplayItemList);
PaintChunksToCcLayer::ConvertInto(chunks.chunks, PropertyTreeState::Root(),
gfx::Vector2dF(5, 10), FloatSize(),
chunks.items, *cc_list);
ASSERT_EQ(11u, cc_list->TotalOpCount());
// This is the visual rect for all filter related paint operations, which is
// the union of the draw record and reference box of the filter in the layer's
// space.
gfx::Rect expected_filter_visual_rect(5, 5, 44, 71);
// This is the visual rect of the DrawingDisplayItem in the layer's space.
gfx::Rect expected_draw_visual_rect(5, 5, 20, 30);
// TotalOpCount() - 1 because the DrawRecord op has a sub operation.
for (size_t i = 0; i < cc_list->TotalOpCount() - 1; i++) {
SCOPED_TRACE(testing::Message() << "Visual rect of op " << i);
EXPECT_EQ(i == 6 ? expected_draw_visual_rect : expected_filter_visual_rect,
cc_list->VisualRectForTesting(i));
}
auto output = cc_list->ReleaseAsRecord();
EXPECT_THAT(*output,
PaintRecordMatcher::Make(
{cc::PaintOpType::Save,
cc::PaintOpType::Translate, // layer offset
cc::PaintOpType::Save, //
cc::PaintOpType::Translate, // e1->FilterOrigin()
cc::PaintOpType::SaveLayer, // <e1>
cc::PaintOpType::Translate, // -e1->FilterOrigin()
cc::PaintOpType::DrawRecord, // the DrawingDisplayItem
cc::PaintOpType::Restore, // </e1>
cc::PaintOpType::Restore, cc::PaintOpType::Restore}));
// The effect bounds are the union of the chunk's drawable_bounds and the
// reference box in the filter's space.
EXPECT_EFFECT_BOUNDS(0, -5, 44, 71, *output, 4);
}
} // namespace } // namespace
} // namespace blink } // namespace blink
...@@ -110,6 +110,10 @@ bool CompositorFilterOperations::HasFilterThatMovesPixels() const { ...@@ -110,6 +110,10 @@ bool CompositorFilterOperations::HasFilterThatMovesPixels() const {
return filter_operations_.HasFilterThatMovesPixels(); return filter_operations_.HasFilterThatMovesPixels();
} }
bool CompositorFilterOperations::HasReferenceFilter() const {
return filter_operations_.HasReferenceFilter();
}
bool CompositorFilterOperations::operator==( bool CompositorFilterOperations::operator==(
const CompositorFilterOperations& o) const { const CompositorFilterOperations& o) const {
return reference_box_ == o.reference_box_ && return reference_box_ == o.reference_box_ &&
......
...@@ -49,9 +49,10 @@ class PLATFORM_EXPORT CompositorFilterOperations { ...@@ -49,9 +49,10 @@ class PLATFORM_EXPORT CompositorFilterOperations {
FloatRect MapRect(const FloatRect& input_rect) const; FloatRect MapRect(const FloatRect& input_rect) const;
bool HasFilterThatMovesPixels() const; bool HasFilterThatMovesPixels() const;
bool HasReferenceFilter() const;
void SetReferenceBox(const FloatRect& r) { reference_box_ = r; } void SetReferenceBox(const FloatRect& r) { reference_box_ = r; }
FloatRect ReferenceBox() const { return reference_box_; } const FloatRect& ReferenceBox() const { return reference_box_; }
// For reference filters, this equality operator compares pointers of the // For reference filters, this equality operator compares pointers of the
// image_filter fields instead of their values. // image_filter fields instead of their values.
......
...@@ -82,7 +82,6 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) { ...@@ -82,7 +82,6 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(DocumentBackground); DEBUG_STRING_CASE(DocumentBackground);
DEBUG_STRING_CASE(DragImage); DEBUG_STRING_CASE(DragImage);
DEBUG_STRING_CASE(DragCaret); DEBUG_STRING_CASE(DragCaret);
DEBUG_STRING_CASE(EmptyContentForFilters);
DEBUG_STRING_CASE(ForcedColorsModeBackplate); DEBUG_STRING_CASE(ForcedColorsModeBackplate);
DEBUG_STRING_CASE(SVGImage); DEBUG_STRING_CASE(SVGImage);
DEBUG_STRING_CASE(LinkHighlight); DEBUG_STRING_CASE(LinkHighlight);
......
...@@ -65,7 +65,6 @@ class PLATFORM_EXPORT DisplayItem { ...@@ -65,7 +65,6 @@ class PLATFORM_EXPORT DisplayItem {
kDocumentBackground, kDocumentBackground,
kDragImage, kDragImage,
kDragCaret, kDragCaret,
kEmptyContentForFilters,
kForcedColorsModeBackplate, kForcedColorsModeBackplate,
kSVGImage, kSVGImage,
kLinkHighlight, kLinkHighlight,
...@@ -226,6 +225,8 @@ class PLATFORM_EXPORT DisplayItem { ...@@ -226,6 +225,8 @@ class PLATFORM_EXPORT DisplayItem {
fragment_ = fragment; fragment_ = fragment;
} }
void SetVisualRectForTesting(const IntRect& r) { visual_rect_ = r; }
// See comments of enum Type for usage of the following macros. // See comments of enum Type for usage of the following macros.
#define DEFINE_CATEGORY_METHODS(Category) \ #define DEFINE_CATEGORY_METHODS(Category) \
static constexpr bool Is##Category##Type(Type type) { \ static constexpr bool Is##Category##Type(Type type) { \
......
...@@ -117,8 +117,13 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) { ...@@ -117,8 +117,13 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
void PaintChunker::AddHitTestDataToCurrentChunk(const PaintChunk::Id& id, void PaintChunker::AddHitTestDataToCurrentChunk(const PaintChunk::Id& id,
const IntRect& rect, const IntRect& rect,
TouchAction touch_action) { TouchAction touch_action) {
// In CompositeAfterPaint, we ensure a paint chunk for correct composited
// hit testing. In pre-CompositeAfterPaint, this is unnecessary, except that
// there is special touch action, and that we have a non-root effect so that
// PaintChunksToCcLayer will emit paint operations for filters.
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
touch_action == TouchAction::kAuto) touch_action == TouchAction::kAuto &&
&current_properties_.Effect() == &EffectPaintPropertyNode::Root())
return; return;
auto& chunk = EnsureCurrentChunk(id); auto& chunk = EnsureCurrentChunk(id);
......
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
</style> </style>
</head> </head>
<body> <body>
<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=26084">WebKit Bug 26084: Bug 26084: Multiple missing images in webkit-mask-image prevent rendering</a></p>
<div class="test"></div> <div class="test"></div>
<p>If the test passes, you should be able to see a lime square with a black border. Inside the border, you should see the text: This text should be visible. This test is currently failing.</p> <p>If the test passes, you should see nothing above, because we should not render masked content if the mask image fails to load.</p>
</body> </body>
</html> </html>
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
</style> </style>
</head> </head>
<body> <body>
<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=26084">WebKit Bug 26084: Bug 26084: Multiple missing images in webkit-mask-image prevent rendering</a></p>
<div class="test">This text should be visible.</div> <div class="test">This text should be visible.</div>
<p>If the test passes, you should be able to see a lime square with a black border. Inside the border, you should see the text: This text should be visible. This test is currently failing.</p> <p>If the test passes, you should see nothing above, because we should not render masked content if the mask image fails to load.</p>
</body> </body>
</html> </html>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{ {
"object": "LayoutNGBlockFlow DIV class='box'", "object": "LayoutNGBlockFlow DIV class='box'",
"rect": [78, 70, 100, 100], "rect": [78, 70, 100, 100],
"reason": "chunk appeared" "reason": "appeared"
} }
] ]
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{ {
"object": "LayoutBlockFlow DIV class='box'", "object": "LayoutBlockFlow DIV class='box'",
"rect": [78, 70, 100, 100], "rect": [78, 70, 100, 100],
"reason": "chunk appeared" "reason": "appeared"
} }
] ]
} }
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow HTML", "object": "InlineTextBox 'abc'",
"rect": [18, 18, 22, 19], "rect": [18, 18, 22, 19],
"reason": "chunk disappeared" "reason": "disappeared"
}, },
{ {
"object": "InlineTextBox 'abc'", "object": "InlineTextBox 'abc'",
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutBlockFlow HTML", "object": "LayoutBlockFlow HTML",
"rect": [3, 65, 55, 17], "rect": [3, 65, 55, 17],
"reason": "chunk appeared" "reason": "paint property change"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{ {
"object": "LayoutNGBlockFlow DIV class='box'", "object": "LayoutNGBlockFlow DIV class='box'",
"rect": [78, 70, 100, 100], "rect": [78, 70, 100, 100],
"reason": "chunk appeared" "reason": "appeared"
} }
] ]
} }
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutEmbeddedObject OBJECT",
"rect": [1, 1, 402, 202], "rect": [1, 1, 402, 202],
"reason": "chunk appeared" "reason": "appeared"
}, },
{ {
"object": "HorizontalScrollbar", "object": "HorizontalScrollbar",
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutEmbeddedObject OBJECT",
"rect": [1, 1, 402, 202], "rect": [1, 1, 402, 202],
"reason": "chunk appeared" "reason": "appeared"
}, },
{ {
"object": "HorizontalScrollbar", "object": "HorizontalScrollbar",
......
...@@ -14,7 +14,12 @@ ...@@ -14,7 +14,12 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [8, 300, 60, 22], "rect": [8, 300, 60, 22],
"reason": "chunk appeared" "reason": "incremental"
},
{
"object": "NGPhysicalTextFragment 'Success'",
"rect": [8, 300, 60, 22],
"reason": "appeared"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [3, 65, 55, 17], "rect": [3, 65, 55, 17],
"reason": "chunk appeared" "reason": "paint property change"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutNGBlockFlow HTML", "object": "NGPhysicalTextFragment 'abc'",
"rect": [18, 18, 23, 18], "rect": [18, 18, 23, 18],
"reason": "chunk disappeared" "reason": "disappeared"
}, },
{ {
"object": "NGPhysicalTextFragment 'abc'", "object": "NGPhysicalTextFragment 'abc'",
......
...@@ -14,7 +14,12 @@ ...@@ -14,7 +14,12 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [8, 300, 61, 22], "rect": [8, 300, 61, 22],
"reason": "chunk appeared" "reason": "incremental"
},
{
"object": "NGPhysicalTextFragment 'Success'",
"rect": [8, 300, 61, 22],
"reason": "appeared"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [3, 65, 58, 16], "rect": [3, 65, 58, 16],
"reason": "chunk appeared" "reason": "paint property change"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutNGBlockFlow HTML", "object": "NGPhysicalTextFragment 'abc'",
"rect": [18, 18, 22, 19], "rect": [18, 18, 22, 19],
"reason": "chunk disappeared" "reason": "disappeared"
}, },
{ {
"object": "NGPhysicalTextFragment 'abc'", "object": "NGPhysicalTextFragment 'abc'",
......
...@@ -14,7 +14,12 @@ ...@@ -14,7 +14,12 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [8, 300, 64, 22], "rect": [8, 300, 64, 22],
"reason": "chunk appeared" "reason": "incremental"
},
{
"object": "NGPhysicalTextFragment 'Success'",
"rect": [8, 300, 64, 22],
"reason": "appeared"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutNGBlockFlow HTML", "object": "LayoutNGBlockFlow HTML",
"rect": [3, 65, 52, 17], "rect": [3, 65, 52, 17],
"reason": "chunk appeared" "reason": "paint property change"
}, },
{ {
"object": "VerticalScrollbar", "object": "VerticalScrollbar",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment