diff --git a/DEPS b/DEPS index 7b54c04b..bcce914 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '96d5b9a273a5513fb3215fc06452cda82c3d6872', + 'skia_revision': 'b712089b93fadf3f3b560e9b21803f4c7626c94e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -56,7 +56,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': 'd3074448541662f242bcee623049c13a231b5648', + 'buildtools_revision': '88811f48a6b79786ef35be86825642fc33011151', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '2c2b58de54d8788cccaddf3f3846c9fa1de00306', + 'catapult_revision': '0146f4833cb3c65b3792e756676909648961cdaa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 320b7fce..630db84 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1385,7 +1385,12 @@ if (enabled_frame_pointers) { cflags = [ "-fno-omit-frame-pointer" ] } else { - cflags = [ "-fomit-frame-pointer" ] + if (is_android || current_cpu != "arm") { + # TODO(710131): Remove this special-casing for ARM 32 bit once we + # have determined why -fomit-frame-pointer triggers CPU errata in + # ARM A12/A17 devices. + cflags = [ "-fomit-frame-pointer" ] + } } } # On Windows, the flag to enable framepointers "/Oy-" must always come after
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index f7918544..c62ac3a 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -647,6 +647,8 @@ "test/test_occlusion_tracker.h", "test/test_shared_bitmap_manager.cc", "test/test_shared_bitmap_manager.h", + "test/test_skcanvas.cc", + "test/test_skcanvas.h", "test/test_task_graph_runner.cc", "test/test_task_graph_runner.h", "test/test_texture.cc", @@ -764,6 +766,7 @@ "output/texture_mailbox_deleter_unittest.cc", "paint/discardable_image_map_unittest.cc", "paint/display_item_list_unittest.cc", + "paint/paint_op_buffer_unittest.cc", "quads/draw_polygon_unittest.cc", "quads/draw_quad_unittest.cc", "quads/nine_patch_generator_unittest.cc", @@ -934,6 +937,7 @@ "//cc/ipc", "//cc/ipc:interfaces", "//cc/paint", + "//cc/paint", "//cc/surfaces", "//cc/surfaces:surface_id", "//gpu",
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn index 3af5dee..11f9fdac 100644 --- a/cc/paint/BUILD.gn +++ b/cc/paint/BUILD.gn
@@ -32,13 +32,19 @@ "paint_canvas.cc", "paint_canvas.h", "paint_export.h", + "paint_flags.cc", "paint_flags.h", "paint_image.cc", "paint_image.h", + "paint_op_buffer.cc", + "paint_op_buffer.h", + "paint_record.cc", "paint_record.h", "paint_recorder.cc", "paint_recorder.h", "paint_shader.h", + "record_paint_canvas.cc", + "record_paint_canvas.h", "skia_paint_canvas.cc", "skia_paint_canvas.h", "transform_display_item.cc",
diff --git a/cc/paint/display_item_list.cc b/cc/paint/display_item_list.cc index 8359948..c1b069548 100644 --- a/cc/paint/display_item_list.cc +++ b/cc/paint/display_item_list.cc
@@ -100,9 +100,13 @@ if (canvas->quickReject(item.picture->cullRect())) break; - // SkPicture always does a wrapping save/restore on the canvas, so it is - // not necessary here. + // TODO(enne): Maybe the PaintRecord itself could know whether this + // was needed? It's not clear whether these save/restore semantics + // that SkPicture handles during playback are things that should be + // kept around. + canvas->save(); item.picture->playback(canvas, callback); + canvas->restore(); break; } case DisplayItem::FLOAT_CLIP: { @@ -176,6 +180,33 @@ canvas->restore(); } +// Atttempts to merge a CompositingDisplayItem and DrawingDisplayItem +// into a single "draw with alpha". This function returns true if +// it was successful. If false, then the caller is responsible for +// drawing these items. This is a DisplayItemList version of the +// SkRecord optimization SkRecordNoopSaveLayerDrawRestores. +static bool MergeAndDrawIfPossible(const CompositingDisplayItem& save_item, + const DrawingDisplayItem& draw_item, + SkCanvas* canvas) { + if (save_item.color_filter) + return false; + if (save_item.xfermode != SkBlendMode::kSrcOver) + return false; + // TODO(enne): I believe that lcd_text_requires_opaque_layer is not + // relevant here and that lcd text is preserved post merge, but I haven't + // tested that. + const PaintRecord* record = draw_item.picture.get(); + if (record->approximateOpCount() != 1) + return false; + + const PaintOp* op = record->GetFirstOp(); + if (!op->IsDrawOp()) + return false; + + op->RasterWithAlpha(canvas, save_item.alpha); + return true; +} + void DisplayItemList::Raster(SkCanvas* canvas, SkPicture::AbortCallback* callback) const { gfx::Rect canvas_playback_rect; @@ -184,14 +215,33 @@ std::vector<size_t> indices; rtree_.Search(canvas_playback_rect, &indices); - for (size_t index : indices) { - RasterItem(items_[index], canvas, callback); - + for (size_t i = 0; i < indices.size(); ++i) { // We use a callback during solid color analysis on the compositor thread to // break out early. Since we're handling a sequence of pictures via rtree // query results ourselves, we have to respect the callback and early out. if (callback && callback->abort()) break; + + const DisplayItem& item = items_[indices[i]]; + // Optimize empty begin/end compositing and merge begin/draw/end compositing + // where possible. + // TODO(enne): remove empty clips here too? + // TODO(enne): does this happen recursively? Or is this good enough? + if (i < indices.size() - 2 && item.type == DisplayItem::COMPOSITING) { + const DisplayItem& second = items_[indices[i + 1]]; + const DisplayItem& third = items_[indices[i + 2]]; + if (second.type == DisplayItem::DRAWING && + third.type == DisplayItem::END_COMPOSITING) { + if (MergeAndDrawIfPossible( + static_cast<const CompositingDisplayItem&>(item), + static_cast<const DrawingDisplayItem&>(second), canvas)) { + i += 2; + continue; + } + } + } + + RasterItem(item, canvas, callback); } }
diff --git a/cc/paint/display_item_list_unittest.cc b/cc/paint/display_item_list_unittest.cc index f1b9e75..b166229c6 100644 --- a/cc/paint/display_item_list_unittest.cc +++ b/cc/paint/display_item_list_unittest.cc
@@ -17,16 +17,17 @@ #include "cc/paint/compositing_display_item.h" #include "cc/paint/drawing_display_item.h" #include "cc/paint/filter_display_item.h" - #include "cc/paint/float_clip_display_item.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" #include "cc/paint/paint_record.h" #include "cc/paint/paint_recorder.h" +#include "cc/paint/skia_paint_canvas.h" #include "cc/paint/transform_display_item.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/pixel_test_utils.h" #include "cc/test/skia_common.h" +#include "cc/test/test_skcanvas.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -80,6 +81,19 @@ return recorder.finishRecordingAsPicture(); } +sk_sp<const PaintRecord> CreateRectPictureWithAlpha(const gfx::Rect& bounds, + uint8_t alpha) { + PaintRecorder recorder; + PaintCanvas* canvas = + recorder.beginRecording(bounds.width(), bounds.height()); + PaintFlags flags; + flags.setAlpha(alpha); + canvas->drawRect( + SkRect::MakeXYWH(bounds.x(), bounds.y(), bounds.width(), bounds.height()), + flags); + return recorder.finishRecordingAsPicture(); +} + void AppendFirstSerializationTestPicture(scoped_refptr<DisplayItemList> list, const gfx::Size& layer_size) { gfx::PointF offset(2.f, 3.f); @@ -704,4 +718,110 @@ EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(3)); } +// Verify that raster time optimizations for compositing item / draw single op / +// end compositing item can be collapsed together into a single draw op +// with the opacity from the compositing item folded in. +TEST(DisplayItemListTest, SaveDrawRestore) { + auto list = make_scoped_refptr(new DisplayItemList); + + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 80, SkBlendMode::kSrcOver, nullptr, nullptr, false); + list->CreateAndAppendDrawingItem<DrawingDisplayItem>( + kVisualRect, CreateRectPictureWithAlpha(kVisualRect, 40)); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->Finalize(); + + SaveCountingCanvas canvas; + list->Raster(&canvas, nullptr); + + EXPECT_EQ(0, canvas.save_count_); + EXPECT_EQ(0, canvas.restore_count_); + EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_); + + float expected_alpha = 80 * 40 / 255.f; + EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f); +} + +// Verify that compositing item / end compositing item is a noop. +// Here we're testing that Skia does an optimization that skips +// save/restore with nothing in between. If skia stops doing this +// then we should reimplement this optimization in display list raster. +TEST(DisplayItemListTest, SaveRestoreNoops) { + auto list = make_scoped_refptr(new DisplayItemList); + + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 80, SkBlendMode::kSrcOver, nullptr, nullptr, false); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 255, SkBlendMode::kSrcOver, nullptr, nullptr, false); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 255, SkBlendMode::kSrc, nullptr, nullptr, false); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->Finalize(); + + SaveCountingCanvas canvas; + list->Raster(&canvas, nullptr); + + EXPECT_EQ(0, canvas.save_count_); + EXPECT_EQ(0, canvas.restore_count_); +} + +// The same as SaveDrawRestore, but with save flags that prevent the +// optimization. +TEST(DisplayItemListTest, SaveDrawRestoreFail_BadSaveFlags) { + auto list = make_scoped_refptr(new DisplayItemList); + + // Use a blend mode that's not compatible with the SaveDrawRestore + // optimization. + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 80, SkBlendMode::kSrc, nullptr, nullptr, false); + list->CreateAndAppendDrawingItem<DrawingDisplayItem>( + kVisualRect, CreateRectPictureWithAlpha(kVisualRect, 40)); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->Finalize(); + + SaveCountingCanvas canvas; + list->Raster(&canvas, nullptr); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); + EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_); + EXPECT_LE(40, canvas.paint_.getAlpha()); +} + +// The same as SaveDrawRestore, but with too many ops in the PaintRecord. +TEST(DisplayItemListTest, SaveDrawRestoreFail_TooManyOps) { + sk_sp<const PaintRecord> record; + { + PaintRecorder recorder; + PaintCanvas* canvas = + recorder.beginRecording(kVisualRect.width(), kVisualRect.height()); + PaintFlags flags; + flags.setAlpha(40); + canvas->drawRect(gfx::RectToSkRect(kVisualRect), flags); + // Add an extra op here. + canvas->drawRect(gfx::RectToSkRect(kVisualRect), flags); + record = recorder.finishRecordingAsPicture(); + } + EXPECT_GT(record->approximateOpCount(), 1); + + auto list = make_scoped_refptr(new DisplayItemList); + + list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>( + 80, SkBlendMode::kSrcOver, nullptr, nullptr, false); + list->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect, + std::move(record)); + list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>(); + list->Finalize(); + + SaveCountingCanvas canvas; + list->Raster(&canvas, nullptr); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); + EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_); + EXPECT_LE(40, canvas.paint_.getAlpha()); +} + } // namespace cc
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index 6b9a0df..d45e84b 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -11,19 +11,24 @@ #include "build/build_config.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_image.h" -#include "cc/paint/paint_record.h" #include "third_party/skia/include/core/SkCanvas.h" namespace cc { class DisplayItemList; class PaintFlags; +class PaintOpBuffer; + +using PaintRecord = PaintOpBuffer; class CC_PAINT_EXPORT PaintCanvas { public: virtual ~PaintCanvas() {} virtual SkMetaData& getMetaData() = 0; + + // TODO(enne): this only appears to mostly be used to determine if this is + // recording or not, so could be simplified or removed. virtual SkImageInfo imageInfo() const = 0; // TODO(enne): It would be nice to get rid of flush() entirely, as it @@ -42,7 +47,7 @@ int y) = 0; virtual int save() = 0; virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0; - virtual int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) = 0; + virtual int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) = 0; virtual void restore() = 0; virtual int getSaveCount() const = 0; @@ -93,6 +98,8 @@ virtual bool getDeviceClipBounds(SkIRect* bounds) const = 0; virtual void drawColor(SkColor color, SkBlendMode mode) = 0; void drawColor(SkColor color) { drawColor(color, SkBlendMode::kSrcOver); } + + // TODO(enne): This is a synonym for drawColor with kSrc. Remove it. virtual void clear(SkColor color) = 0; virtual void drawLine(SkScalar x0,
diff --git a/cc/paint/paint_flags.cc b/cc/paint/paint_flags.cc new file mode 100644 index 0000000..e16a8bb --- /dev/null +++ b/cc/paint/paint_flags.cc
@@ -0,0 +1,42 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/paint_flags.h" + +namespace cc { + +bool PaintFlags::IsSimpleOpacity() const { + uint32_t color = getColor(); + if (SK_ColorTRANSPARENT != SkColorSetA(color, SK_AlphaTRANSPARENT)) + return false; + if (!isSrcOver()) + return false; + if (getLooper()) + return false; + if (getPathEffect()) + return false; + if (getShader()) + return false; + if (getMaskFilter()) + return false; + if (getColorFilter()) + return false; + if (getImageFilter()) + return false; + return true; +} + +bool PaintFlags::SupportsFoldingAlpha() const { + if (!isSrcOver()) + return false; + if (getColorFilter()) + return false; + if (getImageFilter()) + return false; + if (getLooper()) + return false; + return true; +} + +} // namespace cc
diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h index b7e96c6..37b460d6 100644 --- a/cc/paint/paint_flags.h +++ b/cc/paint/paint_flags.h
@@ -7,7 +7,6 @@ #include "base/compiler_specific.h" #include "cc/paint/paint_export.h" -#include "cc/paint/paint_shader.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkDrawLooper.h" @@ -19,6 +18,8 @@ namespace cc { +using PaintShader = SkShader; + class CC_PAINT_EXPORT PaintFlags { public: enum Style { @@ -198,6 +199,14 @@ return paint_.computeFastBounds(orig, storage); } + bool operator==(const PaintFlags& flags) { return flags.paint_ == paint_; } + bool operator!=(const PaintFlags& flags) { return flags.paint_ != paint_; } + + // Returns true if this just represents an opacity blend when + // used as saveLayer flags. + bool IsSimpleOpacity() const; + bool SupportsFoldingAlpha() const; + private: friend const SkPaint& ToSkPaint(const PaintFlags& flags); friend const SkPaint* ToSkPaint(const PaintFlags* flags);
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index 70644ed..d34d05d 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -12,6 +12,9 @@ : sk_image_(std::move(sk_image)), animation_type_(animation_type), completion_state_(completion_state) {} + +PaintImage::PaintImage(const PaintImage& image) = default; + PaintImage::~PaintImage() = default; } // namespace cc
diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h index 0ed1edd..c772316 100644 --- a/cc/paint/paint_image.h +++ b/cc/paint/paint_image.h
@@ -23,6 +23,7 @@ PaintImage(sk_sp<const SkImage> sk_image, AnimationType animation_type, CompletionState completion_state); + PaintImage(const PaintImage& image); ~PaintImage(); const sk_sp<const SkImage>& sk_image() const { return sk_image_; }
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc new file mode 100644 index 0000000..a98392a --- /dev/null +++ b/cc/paint/paint_op_buffer.cc
@@ -0,0 +1,556 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/paint_op_buffer.h" + +#include "cc/paint/display_item_list.h" +#include "cc/paint/paint_record.h" +#include "third_party/skia/include/core/SkAnnotation.h" + +namespace cc { + +#define TYPES(M) \ + M(AnnotateOp) \ + M(ClipPathOp) \ + M(ClipRectOp) \ + M(ClipRRectOp) \ + M(ConcatOp) \ + M(DrawArcOp) \ + M(DrawCircleOp) \ + M(DrawColorOp) \ + M(DrawDisplayItemListOp) \ + M(DrawDRRectOp) \ + M(DrawImageOp) \ + M(DrawImageRectOp) \ + M(DrawIRectOp) \ + M(DrawLineOp) \ + M(DrawOvalOp) \ + M(DrawPathOp) \ + M(DrawPosTextOp) \ + M(DrawRecordOp) \ + M(DrawRectOp) \ + M(DrawRRectOp) \ + M(DrawTextOp) \ + M(DrawTextBlobOp) \ + M(NoopOp) \ + M(RestoreOp) \ + M(RotateOp) \ + M(SaveOp) \ + M(SaveLayerOp) \ + M(SaveLayerAlphaOp) \ + M(ScaleOp) \ + M(SetMatrixOp) \ + M(TranslateOp) + +// Helper template to share common code for RasterWithAlpha when paint ops +// have or don't have PaintFlags. +template <typename T, bool HasFlags> +struct Rasterizer { + static void Raster(const T* op, + SkCanvas* canvas, + const SkMatrix& original_ctm) { + // Paint ops with kHasPaintFlags need to declare RasterWithPaintFlags + // otherwise, the paint op needs its own Raster function. Without its + // own, this becomes an infinite loop as PaintOp::Raster calls itself. + static_assert( + !std::is_same<decltype(&PaintOp::Raster), decltype(&T::Raster)>::value, + "No Raster function"); + + op->Raster(canvas); + } + static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { + DCHECK(T::kIsDrawOp); + // TODO(enne): is it ok to just drop the bounds here? + canvas->saveLayerAlpha(nullptr, alpha); + op->Raster(canvas); + canvas->restore(); + } +}; + +template <typename T> +struct Rasterizer<T, true> { + static void Raster(const T* op, + SkCanvas* canvas, + const SkMatrix& original_ctm) { + op->RasterWithFlags(canvas, op->flags); + } + static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { + DCHECK(T::kIsDrawOp); + SkMatrix unused_matrix; + if (alpha == 255) { + Raster(op, canvas, unused_matrix); + } else if (op->flags.SupportsFoldingAlpha()) { + PaintFlags flags = op->flags; + flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha)); + op->RasterWithFlags(canvas, flags); + } else { + canvas->saveLayerAlpha(nullptr, alpha); + op->RasterWithFlags(canvas, op->flags); + canvas->restore(); + } + } +}; + +template <> +struct Rasterizer<SetMatrixOp, false> { + static void Raster(const SetMatrixOp* op, + SkCanvas* canvas, + const SkMatrix& original_ctm) { + op->Raster(canvas, original_ctm); + } + static void RasterWithAlpha(const SetMatrixOp* op, + SkCanvas* canvas, + uint8_t alpha) { + NOTREACHED(); + } +}; + +template <> +struct Rasterizer<DrawRecordOp, false> { + static void Raster(const DrawRecordOp* op, + SkCanvas* canvas, + const SkMatrix& original_ctm) { + op->Raster(canvas); + } + static void RasterWithAlpha(const DrawRecordOp* op, + SkCanvas* canvas, + uint8_t alpha) { + // This "looking into records" optimization is done here instead of + // in the PaintOpBuffer::Raster function as DisplayItemList calls + // into RasterWithAlpha directly. + if (op->record->approximateOpCount() == 1) { + op->record->GetFirstOp()->RasterWithAlpha(canvas, alpha); + return; + } + + canvas->saveLayerAlpha(nullptr, alpha); + op->Raster(canvas); + canvas->restore(); + } +}; + +// TODO(enne): partially specialize RasterWithAlpha for draw color? + +static constexpr size_t kNumOpTypes = + static_cast<size_t>(PaintOpType::LastPaintOpType) + 1; + +// Verify that every op is in the TYPES macro. +#define M(T) +1 +static_assert(kNumOpTypes == TYPES(M), "Missing op in list"); +#undef M + +using RasterFunction = void (*)(const PaintOp* op, + SkCanvas* canvas, + const SkMatrix& original_ctm); +#define M(T) \ + [](const PaintOp* op, SkCanvas* canvas, const SkMatrix& original_ctm) { \ + Rasterizer<T, T::kHasPaintFlags>::Raster(static_cast<const T*>(op), \ + canvas, original_ctm); \ + }, +static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; +#undef M + +using RasterAlphaFunction = void (*)(const PaintOp* op, + SkCanvas* canvas, + uint8_t alpha); +#define M(T) \ + T::kIsDrawOp ? \ + [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \ + Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ + static_cast<const T*>(op), canvas, alpha); \ + } : static_cast<RasterAlphaFunction>(nullptr), +static const RasterAlphaFunction g_raster_alpha_functions[kNumOpTypes] = { + TYPES(M)}; +#undef M + +// Most state ops (matrix, clip, save, restore) have a trivial destructor. +// TODO(enne): evaluate if we need the nullptr optimization or if +// we even need to differentiate trivial destructors here. +using VoidFunction = void (*)(PaintOp* op); +#define M(T) \ + !std::is_trivially_destructible<T>::value \ + ? [](PaintOp* op) { static_cast<T*>(op)->~T(); } \ + : static_cast<VoidFunction>(nullptr), +static const VoidFunction g_destructor_functions[kNumOpTypes] = {TYPES(M)}; +#undef M + +#define M(T) T::kIsDrawOp, +static bool g_is_draw_op[kNumOpTypes] = {TYPES(M)}; +#undef M + +#define M(T) \ + static_assert(sizeof(T) <= sizeof(LargestPaintOp), \ + #T " must be no bigger than LargestPaintOp"); +TYPES(M); +#undef M + +#undef TYPES + +SkRect PaintOp::kUnsetRect = {SK_ScalarInfinity, 0, 0, 0}; + +void AnnotateOp::Raster(SkCanvas* canvas) const { + switch (annotation_type) { + case PaintCanvas::AnnotationType::URL: + SkAnnotateRectWithURL(canvas, rect, data.get()); + break; + case PaintCanvas::AnnotationType::LINK_TO_DESTINATION: + SkAnnotateLinkToDestination(canvas, rect, data.get()); + break; + case PaintCanvas::AnnotationType::NAMED_DESTINATION: { + SkPoint point = SkPoint::Make(rect.x(), rect.y()); + SkAnnotateNamedDestination(canvas, point, data.get()); + break; + } + } +} + +void ClipPathOp::Raster(SkCanvas* canvas) const { + canvas->clipPath(path, op, antialias); +} + +void ClipRectOp::Raster(SkCanvas* canvas) const { + canvas->clipRect(rect, op, antialias); +} + +void ClipRRectOp::Raster(SkCanvas* canvas) const { + canvas->clipRRect(rrect, op, antialias); +} + +void ConcatOp::Raster(SkCanvas* canvas) const { + canvas->concat(matrix); +} + +void DrawArcOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawArc(oval, start_angle, sweep_angle, use_center, ToSkPaint(flags)); +} + +void DrawCircleOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawCircle(cx, cy, radius, ToSkPaint(flags)); +} + +void DrawColorOp::Raster(SkCanvas* canvas) const { + canvas->drawColor(color, mode); +} + +void DrawDisplayItemListOp::Raster(SkCanvas* canvas) const { + list->Raster(canvas, nullptr); +} + +void DrawDRRectOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawDRRect(outer, inner, ToSkPaint(flags)); +} + +void DrawImageOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawImage(image.sk_image().get(), left, top, ToSkPaint(&flags)); +} + +void DrawImageRectOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + // TODO(enne): Probably PaintCanvas should just use the skia enum directly. + SkCanvas::SrcRectConstraint skconstraint = + static_cast<SkCanvas::SrcRectConstraint>(constraint); + canvas->drawImageRect(image.sk_image().get(), src, dst, ToSkPaint(&flags), + skconstraint); +} + +void DrawIRectOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawIRect(rect, ToSkPaint(flags)); +} + +void DrawLineOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawLine(x0, y0, x1, y1, ToSkPaint(flags)); +} + +void DrawOvalOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawOval(oval, ToSkPaint(flags)); +} + +void DrawPathOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawPath(path, ToSkPaint(flags)); +} + +void DrawPosTextOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawPosText(paint_op_data(this), bytes, paint_op_array<SkPoint>(this), + ToSkPaint(flags)); +} + +void DrawRecordOp::Raster(SkCanvas* canvas) const { + record->playback(canvas); +} + +void DrawRectOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawRect(rect, ToSkPaint(flags)); +} + +void DrawRRectOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawRRect(rrect, ToSkPaint(flags)); +} + +void DrawTextOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawText(paint_op_data(this), bytes, x, y, ToSkPaint(flags)); +} + +void DrawTextBlobOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + canvas->drawTextBlob(blob.get(), x, y, ToSkPaint(flags)); +} + +void RestoreOp::Raster(SkCanvas* canvas) const { + canvas->restore(); +} + +void RotateOp::Raster(SkCanvas* canvas) const { + canvas->rotate(degrees); +} + +void SaveOp::Raster(SkCanvas* canvas) const { + canvas->save(); +} + +void SaveLayerOp::RasterWithFlags(SkCanvas* canvas, + const PaintFlags& flags) const { + // See PaintOp::kUnsetRect + bool unset = bounds.left() == SK_ScalarInfinity; + + canvas->saveLayer(unset ? nullptr : &bounds, ToSkPaint(&flags)); +} + +void SaveLayerAlphaOp::Raster(SkCanvas* canvas) const { + // See PaintOp::kUnsetRect + bool unset = bounds.left() == SK_ScalarInfinity; + canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); +} + +void ScaleOp::Raster(SkCanvas* canvas) const { + canvas->scale(sx, sy); +} + +void SetMatrixOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { + canvas->setMatrix(SkMatrix::Concat(original_ctm, matrix)); +} + +void TranslateOp::Raster(SkCanvas* canvas) const { + canvas->translate(dx, dy); +} + +bool PaintOp::IsDrawOp() const { + return g_is_draw_op[type]; +} + +void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { + g_raster_functions[type](this, canvas, original_ctm); +} + +void PaintOp::RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const { + g_raster_alpha_functions[type](this, canvas, alpha); +} + +DrawDisplayItemListOp::DrawDisplayItemListOp( + scoped_refptr<DisplayItemList> list) + : list(list) {} + +size_t DrawDisplayItemListOp::AdditionalBytesUsed() const { + return list->ApproximateMemoryUsage(); +} + +int ClipPathOp::CountSlowPaths() const { + return antialias && !path.isConvex() ? 1 : 0; +} + +int DrawLineOp::CountSlowPaths() const { + if (const SkPathEffect* effect = flags.getPathEffect()) { + SkPathEffect::DashInfo info; + SkPathEffect::DashType dashType = effect->asADash(&info); + if (flags.getStrokeCap() != PaintFlags::kRound_Cap && + dashType == SkPathEffect::kDash_DashType && info.fCount == 2) { + // The PaintFlags will count this as 1, so uncount that here as + // this kind of line is special cased and not slow. + return -1; + } + } + return 0; +} + +int DrawPathOp::CountSlowPaths() const { + // This logic is copied from SkPathCounter instead of attempting to expose + // that from Skia. + if (!flags.isAntiAlias() || path.isConvex()) + return 0; + + PaintFlags::Style paintStyle = flags.getStyle(); + const SkRect& pathBounds = path.getBounds(); + if (paintStyle == PaintFlags::kStroke_Style && flags.getStrokeWidth() == 0) { + // AA hairline concave path is not slow. + return 0; + } else if (paintStyle == PaintFlags::kFill_Style && + pathBounds.width() < 64.f && pathBounds.height() < 64.f && + !path.isVolatile()) { + // AADF eligible concave path is not slow. + return 0; + } else { + return 1; + } +} + +AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type, + const SkRect& rect, + sk_sp<SkData> data) + : annotation_type(annotation_type), rect(rect), data(std::move(data)) {} + +AnnotateOp::~AnnotateOp() = default; + +DrawDisplayItemListOp::~DrawDisplayItemListOp() = default; + +DrawImageOp::DrawImageOp(const PaintImage& image, + SkScalar left, + SkScalar top, + const PaintFlags* flags) + : image(image), + left(left), + top(top), + flags(flags ? *flags : PaintFlags()) {} + +DrawImageOp::~DrawImageOp() = default; + +DrawImageRectOp::DrawImageRectOp(const PaintImage& image, + const SkRect& src, + const SkRect& dst, + const PaintFlags* flags, + PaintCanvas::SrcRectConstraint constraint) + : image(image), + flags(flags ? *flags : PaintFlags()), + src(src), + dst(dst), + constraint(constraint) {} + +DrawImageRectOp::~DrawImageRectOp() = default; + +DrawPosTextOp::DrawPosTextOp(size_t bytes, + size_t count, + const PaintFlags& flags) + : PaintOpWithDataArray(bytes, count), flags(flags) {} + +DrawPosTextOp::~DrawPosTextOp() = default; + +DrawRecordOp::DrawRecordOp(sk_sp<const PaintRecord> record) + : record(std::move(record)) {} + +DrawRecordOp::~DrawRecordOp() = default; + +size_t DrawRecordOp::AdditionalBytesUsed() const { + return record->approximateBytesUsed(); +} + +DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob, + SkScalar x, + SkScalar y, + const PaintFlags& flags) + : blob(std::move(blob)), x(x), y(y), flags(flags) {} + +DrawTextBlobOp::~DrawTextBlobOp() = default; + +PaintOpBuffer::PaintOpBuffer() : cull_rect_(SkRect::MakeEmpty()) {} + +PaintOpBuffer::PaintOpBuffer(const SkRect& cull_rect) : cull_rect_(cull_rect) {} + +PaintOpBuffer::~PaintOpBuffer() { + Reset(); +} + +void PaintOpBuffer::Reset() { + for (auto* op : Iterator(this)) { + auto func = g_destructor_functions[op->type]; + if (func) + func(op); + } + + // Leave data_ allocated, reserved_ unchanged. + used_ = 0; + op_count_ = 0; + num_slow_paths_ = 0; +} + +void PaintOpBuffer::playback(SkCanvas* canvas) const { + // TODO(enne): a PaintRecord that contains a SetMatrix assumes that the + // SetMatrix is local to that PaintRecord itself. Said differently, if you + // translate(x, y), then draw a paint record with a SetMatrix(identity), + // the translation should be preserved instead of clobbering the top level + // transform. This could probably be done more efficiently. + SkMatrix original = canvas->getTotalMatrix(); + + for (Iterator iter(this); iter; ++iter) { + // Optimize out save/restores or save/draw/restore that can be a single + // draw. See also: similar code in SkRecordOpts and cc's DisplayItemList. + // TODO(enne): consider making this recursive? + const PaintOp* op = *iter; + if (op->GetType() == PaintOpType::SaveLayerAlpha) { + const PaintOp* second = iter.peek1(); + if (second) { + if (second->GetType() == PaintOpType::Restore) { + ++iter; + continue; + } + if (second->IsDrawOp()) { + const PaintOp* third = iter.peek2(); + if (third && third->GetType() == PaintOpType::Restore) { + const SaveLayerAlphaOp* save_op = + static_cast<const SaveLayerAlphaOp*>(op); + second->RasterWithAlpha(canvas, save_op->alpha); + ++iter; + ++iter; + continue; + } + } + } + } + // TODO(enne): skip SaveLayer followed by restore with nothing in + // between, however SaveLayer with image filters on it (or maybe + // other PaintFlags options) are not a noop. Figure out what these + // are so we can skip them correctly. + + op->Raster(canvas, original); + } +} + +void PaintOpBuffer::playback(SkCanvas* canvas, + SkPicture::AbortCallback* callback) const { + // The abort callback is only used for analysis, in general, so + // this playback code can be more straightforward and not do the + // optimizations in the other function. + if (!callback) { + playback(canvas); + return; + } + + SkMatrix original = canvas->getTotalMatrix(); + + // TODO(enne): ideally callers would just iterate themselves and we + // can remove the entire notion of an abort callback. + for (auto* op : Iterator(this)) { + op->Raster(canvas, original); + if (callback && callback->abort()) + return; + } +} + +void PaintOpBuffer::ShrinkToFit() { + if (!used_ || used_ == reserved_) + return; + data_.realloc(used_); + reserved_ = used_; +} + +} // namespace cc
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h new file mode 100644 index 0000000..b5f60a4d --- /dev/null +++ b/cc/paint/paint_op_buffer.h
@@ -0,0 +1,782 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_PAINT_PAINT_OP_BUFFER_H_ +#define CC_PAINT_PAINT_OP_BUFFER_H_ + +#include <stdint.h> + +#include "base/logging.h" +#include "cc/paint/paint_canvas.h" +#include "cc/paint/paint_export.h" +#include "cc/paint/paint_flags.h" +#include "third_party/skia/include/core/SkPicture.h" +#include "third_party/skia/include/core/SkRect.h" +#include "third_party/skia/include/core/SkTextBlob.h" + +// PaintOpBuffer is a reimplementation of SkLiteDL. +// See: third_party/skia/src/core/SkLiteDL.h. + +namespace cc { + +class DisplayItemList; + +class ThreadsafeMatrix : public SkMatrix { + public: + explicit ThreadsafeMatrix(const SkMatrix& matrix) : SkMatrix(matrix) { + (void)getType(); + } +}; + +class ThreadsafePath : public SkPath { + public: + explicit ThreadsafePath(const SkPath& path) : SkPath(path) { + updateBoundsCache(); + } +}; + +enum class PaintOpType : uint8_t { + Annotate, + ClipPath, + ClipRect, + ClipRRect, + Concat, + DrawArc, + DrawCircle, + DrawColor, + DrawDisplayItemList, + DrawDRRect, + DrawImage, + DrawImageRect, + DrawIRect, + DrawLine, + DrawOval, + DrawPath, + DrawPosText, + DrawRecord, + DrawRect, + DrawRRect, + DrawText, + DrawTextBlob, + Noop, + Restore, + Rotate, + Save, + SaveLayer, + SaveLayerAlpha, + Scale, + SetMatrix, + Translate, + LastPaintOpType = Translate, +}; + +struct CC_PAINT_EXPORT PaintOp { + uint32_t type : 8; + uint32_t skip : 24; + + PaintOpType GetType() const { return static_cast<PaintOpType>(type); } + + void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const; + bool IsDrawOp() const; + + // Only valid for draw ops. + void RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const; + + int CountSlowPaths() const { return 0; } + + // Returns the number of bytes used by this op in referenced sub records + // and display lists. This doesn't count other objects like paths or blobs. + size_t AdditionalBytesUsed() const { return 0; } + + static constexpr bool kIsDrawOp = false; + // If an op has |kHasPaintFlags| set to true, it must: + // (1) Provide a PaintFlags member called |flags| + // (2) Provide a RasterWithFlags function instead of a Raster function. + static constexpr bool kHasPaintFlags = false; + static SkRect kUnsetRect; +}; + +struct PaintOpWithData : PaintOp { + // Having data is just a helper for ops that have a varying amount of data and + // want a way to store that inline. This is for ops that pass in a + // void* and a length. + explicit PaintOpWithData(size_t bytes) : bytes(bytes) {} + + // Get data out by calling paint_op_data. This can't be part of the class + // because it needs to know the size of the derived type. + size_t bytes; +}; + +template <typename T> +const void* paint_op_data(const T* op) { + static_assert(std::is_convertible<T, PaintOpWithData>::value, + "T is not a PaintOpWithData"); + // Arbitrary data for a PaintOp is stored after the PaintOp itself + // in the PaintOpBuffer. Therefore, to access this data, it's + // pointer math to increment past the size of T. Accessing the + // next op in the buffer is ((char*)op) + op->skip, with the data + // fitting between. + return op + 1; +} + +template <typename T> +void* paint_op_data(T* op) { + static_assert(std::is_convertible<T, PaintOpWithData>::value, + "T is not a PaintOpWithData"); + return op + 1; +} + +struct PaintOpWithDataArrayBase : PaintOpWithData { + // Helper class for static asserts in push functions. + using PaintOpWithData::PaintOpWithData; +}; + +template <typename T> +struct PaintOpWithDataArray : PaintOpWithDataArrayBase { + // Paint op that has a T[count] and a char[bytes]. + PaintOpWithDataArray(size_t bytes, size_t count) + : PaintOpWithDataArrayBase(bytes), count(count) {} + // Use paint_op_array to get array data. + + size_t count; +}; + +template <typename M, typename T> +const M* paint_op_array(const T* op) { + static_assert(std::is_convertible<T, PaintOpWithDataArrayBase>::value, + "T is not a PaintOpWithDataArray"); + // See comment in paint_op_data. Array data is stored after + // any void* data. Memory layout here is: |op|data|array data|next op| + return SkTAddOffset<const M>(op + 1, op->bytes); +} +template <typename M, typename T> +M* paint_op_array(T* op) { + static_assert(std::is_convertible<T, PaintOpWithDataArrayBase>::value, + "T is not a PaintOpWithDataArray"); + return SkTAddOffset<M>(op + 1, op->bytes); +} + +struct AnnotateOp final : PaintOp { + enum class AnnotationType { + URL, + LinkToDestination, + NamedDestination, + }; + + static constexpr PaintOpType kType = PaintOpType::Annotate; + AnnotateOp(PaintCanvas::AnnotationType annotation_type, + const SkRect& rect, + sk_sp<SkData> data); + ~AnnotateOp(); + void Raster(SkCanvas* canvas) const; + + PaintCanvas::AnnotationType annotation_type; + SkRect rect; + sk_sp<SkData> data; +}; + +struct ClipPathOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::ClipPath; + ClipPathOp(SkPath path, SkClipOp op, bool antialias) + : path(path), op(op), antialias(antialias) {} + void Raster(SkCanvas* canvas) const; + int CountSlowPaths() const; + + ThreadsafePath path; + SkClipOp op; + bool antialias; +}; + +struct ClipRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::ClipRect; + ClipRectOp(const SkRect& rect, SkClipOp op, bool antialias) + : rect(rect), op(op), antialias(antialias) {} + void Raster(SkCanvas* canvas) const; + + SkRect rect; + SkClipOp op; + bool antialias; +}; + +struct ClipRRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::ClipRRect; + ClipRRectOp(const SkRRect& rrect, SkClipOp op, bool antialias) + : rrect(rrect), op(op), antialias(antialias) {} + void Raster(SkCanvas* canvas) const; + + SkRRect rrect; + SkClipOp op; + bool antialias; +}; + +struct ConcatOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Concat; + explicit ConcatOp(const SkMatrix& matrix) : matrix(matrix) {} + void Raster(SkCanvas* canvas) const; + + ThreadsafeMatrix matrix; +}; + +struct DrawArcOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawArc; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawArcOp(const SkRect& oval, + SkScalar start_angle, + SkScalar sweep_angle, + bool use_center, + const PaintFlags& flags) + : oval(oval), + start_angle(start_angle), + sweep_angle(sweep_angle), + use_center(use_center), + flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRect oval; + SkScalar start_angle; + SkScalar sweep_angle; + bool use_center; + PaintFlags flags; +}; + +struct DrawCircleOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawCircle; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawCircleOp(SkScalar cx, + SkScalar cy, + SkScalar radius, + const PaintFlags& flags) + : cx(cx), cy(cy), radius(radius), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkScalar cx; + SkScalar cy; + SkScalar radius; + PaintFlags flags; +}; + +struct DrawColorOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawColor; + static constexpr bool kIsDrawOp = true; + DrawColorOp(SkColor color, SkBlendMode mode) : color(color), mode(mode) {} + void Raster(SkCanvas* canvas) const; + + SkColor color; + SkBlendMode mode; +}; + +struct DrawDisplayItemListOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawDisplayItemList; + static constexpr bool kIsDrawOp = true; + explicit DrawDisplayItemListOp(scoped_refptr<DisplayItemList> list); + ~DrawDisplayItemListOp(); + void Raster(SkCanvas* canvas) const; + size_t AdditionalBytesUsed() const; + // TODO(enne): DisplayItemList should know number of slow paths. + + scoped_refptr<DisplayItemList> list; +}; + +struct DrawDRRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawDRRect; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawDRRectOp(const SkRRect& outer, + const SkRRect& inner, + const PaintFlags& flags) + : outer(outer), inner(inner), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRRect outer; + SkRRect inner; + PaintFlags flags; +}; + +struct DrawImageOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawImage; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawImageOp(const PaintImage& image, + SkScalar left, + SkScalar top, + const PaintFlags* flags); + ~DrawImageOp(); + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + PaintImage image; + SkScalar left; + SkScalar top; + PaintFlags flags; +}; + +struct DrawImageRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawImageRect; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawImageRectOp(const PaintImage& image, + const SkRect& src, + const SkRect& dst, + const PaintFlags* flags, + PaintCanvas::SrcRectConstraint constraint); + ~DrawImageRectOp(); + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + PaintImage image; + PaintFlags flags; + SkRect src; + SkRect dst; + PaintCanvas::SrcRectConstraint constraint; +}; + +struct DrawIRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawIRect; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawIRectOp(const SkIRect& rect, const PaintFlags& flags) + : rect(rect), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkIRect rect; + PaintFlags flags; +}; + +struct DrawLineOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawLine; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawLineOp(SkScalar x0, + SkScalar y0, + SkScalar x1, + SkScalar y1, + const PaintFlags& flags) + : x0(x0), y0(y0), x1(x1), y1(y1), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + int CountSlowPaths() const; + + SkScalar x0; + SkScalar y0; + SkScalar x1; + SkScalar y1; + PaintFlags flags; +}; + +struct DrawOvalOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawOval; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawOvalOp(const SkRect& oval, const PaintFlags& flags) + : oval(oval), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRect oval; + PaintFlags flags; +}; + +struct DrawPathOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawPath; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawPathOp(const SkPath& path, const PaintFlags& flags) + : path(path), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + int CountSlowPaths() const; + + ThreadsafePath path; + PaintFlags flags; +}; + +struct DrawPosTextOp final : PaintOpWithDataArray<SkPoint> { + static constexpr PaintOpType kType = PaintOpType::DrawPosText; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawPosTextOp(size_t bytes, size_t count, const PaintFlags& flags); + ~DrawPosTextOp(); + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + PaintFlags flags; +}; + +struct DrawRecordOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawRecord; + static constexpr bool kIsDrawOp = true; + explicit DrawRecordOp(sk_sp<const PaintRecord> record); + ~DrawRecordOp(); + void Raster(SkCanvas* canvas) const; + size_t AdditionalBytesUsed() const; + + sk_sp<const PaintRecord> record; +}; + +struct DrawRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawRect; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawRectOp(const SkRect& rect, const PaintFlags& flags) + : rect(rect), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRect rect; + PaintFlags flags; +}; + +struct DrawRRectOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawRRect; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawRRectOp(const SkRRect& rrect, const PaintFlags& flags) + : rrect(rrect), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRRect rrect; + PaintFlags flags; +}; + +struct DrawTextOp final : PaintOpWithData { + static constexpr PaintOpType kType = PaintOpType::DrawText; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawTextOp(size_t bytes, SkScalar x, SkScalar y, const PaintFlags& flags) + : PaintOpWithData(bytes), x(x), y(y), flags(flags) {} + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkScalar x; + SkScalar y; + PaintFlags flags; +}; + +struct DrawTextBlobOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawTextBlob; + static constexpr bool kIsDrawOp = true; + static constexpr bool kHasPaintFlags = true; + DrawTextBlobOp(sk_sp<SkTextBlob> blob, + SkScalar x, + SkScalar y, + const PaintFlags& flags); + ~DrawTextBlobOp(); + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + sk_sp<SkTextBlob> blob; + SkScalar x; + SkScalar y; + PaintFlags flags; +}; + +struct NoopOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Noop; + void Raster(SkCanvas* canvas) const {} +}; + +struct RestoreOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Restore; + void Raster(SkCanvas* canvas) const; +}; + +struct RotateOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Rotate; + explicit RotateOp(SkScalar degrees) : degrees(degrees) {} + void Raster(SkCanvas* canvas) const; + + SkScalar degrees; +}; + +struct SaveOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Save; + void Raster(SkCanvas* canvas) const; +}; + +struct SaveLayerOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::SaveLayer; + static constexpr bool kHasPaintFlags = true; + SaveLayerOp(const SkRect* bounds, const PaintFlags* flags) + : bounds(bounds ? *bounds : kUnsetRect) { + if (flags) + this->flags = *flags; + } + void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; + + SkRect bounds; + PaintFlags flags; +}; + +struct SaveLayerAlphaOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::SaveLayerAlpha; + SaveLayerAlphaOp(const SkRect* bounds, uint8_t alpha) + : bounds(bounds ? *bounds : kUnsetRect), alpha(alpha) {} + void Raster(SkCanvas* canvas) const; + + SkRect bounds; + uint8_t alpha; +}; + +struct ScaleOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Scale; + ScaleOp(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {} + void Raster(SkCanvas* canvas) const; + + SkScalar sx; + SkScalar sy; +}; + +struct SetMatrixOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::SetMatrix; + explicit SetMatrixOp(const SkMatrix& matrix) : matrix(matrix) {} + // This is the only op that needs the original ctm of the SkCanvas + // used for raster (since SetMatrix is relative to the recording origin and + // shouldn't clobber the SkCanvas raster origin). + // + // TODO(enne): Find some cleaner way to do this, possibly by making + // all SetMatrix calls Concat?? + void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const; + + ThreadsafeMatrix matrix; +}; + +struct TranslateOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Translate; + TranslateOp(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {} + void Raster(SkCanvas* canvas) const; + + SkScalar dx; + SkScalar dy; +}; + +using LargestPaintOp = DrawDRRectOp; + +class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { + public: + enum { kInitialBufferSize = 4096 }; + + PaintOpBuffer(); + explicit PaintOpBuffer(const SkRect& cull_rect); + ~PaintOpBuffer() override; + + void Reset(); + + void playback(SkCanvas* canvas) const; + void playback(SkCanvas* canvas, SkPicture::AbortCallback* callback) const; + + // TODO(enne): These are no longer approximate. Rename these. + int approximateOpCount() const { return op_count_; } + size_t approximateBytesUsed() const { + return sizeof(*this) + reserved_ + subrecord_bytes_used_; + } + int numSlowPaths() const { return num_slow_paths_; } + + // Resize the PaintOpBuffer to exactly fit the current amount of used space. + void ShrinkToFit(); + + const SkRect& cullRect() const { return cull_rect_; } + + PaintOp* GetFirstOp() const { + return reinterpret_cast<PaintOp*>(const_cast<char*>(&first_op_[0])); + } + + template <typename T, typename... Args> + void push(Args&&... args) { + static_assert(std::is_convertible<T, PaintOp>::value, "T not a PaintOp."); + static_assert(!std::is_convertible<T, PaintOpWithData>::value, + "Type needs to use push_with_data"); + push_internal<T>(0, std::forward<Args>(args)...); + } + + template <typename T, typename... Args> + void push_with_data(const void* data, size_t bytes, Args&&... args) { + static_assert(std::is_convertible<T, PaintOpWithData>::value, + "T is not a PaintOpWithData"); +#if !defined(OS_CHROMEOS) + // TODO(enne): non-linux chromeos builds think that DrawTextOp + // can be converted to a PaintOpWithDataArrayBase. OOPS. + static_assert(!std::is_convertible<T, PaintOpWithDataArrayBase>::value, + "Type needs to use push_with_data_array"); +#endif + DCHECK_GE(bytes, 0u); + T* op = push_internal<T>(bytes, bytes, std::forward<Args>(args)...); + memcpy(paint_op_data(op), data, bytes); + +#if DCHECK_IS_ON() + // Double check the data fits between op and next op and doesn't clobber. + char* op_start = reinterpret_cast<char*>(op); + char* op_end = op_start + sizeof(T); + char* next_op = op_start + op->skip; + char* data_start = reinterpret_cast<char*>(paint_op_data(op)); + char* data_end = data_start + bytes; + DCHECK_GE(data_start, op_end); + DCHECK_LT(data_start, next_op); + DCHECK_LE(data_end, next_op); +#endif + } + + template <typename T, typename M, typename... Args> + void push_with_data_array(const void* data, + size_t bytes, + const M* array, + size_t count, + Args&&... args) { + static_assert(std::is_convertible<T, PaintOpWithDataArray<M>>::value, + "T is not a PaintOpWithDataArray"); + DCHECK_GE(bytes, 0u); + DCHECK_GE(count, 0u); + size_t array_size = sizeof(M) * count; + size_t total_size = bytes + array_size; + T* op = + push_internal<T>(total_size, bytes, count, std::forward<Args>(args)...); + memcpy(paint_op_data(op), data, bytes); + memcpy(paint_op_array<M>(op), array, array_size); + +#if DCHECK_IS_ON() + // Double check data and array don't clobber op, next op, or each other + char* op_start = reinterpret_cast<char*>(op); + char* op_end = op_start + sizeof(T); + char* next_op = op_start + op->skip; + char* data_start = reinterpret_cast<char*>(paint_op_data(op)); + char* data_end = data_start + bytes; + char* array_start = reinterpret_cast<char*>(paint_op_array<M>(op)); + char* array_end = array_start + array_size; + DCHECK_GE(data_start, op_end); + DCHECK_LE(data_start, array_start); + DCHECK_GE(array_start, data_end); + DCHECK_LE(array_end, next_op); +#endif + } + + class Iterator { + public: + explicit Iterator(const PaintOpBuffer* buffer) + : buffer_(buffer), ptr_(buffer_->data_.get()) {} + + PaintOp* operator->() const { + return op_idx_ ? reinterpret_cast<PaintOp*>(ptr_) : buffer_->GetFirstOp(); + } + PaintOp* operator*() const { return operator->(); } + Iterator begin() { return Iterator(buffer_, buffer_->data_.get(), 0); } + Iterator end() { + return Iterator(buffer_, buffer_->data_.get() + buffer_->used_, + buffer_->approximateOpCount()); + } + bool operator!=(const Iterator& other) { + // Not valid to compare iterators on different buffers. + DCHECK_EQ(other.buffer_, buffer_); + return other.op_idx_ != op_idx_; + } + Iterator& operator++() { + if (!op_idx_++) + return *this; + PaintOp* op = **this; + uint32_t type = op->type; + CHECK_LE(type, static_cast<uint32_t>(PaintOpType::LastPaintOpType)); + ptr_ += op->skip; + return *this; + } + operator bool() const { return op_idx_ < buffer_->approximateOpCount(); } + + int op_idx() const { return op_idx_; } + + // Return the next op without advancing the iterator, or nullptr if none. + PaintOp* peek1() const { + if (op_idx_ + 1 >= buffer_->approximateOpCount()) + return nullptr; + if (!op_idx_) + return reinterpret_cast<PaintOp*>(ptr_); + return reinterpret_cast<PaintOp*>(ptr_ + (*this)->skip); + } + + // Return the op two ops ahead without advancing the iterator, or nullptr if + // none. + PaintOp* peek2() const { + if (op_idx_ + 2 >= buffer_->approximateOpCount()) + return nullptr; + char* next = ptr_ + reinterpret_cast<PaintOp*>(ptr_)->skip; + PaintOp* next_op = reinterpret_cast<PaintOp*>(next); + if (!op_idx_) + return next_op; + return reinterpret_cast<PaintOp*>(next + next_op->skip); + } + + private: + Iterator(const PaintOpBuffer* buffer, char* ptr, int op_idx) + : buffer_(buffer), ptr_(ptr), op_idx_(op_idx) {} + + const PaintOpBuffer* buffer_ = nullptr; + char* ptr_ = nullptr; + int op_idx_ = 0; + }; + + private: + template <typename T, bool HasFlags> + struct CountSlowPathsFromFlags { + static int Count(const T* op) { return 0; } + }; + + template <typename T> + struct CountSlowPathsFromFlags<T, true> { + static int Count(const T* op) { return op->flags.getPathEffect() ? 1 : 0; } + }; + + template <typename T, typename... Args> + T* push_internal(size_t bytes, Args&&... args) { + size_t skip = SkAlignPtr(sizeof(T) + bytes); + DCHECK_LT(skip, static_cast<size_t>(1) << 24); + if (used_ + skip > reserved_ || !op_count_) { + if (!op_count_) { + if (bytes) { + // Internal first_op buffer doesn't have room for extra data. + // If the op wants extra bytes, then we'll just store a Noop + // in the first_op and proceed from there. This seems unlikely + // to be a common case. + push<NoopOp>(); + } else { + T* op = reinterpret_cast<T*>(&first_op_[0]); + new (op) T{std::forward<Args>(args)...}; + op->type = static_cast<uint32_t>(T::kType); + op->skip = 0; + op_count_++; + return op; + } + } + + // Start reserved_ at kInitialBufferSize and then double. + // ShrinkToFit can make this smaller afterwards. + while (used_ + skip > reserved_) + reserved_ = reserved_ ? reserved_ * 2 : kInitialBufferSize; + data_.realloc(reserved_); + } + DCHECK_LE(used_ + skip, reserved_); + + T* op = reinterpret_cast<T*>(data_.get() + used_); + used_ += skip; + new (op) T(std::forward<Args>(args)...); + op->type = static_cast<uint32_t>(T::kType); + op->skip = skip; + op_count_++; + + num_slow_paths_ += CountSlowPathsFromFlags<T, T::kHasPaintFlags>::Count(op); + num_slow_paths_ += op->CountSlowPaths(); + + subrecord_bytes_used_ += op->AdditionalBytesUsed(); + + return op; + } + + // As a performance optimization because n=1 is an extremely common case just + // store the first op in the PaintOpBuffer itself to avoid an extra alloc. + char first_op_[sizeof(LargestPaintOp)]; + SkAutoTMalloc<char> data_; + size_t used_ = 0; + size_t reserved_ = 0; + int op_count_ = 0; + + // Record paths for veto-to-msaa for gpu raster. + int num_slow_paths_ = 0; + // Record additional bytes used by referenced sub-records and display lists. + size_t subrecord_bytes_used_ = 0; + SkRect cull_rect_; + + DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer); +}; + +} // namespace cc + +#endif // CC_PAINT_PAINT_OP_BUFFER_H_
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc new file mode 100644 index 0000000..5e0bf2aa --- /dev/null +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -0,0 +1,259 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/paint_op_buffer.h" +#include "cc/test/test_skcanvas.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +template <typename T> +void CheckRefCnt(const T& obj, int32_t count) { +// Skia doesn't define getRefCnt in all builds. +#ifdef SK_DEBUG + EXPECT_EQ(obj->getRefCnt(), count); +#endif +} + +} // namespace + +namespace cc { + +TEST(PaintOpBufferTest, Empty) { + PaintOpBuffer buffer; + EXPECT_EQ(buffer.approximateOpCount(), 0); + EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer)); + EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false); + + buffer.Reset(); + EXPECT_EQ(buffer.approximateOpCount(), 0); + EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer)); + EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false); +} + +TEST(PaintOpBufferTest, SimpleAppend) { + SkRect rect = SkRect::MakeXYWH(2, 3, 4, 5); + PaintFlags flags; + flags.setColor(SK_ColorMAGENTA); + flags.setAlpha(100); + SkColor draw_color = SK_ColorRED; + SkBlendMode blend = SkBlendMode::kSrc; + + PaintOpBuffer buffer; + buffer.push<SaveLayerOp>(&rect, &flags); + buffer.push<SaveOp>(); + buffer.push<DrawColorOp>(draw_color, blend); + buffer.push<RestoreOp>(); + + EXPECT_EQ(buffer.approximateOpCount(), 4); + + PaintOpBuffer::Iterator iter(&buffer); + ASSERT_EQ(iter->GetType(), PaintOpType::SaveLayer); + SaveLayerOp* save_op = static_cast<SaveLayerOp*>(*iter); + EXPECT_EQ(save_op->bounds, rect); + EXPECT_TRUE(save_op->flags == flags); + ++iter; + + ASSERT_EQ(iter->GetType(), PaintOpType::Save); + ++iter; + + ASSERT_EQ(iter->GetType(), PaintOpType::DrawColor); + DrawColorOp* op = static_cast<DrawColorOp*>(*iter); + EXPECT_EQ(op->color, draw_color); + EXPECT_EQ(op->mode, blend); + ++iter; + + ASSERT_EQ(iter->GetType(), PaintOpType::Restore); + ++iter; + + EXPECT_FALSE(iter); +} + +// PaintOpBuffer has a special case for first ops stored locally, so +// make sure that appending different kind of ops as a first op works +// properly, as well as resetting and reusing the first local op. +TEST(PaintOpBufferTest, FirstOpWithAndWithoutData) { + PaintOpBuffer buffer; + char text[] = "asdf"; + + // Use a color filter and its ref count to verify that the destructor + // is called on ops after reset. + PaintFlags flags; + sk_sp<SkColorFilter> filter = + SkColorFilter::MakeModeFilter(SK_ColorMAGENTA, SkBlendMode::kSrcOver); + flags.setColorFilter(filter); + CheckRefCnt(filter, 2); + + buffer.push_with_data<DrawTextOp>(text, arraysize(text), 0.f, 0.f, flags); + CheckRefCnt(filter, 3); + + // Verify that when the first op has data, which may not fit in the + // PaintRecord internal buffer, that it adds a noop as the first op + // and then appends the "op with data" into the heap buffer. + ASSERT_EQ(buffer.approximateOpCount(), 2); + EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::Noop); + + // Verify iteration behavior and brief smoke test of op state. + { + PaintOpBuffer::Iterator iter(&buffer); + PaintOp* noop = *iter; + EXPECT_EQ(buffer.GetFirstOp(), noop); + ++iter; + + PaintOp* op = *iter; + ASSERT_EQ(op->GetType(), PaintOpType::DrawText); + DrawTextOp* draw_text_op = static_cast<DrawTextOp*>(op); + EXPECT_EQ(draw_text_op->bytes, arraysize(text)); + + void* data = paint_op_data(draw_text_op); + EXPECT_EQ(memcmp(data, text, arraysize(text)), 0); + + ++iter; + EXPECT_FALSE(iter); + } + + // Reset, verify state, and append an op that will fit in the first slot. + buffer.Reset(); + CheckRefCnt(filter, 2); + + ASSERT_EQ(buffer.approximateOpCount(), 0); + EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false); + + SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); + buffer.push<DrawRectOp>(rect, flags); + CheckRefCnt(filter, 3); + + ASSERT_EQ(buffer.approximateOpCount(), 1); + EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::DrawRect); + + PaintOpBuffer::Iterator iter(&buffer); + ASSERT_EQ(iter->GetType(), PaintOpType::DrawRect); + DrawRectOp* draw_rect_op = static_cast<DrawRectOp*>(*iter); + EXPECT_EQ(draw_rect_op->rect, rect); + + ++iter; + EXPECT_FALSE(iter); + + buffer.Reset(); + ASSERT_EQ(buffer.approximateOpCount(), 0); + CheckRefCnt(filter, 2); +} + +TEST(PaintOpBufferTest, Peek) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + PaintFlags draw_flags; + buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 2, 3, 4), draw_flags); + buffer.push<RestoreOp>(); + buffer.push<SaveOp>(); + buffer.push<NoopOp>(); + buffer.push<RestoreOp>(); + + PaintOpBuffer::Iterator init_iter(&buffer); + PaintOp* peek[2] = {*init_iter, init_iter.peek1()}; + + // Expect that while iterating that next = current.peek1() and that + // next.peek1() == current.peek2(). + for (PaintOpBuffer::Iterator iter(&buffer); iter; ++iter) { + EXPECT_EQ(*iter, peek[0]) << iter.op_idx(); + EXPECT_EQ(iter.peek1(), peek[1]) << iter.op_idx(); + + peek[0] = iter.peek1(); + peek[1] = iter.peek2(); + } +} + +TEST(PaintOpBufferTest, PeekEmpty) { + PaintOpBuffer empty; + PaintOpBuffer::Iterator empty_iter(&empty); + EXPECT_EQ(nullptr, empty_iter.peek1()); + EXPECT_EQ(nullptr, empty_iter.peek2()); +} + +// Verify that a SaveLayerAlpha / Draw / Restore can be optimized to just +// a draw with opacity. +TEST(PaintOpBufferTest, SaveDrawRestore) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + + PaintFlags draw_flags; + draw_flags.setColor(SK_ColorMAGENTA); + draw_flags.setAlpha(50); + EXPECT_TRUE(draw_flags.SupportsFoldingAlpha()); + SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); + buffer.push<DrawRectOp>(rect, draw_flags); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.playback(&canvas); + + EXPECT_EQ(0, canvas.save_count_); + EXPECT_EQ(0, canvas.restore_count_); + EXPECT_EQ(rect, canvas.draw_rect_); + + // Expect the alpha from the draw and the save layer to be folded together. + // Since alpha is stored in a uint8_t and gets rounded, so use tolerance. + float expected_alpha = alpha * 50 / 255.f; + EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f); +} + +// The same as SaveDrawRestore, but test that the optimization doesn't apply +// when the drawing op's flags are not compatible with being folded into the +// save layer with opacity. +TEST(PaintOpBufferTest, SaveDrawRestoreFail_BadFlags) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + + PaintFlags draw_flags; + draw_flags.setColor(SK_ColorMAGENTA); + draw_flags.setAlpha(50); + draw_flags.setBlendMode(SkBlendMode::kSrc); + EXPECT_FALSE(draw_flags.SupportsFoldingAlpha()); + SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); + buffer.push<DrawRectOp>(rect, draw_flags); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.playback(&canvas); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); + EXPECT_EQ(rect, canvas.draw_rect_); + EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha()); +} + +// The same as SaveDrawRestore, but test that the optimization doesn't apply +// when there are more than one ops between the save and restore. +TEST(PaintOpBufferTest, SaveDrawRestoreFail_TooManyOps) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + + PaintFlags draw_flags; + draw_flags.setColor(SK_ColorMAGENTA); + draw_flags.setAlpha(50); + draw_flags.setBlendMode(SkBlendMode::kSrcOver); + EXPECT_TRUE(draw_flags.SupportsFoldingAlpha()); + SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); + buffer.push<DrawRectOp>(rect, draw_flags); + buffer.push<NoopOp>(); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.playback(&canvas); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); + EXPECT_EQ(rect, canvas.draw_rect_); + EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha()); +} + +} // namespace cc
diff --git a/cc/paint/paint_record.cc b/cc/paint/paint_record.cc new file mode 100644 index 0000000..52cb2524 --- /dev/null +++ b/cc/paint/paint_record.cc
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/paint_record.h" + +#include "cc/paint/paint_op_buffer.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" + +namespace cc { + +sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record) { + SkPictureRecorder recorder; + SkCanvas* canvas = recorder.beginRecording(record->cullRect()); + record->playback(canvas); + return recorder.finishRecordingAsPicture(); +} + +sk_sp<const SkPicture> ToSkPicture(sk_sp<const PaintRecord> record) { + SkPictureRecorder recorder; + SkCanvas* canvas = recorder.beginRecording(record->cullRect()); + record->playback(canvas); + return recorder.finishRecordingAsPicture(); +} + +} // namespace cc
diff --git a/cc/paint/paint_record.h b/cc/paint/paint_record.h index 8506606b..daeee004 100644 --- a/cc/paint/paint_record.h +++ b/cc/paint/paint_record.h
@@ -5,19 +5,22 @@ #ifndef CC_PAINT_PAINT_RECORD_H_ #define CC_PAINT_PAINT_RECORD_H_ +#include "cc/paint/paint_export.h" +#include "cc/paint/paint_op_buffer.h" #include "third_party/skia/include/core/SkPicture.h" namespace cc { -using PaintRecord = SkPicture; +// TODO(enne): Don't want to rename the world for this. Using these as the +// same types for now prevents an extra allocation. Probably PaintRecord +// will become an interface in the future. +using PaintRecord = PaintOpBuffer; -inline sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record) { - return record; -} +// TODO(enne): Remove these if possible, they are really expensive. +CC_PAINT_EXPORT sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record); -inline sk_sp<const SkPicture> ToSkPicture(sk_sp<const PaintRecord> record) { - return record; -} +CC_PAINT_EXPORT sk_sp<const SkPicture> ToSkPicture( + sk_sp<const PaintRecord> record); } // namespace cc
diff --git a/cc/paint/paint_recorder.cc b/cc/paint/paint_recorder.cc index 672f0712..c43f965 100644 --- a/cc/paint/paint_recorder.cc +++ b/cc/paint/paint_recorder.cc
@@ -4,9 +4,36 @@ #include "cc/paint/paint_recorder.h" +#include "cc/paint/paint_op_buffer.h" + namespace cc { PaintRecorder::PaintRecorder() = default; + PaintRecorder::~PaintRecorder() = default; +PaintCanvas* PaintRecorder::beginRecording(const SkRect& bounds) { + buffer_.reset(new PaintOpBuffer(bounds)); + canvas_.emplace(buffer_.get(), bounds); + return getRecordingCanvas(); +} + +sk_sp<PaintRecord> PaintRecorder::finishRecordingAsPicture() { + // SkPictureRecorder users expect that their saves are automatically + // closed for them. + // + // NOTE: Blink paint in general doesn't appear to need this, but the + // RecordingImageBufferSurface::fallBackToRasterCanvas finishing off the + // current frame depends on this. Maybe we could remove this assumption and + // just have callers do it. + canvas_->restoreToCount(1); + + // Some users (e.g. printing) use the existence of the recording canvas + // to know if recording is finished, so reset it here. + canvas_.reset(); + + buffer_->ShrinkToFit(); + return std::move(buffer_); +} + } // namespace cc
diff --git a/cc/paint/paint_recorder.h b/cc/paint/paint_recorder.h index 2bbea83b..7f582b85 100644 --- a/cc/paint/paint_recorder.h +++ b/cc/paint/paint_recorder.h
@@ -9,47 +9,36 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/optional.h" -#include "cc/paint/paint_canvas.h" #include "cc/paint/paint_record.h" -#include "cc/paint/skia_paint_canvas.h" -#include "third_party/skia/include/core/SkPictureRecorder.h" +#include "cc/paint/record_paint_canvas.h" namespace cc { +class PaintOpBuffer; + class CC_PAINT_EXPORT PaintRecorder { public: PaintRecorder(); ~PaintRecorder(); - ALWAYS_INLINE PaintCanvas* beginRecording(const SkRect& bounds) { - uint32_t record_flags = 0; - canvas_.emplace(recorder_.beginRecording(bounds, nullptr, record_flags)); - return getRecordingCanvas(); - } + PaintCanvas* beginRecording(const SkRect& bounds); - ALWAYS_INLINE PaintCanvas* beginRecording(SkScalar width, SkScalar height) { - uint32_t record_flags = 0; - canvas_.emplace( - recorder_.beginRecording(width, height, nullptr, record_flags)); - return getRecordingCanvas(); + // TODO(enne): should make everything go through the non-rect version. + // See comments in RecordPaintCanvas ctor for why. + PaintCanvas* beginRecording(SkScalar width, SkScalar height) { + return beginRecording(SkRect::MakeWH(width, height)); } // Only valid between between and finish recording. - ALWAYS_INLINE PaintCanvas* getRecordingCanvas() { + ALWAYS_INLINE RecordPaintCanvas* getRecordingCanvas() { return canvas_.has_value() ? &canvas_.value() : nullptr; } - ALWAYS_INLINE sk_sp<PaintRecord> finishRecordingAsPicture() { - sk_sp<SkPicture> picture = recorder_.finishRecordingAsPicture(); - // Some users (e.g. printing) use the existence of the recording canvas - // to know if recording is finished, so reset it here. - canvas_.reset(); - return sk_ref_sp(static_cast<PaintRecord*>(picture.get())); - } + sk_sp<PaintRecord> finishRecordingAsPicture(); private: - SkPictureRecorder recorder_; - base::Optional<SkiaPaintCanvas> canvas_; + sk_sp<PaintOpBuffer> buffer_; + base::Optional<RecordPaintCanvas> canvas_; DISALLOW_COPY_AND_ASSIGN(PaintRecorder); };
diff --git a/cc/paint/record_paint_canvas.cc b/cc/paint/record_paint_canvas.cc new file mode 100644 index 0000000..7f2ba61 --- /dev/null +++ b/cc/paint/record_paint_canvas.cc
@@ -0,0 +1,384 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/record_paint_canvas.h" + +#include "base/memory/ptr_util.h" +#include "cc/paint/display_item_list.h" +#include "cc/paint/paint_op_buffer.h" +#include "cc/paint/paint_record.h" +#include "cc/paint/paint_recorder.h" +#include "third_party/skia/include/core/SkAnnotation.h" +#include "third_party/skia/include/core/SkMetaData.h" +#include "third_party/skia/include/utils/SkNWayCanvas.h" + +namespace cc { + +RecordPaintCanvas::RecordPaintCanvas(PaintOpBuffer* buffer, + const SkRect& cull_rect) + : buffer_(buffer), + canvas_(static_cast<int>(std::ceil(cull_rect.right())), + static_cast<int>(std::ceil(cull_rect.bottom()))) { + DCHECK(buffer_); + + // This is part of the "recording canvases have a size, but why" dance. + // By creating a canvas of size (right x bottom) and then clipping it, + // It makes getDeviceClipBounds return the original cull rect, which code + // in GraphicsContextCanvas on Mac expects. (Just creating an SkNoDrawCanvas + // with the cull_rect makes a canvas of size (width x height) instead + // which is incorrect. SkRecorder cheats with private resetForNextCanvas. + canvas_.clipRect(SkRect::Make(cull_rect.roundOut()), SkClipOp::kIntersect, + false); +} + +RecordPaintCanvas::~RecordPaintCanvas() = default; + +SkMetaData& RecordPaintCanvas::getMetaData() { + // This could just be SkMetaData owned by RecordPaintCanvas, but since + // SkCanvas already has one, we might as well use it directly. + return canvas_.getMetaData(); +} + +SkImageInfo RecordPaintCanvas::imageInfo() const { + return canvas_.imageInfo(); +} + +void RecordPaintCanvas::flush() { + // This is a noop when recording. +} + +SkISize RecordPaintCanvas::getBaseLayerSize() const { + return canvas_.getBaseLayerSize(); +} + +bool RecordPaintCanvas::writePixels(const SkImageInfo& info, + const void* pixels, + size_t row_bytes, + int x, + int y) { + NOTREACHED(); + return false; +} + +int RecordPaintCanvas::save() { + buffer_->push<SaveOp>(); + return canvas_.save(); +} + +int RecordPaintCanvas::saveLayer(const SkRect* bounds, + const PaintFlags* flags) { + if (flags) { + if (flags->IsSimpleOpacity()) { + // TODO(enne): maybe more callers should know this and call + // saveLayerAlpha instead of needing to check here. + uint8_t alpha = SkColorGetA(flags->getColor()); + return saveLayerAlpha(bounds, alpha); + } + + // TODO(enne): it appears that image filters affect matrices and color + // matrices affect transparent flags on SkCanvas layers, but it's not clear + // whether those are actually needed and we could just skip ToSkPaint here. + buffer_->push<SaveLayerOp>(bounds, flags); + const SkPaint& paint = ToSkPaint(*flags); + return canvas_.saveLayer(bounds, &paint); + } + buffer_->push<SaveLayerOp>(bounds, flags); + return canvas_.saveLayer(bounds, nullptr); +} + +int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) { + buffer_->push<SaveLayerAlphaOp>(bounds, alpha); + return canvas_.saveLayerAlpha(bounds, alpha); +} + +void RecordPaintCanvas::restore() { + buffer_->push<RestoreOp>(); + canvas_.restore(); +} + +int RecordPaintCanvas::getSaveCount() const { + return canvas_.getSaveCount(); +} + +void RecordPaintCanvas::restoreToCount(int save_count) { + DCHECK_GE(save_count, 1); + int diff = canvas_.getSaveCount() - save_count; + DCHECK_GE(diff, 0); + for (int i = 0; i < diff; ++i) + restore(); +} + +void RecordPaintCanvas::translate(SkScalar dx, SkScalar dy) { + buffer_->push<TranslateOp>(dx, dy); + canvas_.translate(dx, dy); +} + +void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) { + buffer_->push<ScaleOp>(sx, sy); + canvas_.scale(sx, sy); +} + +void RecordPaintCanvas::rotate(SkScalar degrees) { + buffer_->push<RotateOp>(degrees); + canvas_.rotate(degrees); +} + +void RecordPaintCanvas::concat(const SkMatrix& matrix) { + buffer_->push<ConcatOp>(matrix); + canvas_.concat(matrix); +} + +void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) { + buffer_->push<SetMatrixOp>(matrix); + canvas_.setMatrix(matrix); +} + +void RecordPaintCanvas::clipRect(const SkRect& rect, + SkClipOp op, + bool antialias) { + buffer_->push<ClipRectOp>(rect, op, antialias); + canvas_.clipRect(rect, op, antialias); +} + +void RecordPaintCanvas::clipRRect(const SkRRect& rrect, + SkClipOp op, + bool antialias) { + // TODO(enne): does this happen? Should the caller know this? + if (rrect.isRect()) { + clipRect(rrect.getBounds(), op, antialias); + return; + } + buffer_->push<ClipRRectOp>(rrect, op, antialias); + canvas_.clipRRect(rrect, op, antialias); +} + +void RecordPaintCanvas::clipPath(const SkPath& path, + SkClipOp op, + bool antialias) { + if (!path.isInverseFillType() && canvas_.getTotalMatrix().rectStaysRect()) { + // TODO(enne): do these cases happen? should the caller know that this isn't + // a path? + SkRect rect; + if (path.isRect(&rect)) { + clipRect(rect, op, antialias); + return; + } + SkRRect rrect; + if (path.isOval(&rect)) { + rrect.setOval(rect); + clipRRect(rrect, op, antialias); + return; + } + if (path.isRRect(&rrect)) { + clipRRect(rrect, op, antialias); + return; + } + } + + buffer_->push<ClipPathOp>(path, op, antialias); + canvas_.clipPath(path, op, antialias); + return; +} + +bool RecordPaintCanvas::quickReject(const SkRect& rect) const { + return canvas_.quickReject(rect); +} + +bool RecordPaintCanvas::quickReject(const SkPath& path) const { + return canvas_.quickReject(path); +} + +SkRect RecordPaintCanvas::getLocalClipBounds() const { + return canvas_.getLocalClipBounds(); +} + +bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const { + return canvas_.getLocalClipBounds(bounds); +} + +SkIRect RecordPaintCanvas::getDeviceClipBounds() const { + return canvas_.getDeviceClipBounds(); +} + +bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const { + return canvas_.getDeviceClipBounds(bounds); +} + +void RecordPaintCanvas::drawColor(SkColor color, SkBlendMode mode) { + buffer_->push<DrawColorOp>(color, mode); +} + +void RecordPaintCanvas::clear(SkColor color) { + buffer_->push<DrawColorOp>(color, SkBlendMode::kSrc); +} + +void RecordPaintCanvas::drawLine(SkScalar x0, + SkScalar y0, + SkScalar x1, + SkScalar y1, + const PaintFlags& flags) { + buffer_->push<DrawLineOp>(x0, y0, x1, y1, flags); +} + +void RecordPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) { + buffer_->push<DrawRectOp>(rect, flags); +} + +void RecordPaintCanvas::drawIRect(const SkIRect& rect, + const PaintFlags& flags) { + buffer_->push<DrawIRectOp>(rect, flags); +} + +void RecordPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) { + buffer_->push<DrawOvalOp>(oval, flags); +} + +void RecordPaintCanvas::drawRRect(const SkRRect& rrect, + const PaintFlags& flags) { + buffer_->push<DrawRRectOp>(rrect, flags); +} + +void RecordPaintCanvas::drawDRRect(const SkRRect& outer, + const SkRRect& inner, + const PaintFlags& flags) { + if (outer.isEmpty()) + return; + if (inner.isEmpty()) { + drawRRect(outer, flags); + return; + } + buffer_->push<DrawDRRectOp>(outer, inner, flags); +} + +void RecordPaintCanvas::drawCircle(SkScalar cx, + SkScalar cy, + SkScalar radius, + const PaintFlags& flags) { + buffer_->push<DrawCircleOp>(cx, cy, radius, flags); +} + +void RecordPaintCanvas::drawArc(const SkRect& oval, + SkScalar start_angle, + SkScalar sweep_angle, + bool use_center, + const PaintFlags& flags) { + buffer_->push<DrawArcOp>(oval, start_angle, sweep_angle, use_center, flags); +} + +void RecordPaintCanvas::drawRoundRect(const SkRect& rect, + SkScalar rx, + SkScalar ry, + const PaintFlags& flags) { + // TODO(enne): move this into base class? + if (rx > 0 && ry > 0) { + SkRRect rrect; + rrect.setRectXY(rect, rx, ry); + drawRRect(rrect, flags); + } else { + drawRect(rect, flags); + } +} + +void RecordPaintCanvas::drawPath(const SkPath& path, const PaintFlags& flags) { + buffer_->push<DrawPathOp>(path, flags); +} + +void RecordPaintCanvas::drawImage(const PaintImage& image, + SkScalar left, + SkScalar top, + const PaintFlags* flags) { + buffer_->push<DrawImageOp>(image, left, top, flags); +} + +void RecordPaintCanvas::drawImageRect(const PaintImage& image, + const SkRect& src, + const SkRect& dst, + const PaintFlags* flags, + SrcRectConstraint constraint) { + buffer_->push<DrawImageRectOp>(image, src, dst, flags, constraint); +} + +void RecordPaintCanvas::drawBitmap(const SkBitmap& bitmap, + SkScalar left, + SkScalar top, + const PaintFlags* flags) { + // TODO(enne): Move into base class? + if (bitmap.drawsNothing()) + return; + drawImage(PaintImage(SkImage::MakeFromBitmap(bitmap), + PaintImage::AnimationType::UNKNOWN, + PaintImage::CompletionState::UNKNOWN), + left, top, flags); +} + +void RecordPaintCanvas::drawText(const void* text, + size_t byte_length, + SkScalar x, + SkScalar y, + const PaintFlags& flags) { + buffer_->push_with_data<DrawTextOp>(text, byte_length, x, y, flags); +} + +void RecordPaintCanvas::drawPosText(const void* text, + size_t byte_length, + const SkPoint pos[], + const PaintFlags& flags) { + size_t count = ToSkPaint(flags).countText(text, byte_length); + buffer_->push_with_data_array<DrawPosTextOp>(text, byte_length, pos, count, + flags); +} + +void RecordPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob, + SkScalar x, + SkScalar y, + const PaintFlags& flags) { + buffer_->push<DrawTextBlobOp>(blob, x, y, flags); +} + +void RecordPaintCanvas::drawDisplayItemList( + scoped_refptr<DisplayItemList> list) { + buffer_->push<DrawDisplayItemListOp>(list); +} + +void RecordPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) { + // TODO(enne): If this is small, maybe flatten it? + buffer_->push<DrawRecordOp>(record); +} + +bool RecordPaintCanvas::isClipEmpty() const { + return canvas_.isClipEmpty(); +} + +bool RecordPaintCanvas::isClipRect() const { + return canvas_.isClipRect(); +} + +const SkMatrix& RecordPaintCanvas::getTotalMatrix() const { + return canvas_.getTotalMatrix(); +} + +void RecordPaintCanvas::temporary_internal_describeTopLayer( + SkMatrix* matrix, + SkIRect* clip_bounds) { + return canvas_.temporary_internal_describeTopLayer(matrix, clip_bounds); +} + +bool RecordPaintCanvas::ToPixmap(SkPixmap* output) { + // TODO(enne): It'd be nice to make this NOTREACHED() or remove this from + // RecordPaintCanvas, but this is used by GraphicsContextCanvas for knowing + // whether or not it can raster directly into pixels with Cg. + return false; +} + +void RecordPaintCanvas::Annotate(AnnotationType type, + const SkRect& rect, + sk_sp<SkData> data) { + buffer_->push<AnnotateOp>(type, rect, data); +} + +void RecordPaintCanvas::PlaybackPaintRecord(sk_sp<const PaintRecord> record) { + drawPicture(record); +} + +} // namespace cc
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h new file mode 100644 index 0000000..15f0102 --- /dev/null +++ b/cc/paint/record_paint_canvas.h
@@ -0,0 +1,160 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_PAINT_RECORD_PAINT_CANVAS_H_ +#define CC_PAINT_RECORD_PAINT_CANVAS_H_ + +#include <memory> + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "cc/paint/paint_canvas.h" +#include "cc/paint/paint_flags.h" +#include "cc/paint/paint_record.h" +#include "third_party/skia/include/utils/SkNoDrawCanvas.h" + +namespace cc { + +class PaintOpBuffer; +class PaintFlags; + +class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas { + public: + explicit RecordPaintCanvas(PaintOpBuffer* buffer, const SkRect& cull_rect); + ~RecordPaintCanvas() override; + + SkMetaData& getMetaData() override; + SkImageInfo imageInfo() const override; + + void flush() override; + + SkISize getBaseLayerSize() const override; + bool writePixels(const SkImageInfo& info, + const void* pixels, + size_t row_bytes, + int x, + int y) override; + int save() override; + int saveLayer(const SkRect* bounds, const PaintFlags* flags) override; + int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override; + + void restore() override; + int getSaveCount() const override; + void restoreToCount(int save_count) override; + void translate(SkScalar dx, SkScalar dy) override; + void scale(SkScalar sx, SkScalar sy) override; + void rotate(SkScalar degrees) override; + void concat(const SkMatrix& matrix) override; + void setMatrix(const SkMatrix& matrix) override; + + void clipRect(const SkRect& rect, SkClipOp op, bool antialias) override; + void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) override; + void clipPath(const SkPath& path, SkClipOp op, bool antialias) override; + bool quickReject(const SkRect& rect) const override; + bool quickReject(const SkPath& path) const override; + SkRect getLocalClipBounds() const override; + bool getLocalClipBounds(SkRect* bounds) const override; + SkIRect getDeviceClipBounds() const override; + bool getDeviceClipBounds(SkIRect* bounds) const override; + void drawColor(SkColor color, SkBlendMode mode) override; + void clear(SkColor color) override; + + void drawLine(SkScalar x0, + SkScalar y0, + SkScalar x1, + SkScalar y1, + const PaintFlags& flags) override; + void drawRect(const SkRect& rect, const PaintFlags& flags) override; + void drawIRect(const SkIRect& rect, const PaintFlags& flags) override; + void drawOval(const SkRect& oval, const PaintFlags& flags) override; + void drawRRect(const SkRRect& rrect, const PaintFlags& flags) override; + void drawDRRect(const SkRRect& outer, + const SkRRect& inner, + const PaintFlags& flags) override; + void drawCircle(SkScalar cx, + SkScalar cy, + SkScalar radius, + const PaintFlags& flags) override; + void drawArc(const SkRect& oval, + SkScalar start_angle, + SkScalar sweep_angle, + bool use_center, + const PaintFlags& flags) override; + void drawRoundRect(const SkRect& rect, + SkScalar rx, + SkScalar ry, + const PaintFlags& flags) override; + void drawPath(const SkPath& path, const PaintFlags& flags) override; + void drawImage(const PaintImage& image, + SkScalar left, + SkScalar top, + const PaintFlags* flags) override; + void drawImageRect(const PaintImage& image, + const SkRect& src, + const SkRect& dst, + const PaintFlags* flags, + SrcRectConstraint constraint) override; + void drawBitmap(const SkBitmap& bitmap, + SkScalar left, + SkScalar top, + const PaintFlags* flags) override; + + void drawText(const void* text, + size_t byte_length, + SkScalar x, + SkScalar y, + const PaintFlags& flags) override; + void drawPosText(const void* text, + size_t byte_length, + const SkPoint pos[], + const PaintFlags& flags) override; + void drawTextBlob(sk_sp<SkTextBlob> blob, + SkScalar x, + SkScalar y, + const PaintFlags& flags) override; + + void drawDisplayItemList( + scoped_refptr<DisplayItemList> display_item_list) override; + + void drawPicture(sk_sp<const PaintRecord> record) override; + + bool isClipEmpty() const override; + bool isClipRect() const override; + const SkMatrix& getTotalMatrix() const override; + + void temporary_internal_describeTopLayer(SkMatrix* matrix, + SkIRect* clip_bounds) override; + + bool ToPixmap(SkPixmap* output) override; + void Annotate(AnnotationType type, + const SkRect& rect, + sk_sp<SkData> data) override; + + void PlaybackPaintRecord(sk_sp<const PaintRecord> record) override; + + // Don't shadow non-virtual helper functions. + using PaintCanvas::clipRect; + using PaintCanvas::clipRRect; + using PaintCanvas::clipPath; + using PaintCanvas::drawBitmap; + using PaintCanvas::drawColor; + using PaintCanvas::drawImage; + using PaintCanvas::drawPicture; + + private: + PaintOpBuffer* buffer_; + + // TODO(enne): Although RecordPaintCanvas is mostly a write-only interface + // where paint commands are stored, occasionally users of PaintCanvas want + // to ask stateful questions mid-stream of clip and transform state. + // To avoid duplicating all this code (for now?), just forward to an SkCanvas + // that's not backed by anything but can answer these questions. + SkNoDrawCanvas canvas_; +}; + +} // namespace cc + +#endif // CC_PAINT_RECORD_PAINT_CANVAS_H_
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc index bfc38b6..501ccdf 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/paint/paint_canvas.h" +#include "cc/paint/skia_paint_canvas.h" #include "base/memory/ptr_util.h" #include "cc/paint/display_item_list.h" @@ -58,7 +58,7 @@ return canvas_->saveLayer(bounds, ToSkPaint(flags)); } -int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { +int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) { return canvas_->saveLayerAlpha(bounds, alpha); }
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h index 47dba86..1bd23f0 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -46,7 +46,7 @@ int y) override; int save() override; int saveLayer(const SkRect* bounds, const PaintFlags* flags) override; - int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) override; + int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override; void restore() override; int getSaveCount() const override;
diff --git a/cc/test/test_skcanvas.cc b/cc/test/test_skcanvas.cc new file mode 100644 index 0000000..e45f42de --- /dev/null +++ b/cc/test/test_skcanvas.cc
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/test/test_skcanvas.h" + +namespace cc { + +SaveCountingCanvas::SaveCountingCanvas() : SkNoDrawCanvas(100, 100) {} + +SkCanvas::SaveLayerStrategy SaveCountingCanvas::getSaveLayerStrategy( + const SaveLayerRec& rec) { + save_count_++; + return SkNoDrawCanvas::getSaveLayerStrategy(rec); +} + +void SaveCountingCanvas::willRestore() { + restore_count_++; +} + +void SaveCountingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { + draw_rect_ = rect; + paint_ = paint; +} + +} // namespace cc
diff --git a/cc/test/test_skcanvas.h b/cc/test/test_skcanvas.h new file mode 100644 index 0000000..2b130a4 --- /dev/null +++ b/cc/test/test_skcanvas.h
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_TEST_TEST_SKCANVAS_H_ +#define CC_TEST_TEST_SKCANVAS_H_ + +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/utils/SkNoDrawCanvas.h" + +namespace cc { + +class SaveCountingCanvas : public SkNoDrawCanvas { + public: + SaveCountingCanvas(); + + // Note: getSaveLayerStrategy is used as "willSave", as willSave + // is not always called. + SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override; + void willRestore() override; + void onDrawRect(const SkRect& rect, const SkPaint& paint) override; + + int save_count_ = 0; + int restore_count_ = 0; + SkRect draw_rect_; + SkPaint paint_; +}; + +} // namespace cc + +#endif // CC_TEST_TEST_SKCANVAS_H_
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java index 43b71b4..8007e82 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java
@@ -1154,7 +1154,6 @@ mBarHeightPeeking = barHeightPx * mPxToDp; mBarHeightMaximized = mBarHeightPeeking; mBarHeightExpanded = mBarHeightPeeking; - mHeight = mBarHeightPeeking; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java index 965e27d..cfcfc1d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java
@@ -202,10 +202,13 @@ removeCallbacks(mKeyboardResizeModeTask); mKeyboardResizeModeTask = null; } - if (windowDelegate.getWindowSoftInputMode() - != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) { - windowDelegate.setWindowSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); + // TODO(mdjones): SOFT_INPUT_ADJUST_NOTHING breaks omnibox suggestions but fixes a + // content jumping bug in Chrome Home. See https://crbug.com/706918 + int softInputMode = mBottomSheet != null + ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING + : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; + if (windowDelegate.getWindowSoftInputMode() != softInputMode) { + windowDelegate.setWindowSoftInputMode(softInputMode); } UiUtils.showKeyboard(mUrlBar); // As the position of the navigation icon has changed, ensure the suggestions are
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java index 28a97830..59f4564 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
@@ -212,9 +212,9 @@ if (hasFocus) { if (mSecurityButton.getVisibility() == VISIBLE) mSecurityButton.setVisibility(GONE); if (getWindowDelegate().getWindowSoftInputMode() - != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) { + != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) { getWindowDelegate().setWindowSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); } UiUtils.showKeyboard(mUrlBar); } else {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java index fe48f0e4..1d003270 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -108,7 +108,7 @@ OmniboxTestUtils.toggleUrlBarFocus(urlBar, true); CriteriaHelper.pollInstrumentationThread(Criteria.equals( - WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING, new Callable<Integer>() { + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN, new Callable<Integer>() { @Override public Integer call() { return getActivity().getWindow().getAttributes().softInputMode;
diff --git a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc index c43ac5ae..2b2015211 100644 --- a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc
@@ -59,6 +59,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.ParseTiming.NavigationToParseStart", timing.parse_timing.parse_start.value()); @@ -109,6 +110,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.PaintTiming." "NavigationToFirstContentfulPaint", @@ -165,6 +167,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.Experimental.PaintTiming." "NavigationToFirstMeaningfulPaint", @@ -211,6 +214,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToDOMContentLoadedEventFired", @@ -252,6 +256,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToLoadEventFired",
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index a455416..760db46b 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -441,9 +441,9 @@ if (this.connectNotAllowed_(networkProperties, globalPolicy)) return false; var type = networkProperties.Type; - if (type == CrOnc.Type.CELLULAR || type == CrOnc.Type.WI_MAX) + if (type == CrOnc.Type.CELLULAR) return false; - if (type == CrOnc.Type.WI_FI && + if ((type == CrOnc.Type.WI_FI || type == CrOnc.Type.WI_MAX) && networkProperties.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED) { return false;
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 264ba63..7ec42c0 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -92,7 +92,7 @@ // is created. void ShowHelpImpl(Browser* browser, Profile* profile, HelpSource source) { base::RecordAction(UserMetricsAction("ShowHelpTab")); -#if defined(OS_CHROMEOS) && defined(OFFICIAL_BUILD) +#if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD) const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile)->GetExtensionById( genius_app::kGeniusAppId,
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index d98a2b9..cdbe2d1 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -65,10 +65,6 @@ class Command; } -namespace { -class OmniboxPopupModelObserverBridge; -} - constexpr const gfx::Size kMinCocoaTabbedWindowSize(400, 272); constexpr const gfx::Size kMinCocoaPopupWindowSize(100, 122); @@ -201,10 +197,6 @@ // handle. std::unique_ptr<ExtensionKeybindingRegistryCocoa> extensionKeybindingRegistry_; - - // Observes whether the omnibox popup is shown or hidden. - std::unique_ptr<OmniboxPopupModelObserverBridge> - omniboxPopupModelObserverBridge_; } // A convenience class method which gets the |BrowserWindowController| for a
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 13ce7a8..2fd4f20f 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -13,7 +13,6 @@ #import "base/mac/foundation_util.h" #include "base/mac/mac_util.h" #import "base/mac/sdk_forward_declarations.h" -#include "base/scoped_observer.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" // IDC_* @@ -65,7 +64,6 @@ #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" #include "chrome/browser/ui/cocoa/l10n_util.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" -#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa.h" #import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h" #import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h" @@ -89,9 +87,6 @@ #include "chrome/common/pref_names.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/managed/managed_bookmark_service.h" -#include "components/omnibox/browser/omnibox_edit_model.h" -#include "components/omnibox/browser/omnibox_popup_model.h" -#include "components/omnibox/browser/omnibox_popup_model_observer.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_ui_delegate.h" @@ -190,43 +185,6 @@ namespace { -// This class shows or hides the top arrow of the infobar in accordance with the -// visibility of the omnibox popup. It hides the top arrow when the omnibox -// popup is shown, and vice versa. -class OmniboxPopupModelObserverBridge final : public OmniboxPopupModelObserver { - public: - explicit OmniboxPopupModelObserverBridge(BrowserWindowController* controller) - : controller_(controller), - omnibox_popup_model_([controller_ locationBarBridge] - ->GetOmniboxView() - ->model() - ->popup_model()), - omnibox_popup_model_observer_(this) { - DCHECK(omnibox_popup_model_); - omnibox_popup_model_observer_.Add(omnibox_popup_model_); - } - - void OnOmniboxPopupShownOrHidden() override { - int max_top_arrow_height = 0; - if (!omnibox_popup_model_->IsOpen()) { - base::scoped_nsobject<BrowserWindowLayout> layout( - [[BrowserWindowLayout alloc] init]); - [controller_ updateLayoutParameters:layout]; - max_top_arrow_height = [layout computeLayout].infoBarMaxTopArrowHeight; - } - [[controller_ infoBarContainerController] - setMaxTopArrowHeight:max_top_arrow_height]; - } - - private: - BrowserWindowController* controller_; - OmniboxPopupModel* omnibox_popup_model_; - ScopedObserver<OmniboxPopupModel, OmniboxPopupModelObserver> - omnibox_popup_model_observer_; - - DISALLOW_COPY_AND_ASSIGN(OmniboxPopupModelObserverBridge); -}; - void SetUpBrowserWindowCommandHandler(NSWindow* window) { // Make the window handle browser window commands. [base::mac::ObjCCastStrict<ChromeEventProcessingWindow>(window) @@ -431,9 +389,6 @@ extensions::ExtensionKeybindingRegistry::ALL_EXTENSIONS, windowShim_.get())); - omniboxPopupModelObserverBridge_.reset( - new OmniboxPopupModelObserverBridge(self)); - blockLayoutSubviews_ = NO; // We are done initializing now.
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc index eebe9f1..eae1c60 100644 --- a/chrome/browser/ui/webui/certificate_viewer_webui.cc +++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -11,9 +11,12 @@ #include "base/bind_helpers.h" #include "base/i18n/time_formatting.h" #include "base/json/json_writer.h" +#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "chrome/browser/certificate_viewer.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -30,6 +33,84 @@ using content::WebContents; using content::WebUIMessageHandler; +namespace { + +// Helper class for building a Value representation of a certificate. The class +// gathers data for a single node of the representation tree and builds a +// DictionaryValue out of that. +class CertNodeBuilder { + public: + // Starts the node with "label" set to |label|. + explicit CertNodeBuilder(base::StringPiece label); + + // Convenience version: Converts |label_id| to the corresponding resource + // string, then delegates to the other constructor. + explicit CertNodeBuilder(int label_id); + + // Builder methods all return |*this| so that they can be chained in single + // expressions. + + // Sets the "payload.val" field. Call this at most once. + CertNodeBuilder& Payload(base::StringPiece payload); + + // Adds |child| in the list keyed "children". Can be called multiple times. + CertNodeBuilder& Child(std::unique_ptr<base::DictionaryValue> child); + + // Similar to Child, but if the argument is null, then this does not add + // anything. + CertNodeBuilder& ChildIfNotNull(std::unique_ptr<base::DictionaryValue> child); + + // Creates a DictionaryValue representation of the collected information. Only + // call this once. + std::unique_ptr<base::DictionaryValue> Build(); + + private: + base::DictionaryValue node_; + base::ListValue children_; + // |built_| is false until Build() is called. Once it is |true|, |node_| and + // |children_| are no longer valid for use. + bool built_ = false; + + DISALLOW_COPY_AND_ASSIGN(CertNodeBuilder); +}; + +CertNodeBuilder::CertNodeBuilder(base::StringPiece label) { + node_.SetString("label", label); +} + +CertNodeBuilder::CertNodeBuilder(int label_id) + : CertNodeBuilder(l10n_util::GetStringUTF8(label_id)) {} + +CertNodeBuilder& CertNodeBuilder::Payload(base::StringPiece payload) { + DCHECK(!node_.HasKey("payload.val")); + node_.SetString("payload.val", payload); + return *this; +} + +CertNodeBuilder& CertNodeBuilder::Child( + std::unique_ptr<base::DictionaryValue> child) { + children_.Append(std::move(child)); + return *this; +} + +CertNodeBuilder& CertNodeBuilder::ChildIfNotNull( + std::unique_ptr<base::DictionaryValue> child) { + if (child) + return Child(std::move(child)); + return *this; +} + +std::unique_ptr<base::DictionaryValue> CertNodeBuilder::Build() { + DCHECK(!built_); + if (!children_.empty()) { + node_.Set("children", base::MakeUnique<base::Value>(std::move(children_))); + } + built_ = true; + return base::MakeUnique<base::DictionaryValue>(std::move(node_)); +} + +} // namespace + // Shows a certificate using the WebUI certificate viewer. void ShowCertificateViewer(WebContents* web_contents, gfx::NativeWindow parent, @@ -169,7 +250,7 @@ x509_certificate_model::HashCertSHA1(cert_hnd)); // Certificate hierarchy is constructed from bottom up. - base::ListValue* children = NULL; + std::unique_ptr<base::ListValue> children; int index = 0; for (net::X509Certificate::OSCertHandles::const_iterator i = cert_chain.begin(); i != cert_chain.end(); ++i, ++index) { @@ -180,14 +261,14 @@ cert_node->SetDouble("payload.index", index); // Add the child from the previous iteration. if (children) - cert_node->Set("children", children); + cert_node->Set("children", std::move(children)); // Add this node to the children list for the next iteration. - children = new base::ListValue(); + children = base::MakeUnique<base::ListValue>(); children->Append(std::move(cert_node)); } // Set the last node as the top of the certificate hierarchy. - cert_info.Set("hierarchy", children); + cert_info.Set("hierarchy", std::move(children)); base::JSONWriter::Write(cert_info, &data); @@ -291,181 +372,115 @@ net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index]; - // Main certificate fields. - auto cert_fields = base::MakeUnique<base::ListValue>(); - auto node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION)); + CertNodeBuilder version_node(IDS_CERT_DETAILS_VERSION); std::string version = x509_certificate_model::GetVersion(cert); if (!version.empty()) { - node_details->SetString("payload.val", - l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT, - base::UTF8ToUTF16(version))); + version_node.Payload(l10n_util::GetStringFUTF8( + IDS_CERT_DETAILS_VERSION_FORMAT, base::UTF8ToUTF16(version))); } - cert_fields->Append(std::move(node_details)); - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER)); - node_details->SetString("payload.val", - x509_certificate_model::GetSerialNumberHexified(cert, - l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT))); - cert_fields->Append(std::move(node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); - node_details->SetString("payload.val", - x509_certificate_model::ProcessSecAlgorithmSignature(cert)); - cert_fields->Append(std::move(node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER)); - node_details->SetString("payload.val", - x509_certificate_model::GetIssuerName(cert)); - cert_fields->Append(std::move(node_details)); - - // Validity period. - auto cert_sub_fields = base::MakeUnique<base::ListValue>(); - - auto sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE)); - - auto alt_node_details = base::MakeUnique<base::DictionaryValue>(); - alt_node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER)); - + CertNodeBuilder issued_node_builder(IDS_CERT_DETAILS_NOT_BEFORE); + CertNodeBuilder expires_node_builder(IDS_CERT_DETAILS_NOT_AFTER); base::Time issued, expires; if (x509_certificate_model::GetTimes(cert, &issued, &expires)) { - sub_node_details->SetString( - "payload.val", - base::UTF16ToUTF8( - base::TimeFormatShortDateAndTimeWithTimeZone(issued))); - alt_node_details->SetString( - "payload.val", - base::UTF16ToUTF8( - base::TimeFormatShortDateAndTimeWithTimeZone(expires))); + issued_node_builder.Payload(base::UTF16ToUTF8( + base::TimeFormatShortDateAndTimeWithTimeZone(issued))); + expires_node_builder.Payload(base::UTF16ToUTF8( + base::TimeFormatShortDateAndTimeWithTimeZone(expires))); } - cert_sub_fields->Append(std::move(sub_node_details)); - cert_sub_fields->Append(std::move(alt_node_details)); - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY)); - node_details->Set("children", std::move(cert_sub_fields)); - cert_fields->Append(std::move(node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT)); - node_details->SetString("payload.val", - x509_certificate_model::GetSubjectName(cert)); - cert_fields->Append(std::move(node_details)); - - // Subject key information. - cert_sub_fields = base::MakeUnique<base::ListValue>(); - - sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG)); - sub_node_details->SetString( - "payload.val", - x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert)); - cert_sub_fields->Append(std::move(sub_node_details)); - - sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY)); - sub_node_details->SetString( - "payload.val", x509_certificate_model::ProcessSubjectPublicKeyInfo(cert)); - cert_sub_fields->Append(std::move(sub_node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO)); - node_details->Set("children", std::move(cert_sub_fields)); - cert_fields->Append(std::move(node_details)); - - // Extensions. x509_certificate_model::Extensions extensions; x509_certificate_model::GetExtensions( l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL), l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL), cert, &extensions); + std::unique_ptr<base::DictionaryValue> details_extensions; if (!extensions.empty()) { - cert_sub_fields = base::MakeUnique<base::ListValue>(); - - for (x509_certificate_model::Extensions::const_iterator i = - extensions.begin(); i != extensions.end(); ++i) { - sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString("label", i->name); - sub_node_details->SetString("payload.val", i->value); - cert_sub_fields->Append(std::move(sub_node_details)); + CertNodeBuilder details_extensions_builder(IDS_CERT_DETAILS_EXTENSIONS); + for (const x509_certificate_model::Extension& extension : extensions) { + details_extensions_builder.Child( + CertNodeBuilder(extension.name).Payload(extension.value).Build()); } - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS)); - node_details->Set("children", std::move(cert_sub_fields)); - cert_fields->Append(std::move(node_details)); + details_extensions = details_extensions_builder.Build(); } - // Details certificate information. - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); - node_details->SetString("payload.val", - x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert)); - cert_fields->Append(std::move(node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE)); - node_details->SetString("payload.val", - x509_certificate_model::ProcessRawBitsSignatureWrap(cert)); - cert_fields->Append(std::move(node_details)); - - // Fingerprint information. - cert_sub_fields = base::MakeUnique<base::ListValue>(); - - sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString( - "label", - l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL)); - sub_node_details->SetString("payload.val", - x509_certificate_model::HashCertSHA256(cert)); - cert_sub_fields->Append(std::move(sub_node_details)); - - sub_node_details = base::MakeUnique<base::DictionaryValue>(); - sub_node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL)); - sub_node_details->SetString("payload.val", - x509_certificate_model::HashCertSHA1(cert)); - cert_sub_fields->Append(std::move(sub_node_details)); - - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP)); - node_details->Set("children", std::move(cert_sub_fields)); - cert_fields->Append(std::move(node_details)); - - // Certificate information. - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString( - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE)); - node_details->Set("children", std::move(cert_fields)); - cert_fields = base::MakeUnique<base::ListValue>(); - cert_fields->Append(std::move(node_details)); - - // Top level information. base::ListValue root_list; - node_details = base::MakeUnique<base::DictionaryValue>(); - node_details->SetString("label", x509_certificate_model::GetTitle(cert)); - node_details->Set("children", std::move(cert_fields)); - root_list.Append(std::move(node_details)); + root_list.Append( + CertNodeBuilder(x509_certificate_model::GetTitle(cert)) + .Child( + CertNodeBuilder( + l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE)) + // Main certificate fields. + .Child(version_node.Build()) + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_SERIAL_NUMBER) + .Payload( + x509_certificate_model::GetSerialNumberHexified( + cert, l10n_util::GetStringUTF8( + IDS_CERT_INFO_FIELD_NOT_PRESENT))) + .Build()) + .Child(CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG) + .Payload(x509_certificate_model:: + ProcessSecAlgorithmSignature(cert)) + .Build()) + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_ISSUER) + .Payload(x509_certificate_model::GetIssuerName(cert)) + .Build()) + // Validity period. + .Child(CertNodeBuilder(IDS_CERT_DETAILS_VALIDITY) + .Child(issued_node_builder.Build()) + .Child(expires_node_builder.Build()) + .Build()) + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT) + .Payload(x509_certificate_model::GetSubjectName(cert)) + .Build()) + // Subject key information. + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY_INFO) + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY_ALG) + .Payload( + x509_certificate_model:: + ProcessSecAlgorithmSubjectPublicKey( + cert)) + .Build()) + .Child(CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY) + .Payload( + x509_certificate_model:: + ProcessSubjectPublicKeyInfo(cert)) + .Build()) + .Build()) + // Extensions. + .ChildIfNotNull(std::move(details_extensions)) + .Child( + CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG) + .Payload(x509_certificate_model:: + ProcessSecAlgorithmSignatureWrap(cert)) + .Build()) + .Child(CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE) + .Payload(x509_certificate_model:: + ProcessRawBitsSignatureWrap(cert)) + .Build()) + .Child( + CertNodeBuilder(IDS_CERT_INFO_FINGERPRINTS_GROUP) + .Child(CertNodeBuilder( + IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL) + .Payload( + x509_certificate_model::HashCertSHA256( + cert)) + .Build()) + .Child( + CertNodeBuilder( + IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL) + .Payload(x509_certificate_model::HashCertSHA1( + cert)) + .Build()) + .Build()) + .Build()) + .Build()); // Send certificate information to javascript. web_ui()->CallJavascriptFunctionUnsafe("cert_viewer.getCertificateFields",
diff --git a/components/domain_reliability/quic_error_mapping.cc b/components/domain_reliability/quic_error_mapping.cc index 56d3c76..41283a5 100644 --- a/components/domain_reliability/quic_error_mapping.cc +++ b/components/domain_reliability/quic_error_mapping.cc
@@ -126,8 +126,6 @@ // Disabled QUIC because of too many PUBLIC_RESETs post handshake. {net::QUIC_PUBLIC_RESETS_POST_HANDSHAKE, "quic.public_resets_post_handshake"}, - // Disabled QUIC because of too many timeouts with streams open. - {net::QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "quic.timeouts_with_open_streams"}, // Closed because we failed to serialize a packet. {net::QUIC_FAILED_TO_SERIALIZE_PACKET, "quic.failed_to_serialize_packet"}, // QUIC timed out after too many RTOs. @@ -253,7 +251,7 @@ // Must be updated any time a net::QuicErrorCode is deprecated in // net/quic/core/quic_packets.h. -const int kDeprecatedQuicErrorCount = 4; +const int kDeprecatedQuicErrorCount = 5; const int kActiveQuicErrorCount = net::QUIC_LAST_ERROR - kDeprecatedQuicErrorCount;
diff --git a/components/domain_reliability/util.cc b/components/domain_reliability/util.cc index 517b304d..1b3431a0 100644 --- a/components/domain_reliability/util.cc +++ b/components/domain_reliability/util.cc
@@ -126,6 +126,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: return "QUIC"; case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: NOTREACHED();
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 85a41b8..88ef494 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -1558,7 +1558,15 @@ if (!widget_ || !surface_) return; aura::Window* window = widget_->GetNativeWindow(); - if (!shadow_enabled_) { + + bool underlay_capture_events = + WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && widget_->IsActive(); + bool black_background_enabled = + ((widget_->IsFullscreen() || widget_->IsMaximized()) || + underlay_capture_events) && + ash::wm::GetWindowState(window)->allow_set_bounds_direct() && + window->layer()->GetTargetTransform().IsIdentity(); + if (!shadow_enabled_ && !black_background_enabled) { wm::SetShadowElevation(window, wm::ShadowElevation::NONE); if (shadow_underlay_) shadow_underlay_->Hide(); @@ -1626,10 +1634,6 @@ } } - bool underlay_capture_events = - WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && - widget_->IsActive(); - float shadow_underlay_opacity = shadow_background_opacity_; // Put the black background layer behind the window if @@ -1639,10 +1643,7 @@ // thus the background can be visible). // 3) the window has no transform (the transformed background may // not cover the entire background, e.g. overview mode). - if ((widget_->IsFullscreen() || widget_->IsMaximized() || - underlay_capture_events) && - ash::wm::GetWindowState(window)->allow_set_bounds_direct() && - window->layer()->GetTargetTransform().IsIdentity()) { + if (black_background_enabled) { if (shadow_underlay_in_surface_) { shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); } else { @@ -1657,6 +1658,8 @@ if (!shadow_underlay_in_surface_) shadow_underlay_bounds = shadow_bounds; + shadow_underlay_->SetBounds(shadow_underlay_bounds); + // Constrain the underlay bounds to the client area in case shell surface // frame is enabled. if (frame_enabled_) { @@ -1664,15 +1667,12 @@ widget_->non_client_view()->frame_view()->GetBoundsForClientView()); } - shadow_underlay_->SetBounds(shadow_underlay_bounds); - // TODO(oshima): Setting to the same value should be no-op. // crbug.com/642223. if (shadow_underlay_opacity != shadow_underlay_->layer()->GetTargetOpacity()) { shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); } - shadow_underlay_->Show(); wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window);
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc index d590cbb..d88d546 100644 --- a/components/exo/shell_surface_unittest.cc +++ b/components/exo/shell_surface_unittest.cc
@@ -832,6 +832,20 @@ ASSERT_TRUE(shell_surface->shadow_underlay()); EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible()); + shell_surface->SetRectangularSurfaceShadow(gfx::Rect(0, 0, 0, 0)); + // Underlay should be created even without shadow. + ASSERT_TRUE(shell_surface->shadow_underlay()); + EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible()); + shell_surface->SetRectangularShadowEnabled(false); + surface->Commit(); + // Underlay should be created even without shadow. + ASSERT_TRUE(shell_surface->shadow_underlay()); + EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible()); + + shell_surface->SetRectangularShadowEnabled(true); + shell_surface->SetRectangularSurfaceShadow(gfx::Rect(10, 10, 100, 100)); + surface->Commit(); + // Restore the window and make sure the shadow is created, visible and // has the latest bounds. widget->Restore();
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index b4d13ee..f572bb6 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -169,7 +169,7 @@ if (has_transparent_background) { attributes.alpha_size = 8; - } else if (base::SysInfo::IsLowEndDevice()) { + } else if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) { // In this case we prefer to use RGB565 format instead of RGBA8888 if // possible. // TODO(danakj): GpuCommandBufferStub constructor checks for alpha == 0 in
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index ed8514c2..7bffa0d 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -418,7 +418,8 @@ // RGBA_4444 textures are only enabled by default for low end devices // and are disabled for Android WebView as it doesn't support the format. - if (!cmd.HasSwitch(switches::kDisableRGBA4444Textures)) + if (!cmd.HasSwitch(switches::kDisableRGBA4444Textures) && + base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) settings.renderer_settings.preferred_tile_format = cc::RGBA_4444; } else { // On other devices we have increased memory excessively to avoid @@ -550,21 +551,20 @@ if (actual.bytes_limit_when_visible == 0) { // NOTE: Non-low-end devices use only 50% of these limits, // except during 'emergencies' where 100% can be used. - if (!base::SysInfo::IsLowEndDevice()) { - if (physical_memory_mb >= 1536) - actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB - else if (physical_memory_mb >= 1152) - actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB - else if (physical_memory_mb >= 768) - actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB - else - actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB - } else { - // Low-end devices have 512MB or less memory by definition - // so we hard code the limit rather than relying on the heuristics - // above. Low-end devices use 4444 textures so we can use a lower limit. + if (physical_memory_mb >= 1536) + actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB + else if (physical_memory_mb >= 1152) + actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB + else if (physical_memory_mb >= 768) + actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB + else if (physical_memory_mb >= 513) + actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB + else + // Devices with this little RAM have very little headroom so we hardcode + // the limit rather than relying on the heuristics above. (They also use + // 4444 textures so we can use a lower limit.) actual.bytes_limit_when_visible = 8; - } + actual.bytes_limit_when_visible = actual.bytes_limit_when_visible * 1024 * 1024; // Clamp the observed value to a specific range on Android.
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc index 08b4e70..99d76f6 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -38,14 +38,12 @@ idle_cleanup_interval_ = base::TimeDelta::FromSeconds(5); idle_timeout_ = base::TimeDelta::FromSeconds(15); - // Idle players time out more aggressively on low end devices. - is_low_end_device_ = base::SysInfo::IsLowEndDevice(); + is_jelly_bean_ = false; #if defined(OS_ANDROID) // On Android, due to the instability of the OS level media components, we - // consider all pre-KitKat devices to be low end. - is_low_end_device_ |= - base::android::BuildInfo::GetInstance()->sdk_int() <= 18; + // consider all pre-KitKat devices to be potentially buggy. + is_jelly_bean_ |= base::android::BuildInfo::GetInstance()->sdk_int() <= 18; #endif } @@ -209,11 +207,11 @@ void RendererWebMediaPlayerDelegate::SetIdleCleanupParamsForTesting( base::TimeDelta idle_timeout, base::TickClock* tick_clock, - bool is_low_end_device) { + bool is_jelly_bean) { idle_cleanup_interval_ = base::TimeDelta(); idle_timeout_ = idle_timeout; tick_clock_ = tick_clock; - is_low_end_device_ = is_low_end_device; + is_jelly_bean_ = is_jelly_bean; } bool RendererWebMediaPlayerDelegate::IsIdleCleanupTimerRunningForTesting() @@ -311,12 +309,12 @@ // When we reach the maximum number of idle players, clean them up // aggressively. Values chosen after testing on a Galaxy Nexus device for // http://crbug.com/612909. - if (idle_player_map_.size() > (is_low_end_device_ ? 2u : 8u)) + if (idle_player_map_.size() > (is_jelly_bean_ ? 2u : 8u)) aggressive_cleanup = true; - // When a player plays on a low-end device, clean up idle players + // When a player plays on a buggy old device, clean up idle players // aggressively. - if (has_played_video_since_last_update_task && is_low_end_device_) + if (has_played_video_since_last_update_task && is_jelly_bean_) aggressive_cleanup = true; CleanUpIdlePlayers(aggressive_cleanup ? base::TimeDelta() : idle_timeout_);
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index 46886e8..de7f7ed 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -66,11 +66,11 @@ void OnDestruct() override; // Zeros out |idle_cleanup_interval_|, sets |idle_timeout_| to |idle_timeout|, - // and |is_low_end_device_| to |is_low_end_device|. A zero cleanup interval + // and |is_jelly_bean_| to |is_jelly_bean|. A zero cleanup interval // will cause the idle timer to run with each run of the message loop. void SetIdleCleanupParamsForTesting(base::TimeDelta idle_timeout, base::TickClock* tick_clock, - bool is_low_end_device); + bool is_jelly_bean); bool IsIdleCleanupTimerRunningForTesting() const; // Note: Does not call OnFrameHidden()/OnFrameShown(). @@ -145,7 +145,7 @@ // Determined at construction time based on system information; determines // when the idle cleanup timer should be fired more aggressively. - bool is_low_end_device_; + bool is_jelly_bean_; DISALLOW_COPY_AND_ASSIGN(RendererWebMediaPlayerDelegate); };
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 7d6113c..b8c4c05 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1037,15 +1037,13 @@ settings->SetPreferHiddenVolumeControls(true); settings->SetSpellCheckEnabledByDefault(prefs.spellcheck_enabled_by_default); - // Force preload=none and disable autoplay on older or low end Android + // Force preload=none and disable autoplay on older Android // platforms because their media pipelines are not stable enough to handle // concurrent elements. See http://crbug.com/612909, http://crbug.com/622826. - const bool is_low_end_device = + const bool is_jelly_bean = base::android::BuildInfo::GetInstance()->sdk_int() <= - base::android::SDK_VERSION_JELLY_BEAN_MR2 || - base::SysInfo::IsLowEndDevice(); - // TODO(mlamouri): rename this setting "isLowEndDevice". - settings->SetForcePreloadNoneForMediaElements(is_low_end_device); + base::android::SDK_VERSION_JELLY_BEAN_MR2; + settings->SetForcePreloadNoneForMediaElements(is_jelly_bean); WebRuntimeFeatures::EnableVideoFullscreenOrientationLock( prefs.video_fullscreen_orientation_lock_enabled);
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 5d85784..6228c9a 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -495,13 +495,13 @@ 'pixel_video_mp4.html', base_name + '_DirectComposition_Video_MP4', test_rect=[0, 0, 300, 300], - revision=1, + revision=2, browser_args=browser_args), PixelTestPage( 'pixel_video_vp9.html', base_name + '_DirectComposition_Video_VP9', test_rect=[0, 0, 300, 300], - revision=1, + revision=2, browser_args=browser_args), ]
diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn index f8d7af0..1a980af 100644 --- a/gpu/config/BUILD.gn +++ b/gpu/config/BUILD.gn
@@ -55,7 +55,19 @@ "--output-dir", rebase_path("$target_gen_dir", root_build_dir), "--skip-testing-data", + "--os-filter", ] + if (is_win) { + args += [ "win" ] + } else if (is_mac) { + args += [ "macosx" ] + } else if (is_android) { + args += [ "android" ] + } else if (is_chromeos) { + args += [ "chromeos" ] + } else { + args += [ "linux" ] + } } source_set("config_sources") {
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index fe5d306c0b..a7399a4c 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -2365,7 +2365,6 @@ } ], "comment": [ - "Please update the version number on top whenever you change this file", - "Please run gpu/config/process_json.py whenever you change this file" + "Please update the version number on top whenever you change this file" ] }
diff --git a/gpu/config/gpu_driver_bug_list_unittest.cc b/gpu/config/gpu_driver_bug_list_unittest.cc index 5ed55ec..99cbe08e5 100644 --- a/gpu/config/gpu_driver_bug_list_unittest.cc +++ b/gpu/config/gpu_driver_bug_list_unittest.cc
@@ -16,6 +16,7 @@ ~GpuDriverBugListTest() override {} }; +#if defined(OS_ANDROID) TEST_F(GpuDriverBugListTest, CurrentListForARM) { std::unique_ptr<GpuDriverBugList> list = GpuDriverBugList::Create(); GPUInfo gpu_info; @@ -35,6 +36,7 @@ GpuControlList::kOsAndroid, "4.1", gpu_info); EXPECT_EQ(1u, bugs.count(USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS)); } +#endif // OS_ANDROID TEST_F(GpuDriverBugListTest, AppendSingleWorkaround) { base::CommandLine command_line(0, NULL);
diff --git a/gpu/config/process_json.py b/gpu/config/process_json.py index 05ec4a2..648fb06 100755 --- a/gpu/config/process_json.py +++ b/gpu/config/process_json.py
@@ -500,7 +500,7 @@ def write_entry(entry, total_feature_set, feature_name_prefix, - data_file, data_helper_file, data_exception_file): + data_file, data_helper_file, data_exception_file): data_file.write('{\n') # ID entry_id = entry['id'] @@ -582,7 +582,7 @@ feature_header_filename, total_features, feature_tag, output_header_filepath, output_data_filepath, output_helper_filepath, output_exception_filepath, path, - export_tag, git_format): + export_tag, git_format, os_filter): output_header_filename = os.path.basename(output_header_filepath) output_helper_filename = os.path.basename(output_helper_filepath) output_exception_filename = os.path.basename(output_exception_filepath) @@ -611,20 +611,22 @@ data_file.write('namespace gpu {\n\n') data_file.write('const char k%sVersion[] = "%s";\n\n' % (list_tag, json_data['version'])) - entry_count = len(json_data['entries']) - data_file.write('const size_t k%sEntryCount = %d;\n' % - (list_tag, entry_count)) - data_file.write('const GpuControlList::Entry k%sEntries[%d] = {\n' % - (list_tag, entry_count)) + data_file.write('const GpuControlList::Entry k%sEntries[] = {\n' % list_tag) ids = [] - for index in range(entry_count): + entry_count = 0 + for index in range(len(json_data['entries'])): entry = json_data['entries'][index] entry_id = entry['id'] assert entry_id not in ids ids.append(entry_id) + if os_filter != None and 'os' in entry and entry['os']['type'] != os_filter: + continue + entry_count += 1 write_entry(entry, total_features, feature_tag, data_file, data_helper_file, data_exception_file) data_file.write('};\n') + data_file.write('const size_t k%sEntryCount = %d;\n' % + (list_tag, entry_count)) data_file.write('} // namespace gpu\n') data_file.close() data_helper_file.write('} // namespace gpu\n') @@ -658,7 +660,7 @@ output_helper_filepath, output_exception_filepath]) -def process_software_rendering_list(script_dir, output_dir): +def process_software_rendering_list(script_dir, output_dir, os_filter): total_features = load_software_rendering_list_features( os.path.join(script_dir, 'gpu_feature_type.h')) process_json_file( @@ -674,10 +676,11 @@ os.path.join(output_dir, 'software_rendering_list_exceptions_autogen.h'), 'gpu/config', 'GPU_EXPORT ', - False) + False, + os_filter) -def process_gpu_driver_bug_list(script_dir, output_dir): +def process_gpu_driver_bug_list(script_dir, output_dir, os_filter): total_features = load_gpu_driver_bug_workarounds( os.path.join(script_dir, 'gpu_driver_bug_workaround_type.h')) process_json_file( @@ -693,7 +696,8 @@ os.path.join(output_dir, 'gpu_driver_bug_list_exceptions_autogen.h'), 'gpu/config', 'GPU_EXPORT ', - False) + False, + os_filter) def process_gpu_control_list_testing(script_dir, output_dir): @@ -711,7 +715,8 @@ os.path.join(output_dir, 'gpu_control_list_testing_exceptions_autogen.h'), 'gpu/config', '', - True) + True, + None) def process_gpu_data_manager_testing(script_dir, output_dir): @@ -730,7 +735,8 @@ os.path.join(output_dir, 'gpu_data_manager_testing_exceptions_autogen.h'), 'content/browser/gpu', '', - True) + True, + None) def write_test_entry_enums(input_json_filepath, output_entry_enums_filepath, @@ -771,13 +777,17 @@ parser.add_option("--skip-testing-data", action="store_false", dest="generate_testing_data", default=True, help="skip testing data generation.") + parser.add_option("--os-filter", + help="only output entries applied to the specified os.") (options, args) = parser.parse_args(args=argv) script_dir = os.path.dirname(os.path.realpath(__file__)) if options.output_dir != None: - process_software_rendering_list(script_dir, options.output_dir) - process_gpu_driver_bug_list(script_dir, options.output_dir) + process_software_rendering_list( + script_dir, options.output_dir, options.os_filter) + process_gpu_driver_bug_list( + script_dir, options.output_dir, options.os_filter) if options.generate_testing_data: # Testing data files are generated by calling the script manually.
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json index 43709fe..f3e6a67 100644 --- a/gpu/config/software_rendering_list.json +++ b/gpu/config/software_rendering_list.json
@@ -1497,7 +1497,6 @@ } ], "comment": [ - "Please update the version number on top whenever you change this file", - "Please run gpu/config/process_json.py whenever you change this file" + "Please update the version number on top whenever you change this file" ] }
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index e79fa22..23a0d1d 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -15,8 +15,8 @@ "ios_chrome_metrics_services_manager_client.mm", "ios_chrome_origins_seen_service_factory.cc", "ios_chrome_origins_seen_service_factory.h", - "ios_chrome_stability_metrics_provider.cc", "ios_chrome_stability_metrics_provider.h", + "ios_chrome_stability_metrics_provider.mm", "mobile_session_shutdown_metrics_provider.h", "mobile_session_shutdown_metrics_provider.mm", "previous_session_info.h",
diff --git a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h index 155e59f8..9389c0a 100644 --- a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h +++ b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
@@ -29,6 +29,7 @@ // web::GlobalWebStateObserver: void WebStateDidStartLoading(web::WebState* web_state) override; + void RenderProcessGone(web::WebState* web_state) override; // Records a renderer process crash. void LogRendererCrash();
diff --git a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.cc b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.mm similarity index 82% rename from ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.cc rename to ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.mm index c7c22b0..09db12b5 100644 --- a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.cc +++ b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.mm
@@ -4,6 +4,8 @@ #include "ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h" +#import "ios/web/public/web_state/web_state.h" + IOSChromeStabilityMetricsProvider::IOSChromeStabilityMetricsProvider( PrefService* local_state) : helper_(local_state), recording_enabled_(false) {} @@ -47,3 +49,12 @@ helper_.LogLoadStarted(); } + +void IOSChromeStabilityMetricsProvider::RenderProcessGone( + web::WebState* web_state) { + if (!recording_enabled_) + return; + LogRendererCrash(); + // TODO(crbug.com/685649): web_state->GetLastCommittedURL() is likely the URL + // that caused a renderer crash and can be logged here. +}
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h index 8c87b026..bd4b5aa 100644 --- a/ios/chrome/browser/tabs/tab.h +++ b/ios/chrome/browser/tabs/tab.h
@@ -106,6 +106,12 @@ // Do not add new calls to this method. @property(nonatomic, readonly) const GURL& url; +// Returns the URL of the last committed NavigationItem for this Tab. +@property(nonatomic, readonly) const GURL& lastCommittedURL; + +// Returns the URL of the visible NavigationItem for this Tab. +@property(nonatomic, readonly) const GURL& visibleURL; + // The Passkit Dialog provider used to show the UI to download a passkit object. @property(nonatomic, assign) id<PassKitDialogProvider> passKitDialogProvider;
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 7fa0dbb..f6f011d 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -631,7 +631,17 @@ - (const GURL&)url { // See note in header; this method should be removed. web::NavigationItem* item = - [[self navigationManagerImpl]->GetSessionController() currentItem]; + [self navigationManagerImpl]->GetSessionController().currentItem; + return item ? item->GetVirtualURL() : GURL::EmptyGURL(); +} + +- (const GURL&)lastCommittedURL { + web::NavigationItem* item = self.navigationManager->GetLastCommittedItem(); + return item ? item->GetVirtualURL() : GURL::EmptyGURL(); +} + +- (const GURL&)visibleURL { + web::NavigationItem* item = self.navigationManager->GetVisibleItem(); return item ? item->GetVirtualURL() : GURL::EmptyGURL(); } @@ -1367,9 +1377,6 @@ } - (void)reloadWithUserAgentType:(web::UserAgentType)userAgentType { - // This removes the web view, which will be recreated at the end of this. - [self.webController requirePageReconstruction]; - // TODO(crbug.com/228171): A hack in session_controller -addPendingItem // discusses making tab responsible for distinguishing history stack // navigation from new navigations. @@ -1805,11 +1812,6 @@ UIApplicationState state = [UIApplication sharedApplication].applicationState; BOOL applicationIsNotActive = IsApplicationStateNotActive(state); if (browserState_ && !browserState_->IsOffTheRecord()) { - // Report the crash. - GetApplicationContext() - ->GetMetricsServicesManager() - ->OnRendererProcessCrash(); - // Log the tab state for the termination. RendererTerminationTabState tab_state = visible_ ? RendererTerminationTabState::FOREGROUND_TAB_FOREGROUND_APP
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index b770627..0b227410 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -191,14 +191,6 @@ // Dismisses the soft keyboard. - (void)dismissKeyboard; -// Requires that the next load rebuild the UIWebView. This is expensive, and -// should be used only in the case where something has changed that UIWebView -// only checks on creation, such that the whole object needs to be rebuilt. -// TODO(stuartmorgan): Merge this and reinitializeWebViewAndReload:. They are -// currently subtly different in terms of implementation, but are for -// fundamentally the same purpose. -- (void)requirePageReconstruction; - - (void)reinitializeWebViewAndReload:(BOOL)reload; // Requires that the next display reload the page, using a placeholder while
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index ddd1677..a11db2c 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -135,6 +135,23 @@ // Key of UMA IOSFix.ViewportZoomBugCount histogram. const char kUMAViewportZoomBugCount[] = "Renderer.ViewportZoomBugCount"; +// Key of the UMA Navigation.IOSWKWebViewSlowFastBackForward histogram. +const char kUMAWKWebViewSlowFastBackForwardNavigationKey[] = + "Navigation.IOSWKWebViewSlowFastBackForward"; + +// Values for the histogram that counts slow/fast back/forward navigations. +enum class BackForwardNavigationType { + // Fast back navigation through WKWebView back-forward list. + FAST_BACK = 0, + // Slow back navigation when back-forward list navigation is not possible. + SLOW_BACK = 1, + // Fast forward navigation through WKWebView back-forward list. + FAST_FORWARD = 2, + // Slow forward navigation when back-forward list navigation is not possible. + SLOW_FORWARD = 3, + BACK_FORWARD_NAVIGATION_TYPE_COUNT +}; + // URL scheme for messages sent from javascript for asynchronous processing. NSString* const kScriptMessageName = @"crwebinvoke"; @@ -459,8 +476,10 @@ // Returns YES if the user interacted with the page recently. @property(nonatomic, readonly) BOOL userClickedRecently; -// Whether or not desktop user agent is used for the currentItem. -@property(nonatomic, readonly) BOOL usesDesktopUserAgent; +// User agent type of the transient item if any, the pending item if a +// navigation is in progress or the last committed item otherwise. +// Returns MOBILE, the default type, if navigation manager is nullptr or empty. +@property(nonatomic, readonly) web::UserAgentType userAgentType; // Facade for Mojo API. @property(nonatomic, readonly) web::MojoFacade* mojoFacade; @@ -477,10 +496,18 @@ // unless the request was a POST. @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; -// Requires page reconstruction if |item| has a non-NONE UserAgentType and it -// differs from that of |fromItem|. -- (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item - previousUserAgentType:(web::UserAgentType)userAgentType; +// Updates web view's user agent according to |userAgentType|. It is no-op if +// |userAgentType| is NONE. +- (void)updateWebViewUserAgentFromUserAgentType: + (web::UserAgentType)userAgentType; + +// Requires that the next load rebuild the web view. This is expensive, and +// should be used only in the case where something has changed that web view +// only checks on creation, such that the whole object needs to be rebuilt. +// TODO(stuartmorgan): Merge this and reinitializeWebViewAndReload:. They are +// currently subtly different in terms of implementation, but are for +// fundamentally the same purpose. +- (void)requirePageReconstruction; // Removes the container view from the hierarchy and resets the ivar. - (void)resetContainerView; @@ -786,6 +813,9 @@ // web view, or use native web view navigation where possible (for example, // going back and forward through the history stack). - (void)loadRequestForCurrentNavigationItem; +// Reports Navigation.IOSWKWebViewSlowFastBackForward UMA. No-op if pending +// navigation is not back forward navigation. +- (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast; // Handlers for JavaScript messages. |message| contains a JavaScript command and // data relevant to the message, and |context| contains contextual information @@ -1616,6 +1646,13 @@ [self ensureWebViewCreated]; + // Update web view's user agent is called for every load, which may have + // performance implications because update web view's user agent may + // potentially send a message to a separate thread. However, this is not an + // issue for WKWebView because WKWebView's |setCustomUserAgent| is non-op if + // user agent stays thesame. + [self updateWebViewUserAgentFromUserAgentType:self.userAgentType]; + [self loadRequestForCurrentNavigationItem]; } @@ -2026,15 +2063,11 @@ // Update the user agent before attempting the navigation. web::NavigationItem* toItem = items[index].get(); - web::NavigationItem* previousItem = sessionController.currentItem; - web::UserAgentType previousUserAgentType = - previousItem ? previousItem->GetUserAgentType() - : web::UserAgentType::NONE; - [self updateDesktopUserAgentForItem:toItem - previousUserAgentType:previousUserAgentType]; + [self updateWebViewUserAgentFromUserAgentType:toItem->GetUserAgentType()]; + web::NavigationItem* fromItem = sessionController.currentItem; BOOL sameDocumentNavigation = - [sessionController isSameDocumentNavigationBetweenItem:previousItem + [sessionController isSameDocumentNavigationBetweenItem:fromItem andItem:toItem]; if (sameDocumentNavigation) { [sessionController goToItemAtIndex:index]; @@ -2189,9 +2222,9 @@ return rendererInitiatedWithoutInteraction || noNavigationItems; } -- (BOOL)usesDesktopUserAgent { +- (web::UserAgentType)userAgentType { web::NavigationItem* item = self.currentNavItem; - return item && item->GetUserAgentType() == web::UserAgentType::DESKTOP; + return item ? item->GetUserAgentType() : web::UserAgentType::MOBILE; } - (web::MojoFacade*)mojoFacade { @@ -2230,15 +2263,14 @@ return _passKitDownloader.get(); } -- (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item - previousUserAgentType:(web::UserAgentType)userAgentType { - if (!item) +- (void)updateWebViewUserAgentFromUserAgentType: + (web::UserAgentType)userAgentType { + if (userAgentType == web::UserAgentType::NONE) return; - web::UserAgentType itemUserAgentType = item->GetUserAgentType(); - if (itemUserAgentType == web::UserAgentType::NONE) - return; - if (itemUserAgentType != userAgentType) - [self requirePageReconstruction]; + + NSString* userAgent = + base::SysUTF8ToNSString(web::GetWebClient()->GetUserAgent(userAgentType)); + [_webView setCustomUserAgent:userAgent]; } #pragma mark - @@ -4035,7 +4067,7 @@ // delegate must be specified. return web::BuildWKWebView(CGRectZero, config, self.webStateImpl->GetBrowserState(), - self.usesDesktopUserAgent); + self.userAgentType); } - (void)setWebView:(WKWebView*)webView { @@ -4939,6 +4971,7 @@ referrer:self.currentNavItemReferrer transition:self.currentTransition]; [self loadRequest:request]; + [self reportBackForwardNavigationTypeForFastNavigation:NO]; }; // When navigating via WKBackForwardListItem to pages created or updated by @@ -4985,6 +5018,7 @@ [_webView goToBackForwardListItem:holder->back_forward_list_item()]; [_navigationStates setState:web::WKNavigationState::REQUESTED forNavigation:navigation]; + [self reportBackForwardNavigationTypeForFastNavigation:YES]; } }; @@ -5008,6 +5042,30 @@ })); } +- (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast { + // TODO(crbug.com/665189): Use NavigationManager::GetPendingItemIndex() once + // it returns correct result. + int pendingIndex = self.sessionController.pendingItemIndex; + if (pendingIndex == -1) { + // Pending navigation is not a back forward navigation. + return; + } + + BOOL isBack = pendingIndex < self.sessionController.lastCommittedItemIndex; + BackForwardNavigationType type = BackForwardNavigationType::FAST_BACK; + if (isBack) { + type = isFast ? BackForwardNavigationType::FAST_BACK + : BackForwardNavigationType::SLOW_BACK; + } else { + type = isFast ? BackForwardNavigationType::FAST_FORWARD + : BackForwardNavigationType::SLOW_FORWARD; + } + + UMA_HISTOGRAM_ENUMERATION( + kUMAWKWebViewSlowFastBackForwardNavigationKey, type, + BackForwardNavigationType::BACK_FORWARD_NAVIGATION_TYPE_COUNT); +} + #pragma mark - #pragma mark Testing-Only Methods
diff --git a/ios/web/web_state/web_view_internal_creation_util.h b/ios/web/web_state/web_view_internal_creation_util.h index 68e8912..38226bf 100644 --- a/ios/web/web_state/web_view_internal_creation_util.h +++ b/ios/web/web_state/web_view_internal_creation_util.h
@@ -8,6 +8,8 @@ #import <CoreGraphics/CoreGraphics.h> #import <WebKit/WebKit.h> +#include "ios/web/public/user_agent.h" + @protocol CRWContextMenuDelegate; // This file is a collection of functions that vend web views. @@ -26,7 +28,7 @@ WKWebView* BuildWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - BOOL use_desktop_user_agent, + UserAgentType user_agent_type, id<CRWContextMenuDelegate> context_menu_delegate); // Creates and returns a new WKWebView for displaying regular web content. @@ -35,7 +37,7 @@ WKWebView* BuildWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - BOOL use_desktop_user_agent); + UserAgentType user_agent_type); // Creates and returns a new WKWebView for displaying regular web content. // The preconditions for the creation of a WKWebView are the same as the
diff --git a/ios/web/web_state/web_view_internal_creation_util.mm b/ios/web/web_state/web_view_internal_creation_util.mm index c13b8b7..7c9fc45 100644 --- a/ios/web/web_state/web_view_internal_creation_util.mm +++ b/ios/web/web_state/web_view_internal_creation_util.mm
@@ -36,7 +36,7 @@ WKWebView* BuildWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - BOOL use_desktop_user_agent, + UserAgentType user_agent_type, id<CRWContextMenuDelegate> context_menu_delegate) { VerifyWKWebViewCreationPreConditions(browser_state, configuration); @@ -44,9 +44,6 @@ WKWebView* web_view = [[WKWebView alloc] initWithFrame:frame configuration:configuration]; - // Set the user agent. - UserAgentType user_agent_type = - use_desktop_user_agent ? UserAgentType::DESKTOP : UserAgentType::MOBILE; web_view.customUserAgent = base::SysUTF8ToNSString( web::GetWebClient()->GetUserAgent(user_agent_type)); @@ -77,17 +74,16 @@ WKWebView* BuildWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - BOOL use_desktop_user_agent) { - return BuildWKWebView(frame, configuration, browser_state, - use_desktop_user_agent, nil); + UserAgentType user_agent_type) { + return BuildWKWebView(frame, configuration, browser_state, user_agent_type, + nil); } WKWebView* BuildWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state) { - BOOL use_desktop_user_agent = NO; return BuildWKWebView(frame, configuration, browser_state, - use_desktop_user_agent); + UserAgentType::MOBILE); } } // namespace web
diff --git a/ios/web/web_view_creation_util.mm b/ios/web/web_view_creation_util.mm index d3023e06..0edd5c4 100644 --- a/ios/web/web_view_creation_util.mm +++ b/ios/web/web_view_creation_util.mm
@@ -5,6 +5,7 @@ #import "ios/web/public/web_view_creation_util.h" #include "base/logging.h" +#include "ios/web/public/user_agent.h" #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" #import "ios/web/web_state/web_view_internal_creation_util.h" @@ -27,7 +28,8 @@ WKWebViewConfigurationProvider& config_provider = WKWebViewConfigurationProvider::FromBrowserState(browser_state); return BuildWKWebView(frame, config_provider.GetWebViewConfiguration(), - browser_state, NO, context_menu_delegate); + browser_state, UserAgentType::MOBILE, + context_menu_delegate); } } // namespace web
diff --git a/media/blink/watch_time_reporter.cc b/media/blink/watch_time_reporter.cc index f279e9c..b0127d7 100644 --- a/media/blink/watch_time_reporter.cc +++ b/media/blink/watch_time_reporter.cc
@@ -162,6 +162,11 @@ MaybeFinalizeWatchTime(FinalizeTime::ON_NEXT_UPDATE); } +bool WatchTimeReporter::IsSizeLargeEnoughToReportWatchTime() const { + return initial_video_size_.height() >= kMinimumVideoSize.height() && + initial_video_size_.width() >= kMinimumVideoSize.width(); +} + void WatchTimeReporter::OnPowerStateChange(bool on_battery_power) { if (!reporting_timer_.IsRunning()) return; @@ -184,9 +189,7 @@ // Report listen time or watch time only for tracks that are audio-only or // have both an audio and video track of sufficient size. return (!has_video_ && has_audio_) || - (has_video_ && has_audio_ && - initial_video_size_.height() >= kMinimumVideoSize.height() && - initial_video_size_.width() >= kMinimumVideoSize.width()); + (has_video_ && has_audio_ && IsSizeLargeEnoughToReportWatchTime()); } void WatchTimeReporter::MaybeStartReportingTimer(
diff --git a/media/blink/watch_time_reporter.h b/media/blink/watch_time_reporter.h index 8290bdc..9b3b93b 100644 --- a/media/blink/watch_time_reporter.h +++ b/media/blink/watch_time_reporter.h
@@ -103,6 +103,10 @@ void OnShown(); void OnHidden(); + // Returns true if the current size is large enough that watch time will be + // recorded for playback. + bool IsSizeLargeEnoughToReportWatchTime() const; + // Setup the reporting interval to be immediate to avoid spinning real time // within the unit test. void set_reporting_interval_for_testing() {
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc index 3bdad7a2..2aa2635a 100644 --- a/media/blink/watch_time_reporter_unittest.cc +++ b/media/blink/watch_time_reporter_unittest.cc
@@ -279,39 +279,48 @@ Initialize(!has_video_, true, true, gfx::Size()); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, true, true, gfx::Size()); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); constexpr gfx::Size kSizeTooSmall = gfx::Size(100, 100); Initialize(!has_video_, true, true, kSizeTooSmall); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, true, true, kSizeJustRight); wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); + EXPECT_TRUE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, false, false, kSizeJustRight); wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); + EXPECT_TRUE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, true, false, kSizeJustRight); wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); + EXPECT_TRUE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, true, true, gfx::Size()); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, false, false, gfx::Size()); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); Initialize(true, true, false, gfx::Size()); wtr_->OnPlaying(); EXPECT_EQ(!has_video_, IsMonitoring()); + EXPECT_FALSE(wtr_->IsSizeLargeEnoughToReportWatchTime()); if (!has_video_) EXPECT_WATCH_TIME_FINALIZED();
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 20796d3..172541b 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1421,13 +1421,13 @@ if (overlay_enabled_ && surface_manager_) surface_manager_->NaturalSizeChanged(rotated_size); - gfx::Size old_size = pipeline_metadata_.natural_size; pipeline_metadata_.natural_size = rotated_size; - if (old_size.IsEmpty()) { - // WatchTimeReporter doesn't report metrics for empty videos. Re-create - // |watch_time_reporter_| if we didn't originally know the video size. + + // Re-create |watch_time_reporter_| if we didn't originally know the video + // size or the previous size was too small for reporting. + if (!watch_time_reporter_->IsSizeLargeEnoughToReportWatchTime()) CreateWatchTimeReporter(); - } + client_->SizeChanged(); if (observer_)
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc index 773b09e5..a3a358a 100644 --- a/media/gpu/android_video_decode_accelerator.cc +++ b/media/gpu/android_video_decode_accelerator.cc
@@ -114,8 +114,7 @@ VideoCodec codec) { return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && codec_allocator->IsAnyRegisteredAVDA() && - (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || - base::SysInfo::IsLowEndDevice()); + base::android::BuildInfo::GetInstance()->sdk_int() <= 18; } } // namespace
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 361156b..162255b2 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -164,7 +164,7 @@ enable_token_binding(false), http_09_on_non_default_ports_enabled(false), restrict_to_one_preconnect_for_proxies(false) { - quic_supported_versions.push_back(QUIC_VERSION_35); + quic_supported_versions.push_back(QUIC_VERSION_37); } HttpNetworkSession::Params::Params(const Params& other) = default;
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index ff94a6de..3bc6c3af 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -437,6 +437,7 @@ case CONNECTION_INFO_QUIC_36: case CONNECTION_INFO_QUIC_37: case CONNECTION_INFO_QUIC_38: + case CONNECTION_INFO_QUIC_39: return true; case NUM_OF_CONNECTION_INFOS: NOTREACHED(); @@ -483,6 +484,8 @@ return "http/2+quic/37"; case CONNECTION_INFO_QUIC_38: return "http/2+quic/38"; + case CONNECTION_INFO_QUIC_39: + return "http/2+quic/39"; case CONNECTION_INFO_HTTP0_9: return "http/0.9"; case CONNECTION_INFO_HTTP1_0:
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index 22b3d07..89366f4 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -50,6 +50,7 @@ CONNECTION_INFO_QUIC_36 = 14, CONNECTION_INFO_QUIC_37 = 15, CONNECTION_INFO_QUIC_38 = 16, + CONNECTION_INFO_QUIC_39 = 17, NUM_OF_CONNECTION_INFOS, };
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 9c38e69..111ebaf 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -376,6 +376,10 @@ for (const auto& job_controller : job_controller_set_) { DCHECK(job_controller->HasPendingAltJob() || job_controller->HasPendingMainJob()); + // Additionally logs the states of the jobs if there are at least 500 + // controllers, which suggests that there might be a leak. + if (job_controller_set_.size() >= 500) + job_controller->LogHistograms(); // For a preconnect controller, it should have exactly the main job. if (job_controller->is_preconnect()) { preconnect_controller_count++;
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 398f84e1..1c12a9e7 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -208,6 +208,7 @@ io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), connection_(new ClientSocketHandle), session_(session), + state_(STATE_NONE), next_state_(STATE_NONE), pac_request_(NULL), destination_(destination), @@ -383,6 +384,20 @@ return proxy_info_; } +void HttpStreamFactoryImpl::Job::LogHistograms() const { + if (job_type_ == MAIN) { + UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.NextState", + next_state_, STATE_MAX); + UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.State", state_, + STATE_MAX); + } else if (job_type_ == ALTERNATIVE) { + UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.NextState", + next_state_, STATE_MAX); + UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.State", state_, + STATE_MAX); + } +} + void HttpStreamFactoryImpl::Job::GetSSLInfo() { DCHECK(using_ssl_); DCHECK(!establishing_tunnel_); @@ -659,6 +674,8 @@ int rv = result; do { State state = next_state_; + // Added to investigate crbug.com/711721. + state_ = state; next_state_ = STATE_NONE; switch (state) { case STATE_START:
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index f73587a..b1c2b66 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h
@@ -251,6 +251,10 @@ return using_existing_quic_session_; } + // TODO(xunjieli): Added to investigate crbug.com/711721. Remove when no + // longer needed. + void LogHistograms() const; + private: friend class HttpStreamFactoryImplJobPeer; @@ -285,7 +289,9 @@ STATE_DRAIN_BODY_FOR_AUTH_RESTART, STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE, STATE_DONE, - STATE_NONE + STATE_NONE, + // Used for UMA. + STATE_MAX, }; void OnStreamReadyCallback(); @@ -405,6 +411,10 @@ CompletionCallback io_callback_; std::unique_ptr<ClientSocketHandle> connection_; HttpNetworkSession* const session_; + + // |state_| is only used for LogHistograms(). + State state_; + State next_state_; ProxyService::PacRequest* pac_request_; SSLInfo ssl_info_;
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index ec382771..0bbca3c 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -681,6 +681,13 @@ return alternative_job_.get() != nullptr; } +void HttpStreamFactoryImpl::JobController::LogHistograms() const { + if (main_job_) + main_job_->LogHistograms(); + if (alternative_job_) + alternative_job_->LogHistograms(); +} + size_t HttpStreamFactoryImpl::JobController::EstimateMemoryUsage() const { return base::trace_event::EstimateMemoryUsage(main_job_) + base::trace_event::EstimateMemoryUsage(alternative_job_);
diff --git a/net/http/http_stream_factory_impl_job_controller.h b/net/http/http_stream_factory_impl_job_controller.h index 9a43bfb..8aaaaad 100644 --- a/net/http/http_stream_factory_impl_job_controller.h +++ b/net/http/http_stream_factory_impl_job_controller.h
@@ -178,6 +178,10 @@ // Returns true if |this| has a pending alternative job that is not completed. bool HasPendingAltJob() const; + // TODO(xunjieli): Added to investigate crbug.com/711721. Remove when no + // longer needed. + void LogHistograms() const; + // Returns the estimated memory usage in bytes. size_t EstimateMemoryUsage() const;
diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc index b634dea..56672ba5 100644 --- a/net/quic/chromium/quic_http_stream.cc +++ b/net/quic/chromium/quic_http_stream.cc
@@ -151,6 +151,8 @@ return HttpResponseInfo::CONNECTION_INFO_QUIC_37; case QUIC_VERSION_38: return HttpResponseInfo::CONNECTION_INFO_QUIC_38; + case QUIC_VERSION_39: + return HttpResponseInfo::CONNECTION_INFO_QUIC_39; } NOTREACHED(); return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION;
diff --git a/net/quic/core/congestion_control/bbr_sender_test.cc b/net/quic/core/congestion_control/bbr_sender_test.cc index 4480504..b0813e0 100644 --- a/net/quic/core/congestion_control/bbr_sender_test.cc +++ b/net/quic/core/congestion_control/bbr_sender_test.cc
@@ -82,12 +82,12 @@ "Receiver", "BBR sender", Perspective::IS_SERVER, - /*connection_id=*/42), + /*connection_id=*/GetPeerInMemoryConnectionId(42)), competing_receiver_(&simulator_, "Competing receiver", "Competing sender", Perspective::IS_SERVER, - /*connection_id=*/43), + /*connection_id=*/GetPeerInMemoryConnectionId(43)), receiver_multiplexer_("Receiver multiplexer", {&receiver_, &competing_receiver_}) { rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
diff --git a/net/quic/core/congestion_control/general_loss_algorithm.cc b/net/quic/core/congestion_control/general_loss_algorithm.cc index 722134c0..97f0c98 100644 --- a/net/quic/core/congestion_control/general_loss_algorithm.cc +++ b/net/quic/core/congestion_control/general_loss_algorithm.cc
@@ -8,6 +8,7 @@ #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packets.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_flag_utils.h" namespace net { @@ -134,10 +135,6 @@ if (loss_type_ != kAdaptiveTime || reordering_shift_ == 0) { return; } - if (spurious_retransmission <= largest_sent_on_spurious_retransmit_) { - return; - } - largest_sent_on_spurious_retransmit_ = unacked_packets.largest_sent_packet(); // Calculate the extra time needed so this wouldn't have been declared lost. // Extra time needed is based on how long it's been since the spurious // retransmission was sent, because the SRTT and latest RTT may have changed. @@ -147,6 +144,19 @@ // Increase the reordering fraction until enough time would be allowed. QuicTime::Delta max_rtt = std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt()); + if (FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fix_adaptive_time_loss); + while ((max_rtt >> reordering_shift_) <= extra_time_needed && + reordering_shift_ > 0) { + --reordering_shift_; + } + return; + } + + if (spurious_retransmission <= largest_sent_on_spurious_retransmit_) { + return; + } + largest_sent_on_spurious_retransmit_ = unacked_packets.largest_sent_packet(); QuicTime::Delta proposed_extra_time(QuicTime::Delta::Zero()); do { proposed_extra_time = max_rtt >> reordering_shift_;
diff --git a/net/quic/core/congestion_control/general_loss_algorithm.h b/net/quic/core/congestion_control/general_loss_algorithm.h index d2557e56..281a139 100644 --- a/net/quic/core/congestion_control/general_loss_algorithm.h +++ b/net/quic/core/congestion_control/general_loss_algorithm.h
@@ -59,6 +59,8 @@ QuicTime loss_detection_timeout_; // Largest sent packet when a spurious retransmit is detected. // Prevents increasing the reordering threshold multiple times per epoch. + // TODO(ianswett): Deprecate when + // quic_reloadable_flag_quic_fix_adaptive_time_loss is deprecated. QuicPacketNumber largest_sent_on_spurious_retransmit_; LossDetectionType loss_type_; // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring
diff --git a/net/quic/core/congestion_control/general_loss_algorithm_test.cc b/net/quic/core/congestion_control/general_loss_algorithm_test.cc index 6fa96d7..1bfb2d9 100644 --- a/net/quic/core/congestion_control/general_loss_algorithm_test.cc +++ b/net/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -50,16 +50,15 @@ } void VerifyLosses(QuicPacketNumber largest_newly_acked, - QuicPacketNumber* losses_expected, - size_t num_losses) { + const std::vector<QuicPacketNumber>& losses_expected) { if (largest_newly_acked > unacked_packets_.largest_observed()) { unacked_packets_.IncreaseLargestObserved(largest_newly_acked); } SendAlgorithmInterface::CongestionVector lost_packets; loss_algorithm_.DetectLosses(unacked_packets_, clock_.Now(), rtt_stats_, largest_newly_acked, &lost_packets); - EXPECT_EQ(num_losses, lost_packets.size()); - for (size_t i = 0; i < num_losses; ++i) { + ASSERT_EQ(losses_expected.size(), lost_packets.size()); + for (size_t i = 0; i < losses_expected.size(); ++i) { EXPECT_EQ(lost_packets[i].first, losses_expected[i]); } } @@ -79,14 +78,13 @@ } // No loss on one ack. unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); // No loss on two acks. unacked_packets_.RemoveFromInFlight(3); - VerifyLosses(3, nullptr, 0); + VerifyLosses(3, std::vector<QuicPacketNumber>{}); // Loss on three acks. unacked_packets_.RemoveFromInFlight(4); - QuicPacketNumber lost[] = {1}; - VerifyLosses(4, lost, arraysize(lost)); + VerifyLosses(4, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -103,8 +101,7 @@ unacked_packets_.RemoveFromInFlight(2); unacked_packets_.RemoveFromInFlight(3); unacked_packets_.RemoveFromInFlight(4); - QuicPacketNumber lost[] = {1}; - VerifyLosses(4, lost, arraysize(lost)); + VerifyLosses(4, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -118,8 +115,7 @@ // Nack the first packet 3 times in an AckFrame with three missing packets. unacked_packets_.RemoveFromInFlight(4); - QuicPacketNumber lost[] = {1}; - VerifyLosses(4, lost, arraysize(lost)); + VerifyLosses(4, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -131,13 +127,12 @@ } // Early retransmit when the final packet gets acked and the first is nacked. unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout()); clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt()); - QuicPacketNumber lost[] = {1}; - VerifyLosses(2, lost, arraysize(lost)); + VerifyLosses(2, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -155,21 +150,18 @@ // elapsed since the packets were sent. unacked_packets_.RemoveFromInFlight(kNumSentPackets); // This simulates a single ack following multiple missing packets with FACK. - QuicPacketNumber lost[] = {1, 2}; - VerifyLosses(kNumSentPackets, lost, arraysize(lost)); + VerifyLosses(kNumSentPackets, {1, 2}); // The time has already advanced 1/4 an RTT, so ensure the timeout is set // 1.25 RTTs after the earliest pending packet(3), not the last(4). EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout()); clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); - QuicPacketNumber lost2[] = {1, 2, 3}; - VerifyLosses(kNumSentPackets, lost2, arraysize(lost2)); + VerifyLosses(kNumSentPackets, {1, 2, 3}); EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout()); clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt()); - QuicPacketNumber lost3[] = {1, 2, 3, 4}; - VerifyLosses(kNumSentPackets, lost3, arraysize(lost3)); + VerifyLosses(kNumSentPackets, {1, 2, 3, 4}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -185,7 +177,7 @@ // Early retransmit when the final packet gets acked and the first is nacked. unacked_packets_.IncreaseLargestObserved(2); unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -199,14 +191,13 @@ // Early retransmit when the final packet gets acked and the first is nacked. unacked_packets_.IncreaseLargestObserved(2); unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout()); // The packet should be lost once the loss timeout is reached. clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt()); - QuicPacketNumber lost[] = {1}; - VerifyLosses(2, lost, arraysize(lost)); + VerifyLosses(2, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -224,8 +215,7 @@ clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); unacked_packets_.IncreaseLargestObserved(2); unacked_packets_.RemoveFromInFlight(2); - QuicPacketNumber lost[] = {1}; - VerifyLosses(2, lost, arraysize(lost)); + VerifyLosses(2, {1}); } // NoFack loss detection tests. @@ -238,14 +228,13 @@ } // No loss on one ack. unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); // No loss on two acks. unacked_packets_.RemoveFromInFlight(3); - VerifyLosses(3, nullptr, 0); + VerifyLosses(3, std::vector<QuicPacketNumber>{}); // Loss on three acks. unacked_packets_.RemoveFromInFlight(4); - QuicPacketNumber lost[] = {1}; - VerifyLosses(4, lost, arraysize(lost)); + VerifyLosses(4, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -264,13 +253,12 @@ unacked_packets_.RemoveFromInFlight(2); unacked_packets_.RemoveFromInFlight(3); unacked_packets_.RemoveFromInFlight(4); - VerifyLosses(4, nullptr, 0); + VerifyLosses(4, std::vector<QuicPacketNumber>{}); // The timer isn't set because we expect more acks. EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // Process another ack and then packet 1 will be lost. unacked_packets_.RemoveFromInFlight(5); - QuicPacketNumber lost[] = {1}; - VerifyLosses(5, lost, arraysize(lost)); + VerifyLosses(5, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -285,13 +273,12 @@ // Nack the first packet 3 times in an AckFrame with three missing packets. unacked_packets_.RemoveFromInFlight(4); - VerifyLosses(4, nullptr, 0); + VerifyLosses(4, std::vector<QuicPacketNumber>{}); // The timer isn't set because we expect more acks. EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // Process another ack and then packet 1 and 2 will be lost. unacked_packets_.RemoveFromInFlight(5); - QuicPacketNumber lost[] = {1, 2}; - VerifyLosses(5, lost, arraysize(lost)); + VerifyLosses(5, {1, 2}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -305,7 +292,7 @@ } unacked_packets_.RemoveFromInFlight(2); for (size_t i = 1; i < 500; ++i) { - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); } EXPECT_EQ(1.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout() - clock_.Now()); @@ -323,14 +310,13 @@ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // The packet should not be lost until 1.25 RTTs pass. unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); // Expect the timer to be set to 0.25 RTT's in the future. EXPECT_EQ(0.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout() - clock_.Now()); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt()); - QuicPacketNumber lost[] = {1}; - VerifyLosses(2, lost, arraysize(lost)); + VerifyLosses(2, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -346,13 +332,13 @@ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // The packet should not be lost without a nack. unacked_packets_.RemoveFromInFlight(1); - VerifyLosses(1, nullptr, 0); + VerifyLosses(1, std::vector<QuicPacketNumber>{}); // The timer should still not be set. EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt()); - VerifyLosses(1, nullptr, 0); + VerifyLosses(1, std::vector<QuicPacketNumber>{}); clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); - VerifyLosses(1, nullptr, 0); + VerifyLosses(1, std::vector<QuicPacketNumber>{}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -369,13 +355,12 @@ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // The packet should not be lost until 1.25 RTTs pass. unacked_packets_.RemoveFromInFlight(10); - VerifyLosses(10, nullptr, 0); + VerifyLosses(10, std::vector<QuicPacketNumber>{}); // Expect the timer to be set to 0.25 RTT's in the future. EXPECT_EQ(0.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout() - clock_.Now()); clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt()); - QuicPacketNumber lost[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - VerifyLosses(10, lost, arraysize(lost)); + VerifyLosses(10, {1, 2, 3, 4, 5, 6, 7, 8, 9}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } @@ -392,7 +377,7 @@ // The packet should not be lost until 1.25 RTTs pass. unacked_packets_.RemoveFromInFlight(10); - VerifyLosses(10, nullptr, 0); + VerifyLosses(10, std::vector<QuicPacketNumber>{}); // Expect the timer to be set to 0.25 RTT's in the future. EXPECT_EQ(0.25 * rtt_stats_.smoothed_rtt(), loss_algorithm_.GetLossTimeout() - clock_.Now()); @@ -401,7 +386,7 @@ // are lost. for (QuicPacketNumber i = 1; i <= 9; ++i) { unacked_packets_.RemoveFromInFlight(i); - VerifyLosses(i, nullptr, 0); + VerifyLosses(i, std::vector<QuicPacketNumber>{}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } } @@ -421,14 +406,13 @@ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // Packet 1 should not be lost until 1/16 RTTs pass. unacked_packets_.RemoveFromInFlight(2); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); // Expect the timer to be set to 1/16 RTT's in the future. EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 16), loss_algorithm_.GetLossTimeout() - clock_.Now()); - VerifyLosses(2, nullptr, 0); + VerifyLosses(2, std::vector<QuicPacketNumber>{}); clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 16)); - QuicPacketNumber lost[] = {1}; - VerifyLosses(2, lost, arraysize(lost)); + VerifyLosses(2, {1}); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); // Retransmit packet 1 as 11 and 2 as 12. SendDataPacket(11); @@ -437,6 +421,11 @@ // Advance the time 1/4 RTT and indicate the loss was spurious. // The new threshold should be 1/2 RTT. clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4)); + if (FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss) { + // The flag fixes an issue where adaptive time loss would increase the + // reordering threshold by an extra factor of two. + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); + } loss_algorithm_.SpuriousRetransmitDetected(unacked_packets_, clock_.Now(), rtt_stats_, 11); EXPECT_EQ(1, loss_algorithm_.reordering_shift());
diff --git a/net/quic/core/congestion_control/pacing_sender.cc b/net/quic/core/congestion_control/pacing_sender.cc index 976c408..c645b8a 100644 --- a/net/quic/core/congestion_control/pacing_sender.cc +++ b/net/quic/core/congestion_control/pacing_sender.cc
@@ -109,9 +109,8 @@ return in_flight; } -QuicTime::Delta PacingSender::TimeUntilSend( - QuicTime now, - QuicByteCount bytes_in_flight) const { +QuicTime::Delta PacingSender::TimeUntilSend(QuicTime now, + QuicByteCount bytes_in_flight) { DCHECK(sender_ != nullptr); QuicTime::Delta time_until_send = sender_->TimeUntilSend(now, bytes_in_flight);
diff --git a/net/quic/core/congestion_control/pacing_sender.h b/net/quic/core/congestion_control/pacing_sender.h index b297b8f8..65047210 100644 --- a/net/quic/core/congestion_control/pacing_sender.h +++ b/net/quic/core/congestion_control/pacing_sender.h
@@ -45,13 +45,15 @@ QuicTime event_time, const SendAlgorithmInterface::CongestionVector& acked_packets, const SendAlgorithmInterface::CongestionVector& lost_packets); + bool OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight, QuicPacketNumber packet_number, QuicByteCount bytes, HasRetransmittableData is_retransmittable); - QuicTime::Delta TimeUntilSend(QuicTime now, - QuicByteCount bytes_in_flight) const; + + QuicTime::Delta TimeUntilSend(QuicTime now, QuicByteCount bytes_in_flight); + QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const; private: @@ -65,7 +67,7 @@ // Send time of the last packet considered delayed. QuicTime last_delayed_packet_sent_time_; QuicTime ideal_next_packet_send_time_; // When can the next packet be sent. - mutable bool was_last_send_delayed_; // True when the last send was delayed. + bool was_last_send_delayed_; // True when the last send was delayed. DISALLOW_COPY_AND_ASSIGN(PacingSender); };
diff --git a/net/quic/core/congestion_control/send_algorithm_test.cc b/net/quic/core/congestion_control/send_algorithm_test.cc index 4078944..f9afe7c5 100644 --- a/net/quic/core/congestion_control/send_algorithm_test.cc +++ b/net/quic/core/congestion_control/send_algorithm_test.cc
@@ -217,7 +217,7 @@ "Receiver", "QUIC sender", Perspective::IS_SERVER, - 42) { + net::test::GetPeerInMemoryConnectionId(42)) { rtt_stats_ = quic_sender_.connection()->sent_packet_manager().GetRttStats(); sender_ = SendAlgorithmInterface::Create( simulator_.GetClock(), rtt_stats_,
diff --git a/net/quic/core/crypto/crypto_handshake_message.cc b/net/quic/core/crypto/crypto_handshake_message.cc index 4e03d4e..220c46a 100644 --- a/net/quic/core/crypto/crypto_handshake_message.cc +++ b/net/quic/core/crypto/crypto_handshake_message.cc
@@ -11,6 +11,7 @@ #include "net/quic/core/crypto/crypto_utils.h" #include "net/quic/core/quic_socket_address_coder.h" #include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/platform/api/quic_text_utils.h" @@ -246,6 +247,9 @@ if (it->second.size() == 8) { uint64_t value; memcpy(&value, it->second.data(), sizeof(value)); + if (QuicUtils::IsConnectionIdWireFormatBigEndian(perspective)) { + value = QuicEndian::NetToHost64(value); + } ret += QuicTextUtils::Uint64ToString(value); done = true; }
diff --git a/net/quic/core/crypto/crypto_server_test.cc b/net/quic/core/crypto/crypto_server_test.cc index 85f0752..65cdc12c 100644 --- a/net/quic/core/crypto/crypto_server_test.cc +++ b/net/quic/core/crypto/crypto_server_test.cc
@@ -19,6 +19,7 @@ #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_socket_address_coder.h" #include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_string_piece.h" #include "net/quic/platform/api/quic_text_utils.h" #include "net/quic/test_tools/crypto_test_utils.h" @@ -363,6 +364,11 @@ } else { ASSERT_EQ(QUIC_NO_ERROR, out_.GetUint64(kRCID, &server_designated_connection_id)); + if (QuicUtils::IsConnectionIdWireFormatBigEndian( + Perspective::IS_SERVER)) { + server_designated_connection_id = + QuicEndian::NetToHost64(server_designated_connection_id); + } EXPECT_EQ(rand_for_id_generation_.RandUint64(), server_designated_connection_id); }
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc index 35b44e9..d70f79aa5 100644 --- a/net/quic/core/crypto/quic_crypto_client_config.cc +++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -22,6 +22,7 @@ #include "net/quic/core/crypto/quic_random.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_hostname_utils.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_map_util.h" @@ -192,6 +193,7 @@ scfg_.reset(); SetProofInvalid(); std::queue<QuicConnectionId> empty_queue; + using std::swap; swap(server_designated_connection_ids_, empty_queue); } @@ -236,6 +238,7 @@ scfg_.reset(); ++generation_counter_; std::queue<QuicConnectionId> empty_queue; + using std::swap; swap(server_designated_connection_ids_, empty_queue); } @@ -499,6 +502,9 @@ CryptoHandshakeMessage* out, string* error_details) const { DCHECK(error_details != nullptr); + if (QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective::IS_CLIENT)) { + connection_id = QuicEndian::HostToNet64(connection_id); + } FillInchoateClientHello(server_id, preferred_version, cached, rand, /* demand_x509_proof= */ true, out_params, out); @@ -819,6 +825,9 @@ *error_details = "Missing kRCID"; return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; } + if (QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective::IS_CLIENT)) { + connection_id = QuicEndian::NetToHost64(connection_id); + } cached->add_server_designated_connection_id(connection_id); if (!nonce.empty()) { cached->add_server_nonce(nonce.as_string());
diff --git a/net/quic/core/crypto/quic_crypto_client_config_test.cc b/net/quic/core/crypto/quic_crypto_client_config_test.cc index 694767f..c38d8058 100644 --- a/net/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -6,6 +6,8 @@ #include "net/quic/core/crypto/proof_verifier.h" #include "net/quic/core/quic_server_id.h" +#include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/test_tools/crypto_test_utils.h" #include "net/quic/test_tools/mock_random.h" #include "net/quic/test_tools/quic_test_utils.h" @@ -525,7 +527,10 @@ AllSupportedVersions().front(), "", &cached, out_params, &error)); EXPECT_TRUE(cached.has_server_designated_connection_id()); - EXPECT_EQ(kConnectionId, cached.GetNextServerDesignatedConnectionId()); + EXPECT_EQ(QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective::IS_CLIENT) + ? QuicEndian::NetToHost64(kConnectionId) + : kConnectionId, + cached.GetNextServerDesignatedConnectionId()); EXPECT_EQ(server_nonce, cached.GetNextServerNonce()); }
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc index b7a44bd..b807d46 100644 --- a/net/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -35,6 +35,7 @@ #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_clock.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_hostname_utils.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_reference_counted.h" @@ -745,6 +746,10 @@ const QuicReferenceCountedPointer<Config>& requested_config, const QuicReferenceCountedPointer<Config>& primary_config, std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { + if (QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective::IS_SERVER)) { + connection_id = QuicEndian::HostToNet64(connection_id); + } + ProcessClientHelloHelper helper(&done_cb); if (found_error) { @@ -1479,6 +1484,10 @@ << "with server-designated connection ID " << server_designated_connection_id; out->set_tag(kSREJ); + if (QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective::IS_SERVER)) { + server_designated_connection_id = + QuicEndian::HostToNet64(server_designated_connection_id); + } out->SetValue(kRCID, server_designated_connection_id); } else { out->set_tag(kREJ);
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc index 99daacf..66f5be6 100644 --- a/net/quic/core/quic_connection.cc +++ b/net/quic/core/quic_connection.cc
@@ -346,6 +346,7 @@ close_connection_after_five_rtos_ = true; } if (packet_generator_.latched_flag_no_stop_waiting_frames() && + version() > QUIC_VERSION_37 && config.HasClientSentConnectionOption(kNSTP, perspective_)) { QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_no_stop_waiting_frames, 2, 2); no_stop_waiting_frames_ = true;
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc index 92b57be..144f674 100644 --- a/net/quic/core/quic_connection_test.cc +++ b/net/quic/core/quic_connection_test.cc
@@ -690,7 +690,7 @@ peer_framer_(SupportedVersions(version()), QuicTime::Zero(), Perspective::IS_SERVER), - peer_creator_(connection_id_, + peer_creator_(GetPeerInMemoryConnectionId(connection_id_), &peer_framer_, &buffer_allocator_, /*delegate=*/nullptr), @@ -832,7 +832,8 @@ QuicFrame frame, EncryptionLevel level) { QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.packet_number_length = packet_number_length_; header.public_header.connection_id_length = connection_id_length_; header.public_header.multipath_flag = false; @@ -942,7 +943,10 @@ QuicPacket* ConstructDataPacket(QuicPacketNumber number, bool has_stop_waiting) { QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + // Set connection_id to peer's in memory representation as this data packet + // is created by peer_framer. + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.packet_number_length = packet_number_length_; header.public_header.connection_id_length = connection_id_length_; header.public_header.multipath_flag = false; @@ -958,7 +962,10 @@ QuicPacket* ConstructClosePacket(QuicPacketNumber number) { QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + // Set connection_id to peer's in memory representation as this connection + // close packet is created by peer_framer. + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.packet_number = number; QuicConnectionCloseFrame qccf; @@ -1199,7 +1206,8 @@ connection_.SetMaxPacketLength(1000); QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.version_flag = true; header.packet_number = 1; @@ -1232,7 +1240,8 @@ EXPECT_EQ(1000u, connection_.max_packet_length()); QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.version_flag = true; header.packet_number = 1; @@ -4323,7 +4332,9 @@ TEST_P(QuicConnectionTest, PublicReset) { QuicPublicResetPacket header; - header.public_header.connection_id = connection_id_; + // Public reset packet in only built by server. + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.reset_flag = true; header.public_header.version_flag = false; header.rejected_packet_number = 10101; @@ -4390,7 +4401,8 @@ peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.version_flag = true; header.packet_number = 12; @@ -4425,7 +4437,8 @@ peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.version_flag = true; header.packet_number = 12; @@ -4467,7 +4480,8 @@ peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.public_header.version_flag = true; header.packet_number = 12; @@ -4496,8 +4510,8 @@ // Send a version negotiation packet. std::unique_ptr<QuicEncryptedPacket> encrypted( - peer_framer_.BuildVersionNegotiationPacket(connection_id_, - AllSupportedVersions())); + peer_framer_.BuildVersionNegotiationPacket( + GetPeerInMemoryConnectionId(connection_id_), AllSupportedVersions())); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*encrypted, QuicTime::Zero())); connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received); @@ -4505,7 +4519,8 @@ // Now force another packet. The connection should transition into // NEGOTIATED_VERSION state and tell the packet creator to StopSendingVersion. QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.packet_number = 12; header.public_header.version_flag = false; QuicFrames frames; @@ -4531,8 +4546,8 @@ OnConnectionClosed(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, _, ConnectionCloseSource::FROM_SELF)); std::unique_ptr<QuicEncryptedPacket> encrypted( - framer_.BuildVersionNegotiationPacket(connection_id_, - AllSupportedVersions())); + framer_.BuildVersionNegotiationPacket( + GetPeerInMemoryConnectionId(connection_id_), AllSupportedVersions())); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*encrypted, QuicTime::Zero())); connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received); @@ -4588,7 +4603,8 @@ TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) { // Construct a packet with stream frame and connection close frame. QuicPacketHeader header; - header.public_header.connection_id = connection_id_; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id_); header.packet_number = 1; header.public_header.version_flag = false;
diff --git a/net/quic/core/quic_crypto_client_stream_test.cc b/net/quic/core/quic_crypto_client_stream_test.cc index e0b9983..d69c7c9 100644 --- a/net/quic/core/quic_crypto_client_stream_test.cc +++ b/net/quic/core/quic_crypto_client_stream_test.cc
@@ -445,7 +445,7 @@ client_state->GetNextServerDesignatedConnectionId(); QuicConnectionId expected_id = server_session_->connection()->random_generator()->RandUint64(); - EXPECT_EQ(expected_id, server_designated_id); + EXPECT_EQ(GetPeerInMemoryConnectionId(expected_id), server_designated_id); EXPECT_FALSE(client_state->has_server_designated_connection_id()); }
diff --git a/net/quic/core/quic_crypto_server_stream_test.cc b/net/quic/core/quic_crypto_server_stream_test.cc index ad3c54e..d6e845c6 100644 --- a/net/quic/core/quic_crypto_server_stream_test.cc +++ b/net/quic/core/quic_crypto_server_stream_test.cc
@@ -257,7 +257,8 @@ client_state->GetNextServerDesignatedConnectionId(); const QuicConnectionId expected_id = server_connection_->random_generator()->RandUint64(); - EXPECT_EQ(expected_id, server_designated_connection_id); + EXPECT_EQ(GetPeerInMemoryConnectionId(expected_id), + server_designated_connection_id); EXPECT_FALSE(client_state->has_server_designated_connection_id()); ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0))); } @@ -284,7 +285,8 @@ client_state->GetNextServerDesignatedConnectionId(); const QuicConnectionId expected_id = server_connection_->random_generator()->RandUint64(); - EXPECT_EQ(expected_id, server_designated_connection_id); + EXPECT_EQ(GetPeerInMemoryConnectionId(expected_id), + server_designated_connection_id); EXPECT_FALSE(client_state->has_server_designated_connection_id()); ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
diff --git a/net/quic/core/quic_data_reader.cc b/net/quic/core/quic_data_reader.cc index 5f2c483..0f728c9 100644 --- a/net/quic/core/quic_data_reader.cc +++ b/net/quic/core/quic_data_reader.cc
@@ -7,6 +7,8 @@ #include "net/base/int128.h" #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packets.h" +#include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_logging.h" @@ -99,7 +101,7 @@ return false; } - if (FLAGS_quic_restart_flag_quic_big_endian_connection_id) { + if (QuicUtils::IsConnectionIdWireFormatBigEndian(perspective_)) { *connection_id = QuicEndian::NetToHost64(*connection_id); } @@ -154,4 +156,13 @@ pos_ = len_; } +uint8_t QuicDataReader::PeekByte() const { + if (pos_ >= len_) { + QUIC_BUG << "Reading is done, cannot peek next byte. Tried to read pos = " + << pos_ << " buffer length = " << len_; + return 0; + } + return data_[pos_]; +} + } // namespace net
diff --git a/net/quic/core/quic_data_reader.h b/net/quic/core/quic_data_reader.h index 9507ec1..ffce87f 100644 --- a/net/quic/core/quic_data_reader.h +++ b/net/quic/core/quic_data_reader.h
@@ -118,6 +118,12 @@ // Returns the number of bytes remaining to be read. size_t BytesRemaining() const; + // Returns the next byte that to be read. Must not be called when there are no + // bytes to be read. + // + // DOES NOT forward the internal iterator. + uint8_t PeekByte() const; + private: // Returns true if the underlying buffer has enough room to read the given // amount of bytes.
diff --git a/net/quic/core/quic_data_writer.cc b/net/quic/core/quic_data_writer.cc index 3ac6450b..28791917 100644 --- a/net/quic/core/quic_data_writer.cc +++ b/net/quic/core/quic_data_writer.cc
@@ -8,6 +8,7 @@ #include <limits> #include "net/quic/core/quic_flags.h" +#include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_logging.h" @@ -149,8 +150,12 @@ length_ = capacity_; } +bool QuicDataWriter::WritePaddingBytes(size_t count) { + return WriteRepeatedByte(0x00, count); +} + bool QuicDataWriter::WriteConnectionId(uint64_t connection_id) { - if (FLAGS_quic_restart_flag_quic_big_endian_connection_id) { + if (QuicUtils::IsConnectionIdWireFormatBigEndian(perspective_)) { connection_id = QuicEndian::HostToNet64(connection_id); }
diff --git a/net/quic/core/quic_data_writer.h b/net/quic/core/quic_data_writer.h index a7faca2..ca4b4a2 100644 --- a/net/quic/core/quic_data_writer.h +++ b/net/quic/core/quic_data_writer.h
@@ -52,6 +52,8 @@ bool WriteRepeatedByte(uint8_t byte, size_t count); // Fills the remaining buffer with null characters. void WritePadding(); + // Write padding of |count| bytes. + bool WritePaddingBytes(size_t count); // Write connection ID as a 64-bit unsigned integer to the payload. // TODO(fayang): Remove this method and use WriteUInt64() once deprecating
diff --git a/net/quic/core/quic_data_writer_test.cc b/net/quic/core/quic_data_writer_test.cc index bc1d0ad..893ff42c 100644 --- a/net/quic/core/quic_data_writer_test.cc +++ b/net/quic/core/quic_data_writer_test.cc
@@ -8,6 +8,7 @@ #include "net/quic/core/quic_data_reader.h" #include "net/quic/core/quic_flags.h" +#include "net/quic/core/quic_utils.h" #include "net/quic/test_tools/quic_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" @@ -215,8 +216,8 @@ writer.WriteConnectionId(connection_id); test::CompareCharArraysWithHexError( "connection_id", buffer, kBufferLength, - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? big_endian - : little_endian, + QuicUtils::IsConnectionIdWireFormatBigEndian(GetParam()) ? big_endian + : little_endian, kBufferLength); uint64_t read_connection_id;
diff --git a/net/quic/core/quic_error_codes.cc b/net/quic/core/quic_error_codes.cc index ca87175..2f734e5 100644 --- a/net/quic/core/quic_error_codes.cc +++ b/net/quic/core/quic_error_codes.cc
@@ -113,7 +113,6 @@ RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED); RETURN_STRING_LITERAL(QUIC_BAD_PACKET_LOSS_RATE); RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE); - RETURN_STRING_LITERAL(QUIC_TIMEOUTS_WITH_OPEN_STREAMS); RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET); RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS); RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
diff --git a/net/quic/core/quic_error_codes.h b/net/quic/core/quic_error_codes.h index 38750a5..2a6f335 100644 --- a/net/quic/core/quic_error_codes.h +++ b/net/quic/core/quic_error_codes.h
@@ -174,8 +174,6 @@ QUIC_BAD_PACKET_LOSS_RATE = 71, // Disabled QUIC because of too many PUBLIC_RESETs post handshake. QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73, - // Disabled QUIC because of too many timeouts with streams open. - QUIC_TIMEOUTS_WITH_OPEN_STREAMS = 74, // Closed because we failed to serialize a packet. QUIC_FAILED_TO_SERIALIZE_PACKET = 75, // QUIC timed out after too many RTOs.
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h index 3924bc8..947186d 100644 --- a/net/quic/core/quic_flags_list.h +++ b/net/quic/core/quic_flags_list.h
@@ -93,7 +93,7 @@ QUIC_FLAG( bool, FLAGS_quic_reloadable_flag_quic_remove_packet_number_from_public_reset, - false) + true) // If true, v33 QUIC client uses 1 bit to specify 8-byte connection id in // public flag. @@ -132,13 +132,6 @@ // If true, disables QUIC v34. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_34, true) -// If true, enable quic version 38 -QUIC_FLAG(bool, FLAGS_quic_enable_version_38, false) - -// When true, ensures the session's flow control window is always at least 1.5x -// larger than the largest stream flow control window. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_flow_control_invariant, true) - // If greater than zero, mean RTT variation is multiplied by the specified // factor and added to the congestion window limit. QUIC_FLAG(double, FLAGS_quic_bbr_rtt_variation_weight, 0.0f) @@ -149,7 +142,7 @@ // If true, bidi streaming is always enabled in QUIC. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_always_enable_bidi_streaming, - false) + true) // If true, allows the 1RTT and 2RTT connection options to reduce the time // in BBR STARTUP to 1 or 2 RTTs with no bandwidth increase from 3. @@ -172,16 +165,12 @@ // quickly for the first adjustment as in subsequent ones. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_flow_control_faster_autotune, - false) + true) // Only consider using the ack spacing in QUIC BBR if 2 packets are acked at // once. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2, false) -// If true, 8-byte connection ID in public header is read and written in big -// endian. -QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_big_endian_connection_id, false) - // If true, QUIC BBR stores a max filtered number of bytes delivered at a rate // faster than the sending rate. QUIC_FLAG(bool, @@ -203,3 +192,26 @@ // Fix a crash that occurs when a client sends multiple CHLOs close together on // the same connection. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_fix_quic_callback_crash, true) + +// If true, enable version 38 which supports new PADDING frame and respects NSTP +// connection option. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_38, false) + +// If true, enable QUIC v39. +QUIC_FLAG(bool, FLAGS_quic_enable_version_39, false) + +// If true, on client side, 8-byte connection ID in public header is read and +// written in big endian. +QUIC_FLAG(bool, + FLAGS_quic_restart_flag_quic_big_endian_connection_id_client, + false) + +// If true, on server side, 8-byte connection ID in public header is read and +// written in big endian. +QUIC_FLAG(bool, + FLAGS_quic_restart_flag_quic_big_endian_connection_id_server, + false) + +// Simplify QUIC\'s adaptive time loss detection to measure the necessary +// reordering window for every spurious retransmit. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss, false)
diff --git a/net/quic/core/quic_flow_controller.h b/net/quic/core/quic_flow_controller.h index b955da15..6f9acb3b 100644 --- a/net/quic/core/quic_flow_controller.h +++ b/net/quic/core/quic_flow_controller.h
@@ -176,8 +176,7 @@ // Used to dynamically enable receive window auto-tuning. bool auto_tune_receive_window_; - // The session's flow controller. null if this is stream id 0 or - // FLAGS_quic_reloadable_flag_quic_flow_control_invariant is false. + // The session's flow controller. null if this is stream id 0. // Not owned. QuicFlowControllerInterface* session_flow_controller_;
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc index fc8e239..18102be 100644 --- a/net/quic/core/quic_framer.cc +++ b/net/quic/core/quic_framer.cc
@@ -336,7 +336,11 @@ switch (frame.type) { case PADDING_FRAME: - writer.WritePadding(); + if (!AppendPaddingFrame(frame.padding_frame, &writer)) { + QUIC_BUG << "AppendPaddingFrame of " + << frame.padding_frame.num_padding_bytes << " failed"; + return 0; + } break; case STREAM_FRAME: if (!AppendStreamFrame(*frame.stream_frame, no_stream_frame_length, @@ -1013,12 +1017,14 @@ switch (frame_type) { case PADDING_FRAME: { - QuicPaddingFrame frame(reader->BytesRemaining()); + QuicPaddingFrame frame; + ProcessPaddingFrame(reader, &frame); if (!visitor_->OnPaddingFrame(frame)) { QUIC_DVLOG(1) << "Visitor asked to stop further processing."; + // Returning true since there was no parsing error. + return true; } - // We're done with the packet. - return true; + continue; } case RST_STREAM_FRAME: { @@ -1438,6 +1444,23 @@ return true; } +void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader, + QuicPaddingFrame* frame) { + if (quic_version_ <= QUIC_VERSION_37) { + frame->num_padding_bytes = reader->BytesRemaining() + 1; + reader->ReadRemainingPayload(); + return; + } + // Type byte has been read. + frame->num_padding_bytes = 1; + uint8_t next_byte; + while (!reader->IsDoneReading() && reader->PeekByte() == 0x00) { + reader->ReadBytes(&next_byte, 1); + DCHECK_EQ(0x00, next_byte); + ++frame->num_padding_bytes; + } +} + // static QuicStringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( QuicVersion version, @@ -2111,6 +2134,25 @@ return true; } +bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame, + QuicDataWriter* writer) { + if (quic_version_ <= QUIC_VERSION_37) { + writer->WritePadding(); + return true; + } + + if (frame.num_padding_bytes == 0) { + return false; + } + if (frame.num_padding_bytes < 0) { + QUIC_BUG_IF(frame.num_padding_bytes != -1); + writer->WritePadding(); + return true; + } + // Please note, num_padding_bytes includes type byte which has been written. + return writer->WritePaddingBytes(frame.num_padding_bytes - 1); +} + bool QuicFramer::RaiseError(QuicErrorCode error) { QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error) << " detail: " << detailed_error_;
diff --git a/net/quic/core/quic_framer.h b/net/quic/core/quic_framer.h index 2ca8ea1..6cb8522 100644 --- a/net/quic/core/quic_framer.h +++ b/net/quic/core/quic_framer.h
@@ -386,6 +386,7 @@ bool ProcessWindowUpdateFrame(QuicDataReader* reader, QuicWindowUpdateFrame* frame); bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame); + void ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame); bool DecryptPayload(QuicDataReader* encrypted_reader, const QuicPacketHeader& header, @@ -460,6 +461,8 @@ QuicDataWriter* writer); bool AppendBlockedFrame(const QuicBlockedFrame& frame, QuicDataWriter* writer); + bool AppendPaddingFrame(const QuicPaddingFrame& frame, + QuicDataWriter* writer); bool RaiseError(QuicErrorCode error);
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc index cf757fa..916127c 100644 --- a/net/quic/core/quic_framer_test.cc +++ b/net/quic/core/quic_framer_test.cc
@@ -591,10 +591,11 @@ memset(packet + header_size, 0, kMaxPacketSize - header_size); QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -629,10 +630,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -659,10 +661,11 @@ } else { expected_error = "Unable to read packet number."; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, QUIC_INVALID_PACKET_HEADER); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, QUIC_INVALID_PACKET_HEADER); } } @@ -735,10 +738,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -768,10 +772,11 @@ } else { expected_error = "Unable to read packet number."; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, QUIC_INVALID_PACKET_HEADER); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, QUIC_INVALID_PACKET_HEADER); } } @@ -799,10 +804,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -829,10 +835,11 @@ } else { expected_error = "Unable to read packet number."; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, QUIC_INVALID_PACKET_HEADER); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, QUIC_INVALID_PACKET_HEADER); } } @@ -860,10 +867,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -892,10 +900,11 @@ } else { expected_error = "Unable to read packet number."; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, QUIC_INVALID_PACKET_HEADER); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, QUIC_INVALID_PACKET_HEADER); } } @@ -923,10 +932,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -955,10 +965,11 @@ } else { expected_error = "Unable to read packet number."; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, QUIC_INVALID_PACKET_HEADER); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, QUIC_INVALID_PACKET_HEADER); } } @@ -1062,10 +1073,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1075,6 +1087,8 @@ for (char i = 0; i < 32; ++i) { EXPECT_EQ(i, (*visitor_.public_header_->nonce)[static_cast<size_t>(i)]); } + EXPECT_EQ(1u, visitor_.padding_frames_.size()); + EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes); }; TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { @@ -1115,10 +1129,11 @@ }; // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1127,6 +1142,8 @@ ASSERT_TRUE(visitor_.header_.get()); EXPECT_EQ(0, visitor_.frame_count_); EXPECT_EQ(1, visitor_.version_mismatch_); + EXPECT_EQ(1u, visitor_.padding_frames_.size()); + EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes); }; TEST_P(QuicFramerTest, PaddingFrame) { @@ -1187,11 +1204,16 @@ }; // clang-format on + if (framer_.version() > QUIC_VERSION_37) { + return; + } + QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1203,16 +1225,109 @@ ASSERT_EQ(0u, visitor_.stream_frames_.size()); EXPECT_EQ(0u, visitor_.ack_frames_.size()); + EXPECT_EQ(1u, visitor_.padding_frames_.size()); + EXPECT_EQ(28, visitor_.padding_frames_[0]->num_padding_bytes); // A packet with no frames is not acceptable. CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), "Packet has no frames.", QUIC_MISSING_PAYLOAD); } +TEST_P(QuicFramerTest, NewPaddingFrame) { + // clang-format off + unsigned char packet[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0x10, 0x32, 0x54, 0x76, + 0x98, 0xBA, 0xDC, 0xFE, + // packet number + 0xBC, 0x9A, 0x78, 0x56, + 0x34, 0x12, + + // paddings + 0x00, 0x00, + // frame type (stream frame with fin) + 0xFF, + // stream id + 0x04, 0x03, 0x02, 0x01, + // offset + 0x54, 0x76, 0x10, 0x32, + 0xDC, 0xFE, 0x98, 0xBA, + // data length + 0x0c, 0x00, + // data + 'h', 'e', 'l', 'l', + 'o', ' ', 'w', 'o', + 'r', 'l', 'd', '!', + // paddings + 0x00, 0x00, + }; + + unsigned char packet_cid_be[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0xBC, 0x9A, 0x78, 0x56, + 0x34, 0x12, + + // paddings + 0x00, 0x00, + // frame type (stream frame with fin) + 0xFF, + // stream id + 0x04, 0x03, 0x02, 0x01, + // offset + 0x54, 0x76, 0x10, 0x32, + 0xDC, 0xFE, 0x98, 0xBA, + // data length + 0x0c, 0x00, + // data + 'h', 'e', 'l', 'l', + 'o', ' ', 'w', 'o', + 'r', 'l', 'd', '!', + // paddings + 0x00, 0x00, + }; + // clang-format on + + if (framer_.version() <= QUIC_VERSION_37) { + return; + } + + QuicEncryptedPacket encrypted( + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? arraysize(packet_cid_be) + : arraysize(packet), + false); + EXPECT_TRUE(framer_.ProcessPacket(encrypted)); + EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); + ASSERT_TRUE(visitor_.header_.get()); + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, + !kIncludeDiversificationNonce)); + + ASSERT_EQ(1u, visitor_.stream_frames_.size()); + EXPECT_EQ(0u, visitor_.ack_frames_.size()); + EXPECT_EQ(2u, visitor_.padding_frames_.size()); + EXPECT_EQ(2, visitor_.padding_frames_[0]->num_padding_bytes); + EXPECT_EQ(2, visitor_.padding_frames_[1]->num_padding_bytes); + EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id); + EXPECT_TRUE(visitor_.stream_frames_[0]->fin); + EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); + CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get()); +} + TEST_P(QuicFramerTest, StreamFrame) { // clang-format off unsigned char packet[] = { @@ -1266,10 +1381,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1289,8 +1405,9 @@ // Now test framing boundaries. CheckStreamFrameBoundaries( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, kQuicMaxStreamIdSize, !kIncludeVersion); } @@ -1353,10 +1470,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1417,10 +1535,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1442,8 +1561,9 @@ // Now test framing boundaries. const size_t stream_id_size = 3; CheckStreamFrameBoundaries( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, stream_id_size, !kIncludeVersion); } @@ -1500,10 +1620,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1525,8 +1646,9 @@ // Now test framing boundaries. const size_t stream_id_size = 2; CheckStreamFrameBoundaries( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, stream_id_size, !kIncludeVersion); } @@ -1583,10 +1705,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1608,8 +1731,9 @@ // Now test framing boundaries. const size_t stream_id_size = 1; CheckStreamFrameBoundaries( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, stream_id_size, !kIncludeVersion); } @@ -1670,10 +1794,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1695,8 +1820,9 @@ // Now test framing boundaries. CheckStreamFrameBoundaries( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, kQuicMaxStreamIdSize, kIncludeVersion); } @@ -1755,10 +1881,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1793,10 +1920,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1853,10 +1981,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -1895,8 +2024,9 @@ expected_error = "Unable to read num received packets."; } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2002,10 +2132,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2095,8 +2226,9 @@ } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2139,10 +2271,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2163,8 +2296,9 @@ string expected_error; expected_error = "Unable to read least unacked delta."; CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2221,10 +2355,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2253,8 +2388,9 @@ expected_error = "Unable to read rst stream error code."; } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2313,10 +2449,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2344,8 +2481,9 @@ expected_error = "Unable to read connection close error details."; } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2406,10 +2544,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2438,8 +2577,9 @@ expected_error = "Unable to read goaway reason."; } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2488,10 +2628,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2515,8 +2656,9 @@ expected_error = "Unable to read window byte_offset."; } CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2559,10 +2701,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2580,8 +2723,9 @@ ++i) { string expected_error = "Unable to read stream_id."; CheckProcessingFails( - FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), @@ -2620,10 +2764,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2694,10 +2839,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2715,7 +2861,7 @@ visitor_.public_reset_packet_->client_address.host().address_family()); // Now test framing boundaries. - if (!FLAGS_quic_restart_flag_quic_big_endian_connection_id) { + if (!QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective())) { for (size_t i = 0; i < arraysize(packet); ++i) { string expected_error; QUIC_DLOG(INFO) << "iteration: " << i; @@ -2812,10 +2958,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -2833,7 +2980,7 @@ visitor_.public_reset_packet_->client_address.host().address_family()); // Now test framing boundaries. - if (!FLAGS_quic_restart_flag_quic_big_endian_connection_id) { + if (!QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective())) { for (size_t i = 0; i < arraysize(packet); ++i) { string expected_error; QUIC_DLOG(INFO) << "iteration: " << i; @@ -2932,13 +3079,14 @@ // clang-format on string expected_error = "Unable to read reset message."; - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? arraysize(packet_cid_be) - : arraysize(packet), - expected_error, QUIC_INVALID_PUBLIC_RST_PACKET); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? arraysize(packet_cid_be) + : arraysize(packet), + expected_error, QUIC_INVALID_PUBLIC_RST_PACKET); } TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) { @@ -3012,10 +3160,11 @@ // clang-format on QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -3033,7 +3182,7 @@ EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port()); // Now test framing boundaries. - if (!FLAGS_quic_restart_flag_quic_big_endian_connection_id) { + if (!QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective())) { for (size_t i = 0; i < arraysize(packet); ++i) { string expected_error; QUIC_DLOG(INFO) << "iteration: " << i; @@ -3100,10 +3249,11 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -3124,10 +3274,11 @@ expected_error = "Unable to read supported version in negotiation."; error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, error_code); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, error_code); } } @@ -3158,10 +3309,11 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -3182,10 +3334,11 @@ expected_error = "Unable to read supported version in negotiation."; error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET; } - CheckProcessingFails(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - i, expected_error, error_code); + CheckProcessingFails( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + i, expected_error, error_code); } } @@ -3232,8 +3385,9 @@ uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); - memset((FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet) + + memset((QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet) + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); @@ -3242,10 +3396,100 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? arraysize(packet_cid_be) + : arraysize(packet)); +} + +TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) { + if (framer_.version() <= QUIC_VERSION_37) { + return; + } + QuicPacketHeader header; + header.public_header.connection_id = kConnectionId; + header.public_header.reset_flag = false; + header.public_header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, + QuicStringPiece("hello world!")); + QuicPaddingFrame padding_frame(2); + QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(&stream_frame), + QuicFrame(padding_frame)}; + + // clang-format off + unsigned char packet[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0x10, 0x32, 0x54, 0x76, + 0x98, 0xBA, 0xDC, 0xFE, + // packet number + 0xBC, 0x9A, 0x78, 0x56, + 0x34, 0x12, + + // paddings + 0x00, 0x00, + // frame type (stream frame with fin) + 0xFF, + // stream id + 0x04, 0x03, 0x02, 0x01, + // offset + 0x54, 0x76, 0x10, 0x32, + 0xDC, 0xFE, 0x98, 0xBA, + // data length + 0x0c, 0x00, + // data + 'h', 'e', 'l', 'l', + 'o', ' ', 'w', 'o', + 'r', 'l', 'd', '!', + // paddings + 0x00, 0x00, + }; + + unsigned char packet_cid_be[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0xBC, 0x9A, 0x78, 0x56, + 0x34, 0x12, + + // paddings + 0x00, 0x00, + // frame type (stream frame with fin) + 0xFF, + // stream id + 0x04, 0x03, 0x02, 0x01, + // offset + 0x54, 0x76, 0x10, 0x32, + 0xDC, 0xFE, 0x98, 0xBA, + // data length + 0x0c, 0x00, + // data + 'h', 'e', 'l', 'l', + 'o', ' ', 'w', 'o', + 'r', 'l', 'd', '!', + // paddings + 0x00, 0x00, + }; + // clang-format on + + std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); + ASSERT_TRUE(data != nullptr); + + test::CompareCharArraysWithHexError( + "constructed packet", data->data(), data->length(), + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3292,8 +3536,9 @@ uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER); - memset((FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet) + + memset((QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet) + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); @@ -3302,10 +3547,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3352,8 +3598,9 @@ uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER); - memset((FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet) + + memset((QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet) + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); @@ -3362,10 +3609,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3412,8 +3660,9 @@ uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER); - memset((FLAGS_quic_restart_flag_quic_big_endian_connection_id ? packet_cid_be - : packet) + + memset((QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet) + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); @@ -3422,10 +3671,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3494,10 +3744,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3563,10 +3814,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3598,10 +3850,11 @@ SupportedVersions(GetParam()))); test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3670,10 +3923,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -3781,10 +4035,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4001,10 +4256,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4059,10 +4315,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4129,10 +4386,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4202,10 +4460,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4280,10 +4539,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4345,10 +4605,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4403,10 +4664,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4454,10 +4716,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4506,10 +4769,11 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4619,19 +4883,21 @@ if (FLAGS_quic_reloadable_flag_quic_remove_packet_number_from_public_reset) { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_no_rejected_packet_number_cid_be - : packet_no_rejected_packet_number), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_no_rejected_packet_number_cid_be + : packet_no_rejected_packet_number), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_no_rejected_packet_number_cid_be) : arraysize(packet_no_rejected_packet_number)); } else { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4743,19 +5009,21 @@ if (FLAGS_quic_reloadable_flag_quic_remove_packet_number_from_public_reset) { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_no_rejected_packet_number_cid_be - : packet_no_rejected_packet_number), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_no_rejected_packet_number_cid_be + : packet_no_rejected_packet_number), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_no_rejected_packet_number_cid_be) : arraysize(packet_no_rejected_packet_number)); } else { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4901,21 +5169,23 @@ if (FLAGS_quic_reloadable_flag_quic_remove_packet_number_from_public_reset) { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_no_rejected_packet_number_cid_be - : packet_no_rejected_packet_number), + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_no_rejected_packet_number_cid_be + : packet_no_rejected_packet_number), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_no_rejected_packet_number_cid_be) : arraysize(packet_no_rejected_packet_number)); } else { test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet)); } @@ -4959,10 +5229,11 @@ // clang-format on std::unique_ptr<QuicPacket> raw(new QuicPacket( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, @@ -5017,10 +5288,11 @@ // clang-format on std::unique_ptr<QuicPacket> raw(new QuicPacket( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, @@ -5227,10 +5499,11 @@ EXPECT_CALL(visitor, OnDecryptedPacket(_)); QuicEncryptedPacket encrypted( - AsChars(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet), - FLAGS_quic_restart_flag_quic_big_endian_connection_id + AsChars( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet), + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) ? arraysize(packet_cid_be) : arraysize(packet), false); @@ -5404,12 +5677,13 @@ }; // clang-format on - QuicFramerFuzzFunc(FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? packet_cid_be - : packet, - FLAGS_quic_restart_flag_quic_big_endian_connection_id - ? arraysize(packet_cid_be) - : arraysize(packet)); + QuicFramerFuzzFunc( + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? packet_cid_be + : packet, + QuicUtils::IsConnectionIdWireFormatBigEndian(framer_.perspective()) + ? arraysize(packet_cid_be) + : arraysize(packet)); } } // namespace test
diff --git a/net/quic/core/quic_packet_generator_test.cc b/net/quic/core/quic_packet_generator_test.cc index 9908883..b7b4c7e 100644 --- a/net/quic/core/quic_packet_generator_test.cc +++ b/net/quic/core/quic_packet_generator_test.cc
@@ -852,7 +852,7 @@ delegate_.SetCanWriteAnything(); QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); frame->error_code = QUIC_PACKET_WRITE_ERROR; - char buf[2000]; + char buf[2000] = {}; QuicStringPiece error_details(buf, 2000); frame->error_details = error_details.as_string(); EXPECT_CALL(delegate_,
diff --git a/net/quic/core/quic_session.cc b/net/quic/core/quic_session.cc index ab7c9b35..453d3b7 100644 --- a/net/quic/core/quic_session.cc +++ b/net/quic/core/quic_session.cc
@@ -44,9 +44,7 @@ config_.GetInitialSessionFlowControlWindowToSend(), perspective() == Perspective::IS_SERVER, nullptr), - currently_writing_stream_id_(0), - flow_control_invariant_( - FLAGS_quic_reloadable_flag_quic_flow_control_invariant) {} + currently_writing_stream_id_(0) {} void QuicSession::Initialize() { connection_->set_visitor(this);
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h index d3f8dda..5eaa169 100644 --- a/net/quic/core/quic_session.h +++ b/net/quic/core/quic_session.h
@@ -248,8 +248,6 @@ // Returns true if this stream should yield writes to another blocked stream. bool ShouldYield(QuicStreamId stream_id); - bool flow_control_invariant() { return flow_control_invariant_; } - protected: using StaticStreamMap = QuicSmallMap<QuicStreamId, QuicStream*, 2>; @@ -441,9 +439,6 @@ // call stack of OnCanWrite. QuicStreamId currently_writing_stream_id_; - // Latched value of quic_reloadable_flag_quic_flow_control_invariant. - const bool flow_control_invariant_; - DISALLOW_COPY_AND_ASSIGN(QuicSession); };
diff --git a/net/quic/core/quic_stream.cc b/net/quic/core/quic_stream.cc index a7ab1afe..d402b4e 100644 --- a/net/quic/core/quic_stream.cc +++ b/net/quic/core/quic_stream.cc
@@ -70,9 +70,7 @@ GetReceivedFlowControlWindow(session), GetInitialStreamFlowControlWindowToSend(session), session_->flow_controller()->auto_tune_receive_window(), - session_->flow_control_invariant() - ? session_->flow_controller() - : nullptr), + session_->flow_controller()), connection_flow_controller_(session_->flow_controller()), stream_contributes_to_connection_flow_control_(true), busy_counter_(0) {
diff --git a/net/quic/core/quic_utils.cc b/net/quic/core/quic_utils.cc index d68c55f..b7f3183 100644 --- a/net/quic/core/quic_utils.cc +++ b/net/quic/core/quic_utils.cc
@@ -208,4 +208,12 @@ return IPV4_TO_IPV4_CHANGE; } +// static +bool QuicUtils::IsConnectionIdWireFormatBigEndian(Perspective perspective) { + return (perspective == Perspective::IS_CLIENT && + FLAGS_quic_restart_flag_quic_big_endian_connection_id_client) || + (perspective == Perspective::IS_SERVER && + FLAGS_quic_restart_flag_quic_big_endian_connection_id_server); +} + } // namespace net
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h index 723874f..7395722 100644 --- a/net/quic/core/quic_utils.h +++ b/net/quic/core/quic_utils.h
@@ -59,6 +59,12 @@ const QuicSocketAddress& old_address, const QuicSocketAddress& new_address); + // Returns whether connection id needs to be read/write in big endian. + // TODO(fayang): Remove this method once deprecating + // FLAGS_quic_restart_flag_quic_big_endian_connection_id_client and + // FLAGS_quic_restart_flag_quic_big_endian_connection_id_server. + static bool IsConnectionIdWireFormatBigEndian(Perspective perspective); + private: DISALLOW_COPY_AND_ASSIGN(QuicUtils); };
diff --git a/net/quic/core/quic_version_manager.cc b/net/quic/core/quic_version_manager.cc index 0273015..7b11073 100644 --- a/net/quic/core/quic_version_manager.cc +++ b/net/quic/core/quic_version_manager.cc
@@ -10,7 +10,8 @@ namespace net { QuicVersionManager::QuicVersionManager(QuicVersionVector supported_versions) - : enable_version_38_(FLAGS_quic_enable_version_38), + : enable_version_39_(base::GetFlag(FLAGS_quic_enable_version_39)), + enable_version_38_(FLAGS_quic_reloadable_flag_quic_enable_version_38), enable_version_37_(FLAGS_quic_reloadable_flag_quic_enable_version_37), enable_version_36_(FLAGS_quic_reloadable_flag_quic_enable_version_36_v3), disable_version_34_(FLAGS_quic_reloadable_flag_quic_disable_version_34), @@ -26,13 +27,15 @@ } void QuicVersionManager::MaybeRefilterSupportedVersions() { - if (enable_version_38_ != FLAGS_quic_enable_version_38 || + if (enable_version_39_ != base::GetFlag(FLAGS_quic_enable_version_39) || + enable_version_38_ != FLAGS_quic_reloadable_flag_quic_enable_version_38 || enable_version_37_ != FLAGS_quic_reloadable_flag_quic_enable_version_37 || enable_version_36_ != FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 || disable_version_34_ != FLAGS_quic_reloadable_flag_quic_disable_version_34) { - enable_version_38_ = FLAGS_quic_enable_version_38; + enable_version_39_ = base::GetFlag(FLAGS_quic_enable_version_39); + enable_version_38_ = FLAGS_quic_reloadable_flag_quic_enable_version_38; enable_version_37_ = FLAGS_quic_reloadable_flag_quic_enable_version_37; enable_version_36_ = FLAGS_quic_reloadable_flag_quic_enable_version_36_v3; disable_version_34_ = FLAGS_quic_reloadable_flag_quic_disable_version_34;
diff --git a/net/quic/core/quic_version_manager.h b/net/quic/core/quic_version_manager.h index c1afef5..d6664b8 100644 --- a/net/quic/core/quic_version_manager.h +++ b/net/quic/core/quic_version_manager.h
@@ -31,7 +31,9 @@ } private: - // FLAGS_quic_enable_version_38 + // FLAGS_quic_enable_version_39 + bool enable_version_39_; + // FLAGS_quic_reloadable_flag_quic_enable_version_38 bool enable_version_38_; // FLAGS_quic_reloadable_flag_quic_enable_version_37 bool enable_version_37_;
diff --git a/net/quic/core/quic_version_manager_test.cc b/net/quic/core/quic_version_manager_test.cc index 22faf09..bd259cb 100644 --- a/net/quic/core/quic_version_manager_test.cc +++ b/net/quic/core/quic_version_manager_test.cc
@@ -16,8 +16,8 @@ TEST(QuicVersionManagerTest, QuicVersionManager) { QuicFlagSaver flags; - FLAGS_quic_enable_version_38 = false; FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 = false; + FLAGS_quic_reloadable_flag_quic_enable_version_38 = false; FLAGS_quic_reloadable_flag_quic_enable_version_37 = false; FLAGS_quic_reloadable_flag_quic_disable_version_34 = false; QuicVersionManager manager(AllSupportedVersions()); @@ -41,7 +41,7 @@ EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[2]); EXPECT_EQ(QUIC_VERSION_34, manager.GetSupportedVersions()[3]); - FLAGS_quic_enable_version_38 = true; + FLAGS_quic_reloadable_flag_quic_enable_version_38 = true; EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), manager.GetSupportedVersions()); ASSERT_EQ(5u, manager.GetSupportedVersions().size()); @@ -51,14 +51,26 @@ EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[3]); EXPECT_EQ(QUIC_VERSION_34, manager.GetSupportedVersions()[4]); + base::SetFlag(&FLAGS_quic_enable_version_39, true); + EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), + manager.GetSupportedVersions()); + ASSERT_EQ(6u, manager.GetSupportedVersions().size()); + EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedVersions()[0]); + EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedVersions()[1]); + EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[2]); + EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[3]); + EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[4]); + EXPECT_EQ(QUIC_VERSION_34, manager.GetSupportedVersions()[5]); + FLAGS_quic_reloadable_flag_quic_disable_version_34 = true; EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), manager.GetSupportedVersions()); - ASSERT_EQ(4u, manager.GetSupportedVersions().size()); - EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedVersions()[0]); - EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[1]); - EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[2]); - EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[3]); + ASSERT_EQ(5u, manager.GetSupportedVersions().size()); + EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedVersions()[0]); + EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedVersions()[1]); + EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[2]); + EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[3]); + EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[4]); } } // namespace
diff --git a/net/quic/core/quic_versions.cc b/net/quic/core/quic_versions.cc index a26aa2dd..6873776 100644 --- a/net/quic/core/quic_versions.cc +++ b/net/quic/core/quic_versions.cc
@@ -30,8 +30,15 @@ QuicVersionVector filtered_versions(versions.size()); filtered_versions.clear(); // Guaranteed by spec not to change capacity. for (QuicVersion version : versions) { - if (version == QUIC_VERSION_38) { - if (FLAGS_quic_enable_version_38 && + if (version == QUIC_VERSION_39) { + if (base::GetFlag(FLAGS_quic_enable_version_39) && + FLAGS_quic_reloadable_flag_quic_enable_version_38 && + FLAGS_quic_reloadable_flag_quic_enable_version_37 && + FLAGS_quic_reloadable_flag_quic_enable_version_36_v3) { + filtered_versions.push_back(version); + } + } else if (version == QUIC_VERSION_38) { + if (FLAGS_quic_reloadable_flag_quic_enable_version_38 && FLAGS_quic_reloadable_flag_quic_enable_version_37 && FLAGS_quic_reloadable_flag_quic_enable_version_36_v3) { filtered_versions.push_back(version); @@ -79,6 +86,8 @@ return MakeQuicTag('Q', '0', '3', '7'); case QUIC_VERSION_38: return MakeQuicTag('Q', '0', '3', '8'); + case QUIC_VERSION_39: + return MakeQuicTag('Q', '0', '3', '9'); default: // This shold be an ERROR because we should never attempt to convert an // invalid QuicVersion to be written to the wire. @@ -110,6 +119,7 @@ RETURN_STRING_LITERAL(QUIC_VERSION_36); RETURN_STRING_LITERAL(QUIC_VERSION_37); RETURN_STRING_LITERAL(QUIC_VERSION_38); + RETURN_STRING_LITERAL(QUIC_VERSION_39); default: return "QUIC_VERSION_UNSUPPORTED"; }
diff --git a/net/quic/core/quic_versions.h b/net/quic/core/quic_versions.h index 546f16b..9d3e457c 100644 --- a/net/quic/core/quic_versions.h +++ b/net/quic/core/quic_versions.h
@@ -29,7 +29,9 @@ QUIC_VERSION_35 = 35, // Allows endpoints to independently set stream limit. QUIC_VERSION_36 = 36, // Add support to force HOL blocking. QUIC_VERSION_37 = 37, // Add perspective into null encryption. - QUIC_VERSION_38 = 38, // Experimental support for HTTP stream pairs + QUIC_VERSION_38 = 38, // PADDING frame is a 1-byte frame with type 0x00. + // Respect NSTP connection option. + QUIC_VERSION_39 = 39, // Experimental support for HTTP stream pairs // and HPACK HoL avoidance. // IMPORTANT: if you are adding to this list, follow the instructions at @@ -44,8 +46,8 @@ // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions static const QuicVersion kSupportedQuicVersions[] = { - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_36, QUIC_VERSION_35, - QUIC_VERSION_34}; + QUIC_VERSION_39, QUIC_VERSION_38, QUIC_VERSION_37, + QUIC_VERSION_36, QUIC_VERSION_35, QUIC_VERSION_34}; typedef std::vector<QuicVersion> QuicVersionVector;
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index adf9df17a..d9e3da8 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc
@@ -18,6 +18,7 @@ #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_packet_creator.h" #include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_endian.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_ptr_util.h" #include "net/quic/test_tools/crypto_test_utils.h" @@ -127,6 +128,15 @@ } } +QuicConnectionId GetPeerInMemoryConnectionId(QuicConnectionId connection_id) { + if (FLAGS_quic_restart_flag_quic_big_endian_connection_id_client == + FLAGS_quic_restart_flag_quic_big_endian_connection_id_server) { + // Both endpoints have same endianess. + return connection_id; + } + return net::QuicEndian::NetToHost64(connection_id); +} + MockFramerVisitor::MockFramerVisitor() { // By default, we want to accept packets. ON_CALL(*this, OnProtocolVersionMismatch(_)) @@ -263,23 +273,29 @@ MockQuicConnection::MockQuicConnection(MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, Perspective perspective) - : MockQuicConnection(kTestConnectionId, - QuicSocketAddress(TestPeerIPAddress(), kTestPort), - helper, - alarm_factory, - perspective, - AllSupportedVersions()) {} + : MockQuicConnection( + QuicUtils::IsConnectionIdWireFormatBigEndian(perspective) + ? QuicEndian::NetToHost64(kTestConnectionId) + : kTestConnectionId, + QuicSocketAddress(TestPeerIPAddress(), kTestPort), + helper, + alarm_factory, + perspective, + AllSupportedVersions()) {} MockQuicConnection::MockQuicConnection(QuicSocketAddress address, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, Perspective perspective) - : MockQuicConnection(kTestConnectionId, - address, - helper, - alarm_factory, - perspective, - AllSupportedVersions()) {} + : MockQuicConnection( + QuicUtils::IsConnectionIdWireFormatBigEndian(perspective) + ? QuicEndian::NetToHost64(kTestConnectionId) + : kTestConnectionId, + address, + helper, + alarm_factory, + perspective, + AllSupportedVersions()) {} MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id, MockQuicConnectionHelper* helper, @@ -297,12 +313,15 @@ MockAlarmFactory* alarm_factory, Perspective perspective, const QuicVersionVector& supported_versions) - : MockQuicConnection(kTestConnectionId, - QuicSocketAddress(TestPeerIPAddress(), kTestPort), - helper, - alarm_factory, - perspective, - supported_versions) {} + : MockQuicConnection( + QuicUtils::IsConnectionIdWireFormatBigEndian(perspective) + ? QuicEndian::NetToHost64(kTestConnectionId) + : kTestConnectionId, + QuicSocketAddress(TestPeerIPAddress(), kTestPort), + helper, + alarm_factory, + perspective, + supported_versions) {} MockQuicConnection::MockQuicConnection( QuicConnectionId connection_id,
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index a53d2fb..6c046d0 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h
@@ -190,6 +190,10 @@ // Compute SHA-1 hash of the supplied std::string. std::string Sha1Hash(QuicStringPiece data); +// Given endpoint in memory |connection_id|, returns peer's in memory connection +// id. +QuicConnectionId GetPeerInMemoryConnectionId(QuicConnectionId connection_id); + // Simple random number generator used to compute random numbers suitable // for pseudo-randomly dropping packets in tests. It works by computing // the sha1 hash of the current seed, and using the first 64 bits as
diff --git a/net/quic/test_tools/simulator/quic_endpoint_test.cc b/net/quic/test_tools/simulator/quic_endpoint_test.cc index 9962b55..5a13673 100644 --- a/net/quic/test_tools/simulator/quic_endpoint_test.cc +++ b/net/quic/test_tools/simulator/quic_endpoint_test.cc
@@ -16,6 +16,7 @@ using ::testing::_; using ::testing::NiceMock; using ::testing::Return; +using net::test::GetPeerInMemoryConnectionId; namespace net { namespace simulator { @@ -48,7 +49,8 @@ QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B", Perspective::IS_CLIENT, 42); QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A", - Perspective::IS_SERVER, 42); + Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(42)); auto link_a = Link(&endpoint_a, switch_.port(1)); auto link_b = Link(&endpoint_b, switch_.port(2)); @@ -83,7 +85,8 @@ QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B", Perspective::IS_CLIENT, 42); QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A", - Perspective::IS_SERVER, 42); + Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(42)); auto link_a = Link(&endpoint_a, switch_.port(1)); auto link_b = Link(&endpoint_b, switch_.port(2)); @@ -123,7 +126,8 @@ QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B", Perspective::IS_CLIENT, 42); QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A", - Perspective::IS_SERVER, 42); + Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(42)); auto link_a = Link(&endpoint_a, switch_.port(1)); auto link_b = Link(&endpoint_b, switch_.port(2)); @@ -153,11 +157,14 @@ auto endpoint_c = QuicMakeUnique<QuicEndpoint>( &simulator_, "Endpoint C", "Endpoint D (C)", Perspective::IS_CLIENT, 44); auto endpoint_d_a = QuicMakeUnique<QuicEndpoint>( - &simulator_, "Endpoint D (A)", "Endpoint A", Perspective::IS_SERVER, 42); + &simulator_, "Endpoint D (A)", "Endpoint A", Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(42)); auto endpoint_d_b = QuicMakeUnique<QuicEndpoint>( - &simulator_, "Endpoint D (B)", "Endpoint B", Perspective::IS_SERVER, 43); + &simulator_, "Endpoint D (B)", "Endpoint B", Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(43)); auto endpoint_d_c = QuicMakeUnique<QuicEndpoint>( - &simulator_, "Endpoint D (C)", "Endpoint C", Perspective::IS_SERVER, 44); + &simulator_, "Endpoint D (C)", "Endpoint C", Perspective::IS_SERVER, + GetPeerInMemoryConnectionId(44)); QuicEndpointMultiplexer endpoint_d( "Endpoint D", {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()});
diff --git a/net/tools/quic/chlo_extractor_test.cc b/net/tools/quic/chlo_extractor_test.cc index f314df67..df069ca 100644 --- a/net/tools/quic/chlo_extractor_test.cc +++ b/net/tools/quic/chlo_extractor_test.cc
@@ -94,7 +94,8 @@ EXPECT_TRUE(ChloExtractor::Extract(*packet_, versions, &delegate_)) << QuicVersionToString(version); EXPECT_EQ(version, delegate_.version()); - EXPECT_EQ(header_.public_header.connection_id, delegate_.connection_id()); + EXPECT_EQ(GetPeerInMemoryConnectionId(header_.public_header.connection_id), + delegate_.connection_id()); EXPECT_EQ(client_hello.DebugString(Perspective::IS_SERVER), delegate_.chlo()) << QuicVersionToString(version);
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index e41e8bb..08d2e43 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -86,7 +86,9 @@ QuicTag congestion_control_tag, bool disable_hpack_dynamic_table, bool force_hol_blocking, - bool use_cheap_stateless_reject) + bool use_cheap_stateless_reject, + bool connection_id_big_endian_client, + bool connection_id_big_endian_server) : client_supported_versions(client_supported_versions), server_supported_versions(server_supported_versions), negotiated_version(negotiated_version), @@ -96,7 +98,9 @@ congestion_control_tag(congestion_control_tag), disable_hpack_dynamic_table(disable_hpack_dynamic_table), force_hol_blocking(force_hol_blocking), - use_cheap_stateless_reject(use_cheap_stateless_reject) {} + use_cheap_stateless_reject(use_cheap_stateless_reject), + connection_id_big_endian_client(connection_id_big_endian_client), + connection_id_big_endian_server(connection_id_big_endian_server) {} friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { os << "{ server_supported_versions: " @@ -112,8 +116,11 @@ << QuicTagToString(p.congestion_control_tag); os << " disable_hpack_dynamic_table: " << p.disable_hpack_dynamic_table; os << " force_hol_blocking: " << p.force_hol_blocking; - os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject - << " }"; + os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject; + os << " connection_id_big_endian_client: " + << p.connection_id_big_endian_client; + os << " connection_id_big_endian_server: " + << p.connection_id_big_endian_server << " }"; return os; } @@ -126,6 +133,8 @@ bool disable_hpack_dynamic_table; bool force_hol_blocking; bool use_cheap_stateless_reject; + bool connection_id_big_endian_client; + bool connection_id_big_endian_server; }; // Constructs various test permutations. @@ -152,7 +161,7 @@ // This must be kept in sync with the number of nested for-loops below as it // is used to prune the number of tests that are run. - const int kMaxEnabledOptions = 5; + const int kMaxEnabledOptions = 7; int max_enabled_options = 0; std::vector<TestParams> params; for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) { @@ -161,79 +170,96 @@ for (bool disable_hpack_dynamic_table : {false}) { for (bool force_hol_blocking : {true, false}) { for (bool use_cheap_stateless_reject : {true, false}) { - int enabled_options = 0; - if (force_hol_blocking) { - ++enabled_options; - } - if (congestion_control_tag != kQBIC) { - ++enabled_options; - } - if (disable_hpack_dynamic_table) { - ++enabled_options; - } - if (client_supports_stateless_rejects) { - ++enabled_options; - } - if (server_uses_stateless_rejects_if_peer_supported) { - ++enabled_options; - } - if (use_cheap_stateless_reject) { - ++enabled_options; - } - CHECK_GE(kMaxEnabledOptions, enabled_options); - if (enabled_options > max_enabled_options) { - max_enabled_options = enabled_options; - } + for (bool connection_id_big_endian_client : {true, false}) { + for (bool connection_id_big_endian_server : {true, false}) { + int enabled_options = 0; + if (force_hol_blocking) { + ++enabled_options; + } + if (congestion_control_tag != kQBIC) { + ++enabled_options; + } + if (disable_hpack_dynamic_table) { + ++enabled_options; + } + if (client_supports_stateless_rejects) { + ++enabled_options; + } + if (server_uses_stateless_rejects_if_peer_supported) { + ++enabled_options; + } + if (use_cheap_stateless_reject) { + ++enabled_options; + } + if (connection_id_big_endian_server) { + ++enabled_options; + } + if (connection_id_big_endian_client) { + ++enabled_options; + } + CHECK_GE(kMaxEnabledOptions, enabled_options); + if (enabled_options > max_enabled_options) { + max_enabled_options = enabled_options; + } - // Run tests with no options, a single option, or all the - // options enabled to avoid a combinatorial explosion. - if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) { - continue; - } - - for (const QuicVersionVector& client_versions : version_buckets) { - CHECK(!client_versions.empty()); - if (FilterSupportedVersions(client_versions).empty()) { - continue; - } - // Add an entry for server and client supporting all - // versions. - params.push_back(TestParams( - client_versions, all_supported_versions, - client_versions.front(), client_supports_stateless_rejects, - server_uses_stateless_rejects_if_peer_supported, - congestion_control_tag, disable_hpack_dynamic_table, - force_hol_blocking, use_cheap_stateless_reject)); - - // Run version negotiation tests tests with no options, or - // all the options enabled to avoid a combinatorial - // explosion. - if (enabled_options > 1 && - enabled_options < kMaxEnabledOptions) { - continue; - } - - // Test client supporting all versions and server supporting - // 1 version. Simulate an old server and exercise version - // downgrade in the client. Protocol negotiation should - // occur. Skip the i = 0 case because it is essentially the - // same as the default case. - for (size_t i = 1; i < client_versions.size(); ++i) { - QuicVersionVector server_supported_versions; - server_supported_versions.push_back(client_versions[i]); - if (FilterSupportedVersions(server_supported_versions) - .empty()) { + // Run tests with no options, a single option, or all the + // options enabled to avoid a combinatorial explosion. + if (enabled_options > 1 && + enabled_options < kMaxEnabledOptions) { continue; } - params.push_back(TestParams( - client_versions, server_supported_versions, - server_supported_versions.front(), - client_supports_stateless_rejects, - server_uses_stateless_rejects_if_peer_supported, - congestion_control_tag, disable_hpack_dynamic_table, - force_hol_blocking, use_cheap_stateless_reject)); - } // End of version for loop. - } // End of 2nd version for loop. + + for (const QuicVersionVector& client_versions : + version_buckets) { + CHECK(!client_versions.empty()); + if (FilterSupportedVersions(client_versions).empty()) { + continue; + } + // Add an entry for server and client supporting all + // versions. + params.push_back(TestParams( + client_versions, all_supported_versions, + client_versions.front(), + client_supports_stateless_rejects, + server_uses_stateless_rejects_if_peer_supported, + congestion_control_tag, disable_hpack_dynamic_table, + force_hol_blocking, use_cheap_stateless_reject, + connection_id_big_endian_client, + connection_id_big_endian_server)); + + // Run version negotiation tests tests with no options, or + // all the options enabled to avoid a combinatorial + // explosion. + if (enabled_options > 1 && + enabled_options < kMaxEnabledOptions) { + continue; + } + + // Test client supporting all versions and server supporting + // 1 version. Simulate an old server and exercise version + // downgrade in the client. Protocol negotiation should + // occur. Skip the i = 0 case because it is essentially the + // same as the default case. + for (size_t i = 1; i < client_versions.size(); ++i) { + QuicVersionVector server_supported_versions; + server_supported_versions.push_back(client_versions[i]); + if (FilterSupportedVersions(server_supported_versions) + .empty()) { + continue; + } + params.push_back(TestParams( + client_versions, server_supported_versions, + server_supported_versions.front(), + client_supports_stateless_rejects, + server_uses_stateless_rejects_if_peer_supported, + congestion_control_tag, disable_hpack_dynamic_table, + force_hol_blocking, use_cheap_stateless_reject, + connection_id_big_endian_client, + connection_id_big_endian_server)); + } // End of version for loop. + } // End of 2nd version for loop. + } // End of connection_id_big_endian_server + } // End of connection_id_big_endian_client } // End of use_cheap_stateless_reject for loop. } // End of force_hol_blocking loop. } // End of disable_hpack_dynamic_table for loop. @@ -306,6 +332,11 @@ AddToCache("/foo", 200, kFooResponseBody); AddToCache("/bar", 200, kBarResponseBody); + + FLAGS_quic_restart_flag_quic_big_endian_connection_id_client = + GetParam().connection_id_big_endian_client; + FLAGS_quic_restart_flag_quic_big_endian_connection_id_server = + GetParam().connection_id_big_endian_server; } ~EndToEndTest() override { @@ -2030,7 +2061,8 @@ QuicConnectionId connection_id = client_->client()->session()->connection()->connection_id(); QuicPublicResetPacket header; - header.public_header.connection_id = connection_id; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(connection_id); header.public_header.reset_flag = true; header.public_header.version_flag = false; header.rejected_packet_number = 10101; @@ -2063,7 +2095,8 @@ QuicConnectionId incorrect_connection_id = client_->client()->session()->connection()->connection_id() + 1; QuicPublicResetPacket header; - header.public_header.connection_id = incorrect_connection_id; + header.public_header.connection_id = + GetPeerInMemoryConnectionId(incorrect_connection_id); header.public_header.reset_flag = true; header.public_header.version_flag = false; header.rejected_packet_number = 10101; @@ -2128,8 +2161,9 @@ QuicConnectionId incorrect_connection_id = client_->client()->session()->connection()->connection_id() + 1; std::unique_ptr<QuicEncryptedPacket> packet( - QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id, - server_supported_versions_)); + QuicFramer::BuildVersionNegotiationPacket( + GetPeerInMemoryConnectionId(incorrect_connection_id), + server_supported_versions_)); testing::NiceMock<MockQuicConnectionDebugVisitor> visitor; client_->client()->session()->connection()->set_debug_visitor(&visitor); EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc index 1909450c..82c20e60 100644 --- a/net/tools/quic/quic_client_session_test.cc +++ b/net/tools/quic/quic_client_session_test.cc
@@ -267,8 +267,9 @@ // Verify that a non-decryptable packet doesn't close the connection. QuicConnectionId connection_id = session_->connection()->connection_id(); std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID, - PACKET_6BYTE_PACKET_NUMBER, nullptr, Perspective::IS_SERVER)); + GetPeerInMemoryConnectionId(connection_id), false, false, 100, "data", + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, nullptr, + Perspective::IS_SERVER)); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*packet, QuicTime::Zero())); // Change the last byte of the encrypted data. @@ -292,8 +293,9 @@ QuicConnectionId connection_id = session_->connection()->connection_id(); QuicVersionVector versions = {GetParam()}; std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket( - connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID, - PACKET_6BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER)); + GetPeerInMemoryConnectionId(connection_id), false, false, 100, "data", + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions, + Perspective::IS_SERVER)); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*packet, QuicTime::Zero())); EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 7731031e..38a4445 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -211,7 +211,8 @@ /*unused*/ QuicTime::Zero(), Perspective::IS_SERVER), last_error_(QUIC_NO_ERROR), - new_sessions_allowed_per_event_loop_(0u) { + new_sessions_allowed_per_event_loop_(0u), + accept_new_connections_(true) { framer_.set_visitor(this); } @@ -363,7 +364,7 @@ QuicPacketNumber packet_number) { switch (fate) { case kFateProcess: { - ProcessChlo(); + ProcessChlo(packet_number); break; } case kFateTimeWait: @@ -449,6 +450,10 @@ session_map_.erase(it); } +void QuicDispatcher::StopAcceptingNewConnections() { + accept_new_connections_ = false; +} + void QuicDispatcher::DeleteSessions() { closed_session_list_.clear(); } @@ -712,7 +717,19 @@ } } -void QuicDispatcher::ProcessChlo() { +void QuicDispatcher::ProcessChlo(QuicPacketNumber packet_number) { + if (!accept_new_connections_) { + // Don't any create new connection. + time_wait_list_manager()->AddConnectionIdToTimeWait( + current_connection_id(), framer()->version(), + /*connection_rejected_statelessly=*/false, + /*termination_packets=*/nullptr); + // This will trigger sending Public Reset packet. + time_wait_list_manager()->ProcessPacket( + current_server_address(), current_client_address(), + current_connection_id(), packet_number, current_packet()); + return; + } if (FLAGS_quic_reloadable_flag_quic_create_session_after_insertion && !buffered_packets_.HasBufferedPackets(current_connection_id_) && !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) {
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 0edcf78..132cd28 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h
@@ -204,7 +204,7 @@ // Called when |current_packet_| is a CHLO packet. Creates a new connection // and delivers any buffered packets for that connection id. - void ProcessChlo(); + void ProcessChlo(QuicPacketNumber packet_number); QuicTimeWaitListManager* time_wait_list_manager() { return time_wait_list_manager_.get(); @@ -274,19 +274,21 @@ QuicBufferedPacketStore::EnqueuePacketResult result, QuicConnectionId connection_id); + // Removes the session from the session map and write blocked list, and adds + // the ConnectionId to the time-wait list. If |session_closed_statelessly| is + // true, any future packets for the ConnectionId will be black-holed. + virtual void CleanUpSession(SessionMap::iterator it, + QuicConnection* connection, + bool session_closed_statelessly); + + void StopAcceptingNewConnections(); + private: friend class test::QuicDispatcherPeer; friend class StatelessRejectorProcessDoneCallback; typedef std::unordered_set<QuicConnectionId> QuicConnectionIdSet; - // Removes the session from the session map and write blocked list, and adds - // the ConnectionId to the time-wait list. If |session_closed_statelessly| is - // true, any future packets for the ConnectionId will be black-holed. - void CleanUpSession(SessionMap::iterator it, - QuicConnection* connection, - bool session_closed_statelessly); - bool HandlePacketForTimeWait(const QuicPacketPublicHeader& header); // Attempts to reject the connection statelessly, if stateless rejects are @@ -389,6 +391,9 @@ // event loop. When reaches 0, it means can't create sessions for now. int16_t new_sessions_allowed_per_event_loop_; + // True if this dispatcher is not draining. + bool accept_new_connections_; + DISALLOW_COPY_AND_ASSIGN(QuicDispatcher); };
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index 384236a..3c78e671 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -249,8 +249,9 @@ QuicPacketNumber packet_number) { QuicVersionVector versions(SupportedVersions(version)); std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - connection_id, has_version_flag, false, packet_number, data, - connection_id_length, packet_number_length, &versions)); + GetPeerInMemoryConnectionId(connection_id), has_version_flag, false, + packet_number, data, connection_id_length, packet_number_length, + &versions)); std::unique_ptr<QuicReceivedPacket> received_packet( ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); @@ -527,12 +528,13 @@ } TEST_F(QuicDispatcherTest, SupportedVersionsChangeInFlight) { - static_assert(arraysize(kSupportedQuicVersions) == 5u, + static_assert(arraysize(kSupportedQuicVersions) == 6u, "Supported versions out of sync"); FLAGS_quic_reloadable_flag_quic_disable_version_34 = false; FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 = true; FLAGS_quic_reloadable_flag_quic_enable_version_37 = true; - FLAGS_quic_enable_version_38 = true; + FLAGS_quic_reloadable_flag_quic_enable_version_38 = true; + base::SetFlag(&FLAGS_quic_enable_version_39, true); QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5); QuicConnectionId connection_id = 1; @@ -570,6 +572,33 @@ ProcessPacket(client_address, connection_id, true, QuicVersionMax(), SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); + + // Turn off version 39. + base::SetFlag(&FLAGS_quic_enable_version_39, false); + ++connection_id; + EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) + .Times(0); + ProcessPacket(client_address, connection_id, true, QUIC_VERSION_39, + SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, + PACKET_6BYTE_PACKET_NUMBER, 1); + + // Turn on version 39. + base::SetFlag(&FLAGS_quic_enable_version_39, true); + ++connection_id; + EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) + .WillOnce(testing::Return(CreateSession( + dispatcher_.get(), config_, connection_id, client_address, + &mock_helper_, &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))); + ProcessPacket(client_address, connection_id, true, QUIC_VERSION_39, + SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, + PACKET_6BYTE_PACKET_NUMBER, 1); + // Turn off version 36. FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 = false; ++connection_id;
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc index 0ff4f8d..6ff7b87 100644 --- a/net/tools/quic/quic_time_wait_list_manager_test.cc +++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -159,7 +159,8 @@ std::tr1::get<1>(packet_buffer)); framer.ProcessPacket(encrypted); QuicPublicResetPacket packet = visitor.public_reset_packet(); - return connection_id_ == packet.public_header.connection_id && + return connection_id_ == GetPeerInMemoryConnectionId( + packet.public_header.connection_id) && packet.public_header.reset_flag && !packet.public_header.version_flag && packet_number_ == packet.rejected_packet_number &&
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc index b2e914b3..aec4d3f 100644 --- a/printing/pdf_metafile_skia.cc +++ b/printing/pdf_metafile_skia.cc
@@ -12,9 +12,9 @@ #include "base/files/file.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" -#include "cc/paint/paint_canvas.h" #include "cc/paint/paint_record.h" #include "cc/paint/paint_recorder.h" +#include "cc/paint/skia_paint_canvas.h" #include "printing/print_settings.h" #include "third_party/skia/include/core/SkDocument.h" #include "third_party/skia/include/core/SkStream.h"
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 0e013c71..8603b4d 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -229,6 +229,44 @@ "test": "cc_unittests" }, { + "args": [ + "--shared-prefs-file=../../chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", + "--additional-apk=../../third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk" + ], + "override_compile_targets": [ + "chrome_public_test_vr_apk" + ], + "override_isolate_target": "chrome_public_test_vr_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "android_devices": "4", + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "chrome_public_test_vr_apk" + }, + { "override_compile_targets": [ "chrome_sync_shell_test_apk" ], @@ -2294,6 +2332,46 @@ "test": "chrome_public_test_apk" }, { + "args": [ + "--shared-prefs-file=../../chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", + "--additional-apk=../../third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk" + ], + "override_compile_targets": [ + "chrome_public_test_vr_apk" + ], + "override_isolate_target": "chrome_public_test_vr_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "android_devices": "4", + "device_os": "LMY48I", + "device_type": "hammerhead" + } + ], + "expiration": 10800, + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "chrome_public_test_vr_apk" + }, + { "override_compile_targets": [ "chrome_sync_shell_test_apk" ], @@ -2769,6 +2847,45 @@ }, { "args": [ + "--shared-prefs-file=../../chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", + "--additional-apk=../../third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk" + ], + "override_compile_targets": [ + "chrome_public_test_vr_apk" + ], + "override_isolate_target": "chrome_public_test_vr_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "android_devices": "4", + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "chrome_public_test_vr_apk" + }, + { + "args": [ "--enable-browser-side-navigation" ], "name": "browser_side_navigation_chrome_public_test_apk",
diff --git a/testing/buildbot/chromium.memory.full.json b/testing/buildbot/chromium.memory.full.json deleted file mode 100644 index aaee5cab..0000000 --- a/testing/buildbot/chromium.memory.full.json +++ /dev/null
@@ -1,625 +0,0 @@ -{ - "Linux ChromeOS MSan Tests": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - } - ] - }, - "Linux MSan Tests": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - } - ] - } -}
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index b8d65ca..1e18c5e 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -4813,36 +4813,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build245-m4--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -16540,36 +16510,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:22b1", - "id": "build141-b1", - "os": "Windows-10-10586", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -28187,36 +28127,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:9874", - "id": "build205-b4", - "os": "Windows-10-10586", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results",
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index ee533c94..747eac1 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -4920,36 +4920,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build149-m1", - "os": "Ubuntu-14.04", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -16587,36 +16557,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0166", - "id": "build103-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -28214,36 +28154,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "id": "build159-m1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -39841,36 +39751,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1626", - "id": "build124-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -51468,36 +51348,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a26", - "id": "build25-b1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -63095,36 +62945,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6821", - "id": "build129-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -74722,36 +74542,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0d26", - "id": "build5-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -86349,36 +86139,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1616", - "id": "build118-b1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -97996,36 +97756,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build133-m1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -109703,36 +109433,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "id": "build102-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -121390,36 +121090,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "id": "build165-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -133097,36 +132767,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "id": "build93-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -144784,36 +144424,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build186-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -156451,36 +156061,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build139-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -168138,36 +167718,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build144-m1", - "os": "Windows-2012ServerR2-SP0", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results", @@ -179765,36 +179315,6 @@ }, { "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "power.idle_platform.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:161e", - "id": "build31-b1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 36000, - "hard_timeout": 7200, - "ignore_task_failure": true, - "io_timeout": 3600 - } - }, - { - "args": [ "power.steady_state", "-v", "--upload-results",
diff --git a/testing/clusterfuzz/OWNERS b/testing/clusterfuzz/OWNERS index 70d27b6..104ea60 100644 --- a/testing/clusterfuzz/OWNERS +++ b/testing/clusterfuzz/OWNERS
@@ -1,3 +1,5 @@ inferno@chromium.org mmoroz@chromium.org ochang@chromium.org + +# COMPONENT: Tools>Stability>Clusterfuzz
diff --git a/testing/libfuzzer/OWNERS b/testing/libfuzzer/OWNERS index 62642811..db0983f92 100644 --- a/testing/libfuzzer/OWNERS +++ b/testing/libfuzzer/OWNERS
@@ -3,3 +3,5 @@ kcc@chromium.org krasin@chromium.org mmoroz@chromium.org + +# COMPONENT: Tools>Stability>Clusterfuzz
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7f9d0b1a..10b7205 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -125,6 +125,19 @@ # ====== Paint team owned tests to here ====== +# ====== Layout team owned tests from here ====== + +#### external/wpt/css/CSS2/floats +#### Passed: 37 +#### Skipped: 5 +crbug.com/711704 external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht [ Skip ] +crbug.com/711704 external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht [ Skip ] +crbug.com/711704 external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht [ Skip ] +crbug.com/711704 external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht [ Skip ] +crbug.com/711704 external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht [ Skip ] + +# ====== Layout team owned tests to here ====== + # ====== LayoutNG-only failures from here ====== # LayoutNG - is a new layout system for Blink. @@ -1546,8 +1559,8 @@ crbug.com/545140 [ Mac10.10 Mac10.11 Retina Mac10.12 ] fast/encoding/denormalised-voiced-japanese-chars.html [ Failure ] -crbug.com/636248 [ Mac ] http/tests/security/img-crossorigin-no-credentials-prompt.html [ Failure Pass ] -crbug.com/636248 [ Mac ] virtual/mojo-loading/http/tests/security/img-crossorigin-no-credentials-prompt.html [ Failure Pass ] +crbug.com/636248 http/tests/security/img-crossorigin-no-credentials-prompt.html [ Failure Pass ] +crbug.com/636248 virtual/mojo-loading/http/tests/security/img-crossorigin-no-credentials-prompt.html [ Failure Pass ] crbug.com/509025 [ Mac10.10 ] fast/events/context-no-deselect.html [ Failure ] crbug.com/509025 [ Mac10.10 ] virtual/rootlayerscrolls/scrollbars/rtl/overflow-scroll-rtl.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index 365a96b..b13c59f 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -82,7 +82,8 @@ external/wpt/css/CSS2/css1 [ Skip ] external/wpt/css/CSS2/css21-errata [ Skip ] external/wpt/css/CSS2/csswg-issues [ Skip ] -external/wpt/css/CSS2/floats [ Skip ] +## Owners: glebl@chromium.org +# external/wpt/css/CSS2/floats [ Pass ] external/wpt/css/CSS2/floats-clear [ Skip ] external/wpt/css/CSS2/fonts [ Skip ] external/wpt/css/CSS2/generate [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001-ref.xht new file mode 100644 index 0000000..15ff213 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001-ref.xht
@@ -0,0 +1,21 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for float placement rules (reference)</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } +</style> +</head> +<body style="width:400px;"> +<p><span class="left"></span>HelloKitty +</p><p><span class="right"></span>HelloKitty +</p><p dir="rtl"><span class="left"></span>HelloKitty +</p><p dir="rtl"><span class="right"></span>HelloKitty +</p><p style="text-align:right;"><span class="left"></span>HelloKitty +</p><p style="text-align:right;"><span class="right"></span>HelloKitty + + +</p></body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001a.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001a.xht new file mode 100644 index 0000000..07de028 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001a.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for float placement rules</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#float-position" /> +<link rel="match" href="floats-placement-vertical-001-ref.xht"/> +<meta name="assert" content="A floating box must be placed as high as possible. " /> +<meta name="flags" content="" /> +<style type="text/css"> +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } +</style> +</head> +<body style="width:400px;"> +<p>Hello<span class="left"></span>Kitty +</p><p>Hello<span class="right"></span>Kitty +</p><p dir="rtl">Hello<span class="left"></span>Kitty +</p><p dir="rtl">Hello<span class="right"></span>Kitty +</p><p style="text-align:right;">Hello<span class="left"></span>Kitty +</p><p style="text-align:right;">Hello<span class="right"></span>Kitty + + +</p></body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001b.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001b.xht new file mode 100644 index 0000000..233cda23 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001b.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for float placement rules</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#float-position" /> +<link rel="match" href="floats-placement-vertical-001-ref.xht"/> +<meta name="assert" content="A floating box must be placed as high as possible. " /> +<meta name="flags" content="" /> +<style type="text/css"> +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } +</style> +</head> +<body style="width:400px"> +<p><span>Hello<span class="left"></span></span>Kitty +</p><p><span>Hello<span class="right"></span></span>Kitty +</p><p dir="rtl"><span>Hello<span class="left"></span></span>Kitty +</p><p dir="rtl"><span>Hello<span class="right"></span></span>Kitty +</p><p style="text-align:right;"><span>Hello<span class="left"></span></span>Kitty +</p><p style="text-align:right;"><span>Hello<span class="right"></span></span>Kitty + + +</p></body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001c.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001c.xht new file mode 100644 index 0000000..894cb01 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-001c.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for float placement rules</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#float-position" /> +<link rel="match" href="floats-placement-vertical-001-ref.xht"/> +<meta name="assert" content="A floating box must be placed as high as possible. " /> +<meta name="flags" content="" /> +<style type="text/css"> +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } +</style> +</head> +<body style="width:400px;"> +<p>Hello<span><span class="left"></span>Kitty</span> +</p><p>Hello<span><span class="right"></span>Kitty</span> +</p><p dir="rtl">Hello<span><span class="left"></span>Kitty</span> +</p><p dir="rtl">Hello<span><span class="right"></span>Kitty</span> +</p><p style="text-align:right;">Hello<span><span class="left"></span>Kitty</span> +</p><p style="text-align:right;">Hello<span><span class="right"></span>Kitty</span> + + +</p></body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003-ref.xht new file mode 100644 index 0000000..f89b9e7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003-ref.xht
@@ -0,0 +1,12 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: Test for float placement rules (reference)</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +</head><body style="width:100px; font-size:5px;"> +<!-- Check that we don't allow floats to reorder --> +H +<div style="background:blue; width:100px; height:100px;"></div> +<div style="background:yellow; width:30px; height:30px; float:left;"></div> +<div style="background:yellow; width:30px; height:30px; float:right;"></div> + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003.xht new file mode 100644 index 0000000..bad9d39b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-003.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: Test for float placement rules</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#float-position" /> +<link rel="match" href="floats-placement-vertical-003-ref.xht"/> +<meta name="assert" content="The outer top of a floating box may not be higher than the outer top of any block or floated box generated by an element earlier in the source document." /> +<meta name="assert" content="A floating box must be placed as high as possible. " /> +<meta name="flags" content="" /> +</head><body style="width:100px; font-size:5px;"> +<!-- Check that we don't allow floats to reorder --> +H +<div style="background:blue; width:100px; height:100px; float:left;"></div> +<div style="background:yellow; width:30px; height:30px; float:left;"></div> +<div style="background:yellow; width:30px; height:30px; float:right;"></div> + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref.xht new file mode 100644 index 0000000..9e2cd46 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref.xht
@@ -0,0 +1,11 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: Test for float placement rules (reference)</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="match" href="floats-placement-vertical-004-ref2.xht"/> +</head><body style="width:200px; font-size:5px;"> +<div style="background:green; width:100px; height:100px; float:left;"></div> +H<br /> +<div style="background:blue; width:100px; height:100px; float:left;"></div> + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref2.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref2.xht new file mode 100644 index 0000000..97b2630 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004-ref2.xht
@@ -0,0 +1,13 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: Test for float placement rules (reference)</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="match" href="floats-placement-vertical-004-ref.xht"/> +</head><body style="width:200px; font-size:5px;"> +<div style="position:absolute; background:green; width:100px; height:100px;"></div> +<div style="position:relative; left:100px; width:100px; height:100px;"> + H + <div style="background:blue; width:100px; height:100px;"></div> +</div> + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004.xht new file mode 100644 index 0000000..d629f5a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-placement-vertical-004.xht
@@ -0,0 +1,16 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: Test for float placement rules</title> +<link rel="author" title="Robert O'Callahan" href="mailto:robert@ocallahan.org" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#float-position" /> +<link rel="match" href="floats-placement-vertical-004-ref.xht"/> +<meta name="assert" content="A floating box must be placed as high as possible. " /> +<meta name="flags" content="" /> +</head><body style="width:200px; font-size:5px;"> +<!-- Check that we're actually taking inline content already in the line into account + when we check whether the blue float fits --> +<div style="background:green; width:100px; height:100px; float:left;"></div> +H +<div style="background:blue; width:100px; height:100px; float:left;"></div> + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001-ref.xht new file mode 100644 index 0000000..a401cd41 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001-ref.xht
@@ -0,0 +1,6 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> + +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="width: 425px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001.xht new file mode 100644 index 0000000..8a510dd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-001.xht
@@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule3-outside-left-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 3 says: + + The right outer edge of a left-floating box may not be to the right + of the left outer edge of any right-floating box that is to the + right of it. Analogous rules hold for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: right; width: 50px; height: 300px"></div> + + <div style="margin-right: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: left; width: 425px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002-ref.xht new file mode 100644 index 0000000..f16aba29 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002-ref.xht
@@ -0,0 +1,5 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="margin-top: 300px; width: 475px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht new file mode 100644 index 0000000..c9965f8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht
@@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule3-outside-left-002-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 3 says: + + The right outer edge of a left-floating box may not be to the right + of the left outer edge of any right-floating box that is to the + right of it. Analogous rules hold for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: right; width: 50px; height: 300px"></div> + + <div style="margin-right: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: left; width: 475px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001-ref.xht new file mode 100644 index 0000000..1495741 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001-ref.xht
@@ -0,0 +1,5 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="margin-left: 75px; width: 425px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001.xht new file mode 100644 index 0000000..6ab45db --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-001.xht
@@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule3-outside-right-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 3 says: + + The right outer edge of a left-floating box may not be to the right + of the left outer edge of any right-floating box that is to the + right of it. Analogous rules hold for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: left; width: 50px; height: 300px"></div> + + <div style="margin-left: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: right; width: 425px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002-ref.xht new file mode 100644 index 0000000..e95714e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002-ref.xht
@@ -0,0 +1,5 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="margin-top: 300px; margin-left: 25px; width: 475px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht new file mode 100644 index 0000000..b17fcedb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht
@@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule3-outside-right-002-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 3 says: + + The right outer edge of a left-floating box may not be to the right + of the left outer edge of any right-floating box that is to the + right of it. Analogous rules hold for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: left; width: 50px; height: 300px"></div> + + <div style="margin-left: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: right; width: 475px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001-ref.xht new file mode 100644 index 0000000..546e2ae4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001-ref.xht
@@ -0,0 +1,5 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="margin-top: 300px; margin-left: 100px; width: 425px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht new file mode 100644 index 0000000..a6494d2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-left-001.xht
@@ -0,0 +1,33 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule7-outside-left-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 7 says: + + A left-floating box that has another left-floating box to its left + may not have its right outer edge to the right of its containing + block's right edge. (Loosely: a left float may not stick out at the + right edge, unless it is already as far to the left as possible.) An + analogous rule holds for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: left; width: 50px; height: 300px"></div> + + <div style="margin-left: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: left; width: 425px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001-ref.xht new file mode 100644 index 0000000..69e1a26 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001-ref.xht
@@ -0,0 +1,5 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for float placement around other float in BFC but outside containing block</title> +</head><body><div style="float: left; width: 500px; height: 500px"> + <div style="margin-top: 300px; margin-left: -25px; width: 425px; height: 10px; background: blue"></div> +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht new file mode 100644 index 0000000..0ebd9a62 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht
@@ -0,0 +1,33 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: float placement around other float in BFC but outside containing block</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-rule7-outside-right-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="Test for float placement around other float in BFC but outside containing block" /> + +<!-- + CSS2.1 9.5.1 rule 7 says: + + A left-floating box that has another left-floating box to its left + may not have its right outer edge to the right of its containing + block's right edge. (Loosely: a left float may not stick out at the + right edge, unless it is already as far to the left as possible.) An + analogous rule holds for right-floating elements. + + --> + +<!-- the block formatting context inside which we're testing --> +</head><body><div style="float: left; width: 500px; height: 500px"> + + <div style="float: right; width: 50px; height: 300px"></div> + + <div style="margin-right: 100px"> <!-- 400px wide --> + + <!-- we're testing the position of this float --> + <div style="float: right; width: 425px; height: 10px; background: blue"></div> + + </div> + +</div> +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow-ref.xht new file mode 100644 index 0000000..9d4c968 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow-ref.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:yellow; width: 200px; height: 50px"> + <div style="background:purple; width: 150px; height: 50px"></div> + </div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht new file mode 100644 index 0000000..becaa112 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-001-left-overflow-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 150px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table-ref.xht new file mode 100644 index 0000000..4b3b439c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:purple; width: 150px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table.xht new file mode 100644 index 0000000..82ebc88 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-table.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-001-left-table-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 150px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow-ref.xht new file mode 100644 index 0000000..00fc8fe6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow-ref.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:yellow; width: 200px; height: 50px"> + <div style="background:purple; width: 150px; height: 50px"></div> + </div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow.xht new file mode 100644 index 0000000..c9ab2da --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-overflow.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-001-right-overflow-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 150px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table-ref.xht new file mode 100644 index 0000000..0b98fa08 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:purple; width: 150px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table.xht new file mode 100644 index 0000000..0735d33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-right-table.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-001-right-table-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 150px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht new file mode 100644 index 0000000..0aca5326 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht
@@ -0,0 +1,35 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-002-left-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 150px; height: 50px; background: purple"></span> + <span style="width: 150px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-ref.xht new file mode 100644 index 0000000..b118e94f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-ref.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:yellow; width: 200px; height: 100px"> + <div style="background:purple; width: 150px; height: 100px"></div> + </div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-table.xht new file mode 100644 index 0000000..7c69ac0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-table.xht
@@ -0,0 +1,35 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-002-left-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 150px; height: 50px; background: purple"></span> + <span style="width: 150px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-overflow.xht new file mode 100644 index 0000000..39029f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-overflow.xht
@@ -0,0 +1,35 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-002-right-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 150px; height: 50px; background: purple"></span> + <span style="width: 150px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-ref.xht new file mode 100644 index 0000000..bb377456 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-ref.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:yellow; width: 200px; height: 100px"> + <div style="background:purple; width: 150px; height: 100px"></div> + </div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-table.xht new file mode 100644 index 0000000..56bbf09 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-table.xht
@@ -0,0 +1,35 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-002-right-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 150px; height: 50px; background: purple"></span> + <span style="width: 150px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow-ref.xht new file mode 100644 index 0000000..41ed0d3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:purple; width: 200px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht new file mode 100644 index 0000000..17702f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-003-left-overflow-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 250px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table-ref.xht new file mode 100644 index 0000000..e9ddad7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 150px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; clear:left; background:purple; width: 250px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table.xht new file mode 100644 index 0000000..91e1405 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-003-left-table-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:left; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 250px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow-ref.xht new file mode 100644 index 0000000..42c7861 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 100px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; background:purple; width: 200px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht new file mode 100644 index 0000000..08f237b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-003-right-overflow-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <div style="overflow: hidden; background: yellow"> + <span style="width: 250px; height: 50px; background: purple"></span> + </div> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table-ref.xht new file mode 100644 index 0000000..768355e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table-ref.xht
@@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 150px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + <div style="float:left; clear:right; background:purple; width: 250px; height: 50px"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table.xht new file mode 100644 index 0000000..2cf65fc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-table.xht
@@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-003-right-table-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + span { display: inline-block; vertical-align: bottom; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + + <div style="float:right; background:blue; width: 100px; height: 100px"></div> + + <table style="background: yellow"><tbody><tr><td> + <span style="width: 250px; height: 50px; background: purple"></span> + </td></tr></tbody></table> + +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004-ref.xht new file mode 100644 index 0000000..fede0e5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004-ref.xht
@@ -0,0 +1,60 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> +</head> +<body> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 150px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 150px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 150px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 150px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 100px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 100px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 100px; height: 10px; background: purple"></div> +</div> + +<div style="width: 300px; height: 20px; background: aqua"> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="float:left; width: 100px; height: 10px; background: purple"></div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht new file mode 100644 index 0000000..0e92613 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht
@@ -0,0 +1,86 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-004-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <table style="background: yellow"><tbody><tr><td> + <div style="width: 150px; height: 10px; background: purple"></div> + </td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <table style="background: yellow"><tbody><tr><td> + <div style="width: 150px; height: 10px; background: purple"></div> + </td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <table style="background: yellow"><tbody><tr><td> + <div style="width: 150px; height: 10px; background: purple"></div> + </td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <table style="background: yellow"><tbody><tr><td> + <div style="width: 150px; height: 10px; background: purple"></div> + </td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="overflow: hidden; background: yellow"> + <div style="width: 150px; height: 10px; background: purple"></div> + </div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="overflow: hidden; background: yellow"> + <div style="width: 150px; height: 10px; background: purple"></div> + </div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:left; background:silver; width: 100px; height: 6px"></div> + <div style="overflow: hidden; background: yellow"> + <div style="width: 150px; height: 10px; background: purple"></div> + </div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 100px; height: 20px"></div> + <div style="float:right; background:silver; width: 100px; height: 6px"></div> + <div style="overflow: hidden; background: yellow"> + <div style="width: 150px; height: 10px; background: purple"></div> + </div> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005-ref.xht new file mode 100644 index 0000000..bb3190d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005-ref.xht
@@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + body { font-size: 10px; } + + </style> +</head> +<body> + +<div style="width: 300px; height: 40px;background: aqua"> + <div style="float:left; background:blue; width: 200px; height: 20px"></div> + <div style="float:left; clear: left; background: yellow; width: 150px; height: 20px">50%</div> +</div> + +<div style="width: 300px; height: 40px;background: aqua"> + <div style="float:right; background:blue; width: 200px; height: 20px"></div> + <div style="float:left; clear: right; background: yellow; width: 150px; height: 20px">50%</div> +</div> + +<div style="width: 300px; height: 40px;background: aqua"> + <div style="float:left; background:blue; width: 200px; height: 20px"></div> + <div style="float:left; clear: left; background: yellow; width: 150px; height: 20px">50%</div> +</div> + +<div style="width: 300px; height: 40px;background: aqua"> + <div style="float:right; background:blue; width: 200px; height: 20px"></div> + <div style="float:left; clear: right; background: yellow; width: 150px; height: 20px">50%</div> +</div> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005.xht new file mode 100644 index 0000000..341c668 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-005.xht
@@ -0,0 +1,44 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-005-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + body { font-size: 10px; } + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; vertical-align: top; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 200px; height: 20px"></div> + <table width="50%" style="background: yellow" height="20"><tbody><tr><td>50%</td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 200px; height: 20px"></div> + <table width="50%" style="background: yellow" height="20"><tbody><tr><td>50%</td></tr></tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; background:blue; width: 200px; height: 20px"></div> + <div style="overflow:hidden; background: yellow; width: 50%; height: 20px;">50%</div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:right; background:blue; width: 200px; height: 20px"></div> + <div style="overflow:hidden; background: yellow; width: 50%; height: 20px;">50%</div> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006-ref.xht new file mode 100644 index 0000000..59051f8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006-ref.xht
@@ -0,0 +1,177 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + body { font-size: 16px; } + + table { margin: 0; border-spacing: 0; } + caption, td, th { padding: 0; vertical-align: top; text-align: left; } + + .capref { background: yellow; } + .tabref { background: purple; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + + <div style="float:right; height: 30px; width: 100px; margin-right: 130px;" class="capref">Caption</div> + + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 230px;" class="tabref">Cell</div> + +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + + <div style="float:right; height: 30px; width: 190px;" class="capref">Caption</div> + + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 100px; margin-right: 90px;" class="tabref">Cell</div> + +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 227px;margin-right:3px;" class="tabref">Cell</div> + + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 100px;margin-right:130px;" class="capref">Caption</div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 100px; margin-right:95px;" class="tabref">Cell</div> + + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + + <div style="float:right; clear: right; height: 30px; width: 192px; margin-right:3px;" class="capref">Caption</div> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht new file mode 100644 index 0000000..1ecef61 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-006.xht
@@ -0,0 +1,175 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-006-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + body { font-size: 16px; } + + table { margin: 0; border-spacing: 0; } + caption, td, th { padding: 0; vertical-align: top; text-align: left; } + + table table caption { background: yellow; } + table table { background: purple; } + + </style> +</head> +<body> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + <table> + <caption style="caption-side: top; height:30px; width: 100px;">Caption</caption> + <tbody><tr><td><div style="height: 30px; width: 230px">Cell</div></td></tr> + </tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + <table> + <caption style="caption-side: top; height:30px; width: 190px;">Caption</caption> + <tbody><tr><td><div style="height: 30px; width: 100px">Cell</div></td></tr> + </tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + <table> + <caption style="caption-side: bottom; height:30px; width: 100px;">Caption</caption> + <tbody><tr><td><div style="height: 30px; width: 227px">Cell</div></td></tr> + </tbody></table> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float:left; clear:left; background:blue; width:150px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:145px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:140px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:135px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:130px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:125px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:120px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:115px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:110px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:105px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:100px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:95px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:90px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:85px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:80px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:75px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:70px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:65px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:60px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:55px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:50px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:45px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:40px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:35px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:30px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:25px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:20px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:15px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:10px; height:1px"></div> + <div style="float:left; clear:left; background:blue; width:5px; height:1px"></div> + <table> + <caption style="caption-side: bottom; height:30px; width: 192px;">Caption</caption> + <tbody><tr><td><div style="height: 30px; width: 100px">Cell</div></td></tr> + </tbody></table> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007-ref.xht new file mode 100644 index 0000000..f67bd79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007-ref.xht
@@ -0,0 +1,110 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats (reference)</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; vertical-align: top; } + + </style> +</head> +<body> + +<!-- 6px margin between (from top, from bottom, from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow; margin-top: 1px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow; margin-top: 1px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow; margin-top: 1px;"></div> +</td></tr></tbody></table> + +<!-- 5px margin between (from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<!-- 4px margin between (from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<!-- negative margin between --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="float: left; clear: left; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007.xht new file mode 100644 index 0000000..0d023e7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-007.xht
@@ -0,0 +1,114 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head> + <title>CSS Test: Test for flow around floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-007-ref.xht"/> + <meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> + <meta name="flags" content="" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <style type="text/css"> + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; vertical-align: top; } + + </style> +</head> +<body> + +<!-- 6px margin between (from top, from bottom, from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 6px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 6px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 6px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 6px;"></div> +</td></tr></tbody></table> + +<!-- 5px margin between (from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 5px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 5px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 10px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -5px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -5px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 10px;"></div> +</td></tr></tbody></table> + +<!-- 4px margin between (from both) --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 4px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 4px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -1px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 5px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -1px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 5px;"></div> +</td></tr></tbody></table> + +<!-- negative margin between --> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -4px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 0px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: 0px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -4px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -4px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -1px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -1px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -4px;"></div> +</td></tr></tbody></table> + +<table width="300" style="background: aqua"><tbody><tr><td> + <div style="float: left; height: 10px; width: 150px; background: blue"></div> + <div style="height: 5px; background: purple; margin-bottom: -4px;"></div> + <div style="overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -4px;"></div> +</td></tr></tbody></table> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001-ref.xht new file mode 100644 index 0000000..5ea97a40 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001-ref.xht
@@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head> +<title>Testcase, bug 472252</title> + +<style type="text/css"> +#wrap {width:600px; border:1px solid;position:relative} +.a {background:lime; color:#fff; width:80%;} +.b {position:absolute; right:0; width:18%; background: cyan; color: #000; height:10em;} +textarea {width: 100%; height:10em;} +</style> + +<title>test</title> +</head> +<body> +<div id="wrap"> + <div class="b"></div> + <div class="a"><textarea></textarea></div> +</div> + + +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001.xht new file mode 100644 index 0000000..9ae6447f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-bfc-outside-001.xht
@@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head> + <title>CSS Test: float</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-wrap-bfc-outside-001-ref.xht"/> + <meta name="flags" content="" /> + +<style type="text/css"> +#wrap {width:600px; border:1px solid;} +.a {background:lime; color:#fff; width:80%;} +.b {float:right; width:18%; background: cyan; color: #000; height:10em;} +textarea {width: 100%; height:10em;} +</style> + +</head> +<body> +<div id="wrap"> + <div class="b"></div> + <div class="a"><textarea></textarea></div> +</div> + + +</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-notref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-notref.xht new file mode 100644 index 0000000..0953df73d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-notref.xht
@@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: left; } +div { float: left; clear: left; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 50px;"></div> +<div style="width: 50px; height: 100px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-ref.xht new file mode 100644 index 0000000..85fd23f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001l-ref.xht
@@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: left; } +div { float: left; clear: left; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 50px;"></div> +<div style="width: 100px; height: 100px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-notref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-notref.xht new file mode 100644 index 0000000..e9aa080 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-notref.xht
@@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: right; } +div { float: right; clear: right; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 50px;"></div> +<div style="width: 50px; height: 100px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-ref.xht new file mode 100644 index 0000000..915e5327 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-001r-ref.xht
@@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: right; } +div { float: right; clear: right; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 50px;"></div> +<div style="width: 100px; height: 100px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002l-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002l-ref.xht new file mode 100644 index 0000000..1b003f4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002l-ref.xht
@@ -0,0 +1,21 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 150px; height: 25px;"></div> +<span></span> +<div style="height: 100px"></div> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002r-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002r-ref.xht new file mode 100644 index 0000000..847ff9a0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-002r-ref.xht
@@ -0,0 +1,21 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 150px; height: 25px;"></div> +<span></span> +<div style="height: 100px"></div> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003l-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003l-ref.xht new file mode 100644 index 0000000..028a65f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003l-ref.xht
@@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 250px; height: 25px;"></div> +<span></span> +<span style="margin-top: 25px; margin-right: 250px"></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003r-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003r-ref.xht new file mode 100644 index 0000000..4155c67 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-003r-ref.xht
@@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 250px; height: 25px;"></div> +<span></span> +<span style="margin-top: 25px; margin-left: 250px"></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001l.xht new file mode 100644 index 0000000..a4441971 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001l.xht
@@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-001l-ref.xht"/> +<link rel="mismatch" href="floats-wrap-top-below-001l-notref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +div { float: left; clear: left; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; margin-right: auto; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 75px;"></div> +<div style="width: 100px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001r.xht new file mode 100644 index 0000000..1899045a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001r.xht
@@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-001r-ref.xht"/> +<link rel="mismatch" href="floats-wrap-top-below-001r-notref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +div { float: right; clear: right; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; margin-left: auto; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 75px;"></div> +<div style="width: 100px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002l.xht new file mode 100644 index 0000000..f4fc6e1d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002l.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-002l-ref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 150px; height: 75px;"></div> +<div style="float: right; width: 300px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002r.xht new file mode 100644 index 0000000..a9026323 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-002r.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-002r-ref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 150px; height: 75px;"></div> +<div style="float: left; width: 300px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003l.xht new file mode 100644 index 0000000..298ea73 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003l.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-003l-ref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 250px; height: 75px;"></div> +<div style="float: right; width: 250px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003r.xht new file mode 100644 index 0000000..46f4fceb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003r.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-003r-ref.xht"/> +<meta name="assert" content="The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 250px; height: 75px;"></div> +<div style="float: left; width: 250px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001l.xht new file mode 100644 index 0000000..42154af9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001l.xht
@@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-001l-ref.xht"/> +<link rel="mismatch" href="floats-wrap-top-below-001l-notref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: left; } +div { float: left; clear: left; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 75px;"></div> +<div style="width: 100px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001r.xht new file mode 100644 index 0000000..74b2445 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001r.xht
@@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-001r-ref.xht"/> +<link rel="mismatch" href="floats-wrap-top-below-001r-notref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; text-align: right; } +div { float: right; clear: right; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="width: 50px; height: 75px;"></div> +<div style="width: 100px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002l.xht new file mode 100644 index 0000000..7a1ca55 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002l.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-002l-ref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 150px; height: 75px;"></div> +<div style="float: right; width: 300px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002r.xht new file mode 100644 index 0000000..596c51c7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002r.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-002r-ref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 150px; height: 75px;"></div> +<div style="float: left; width: 300px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003l.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003l.xht new file mode 100644 index 0000000..685cf9d35 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003l.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-003l-ref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: left; width: 250px; height: 75px;"></div> +<div style="float: right; width: 250px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003r.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003r.xht new file mode 100644 index 0000000..317e8dd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003r.xht
@@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> +<title>CSS Test: Test for wrapping around floats whose top is below the top of what must wrap around them</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/" /> +<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> +<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> +<link rel="match" href="floats-wrap-top-below-003r-ref.xht"/> +<meta name="assert" content="However, line boxes created next to the float are shortened to make room for the margin box of the float." /> +<meta name="flags" content="" /> +<style type="text/css"> + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + +</style> +</head> +<body> + +<div style="float: right; width: 250px; height: 75px;"></div> +<div style="float: left; width: 250px; height: 75px;"></div> +<span></span> +<span></span> + + + +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001-ref.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001-ref.xht new file mode 100644 index 0000000..68139cd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001-ref.xht
@@ -0,0 +1,10 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Test for wrapping around zero-height floats</title> + +</head><body><div style="width: 500px; height: 500px; float: left; font-size: 12px;"> + + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: blue; margin-left: 10px;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: purple; margin-left: 100px;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: fuchsia"></span> + +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001.xht new file mode 100644 index 0000000..b2821267 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-001.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: wrapping around zero-height floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-zero-height-wrap-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="wrapping around zero-height floats" /> + +</head><body><div style="width: 500px; height: 500px; float: left; font-size: 12px;"> + + <div style="float: left; width: 10px; height: 30px"></div> + <div style="float: left; clear: left; width: 100px; height: 1px"></div> + + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: blue;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: purple;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: fuchsia"></span> + +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-002.xht b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-002.xht new file mode 100644 index 0000000..679f5b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/CSS2/floats/floats-zero-height-wrap-002.xht
@@ -0,0 +1,19 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test: wrapping around zero-height floats</title> + <link rel="author" title="L. David Baron" href="https://dbaron.org/" /> + <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" /> + <link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#floats" /> + <link rel="match" href="floats-zero-height-wrap-001-ref.xht"/> + <meta name="flags" content="" /> + <meta name="assert" content="wrapping around zero-height floats" /> + +</head><body><div style="width: 500px; height: 500px; float: left; font-size: 12px;"> + + <div style="float: left; width: 10px; height: 30px"></div> + <div style="float: left; clear: left; width: 100px; height: 0"></div> + + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: blue;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: purple;"></span> + <span style="display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: fuchsia"></span> + +</div> +</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/imagecapture/MediaStreamTrack-applyConstraints.html b/third_party/WebKit/LayoutTests/fast/imagecapture/MediaStreamTrack-applyConstraints.html index 5164d490..af1e92b 100644 --- a/third_party/WebKit/LayoutTests/fast/imagecapture/MediaStreamTrack-applyConstraints.html +++ b/third_party/WebKit/LayoutTests/fast/imagecapture/MediaStreamTrack-applyConstraints.html
@@ -26,6 +26,26 @@ return videoTrack.applyConstraints(); }, 'MediaStreamTrack.applyConstraints()'); +// This test verifies that applyConstraints() rejects the returned Promise if +// passed a non-supported image-capture constraint (https://crbug.com/711694). +promise_test(function(t) { + var canvas = document.getElementById('canvas'); + var context = canvas.getContext("2d"); + context.fillStyle = "red"; + context.fillRect(0, 0, 10, 10); + + var stream = canvas.captureStream(); + var videoTrack = stream.getVideoTracks()[0]; + + var expectedException = + new DOMException('Unsupported constraint(s)', 'NotSupportedError'); + + // Use e.g. |torch| as an example of unsupported constraint. + assert_false("torch" in videoTrack.getCapabilities()); + return promise_rejects( + t, expectedException, + videoTrack.applyConstraints({advanced : [ {torch : true} ]})); +}, 'MediaStreamTrack.applyConstraints() with unsupported constraint'); // This test verifies that applyConstraints() rejects the returned Promise if // passed a non-supported constraint.
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html deleted file mode 100644 index 97d5761f..0000000 --- a/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html +++ /dev/null
@@ -1,87 +0,0 @@ -<!DOCTYPE html> -<style> - .multicol { - width: 300px; - height: 100px; - line-height: 20px; - border: 5px solid maroon; - } - .column { - width: 100px; - float: left; - } - .multicol[dir="rtl"] > .column { - float: right; - } - .block { - display: inline-block; - width: 1em; - height: 10px; - background-color: green; - } - .opacity { - opacity: 0.5; - color: green; - } - .relative { - position: relative; - top: -4px; - color: green; - } -</style> -<p> - Test layers which are fully contained within a single column. -</p> -LTR: -<div class="multicol"> - <div class="column"> - line1<br> - line2<br> - line3<br> - line4<br> - line5<br> - </div> - <div class="column"> - line6<br> - <div class="block"></div> line7<br> - line8<br> - <span class="relative">relative9</span><br> - line10<br> - </div> - <div class="column"> - line11<br> - line12<br> - <!-- The extra inner span below forces the creation of a transparency layer in Skia to work - around optimizations that would cause blending differences between the test and the - expectation. --> - <span class="opacity">opacity<span>13</span></span><br> - line14 - </div> -</div> - -RTL: -<div class="multicol" dir="rtl"> - <div class="column"> - line1<br> - line2<br> - line3<br> - line4<br> - line5<br> - </div> - <div class="column"> - line6<br> - <div class="block"></div> line7<br> - line8<br> - <span class="relative">relative9</span><br> - line10<br> - </div> - <div class="column"> - line11<br> - line12<br> - <!-- The extra inner span below forces the creation of a transparency layer in Skia to work - around optimizations that would cause blending differences between the test and the - expectation. --> - <span class="opacity">opacity<span>13</span></span><br> - line14 - </div> -</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html deleted file mode 100644 index 8bbd920..0000000 --- a/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html +++ /dev/null
@@ -1,90 +0,0 @@ -<!DOCTYPE html> -<style> - .container { - margin-right: 4px; - position: absolute; - } - .multicol { - width: 110px; - height: 150px; - border: 5px solid black; - } - .multicol > div { - float: left; - width: 50px; - height: 50px; - } - - .row1_left { background-color: black; } - .row1_right { background-color: #0000b0; } - .row2_left { background-color: #0000f0; } - .row2_right { background-color: #000090; } - .row3_left { background-color: #0000d0; } - .row3_right { background-color: black; } - - .row1_right, - .row2_right, - .row3_right { - margin-left: 10px; - } - - #opacity .row1_right, - #opacity .row2_left, - #opacity .row2_right, - #opacity .row3_left { - opacity: 0.99; - } - - .pos1 { left: 10px; top: 10px; } - .pos2 { left: 150px; top: 10px; } - .pos3 { left: 10px; top: 200px; } - .pos4 { left: 150px; top: 200px; } - -</style> -<div class="container pos1"> - Overflow: - <div class="multicol"> - <div class="row1_left"></div> - <div class="row1_right"></div> - <div class="row2_left"></div> - <div class="row2_right"></div> - <div class="row3_left"></div> - <div class="row3_right"></div> - </div> -</div> -<div class="container pos2"> - Transforms: - <div class="multicol"> - <div class="row1_left"></div> - <div class="row1_right"></div> - <div class="row2_left"></div> - <div class="row2_right"></div> - <div class="row3_left"></div> - <div class="row3_right"></div> - </div> -</div> -<div class="container pos3"> - Relative Pos.: - <div class="multicol"> - <div class="row1_left"></div> - <div class="row1_right"></div> - <div class="row2_left"></div> - <div class="row2_right"></div> - <div class="row3_left"></div> - <div class="row3_right"></div> - </div> -</div> -<div class="container pos4" id="opacity"> - Opacity: - <div class="multicol"> - <div class="row1_left"></div> - <!-- The extra s below force the creation of transparency layers in Skia to work - around optimizations that would cause blending differences between the test and the - expectation. --> - <div class="row1_right"> </div> - <div class="row2_left"> </div> - <div class="row2_right"> </div> - <div class="row3_left"> </div> - <div class="row3_right"></div> - </div> -</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html deleted file mode 100644 index 0b67873..0000000 --- a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html +++ /dev/null
@@ -1,6 +0,0 @@ -<div style="position:relative; width:420px;border:2px solid black; height:200px"> -<!-- The extra below forces the creation of a transparency layer in Skia to work around - optimizations that would cause blending differences between the test and the expectation. --> -<div style="opacity:0.5; position:absolute;width:200px;height:100px;background-color:green;right:0;top:0"> </div> -</div> -</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png new file mode 100644 index 0000000..1ebb6e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints-getSettings.html b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints-getSettings.html index cfbb985..e2daf387 100644 --- a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints-getSettings.html +++ b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints-getSettings.html
@@ -52,6 +52,14 @@ var stream = canvas.captureStream(); videoTrack = stream.getVideoTracks()[0]; + // |videoTrack|'s capabilities gathering, just like the actual capture, is + // a process kicked off right after creation, we introduce a small delay + // to allow for those to be collected, since they are needed to understand + // which constraints are supported in applyConstraints(). + // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524. + return new Promise(resolve => setTimeout(resolve, 100)); + }) + .then(function() { return videoTrack.applyConstraints(constraints); }) .then(function() {
diff --git a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints.html b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints.html index 9db07b1..dc9da9b1 100644 --- a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints.html +++ b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-applyConstraints.html
@@ -41,18 +41,27 @@ }]}; var theMock = null; + var videoTrack = null; mockImageCaptureReady .then(mock => { theMock = mock; var stream = canvas.captureStream(); - var videoTrack = stream.getVideoTracks()[0]; + videoTrack = stream.getVideoTracks()[0]; - return videoTrack.applyConstraints(constraints); + // |videoTrack|'s capabilities gathering, just like the actual capture, is + // a process kicked off right after creation, we introduce a small delay + // to allow for those to be collected, since they are needed to understand + // which constraints are supported in applyConstraints(). + // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524. + return new Promise(resolve => setTimeout(resolve, 100)); }, error => { assert_unreached("Error creating MockImageCapture: " + error); }) .then(function() { + return videoTrack.applyConstraints(constraints); + }) + .then(function() { assert_equals(constraints.advanced[0].whiteBalanceMode, meteringModeNames[theMock.options().white_balance_mode], 'whiteBalanceMode');
diff --git a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-getCapabilities.html b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-getCapabilities.html index 490d3550..ec9347bf 100644 --- a/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-getCapabilities.html +++ b/third_party/WebKit/LayoutTests/imagecapture/MediaStreamTrack-getCapabilities.html
@@ -33,9 +33,10 @@ var videoTrack = stream.getVideoTracks()[0]; assert_equals(typeof videoTrack.getCapabilities, 'function'); - // |videoTrack|s capabilities, just like the actual capture, is a process - // kicked right after creation, we introduce a small delay to allow for - // those to be collected. + // |videoTrack|'s capabilities gathering, just like the actual capture, is + // a process kicked off right after creation, we introduce a small delay + // to allow for those to be collected. + // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524. setTimeout(() => { capabilities = videoTrack.getCapabilities(); assert_equals(typeof capabilities, 'object');
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png index a92e6a8..c6cabcbb 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png +++ b/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png new file mode 100644 index 0000000..44fc4a4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png new file mode 100644 index 0000000..27fbf58 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index b024e71..5e1fff8 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png index 8d5f6fd3..6f98684 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index b024e71..5e1fff8 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png index 3a881330..0acea10 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 07e019c..991aaf7a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png index 11b5d71..84b89da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png index f409f9e..1693941 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 07e019c..991aaf7a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png new file mode 100644 index 0000000..9243efa --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png new file mode 100644 index 0000000..86cf379 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 56d7e380c..af00c64c0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png index ab426ac..31dd704 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png index 7e1243a1..98ce8c5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png index 8938c8b..556507c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png index 497919fc..70f55312 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png index 38e6870..c57f417b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 56d7e380c..af00c64c0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png new file mode 100644 index 0000000..62b98ea --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png new file mode 100644 index 0000000..608b610 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 8829276ef..6eb1bf6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png index 6837fed..5b597ed 100644 --- a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 8829276ef..6eb1bf6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index bbb8278..27dad6f 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png index 7e9778db..855bfdf8 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index bbb8278..27dad6f 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp index 8efc23cd..4e43b3d 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
@@ -35,6 +35,7 @@ #include "bindings/core/v8/DOMWrapperWorld.h" #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/ScriptState.h" +#include "bindings/core/v8/SerializationTag.h" #include "bindings/core/v8/SerializedScriptValueFactory.h" #include "bindings/core/v8/Transferables.h" #include "bindings/core/v8/V8ArrayBuffer.h" @@ -54,6 +55,7 @@ #include "platform/wtf/ByteOrder.h" #include "platform/wtf/PtrUtil.h" #include "platform/wtf/Vector.h" +#include "platform/wtf/dtoa/utils.h" #include "platform/wtf/text/StringBuffer.h" #include "platform/wtf/text/StringHash.h" @@ -89,22 +91,124 @@ return AdoptRef(new SerializedScriptValue(data)); } +// Versions 16 and below (prior to April 2017) used ntohs() to byte-swap SSV +// data when converting it to the wire format. This was a historical accient. +// +// As IndexedDB stores SSVs to disk indefinitely, we still need to keep around +// the code needed to deserialize the old format. +inline static bool IsByteSwappedWiredData(const char* data, size_t length) { + // TODO(pwnall): Return false early if we're on big-endian hardware. Chromium + // doesn't currently support big-endian hardware, and there's no header + // exposing endianness to Blink yet. ARCH_CPU_LITTLE_ENDIAN seems promising, + // but Blink is not currently allowed to include files from build/. + + // The first SSV version without byte-swapping has two envelopes (Blink, V8), + // each of which is at least 2 bytes long. + if (length < 4) + return true; + + // This code handles the following cases: + // + // v0 (byte-swapped) - [d, t, ...], t = tag byte, d = first data byte + // v1-16 (byte-swapped) - [v, 0xFF, ...], v = version (1 <= v <= 16) + // v17+ - [0xFF, v, ...], v = first byte of version varint + + if (static_cast<uint8_t>(data[0]) == kVersionTag) { + // The only case where byte-swapped data can have 0xFF in byte zero is + // version 0. This can only happen if byte one is a tag (supported in + // version 0) that takes in extra data, and the first byte of extra data is + // 0xFF. There are 13 such tags, listed below. These tags cannot be used as + // version numbers in the Blink-side SSV envelope. + // + // 35 - 0x23 - # - ImageDataTag + // 64 - 0x40 - @ - SparseArrayTag + // 68 - 0x44 - D - DateTag + // 73 - 0x49 - I - Int32Tag + // 78 - 0x4E - N - NumberTag + // 82 - 0x52 - R - RegExpTag + // 83 - 0x53 - S - StringTag + // 85 - 0x55 - U - Uint32Tag + // 91 - 0x5B - [ - ArrayTag + // 98 - 0x62 - b - BlobTag + // 102 - 0x66 - f - FileTag + // 108 - 0x6C - l - FileListTag + // 123 - 0x7B - { - ObjectTag + // + // Why we care about version 0: + // + // IndexedDB stores values using the SSV format. Currently, IndexedDB does + // not do any sort of migration, so a value written with a SSV version will + // be stored with that version until it is removed via an update or delete. + // + // IndexedDB was shipped in Chrome 11, which was released on April 27, 2011. + // SSV version 1 was added in WebKit r91698, which was shipped in Chrome 14, + // which was released on September 16, 2011. + static_assert( + SerializedScriptValue::kWireFormatVersion != 35 && + SerializedScriptValue::kWireFormatVersion != 64 && + SerializedScriptValue::kWireFormatVersion != 68 && + SerializedScriptValue::kWireFormatVersion != 73 && + SerializedScriptValue::kWireFormatVersion != 78 && + SerializedScriptValue::kWireFormatVersion != 82 && + SerializedScriptValue::kWireFormatVersion != 83 && + SerializedScriptValue::kWireFormatVersion != 85 && + SerializedScriptValue::kWireFormatVersion != 91 && + SerializedScriptValue::kWireFormatVersion != 98 && + SerializedScriptValue::kWireFormatVersion != 102 && + SerializedScriptValue::kWireFormatVersion != 108 && + SerializedScriptValue::kWireFormatVersion != 123, + "Using a burned version will prevent us from reading SSV version 0"); + + // Fast path until the Blink-side SSV envelope reaches version 35. + if (SerializedScriptValue::kWireFormatVersion < 35) { + if (static_cast<uint8_t>(data[1]) < 35) + return false; + + // TODO(pwnall): Add UMA metric here. + return true; + } + + // Slower path that would kick in after version 35, assuming we don't remove + // support for SSV version 0 by then. + static constexpr uint8_t version0Tags[] = {35, 64, 68, 73, 78, 82, 83, + 85, 91, 98, 102, 108, 123}; + return std::find(std::begin(version0Tags), std::end(version0Tags), + data[1]) != std::end(version0Tags); + } + + if (static_cast<uint8_t>(data[1]) == kVersionTag) { + // The last SSV format that used byte-swapping was version 16. The version + // number is stored (before byte-swapping) after a serialization tag, which + // is 0xFF. + return static_cast<uint8_t>(data[0]) != kVersionTag; + } + + // If kVersionTag isn't in any of the first two bytes, this is SSV version 0, + // which was byte-swapped. + return true; +} + PassRefPtr<SerializedScriptValue> SerializedScriptValue::Create( const char* data, size_t length) { if (!data) return Create(); - // Decode wire data from big endian to host byte order. DCHECK(!(length % sizeof(UChar))); - size_t string_length = length / sizeof(UChar); - StringBuffer<UChar> buffer(string_length); const UChar* src = reinterpret_cast<const UChar*>(data); - UChar* dst = buffer.Characters(); - for (size_t i = 0; i < string_length; i++) - dst[i] = ntohs(src[i]); + size_t string_length = length / sizeof(UChar); - return AdoptRef(new SerializedScriptValue(String::Adopt(buffer))); + if (IsByteSwappedWiredData(data, length)) { + // Decode wire data from big endian to host byte order. + StringBuffer<UChar> buffer(string_length); + UChar* dst = buffer.Characters(); + for (size_t i = 0; i < string_length; ++i) + dst[i] = ntohs(src[i]); + + return AdoptRef(new SerializedScriptValue(String::Adopt(buffer))); + } + + return AdoptRef(new SerializedScriptValue(String(src, string_length))); } SerializedScriptValue::SerializedScriptValue() @@ -134,8 +238,9 @@ } PassRefPtr<SerializedScriptValue> SerializedScriptValue::NullValue() { - // UChar rather than uint8_t here to get host endian behavior. - static const UChar kNullData[] = {0xff09, 0x3000}; + // The format here may fall a bit out of date, because we support + // deserializing SSVs written by old browser versions. + static const uint8_t kNullData[] = {0xFF, 17, 0xFF, 13, '0', 0x00}; return Create(reinterpret_cast<const char*>(kNullData), sizeof(kNullData)); } @@ -152,22 +257,17 @@ return wire_string; } -// Convert serialized string to big endian wire data. void SerializedScriptValue::ToWireBytes(Vector<char>& result) const { DCHECK(result.IsEmpty()); - size_t wire_size_bytes = (data_buffer_size_ + 1) & ~1; - result.Resize(wire_size_bytes); + size_t result_size = (data_buffer_size_ + 1) & ~1; + result.Resize(result_size); + memcpy(result.Data(), data_buffer_.get(), data_buffer_size_); - const UChar* src = reinterpret_cast<UChar*>(data_buffer_.get()); - UChar* dst = reinterpret_cast<UChar*>(result.Data()); - for (size_t i = 0; i < data_buffer_size_ / 2; i++) - dst[i] = htons(src[i]); - - // This is equivalent to swapping the byte order of the two bytes (x, 0), - // depending on endianness. - if (data_buffer_size_ % 2) - dst[wire_size_bytes / 2 - 1] = data_buffer_[data_buffer_size_ - 1] << 8; + if (result_size > data_buffer_size_) { + DCHECK_EQ(result_size, data_buffer_size_ + 1); + result[data_buffer_size_] = 0; + } } static void AccumulateArrayBuffersForAllWorlds(
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h index 5e9912170..15d211c9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h
@@ -75,7 +75,12 @@ // Version 9: Added Map and Set support. // [versions skipped] // Version 16: Separate versioning between V8 and Blink. - static const uint32_t kWireFormatVersion = 16; + // Version 17: Remove unnecessary byte swapping. + // + // The following versions cannot be used, in order to be able to + // deserialize version 0 SSVs. The class implementation has details. + // DO NOT USE: 35, 64, 68, 73, 78, 82, 83, 85, 91, 98, 102, 108, 123. + static constexpr uint32_t kWireFormatVersion = 17; struct SerializeOptions { STACK_ALLOCATED();
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueTest.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueTest.cpp index 0af3d11..2c606ad 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueTest.cpp
@@ -9,12 +9,115 @@ #include "bindings/core/v8/V8Binding.h" #include "bindings/core/v8/V8BindingForTesting.h" #include "bindings/core/v8/V8File.h" +#include "bindings/core/v8/V8ImageData.h" #include "core/fileapi/File.h" #include "platform/testing/UnitTestHelpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink { +TEST(SerializedScriptValueTest, WireFormatRoundTrip) { + V8TestingScope scope; + + v8::Local<v8::Value> v8OriginalTrue = v8::True(scope.GetIsolate()); + RefPtr<SerializedScriptValue> sourceSerializedScriptValue = + SerializedScriptValue::Serialize( + scope.GetIsolate(), v8OriginalTrue, + SerializedScriptValue::SerializeOptions(), ASSERT_NO_EXCEPTION); + + Vector<char> wireData; + sourceSerializedScriptValue->ToWireBytes(wireData); + + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(wireData.Data(), wireData.size()); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(scope.GetIsolate()); + EXPECT_TRUE(deserialized->IsTrue()); +} + +TEST(SerializedScriptValueTest, WireFormatVersion17NoByteSwapping) { + V8TestingScope scope; + + const uint8_t data[] = {0xFF, 0x11, 0xFF, 0x0D, 0x54, 0x00}; + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(reinterpret_cast<const char*>(data), + sizeof(data)); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(scope.GetIsolate()); + EXPECT_TRUE(deserialized->IsTrue()); +} + +TEST(SerializedScriptValueTest, WireFormatVersion16ByteSwapping) { + V8TestingScope scope; + + // Using UChar instead of uint8_t to get ntohs() byte swapping. + const UChar data[] = {0xFF10, 0xFF0D, 0x5400}; + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(reinterpret_cast<const char*>(data), + sizeof(data)); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(scope.GetIsolate()); + EXPECT_TRUE(deserialized->IsTrue()); +} + +TEST(SerializedScriptValueTest, WireFormatVersion13ByteSwapping) { + V8TestingScope scope; + + // Using UChar instead of uint8_t to get ntohs() byte swapping. + const UChar data[] = {0xFF0D, 0x5400}; + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(reinterpret_cast<const char*>(data), + sizeof(data)); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(scope.GetIsolate()); + EXPECT_TRUE(deserialized->IsTrue()); +} + +TEST(SerializedScriptValueTest, WireFormatVersion0ByteSwapping) { + V8TestingScope scope; + + // Using UChar instead of uint8_t to get ntohs() byte swapping. + const UChar data[] = {0x5400}; + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(reinterpret_cast<const char*>(data), + sizeof(data)); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(scope.GetIsolate()); + EXPECT_TRUE(deserialized->IsTrue()); +} + +TEST(SerializedScriptValueTest, WireFormatVersion0ImageData) { + V8TestingScope scope; + v8::Isolate* isolate = scope.GetIsolate(); + + // Using UChar instead of uint8_t to get ntohs() byte swapping. + // + // This builds the smallest possible ImageData whose first data byte is 0xFF, + // as follows. + // + // width = 127, encoded as 0xFF 0x00 (degenerate varint) + // height = 1, encoded as 0x01 (varint) + // pixelLength = 508 (127 * 1 * 4), encoded as 0xFC 0x03 (varint) + // pixel data = 508 bytes, all zero + Vector<UChar> data; + data.push_back(0x23FF); + data.push_back(0x001); + data.push_back(0xFC03); + data.Resize(257); // (508 pixel data + 6 header bytes) / 2 + + RefPtr<SerializedScriptValue> serializedScriptValue = + SerializedScriptValue::Create(reinterpret_cast<const char*>(data.Data()), + data.size() * sizeof(UChar)); + v8::Local<v8::Value> deserialized = + serializedScriptValue->Deserialize(isolate); + ASSERT_TRUE(deserialized->IsObject()); + v8::Local<v8::Object> deserializedObject = deserialized.As<v8::Object>(); + ASSERT_TRUE(V8ImageData::hasInstance(deserializedObject, isolate)); + ImageData* imageData = V8ImageData::toImpl(deserializedObject); + EXPECT_EQ(imageData->width(), 127); + EXPECT_EQ(imageData->height(), 1); +} + TEST(SerializedScriptValueTest, UserSelectedFile) { V8TestingScope scope; String file_path = testing::BlinkRootDir();
diff --git a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp index 88f104b7..cba0e74 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp +++ b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp
@@ -132,15 +132,10 @@ // SerializedScriptValue header format offsets are inferred from the Blink and // V8 serialization code. The code below DCHECKs that -constexpr static size_t kSSVHeaderBlinkVersionOffset = 0; -constexpr static size_t kSSVHeaderBlinkVersionTagOffset = 1; -constexpr static size_t kSSVHeaderV8VersionOffset = 2; -constexpr static size_t kSSVHeaderV8VersionTagOffset = 3; - -// 13 is v8::internal::kLatestVersion in v8/src/value-serializer.cc at the -// time when this test was written. Unlike Blink, V8 does not currently export -// its serialization version, so this number might get stale. -constexpr static unsigned char kV8LatestKnownVersion = 13; +constexpr static size_t kSSVHeaderBlinkVersionTagOffset = 0; +constexpr static size_t kSSVHeaderBlinkVersionOffset = 1; +constexpr static size_t kSSVHeaderV8VersionTagOffset = 2; +constexpr static size_t kSSVHeaderV8VersionOffset = 3; // Follows the same steps as the IndexedDB value serialization code. void SerializeV8Value(v8::Local<v8::Value> value, @@ -162,16 +157,16 @@ // 0xFF. const unsigned char* wire_data = reinterpret_cast<unsigned char*>(wire_bytes->Data()); + ASSERT_EQ(static_cast<unsigned char>(kVersionTag), + wire_data[kSSVHeaderBlinkVersionTagOffset]); ASSERT_EQ( static_cast<unsigned char>(SerializedScriptValue::kWireFormatVersion), wire_data[kSSVHeaderBlinkVersionOffset]); - ASSERT_EQ(static_cast<unsigned char>(kVersionTag), - wire_data[kSSVHeaderBlinkVersionTagOffset]); - ASSERT_GE(static_cast<unsigned char>(kV8LatestKnownVersion), - wire_data[kSSVHeaderV8VersionOffset]); ASSERT_EQ(static_cast<unsigned char>(kVersionTag), wire_data[kSSVHeaderV8VersionTagOffset]); + ASSERT_EQ(v8::ValueSerializer::GetCurrentDataFormatVersion(), + wire_data[kSSVHeaderV8VersionOffset]); } PassRefPtr<IDBValue> CreateIDBValue(v8::Isolate* isolate,
diff --git a/third_party/WebKit/Source/core/dom/ModuleMapTest.cpp b/third_party/WebKit/Source/core/dom/ModuleMapTest.cpp index d18332e0..87adbf2 100644 --- a/third_party/WebKit/Source/core/dom/ModuleMapTest.cpp +++ b/third_party/WebKit/Source/core/dom/ModuleMapTest.cpp
@@ -132,8 +132,8 @@ void ModuleMapTestModulator::ResolveFetches() { for (const auto& test_request : test_requests_) { ModuleScript* module_script = ModuleScript::Create( - ScriptModule(), test_request->url, test_request->nonce, kParserInserted, - WebURLRequest::kFetchCredentialsModeOmit); + this, ScriptModule(), test_request->url, test_request->nonce, + kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); TaskRunner()->PostTask( BLINK_FROM_HERE, WTF::Bind(&ModuleScriptLoaderClient::NotifyNewSingleModuleFinished,
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.cpp b/third_party/WebKit/Source/core/dom/ModuleScript.cpp index 28fa847d..f175cd9 100644 --- a/third_party/WebKit/Source/core/dom/ModuleScript.cpp +++ b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
@@ -21,6 +21,7 @@ } DEFINE_TRACE(ModuleScript) { + visitor->Trace(settings_object_); Script::Trace(visitor); } DEFINE_TRACE_WRAPPERS(ModuleScript) {
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.h b/third_party/WebKit/Source/core/dom/ModuleScript.h index dbe6db9..17cec9d 100644 --- a/third_party/WebKit/Source/core/dom/ModuleScript.h +++ b/third_party/WebKit/Source/core/dom/ModuleScript.h
@@ -10,6 +10,7 @@ #include "bindings/core/v8/ScriptWrappable.h" #include "bindings/core/v8/TraceWrapperV8Reference.h" #include "core/CoreExport.h" +#include "core/dom/Modulator.h" #include "core/dom/Script.h" #include "platform/heap/Handle.h" #include "platform/loader/fetch/ResourceLoaderOptions.h" @@ -30,13 +31,14 @@ class CORE_EXPORT ModuleScript final : public Script, public TraceWrapperBase { public: static ModuleScript* Create( + Modulator* settings_object, ScriptModule record, const KURL& base_url, const String& nonce, ParserDisposition parser_state, WebURLRequest::FetchCredentialsMode credentials_mode) { - return new ModuleScript(record, base_url, nonce, parser_state, - credentials_mode); + return new ModuleScript(settings_object, record, base_url, nonce, + parser_state, credentials_mode); } ~ModuleScript() override = default; @@ -61,12 +63,14 @@ DECLARE_TRACE_WRAPPERS(); private: - ModuleScript(ScriptModule record, + ModuleScript(Modulator* settings_object, + ScriptModule record, const KURL& base_url, const String& nonce, ParserDisposition parser_state, WebURLRequest::FetchCredentialsMode credentials_mode) - : record_(record), + : settings_object_(settings_object), + record_(record), base_url_(base_url), instantiation_error_(this), nonce_(nonce), @@ -80,10 +84,8 @@ void RunScript(LocalFrame*, const SecurityOrigin*) const override; String InlineSourceTextForCSP() const override; - // Note: A "module script"'s "setttings object" is ommitted, as we currently - // always have access to the corresponding Modulator when operating on a - // ModuleScript instance. // https://html.spec.whatwg.org/multipage/webappapis.html#settings-object + Member<Modulator> settings_object_; // https://html.spec.whatwg.org/multipage/webappapis.html#concept-module-script-module-record ScriptModule record_;
diff --git a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp index a04d97f..6921f7f7 100644 --- a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
@@ -55,26 +55,28 @@ return module_script_.Get(); } -ModuleScript* CreateReferrerModuleScript(V8TestingScope& scope) { +ModuleScript* CreateReferrerModuleScript(Modulator* modulator, + V8TestingScope& scope) { ScriptModule referrer_record = ScriptModule::Compile( scope.GetIsolate(), "import './target.js'; export const a = 42;", "referrer.js", kSharableCrossOrigin); KURL referrer_url(kParsedURLString, "https://example.com/referrer.js"); - ModuleScript* referrer_module_script = - ModuleScript::Create(referrer_record, referrer_url, "", kParserInserted, - WebURLRequest::kFetchCredentialsModeOmit); + ModuleScript* referrer_module_script = ModuleScript::Create( + modulator, referrer_record, referrer_url, "", kParserInserted, + WebURLRequest::kFetchCredentialsModeOmit); // TODO(kouhei): moduleScript->setInstantiateSuccess(); once // https://codereview.chromium.org/2782403002/ landed. return referrer_module_script; } -ModuleScript* CreateTargetModuleScript(V8TestingScope& scope) { +ModuleScript* CreateTargetModuleScript(Modulator* modulator, + V8TestingScope& scope) { ScriptModule record = ScriptModule::Compile(scope.GetIsolate(), "export const pi = 3.14;", "target.js", kSharableCrossOrigin); KURL url(kParsedURLString, "https://example.com/target.js"); ModuleScript* module_script = - ModuleScript::Create(record, url, "", kParserInserted, + ModuleScript::Create(modulator, record, url, "", kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); // TODO(kouhei): moduleScript->setInstantiateSuccess(); once // https://codereview.chromium.org/2782403002/ landed. @@ -107,10 +109,12 @@ ScriptModuleResolverImpl::Create(Modulator()); V8TestingScope scope; - ModuleScript* referrer_module_script = CreateReferrerModuleScript(scope); + ModuleScript* referrer_module_script = + CreateReferrerModuleScript(modulator_, scope); resolver->RegisterModuleScript(referrer_module_script); - ModuleScript* target_module_script = CreateTargetModuleScript(scope); + ModuleScript* target_module_script = + CreateTargetModuleScript(modulator_, scope); Modulator()->SetModuleScript(target_module_script); ScriptModule resolved = @@ -128,10 +132,12 @@ ScriptModuleResolverImpl::Create(Modulator()); V8TestingScope scope; - ModuleScript* referrer_module_script = CreateReferrerModuleScript(scope); + ModuleScript* referrer_module_script = + CreateReferrerModuleScript(modulator_, scope); resolver->RegisterModuleScript(referrer_module_script); - ModuleScript* target_module_script = CreateTargetModuleScript(scope); + ModuleScript* target_module_script = + CreateTargetModuleScript(modulator_, scope); Modulator()->SetModuleScript(target_module_script); ScriptModule resolved = resolver->Resolve( @@ -147,10 +153,12 @@ ScriptModuleResolverImpl::Create(Modulator()); V8TestingScope scope; - ModuleScript* referrer_module_script = CreateReferrerModuleScript(scope); + ModuleScript* referrer_module_script = + CreateReferrerModuleScript(modulator_, scope); resolver->RegisterModuleScript(referrer_module_script); - ModuleScript* target_module_script = CreateTargetModuleScript(scope); + ModuleScript* target_module_script = + CreateTargetModuleScript(modulator_, scope); // Set Modulator::getFetchedModuleScript to return nullptr, which represents // that the target module failed to load. Modulator()->SetModuleScript(nullptr);
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp index 9c58e59..97e66fc 100644 --- a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp
@@ -244,7 +244,7 @@ // Step 10. Set script's parser state to the parser state. // Step 11. Set script's credentials mode to the credentials mode provided. // Step 12. Return script. - return ModuleScript::Create(result, url, nonce, parser_state, + return ModuleScript::Create(modulator, result, url, nonce, parser_state, credentials_mode); }
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index 445cfe074..39564a8 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -365,7 +365,7 @@ FloatRect float_bounds(FloatPoint(), size); const SkRect bounds(float_bounds); - flags.setShader(SkShader::MakePictureShader( + flags.setShader(MakePaintShaderRecord( PaintRecordForCurrentFrame(float_bounds, url), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &local_matrix, &bounds));
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp index 3473914..ca93ddc 100644 --- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp +++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
@@ -261,6 +261,26 @@ // TODO(mcasas): add support more than one single advanced constraint. const auto constraints = constraints_vector[0]; + if ((constraints.hasWhiteBalanceMode() && + !capabilities_.hasWhiteBalanceMode()) || + (constraints.hasExposureMode() && !capabilities_.hasExposureMode()) || + (constraints.hasFocusMode() && !capabilities_.hasFocusMode()) || + (constraints.hasExposureCompensation() && + !capabilities_.hasExposureCompensation()) || + (constraints.hasColorTemperature() && + !capabilities_.hasColorTemperature()) || + (constraints.hasIso() && !capabilities_.hasIso()) || + (constraints.hasBrightness() && !capabilities_.hasBrightness()) || + (constraints.hasContrast() && !capabilities_.hasContrast()) || + (constraints.hasSaturation() && !capabilities_.hasSaturation()) || + (constraints.hasSharpness() && !capabilities_.hasSharpness()) || + (constraints.hasZoom() && !capabilities_.hasZoom()) || + (constraints.hasTorch() && !capabilities_.hasTorch())) { + resolver->Reject( + DOMException::Create(kNotSupportedError, "Unsupported constraint(s)")); + return; + } + auto settings = media::mojom::blink::PhotoSettings::New(); // TODO(mcasas): support other Mode types beyond simple string i.e. the
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp index 236a627..cbe3e04 100644 --- a/third_party/WebKit/Source/modules/webusb/USB.cpp +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -26,7 +26,7 @@ namespace blink { namespace { -const char kNoServiceError[] = "USB service unavailable."; +const char kNoDeviceSelected[] = "No device selected."; usb::DeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter) { auto mojo_filter = usb::DeviceFilter::New(); @@ -172,16 +172,11 @@ chooser_service_requests_.erase(request_entry); EnsureDeviceManagerConnection(); - if (!device_manager_) { - resolver->Reject(DOMException::Create(kNotFoundError, kNoServiceError)); - return; - } - if (device_info) { + if (device_manager_ && device_info) { resolver->Resolve(GetOrCreateDevice(std::move(device_info))); } else { - resolver->Reject( - DOMException::Create(kNotFoundError, "No device selected.")); + resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected)); } } @@ -208,14 +203,14 @@ device_manager_.reset(); client_binding_.Close(); for (ScriptPromiseResolver* resolver : device_manager_requests_) - resolver->Reject(DOMException::Create(kNotFoundError, kNoServiceError)); + resolver->Resolve(HeapVector<Member<USBDevice>>(0)); device_manager_requests_.Clear(); } void USB::OnChooserServiceConnectionError() { chooser_service_.reset(); for (ScriptPromiseResolver* resolver : chooser_service_requests_) - resolver->Reject(DOMException::Create(kNotFoundError, kNoServiceError)); + resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected)); chooser_service_requests_.Clear(); }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp index 75f9fdd2..a215a535 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp
@@ -23,11 +23,12 @@ list->AppendClipPathItem(clip_path_, true); } -void BeginClipPathDisplayItem::AnalyzeForGpuRasterization( - SkPictureGpuAnalyzer& analyzer) const { +int BeginClipPathDisplayItem::NumberOfSlowPaths() const { // Temporarily disabled (pref regressions due to GPU veto stickiness: // http://crbug.com/603969). // analyzer.analyzeClipPath(m_clipPath, SkRegion::kIntersect_Op, true); + // TODO(enne): fixup this code to return an int. + return 0; } void EndClipPathDisplayItem::Replay(GraphicsContext& context) const {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h index 42434ae..3952c87 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
@@ -24,7 +24,7 @@ void AppendToWebDisplayItemList(const IntRect&, WebDisplayItemList*) const override; - void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const override; + int NumberOfSlowPaths() const override; private: #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp index cdcd8fd..7eac3491 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
@@ -29,58 +29,8 @@ CompositingRecorder::~CompositingRecorder() { if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) return; - // If the end of the current display list is of the form - // [BeginCompositingDisplayItem] [DrawingDisplayItem], then fold the - // BeginCompositingDisplayItem into a new DrawingDisplayItem that replaces - // them both. This allows Skia to optimize for the case when the - // BeginCompositingDisplayItem represents a simple opacity/color that can be - // merged into the opacity/color of the drawing. See crbug.com/628831 for more - // details. - PaintController& paint_controller = graphics_context_.GetPaintController(); - const DisplayItem* last_display_item = paint_controller.LastDisplayItem(0); - const DisplayItem* second_to_last_display_item = - paint_controller.LastDisplayItem(1); - // TODO(chrishtr): remove the call to LastDisplayItemIsSubsequenceEnd when - // https://codereview.chromium.org/2768143002 lands. - if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && last_display_item && - second_to_last_display_item && last_display_item->DrawsContent() && - second_to_last_display_item->GetType() == - DisplayItem::kBeginCompositing && - !paint_controller.LastDisplayItemIsSubsequenceEnd()) { - FloatRect cull_rect( - ((DrawingDisplayItem*)last_display_item)->GetPaintRecord()->cullRect()); - const DisplayItemClient& display_item_client = last_display_item->Client(); - DisplayItem::Type display_item_type = last_display_item->GetType(); - - // Re-record the last two DisplayItems into a new drawing. The new item - // cannot be cached, because it is a mutation of the DisplayItem the client - // thought it was painting. - paint_controller.BeginSkippingCache(); - { -#if DCHECK_IS_ON() - // In the recorder's scope we remove the last two display items which - // are combined into a new drawing. - DisableListModificationCheck disabler; -#endif - DrawingRecorder new_recorder(graphics_context_, display_item_client, - display_item_type, cull_rect); - DCHECK(!DrawingRecorder::UseCachedDrawingIfPossible( - graphics_context_, display_item_client, display_item_type)); - - second_to_last_display_item->Replay(graphics_context_); - last_display_item->Replay(graphics_context_); - EndCompositingDisplayItem(client_).Replay(graphics_context_); - - // Remove the DrawingDisplayItem. - paint_controller.RemoveLastDisplayItem(); - // Remove the BeginCompositingDisplayItem. - paint_controller.RemoveLastDisplayItem(); - } - paint_controller.EndSkippingCache(); - } else { - graphics_context_.GetPaintController().EndItem<EndCompositingDisplayItem>( - client_); - } + graphics_context_.GetPaintController().EndItem<EndCompositingDisplayItem>( + client_); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h index a9afcd1..d5f344e6 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h +++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
@@ -17,8 +17,6 @@ #include "platform/wtf/text/WTFString.h" #endif -class SkPictureGpuAnalyzer; - namespace blink { class GraphicsContext; @@ -337,7 +335,7 @@ virtual bool DrawsContent() const { return false; } // Override to implement specific analysis strategies. - virtual void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const {} + virtual int NumberOfSlowPaths() const { return 0; } #ifndef NDEBUG static WTF::String TypeAsDebugString(DisplayItem::Type);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp index 474a7d12..4fe7853 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
@@ -7,7 +7,6 @@ #include "platform/graphics/LoggingCanvas.h" #include "platform/graphics/paint/DrawingDisplayItem.h" #include "platform/graphics/paint/PaintChunk.h" -#include "third_party/skia/include/core/SkPictureAnalyzer.h" #ifndef NDEBUG #include "platform/wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp index 2a17f3d..7c14717 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
@@ -10,7 +10,6 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkData.h" -#include "third_party/skia/include/core/SkPictureAnalyzer.h" namespace blink { @@ -30,14 +29,8 @@ return record_.get(); } -void DrawingDisplayItem::AnalyzeForGpuRasterization( - SkPictureGpuAnalyzer& analyzer) const { - // TODO(enne): Need an SkPictureGpuAnalyzer on PictureRecord. - // This is a bit overkill to ToSkPicture a record just to get - // numSlowPaths. - if (!record_) - return; - analyzer.analyzePicture(ToSkPicture(record_).get()); +int DrawingDisplayItem::NumberOfSlowPaths() const { + return record_ ? record_->numSlowPaths() : 0; } #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h index e5f989f8..3dedbcbd 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h +++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h
@@ -41,7 +41,7 @@ return known_to_be_opaque_; } - void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const override; + int NumberOfSlowPaths() const override; private: #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp index e26681df..d3b7553 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -16,6 +16,8 @@ #include <stdio.h> #endif +static constexpr int kMaxNumberOfSlowPathsBeforeVeto = 5; + namespace blink { void PaintController::SetTracksRasterInvalidations(bool value) { @@ -535,7 +537,7 @@ !new_display_item_list_.IsEmpty()) GenerateChunkRasterInvalidationRects(new_paint_chunks_.LastChunk()); - SkPictureGpuAnalyzer gpu_analyzer; + int num_slow_paths = 0; current_cache_generation_ = DisplayItemClient::CacheGenerationOrInvalidationReason::Next(); @@ -554,8 +556,8 @@ Vector<const DisplayItemClient*> skipped_cache_clients; for (const auto& item : new_display_item_list_) { // No reason to continue the analysis once we have a veto. - if (gpu_analyzer.suitableForGpuRasterization()) - item.AnalyzeForGpuRasterization(gpu_analyzer); + if (num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto) + num_slow_paths += item.NumberOfSlowPaths(); // TODO(wkorman): Only compute and append visual rect for drawings. new_display_item_list_.AppendVisualRect( @@ -593,7 +595,7 @@ new_display_item_list_.ShrinkToFit(); current_paint_artifact_ = PaintArtifact( std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(), - gpu_analyzer.suitableForGpuRasterization()); + num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto); ResetCurrentListIndices(); out_of_order_item_indices_.Clear(); out_of_order_chunk_indices_.Clear();
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp index f4e0aae..5a09e2d8 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -2273,40 +2273,6 @@ DisplayItemClient::EndShouldKeepAliveAllClients(); #endif } - - void TestFoldCompositingDrawingInSubsequence() { - FakeDisplayItemClient container("container"); - FakeDisplayItemClient content("content"); - GraphicsContext context(GetPaintController()); - - { - SubsequenceRecorder subsequence(context, container); - CompositingRecorder compositing(context, content, SkBlendMode::kSrc, 0.5); - DrawRect(context, content, kBackgroundDrawingType, - FloatRect(100, 100, 300, 300)); - } - GetPaintController().CommitNewDisplayItems(); - EXPECT_EQ( - 1u, - GetPaintController().GetPaintArtifact().GetDisplayItemList().size()); - - { - EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible( - context, container)); - SubsequenceRecorder subsequence(context, container); - CompositingRecorder compositing(context, content, SkBlendMode::kSrc, 0.5); - DrawRect(context, content, kBackgroundDrawingType, - FloatRect(100, 100, 300, 300)); - } - GetPaintController().CommitNewDisplayItems(); - EXPECT_EQ( - 1u, - GetPaintController().GetPaintArtifact().GetDisplayItemList().size()); - -#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS - DisplayItemClient::EndShouldKeepAliveAllClients(); -#endif - } }; TEST_F(PaintControllerUnderInvalidationTest, ChangeDrawing) { @@ -2356,11 +2322,6 @@ TestInvalidationInSubsequence(); } -TEST_F(PaintControllerUnderInvalidationTest, - FoldCompositingDrawingInSubsequence) { - TestFoldCompositingDrawingInSubsequence(); -} - #endif // defined(GTEST_HAS_DEATH_TEST) && !OS(ANDROID) } // namespace blink
diff --git a/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm b/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm index 6379d6a..e3eada5 100644 --- a/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm +++ b/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm
@@ -24,6 +24,7 @@ #include "platform/graphics/paint/PaintCanvas.h" #include "platform/mac/ThemeMac.h" #include "platform_canvas.h" +#include "third_party/skia/include/core/SkRegion.h" namespace blink {
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py index 86df73e..13580bb 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
@@ -412,6 +412,7 @@ 'rebaseline-cl', '--verbose', '--no-trigger-jobs', + '--fill-missing', ] + tests_to_rebaseline) return tests_results
diff --git a/third_party/WebKit/public/web/WebSerializedScriptValueVersion.h b/third_party/WebKit/public/web/WebSerializedScriptValueVersion.h index a808ae2..82774e90 100644 --- a/third_party/WebKit/public/web/WebSerializedScriptValueVersion.h +++ b/third_party/WebKit/public/web/WebSerializedScriptValueVersion.h
@@ -38,7 +38,7 @@ // Embedders may serialize this as out-of-band metadata along with // collections of serialized data so that version skew can be detected // before deserializing individual values. -const unsigned kSerializedScriptValueVersion = 16; +const unsigned kSerializedScriptValueVersion = 17; } // namespace blink
diff --git a/tools/blink_rename_merge_helper/COMPONENTS b/tools/blink_rename_merge_helper/COMPONENTS index b376ee0..3737ba94 100644 --- a/tools/blink_rename_merge_helper/COMPONENTS +++ b/tools/blink_rename_merge_helper/COMPONENTS
@@ -4,7 +4,7 @@ "bin-darwin": "f45f58ccbf42a26b0704f63d8740cf008b84afcc", "include-darwin": "7f1790ea6a3257dda2035fe885a33fbfe4078fed", "lib-darwin": "29baf57b55dd0ab060baf0cd6461a7e0fa0105f4", - "bin-linux*": "c7c76f202a6d0feb77dd946b2e605a1ba56d3046", + "bin-linux*": "b8f4be9eeb5ca49059f4d46ae5a1dedfb41e9acb", "lib-linux*": "508b0ba0de0b4191a54360330f74cea8afd5ee93", "bin-win32": "f8ff17a5f080cef7639140b057a0f61b4d1a4f8f", "lib-win32": "afb47503a4fd442c353ddaba6f17a81e6aa5a20f"
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index d97c7ea..8b0af6a 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -54,6 +54,11 @@ const char kGMockMethodNamePrefix[] = "gmock_"; const char kMethodBlocklistParamName[] = "method-blocklist"; +std::set<clang::SourceLocation>& GetRewrittenLocs() { + static auto& locations = *new std::set<clang::SourceLocation>(); + return locations; +} + template <typename MatcherType, typename NodeType> bool IsMatching(const MatcherType& matcher, const NodeType& node, @@ -889,28 +894,8 @@ StringRef original_name = decl.getName(); // Nothing to do for unnamed parameters. - if (clang::isa<clang::ParmVarDecl>(decl)) { - if (original_name.empty()) - return false; - - // Check if |decl| and |decl.getLocation| are in sync. We need to skip - // out-of-sync ParmVarDecls to avoid renaming buggy ParmVarDecls that - // 1) have decl.getLocation() pointing at a parameter declaration without a - // name, but 2) have decl.getName() retained from a template specialization - // of a method. See also: https://llvm.org/bugs/show_bug.cgi?id=29145 - clang::SourceLocation loc = - context.getSourceManager().getSpellingLoc(decl.getLocation()); - auto parents = context.getParents(decl); - bool is_child_location_within_parent_source_range = std::all_of( - parents.begin(), parents.end(), - [&loc](const clang::ast_type_traits::DynTypedNode& parent) { - clang::SourceLocation begin = parent.getSourceRange().getBegin(); - clang::SourceLocation end = parent.getSourceRange().getEnd(); - return (begin < loc) && (loc < end); - }); - if (!is_child_location_within_parent_source_range) - return false; - } + if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty()) + return false; // This is a type trait that appears in consumers of WTF as well as inside // WTF. We want it to be named in this_style_of_case accordingly. @@ -1149,8 +1134,16 @@ if (actual_old_text != expected_old_text) return false; - if (replacement) + if (replacement) { + // If there's already a replacement for this location, don't emit any + // other replacements to avoid potential naming conflicts. This is + // primarily to avoid problems when a function and a parameter are defined + // by the same macro argument. + if (!GetRewrittenLocs().emplace(spell).second) + return false; + *replacement = Replacement(source_manager, range, new_text); + } return true; }
diff --git a/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-expected.cc new file mode 100644 index 0000000..374a094 --- /dev/null +++ b/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-expected.cc
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace blink { + +// On Linux, bool can be a macro. Make sure this case is handled correctly. +#define bool bool + +bool FunctionReturningBool(char* input_data) { + return input_data[0]; +} + +} // namespace blink
diff --git a/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-original.cc b/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-original.cc new file mode 100644 index 0000000..dcddee1 --- /dev/null +++ b/tools/clang/rewrite_to_chrome_style/tests/bool-is-macro-original.cc
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace blink { + +// On Linux, bool can be a macro. Make sure this case is handled correctly. +#define bool bool + +bool functionReturningBool(char* inputData) { + return inputData[0]; +} + +} // namespace blink
diff --git a/tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc index 7136069..00ce6b21 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc
@@ -19,7 +19,7 @@ struct Base {}; struct Derived : public Base {}; -DEFINE_TYPE_CASTS(Derived, Base, object, true); +DEFINE_TYPE_CASTS(Derived, Base, the_object, true); void F() { Base* base_ptr = new Derived; @@ -76,7 +76,7 @@ \ public: \ int name() { return m_##name; } \ - void Set##Name(int value) { m_##name = value; } + void Set##Name(int name) { m_##name = name; } DECLARE_FIELD(FooBar, FooBar) DECLARE_FIELD(BarBaz, BarBaz)
diff --git a/tools/clang/rewrite_to_chrome_style/tests/macros-original.cc b/tools/clang/rewrite_to_chrome_style/tests/macros-original.cc index 8a924eba..78412c9 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/macros-original.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/macros-original.cc
@@ -19,7 +19,7 @@ struct Base {}; struct Derived : public Base {}; -DEFINE_TYPE_CASTS(Derived, Base, object, true); +DEFINE_TYPE_CASTS(Derived, Base, theObject, true); void F() { Base* basePtr = new Derived; @@ -76,7 +76,7 @@ \ public: \ int name() { return m_##name; } \ - void set##Name(int value) { m_##name = value; } + void set##Name(int name) { m_##name = name; } DECLARE_FIELD(fooBar, FooBar) DECLARE_FIELD(barBaz, BarBaz)
diff --git a/tools/clang/rewrite_to_chrome_style/tests/variables-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/variables-expected.cc index 119edd6..7b8a3d8f 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/variables-expected.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/variables-expected.cc
@@ -20,9 +20,9 @@ // Static locals. static int a_static_local_variable = 2; // Make sure references to variables are also rewritten. - return g_frame_count + - g_variable_mentioning_http_and_https * interesting_number / - a_local_variable % a_static_local_variable; + return g_frame_count + g_variable_mentioning_http_and_https * + interesting_number / a_local_variable % + a_static_local_variable; } } // namespace blink
diff --git a/tools/ipc_fuzzer/OWNERS b/tools/ipc_fuzzer/OWNERS index 66e501b..1f569281 100644 --- a/tools/ipc_fuzzer/OWNERS +++ b/tools/ipc_fuzzer/OWNERS
@@ -2,4 +2,4 @@ mbarbella@chromium.org tsepez@chromium.org -# COMPONENT: Tools +# COMPONENT: Tools>Stability>Libfuzzer
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index bf14b47..dc2c81e 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -312,17 +312,6 @@ 'Mac ASan 64 Builder': 'asan_full_symbols_disable_nacl_release_bot_dcheck_always_on', }, - 'chromium.memory.fyi': { - 'Chromium Linux ChromeOS MSan Builder': 'chromeos_msan_release_bot', - 'Chromium Linux MSan Builder': 'msan_release_bot', - }, - - 'chromium.memory.full': { - 'Chromium Linux ChromeOS MSan Builder': 'chromeos_msan_release_bot', - 'Chromium Linux MSan Builder': 'msan_release_bot', - 'Chromium Linux TSan Builder': 'tsan_disable_nacl_release_bot', - }, - 'chromium.perf': { 'Android Builder': 'official_goma_minimal_symbols_android', 'Android arm64 Builder': 'official_goma_minimal_symbols_android_arm64',
diff --git a/tools/metrics/histograms/extract_histograms.py b/tools/metrics/histograms/extract_histograms.py index 61d7e864..6e53bc41 100644 --- a/tools/metrics/histograms/extract_histograms.py +++ b/tools/metrics/histograms/extract_histograms.py
@@ -216,8 +216,7 @@ value_dict['summary'] = _JoinChildNodes(int_tag) enum_dict['values'][int_value] = value_dict - enum_items = sorted(enum_dict['values'].iteritems(), key=lambda i: i[0]) - enum_int_values = list(i[0] for i in enum_items) + enum_int_values = sorted(enum_dict['values'].keys()) last_int_value = None for int_tag in enum.getElementsByTagName('int'): @@ -230,9 +229,10 @@ if left_item_index == 0: logging.warning('Insert value %d at the beginning', int_value) else: - left_int_value, left_value_dict = enum_items[left_item_index - 1] + left_int_value = enum_int_values[left_item_index - 1] + left_label = enum_dict['values'][left_int_value]['label'] logging.warning('Insert value %d after %d ("%s")', - int_value, left_int_value, left_value_dict['label']) + int_value, left_int_value, left_label) else: last_int_value = int_value
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9cf7ba5..40b42f8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -31336,6 +31336,15 @@ </summary> </histogram> +<histogram name="Navigation.IOSWKWebViewSlowFastBackForward" + enum="BackForwardNavigationType"> + <owner>eugenebut@chromium.org</owner> + <summary> + Counts slow/fast back/forward WKWebView navigations on iOS. Fast navigation + is a back/forward navigation done with WKBackForwardList. + </summary> +</histogram> + <histogram name="Navigation.IsMobileOptimized" enum="BooleanIsMobileOptimized"> <owner>cjhopman@chromium.org</owner> <owner>nyquist@chromium.org</owner> @@ -34773,6 +34782,30 @@ </summary> </histogram> +<histogram name="Net.HttpStreamFactoryJob.Alt.NextState" + enum="HttpStreamFactoryJobState"> + <owner>xunjieli@chromium.org</owner> + <summary>Reports the next state that the Alternative Job is in.</summary> +</histogram> + +<histogram name="Net.HttpStreamFactoryJob.Alt.State" + enum="HttpStreamFactoryJobState"> + <owner>xunjieli@chromium.org</owner> + <summary>Reports the state that the Alternative Job is in.</summary> +</histogram> + +<histogram name="Net.HttpStreamFactoryJob.Main.NextState" + enum="HttpStreamFactoryJobState"> + <owner>xunjieli@chromium.org</owner> + <summary>Reports the next state that the Main Job is in.</summary> +</histogram> + +<histogram name="Net.HttpStreamFactoryJob.Main.State" + enum="HttpStreamFactoryJobState"> + <owner>xunjieli@chromium.org</owner> + <summary>Reports the state that the Main Job is in.</summary> +</histogram> + <histogram name="Net.HttpStreamFactoryJob.StreamReadyCallbackTime" units="ms"> <owner>zhongyi@chromium.org</owner> <summary>Time it takes for OnStreamReadyCallback to be called.</summary> @@ -83864,6 +83897,13 @@ <int value="2" label="Ok, got it"/> </enum> +<enum name="BackForwardNavigationType" type="int"> + <int value="0" label="Fast back navigation with WKBackForwardList"/> + <int value="1" label="Slow back navigation"/> + <int value="2" label="Fast forward navigation with WKBackForwardList"/> + <int value="3" label="Slow forward navigation"/> +</enum> + <enum name="BackgroundFetchEventDispatchResult" type="int"> <int value="0" label="Success"/> <int value="1" label="Cannot find worker"/> @@ -98560,6 +98600,29 @@ </int> </enum> +<enum name="HttpStreamFactoryJobState" type="int"> + <summary> + State of HttpStreamFactoryJob. See net::HttpStreamFactoryImpl::Job::State + for more details + </summary> + <int value="0" label="START"/> + <int value="1" label="RESOLVE_PROXY"/> + <int value="2" label="RESOLVE_PROXY_COMPLETE"/> + <int value="3" label="WAIT"/> + <int value="4" label="WAIT_COMPLETE"/> + <int value="5" label="INIT_CONNECTION"/> + <int value="6" label="INIT_CONNECTION_COMPLETE"/> + <int value="7" label="WAITING_USER_ACTION"/> + <int value="8" label="RESTART_TUNNEL_AUTH"/> + <int value="9" label="RESTART_TUNNEL_AUTH_COMPLETE"/> + <int value="10" label="CREATE_STREAM"/> + <int value="11" label="CREATE_STREAM_COMPLETE"/> + <int value="12" label="DRAIN_BODY_FOR_AUTH_RESTART"/> + <int value="13" label="DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE"/> + <int value="14" label="DONE"/> + <int value="15" label="NONE"/> +</enum> + <enum name="ICCProfileAnalyzeResult" type="int"> <int value="0" label="Extracted primary matrix and numerical transfer function"/>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 0c8de0a..4a0565a8 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -162,7 +162,7 @@ system_health.memory_mobile,perezju@chromium.org, system_health.webview_startup,"perezju@chromium.org, torne@chromium.org", system_health.webview_startup_multiprocess,, -tab_switching.typical_25,, +tab_switching.typical_25,vovoy@chromium.org,OS>Performance text_selection.character,mfomitchev@chromium.org, text_selection.direction,mfomitchev@chromium.org, thread_times.key_hit_test_cases,,
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 927965e..b4b42eca 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -580,8 +580,8 @@ ] -def generate_telemetry_tests( - tester_config, benchmarks, benchmark_sharding_map, use_whitelist): +def generate_telemetry_tests(tester_config, benchmarks, benchmark_sharding_map, + use_whitelist, benchmark_ref_build_blacklist): isolated_scripts = [] # First determine the browser that you need based on the tester browser_name = '' @@ -624,13 +624,15 @@ swarming_dimensions, benchmark.Name(), browser_name) isolated_scripts.append(test) # Now create another executable for this benchmark on the reference browser - reference_test = generate_telemetry_test( - swarming_dimensions, benchmark.Name(),'reference') - isolated_scripts.append(reference_test) - if current_shard == (num_shards - 1): - current_shard = 0 - else: - current_shard += 1 + # if it is not blacklisted from running on the reference browser. + if benchmark.Name() not in benchmark_ref_build_blacklist: + reference_test = generate_telemetry_test( + swarming_dimensions, benchmark.Name(),'reference') + isolated_scripts.append(reference_test) + if current_shard == (num_shards - 1): + current_shard = 0 + else: + current_shard += 1 return isolated_scripts @@ -668,6 +670,12 @@ 'Win 10 High-DPI Perf', ] +# List of benchmarks that are to never be run with reference builds. +BENCHMARK_REF_BUILD_BLACKLIST = [ + 'power.idle_platform', +] + + def current_benchmarks(use_whitelist): benchmarks_dir = os.path.join(src_dir(), 'tools', 'perf', 'benchmarks') top_level_dir = os.path.dirname(benchmarks_dir) @@ -768,7 +776,8 @@ if name in LEGACY_DEVICE_AFFIINITY_ALGORITHM: sharding_map = None isolated_scripts = generate_telemetry_tests( - config, benchmark_list, sharding_map, use_whitelist) + config, benchmark_list, sharding_map, use_whitelist, + BENCHMARK_REF_BUILD_BLACKLIST) # Generate swarmed non-telemetry tests if present if config['swarming_dimensions'][0].get('perf_tests', False): isolated_scripts += generate_cplusplus_isolate_script_test(
diff --git a/tools/perf/core/perf_data_generator_unittest.py b/tools/perf/core/perf_data_generator_unittest.py index 4aad5c30..4301ffa 100644 --- a/tools/perf/core/perf_data_generator_unittest.py +++ b/tools/perf/core/perf_data_generator_unittest.py
@@ -6,6 +6,8 @@ from core import perf_data_generator from core.perf_data_generator import BenchmarkMetadata +from telemetry import benchmark + class PerfDataGeneratorTest(unittest.TestCase): def setUp(self): @@ -111,3 +113,30 @@ 'isolate_name': 'telemetry_perf_tests', } self.assertEquals(test, expected_generated_test) + + def testGenerateTelemetryTestsBlacklistedReferenceBuildTest(self): + class BlacklistedBenchmark(benchmark.Benchmark): + @classmethod + def Name(cls): + return 'blacklisted' + + class NotBlacklistedBenchmark(benchmark.Benchmark): + @classmethod + def Name(cls): + return 'not_blacklisted' + + swarming_dimensions = [ + {'os': 'SkyNet', 'id': 'T-850', 'pool': 'T-RIP', 'device_ids': ['a']} + ] + test_config = { + 'platform': 'android', + 'swarming_dimensions': swarming_dimensions, + } + benchmarks = [BlacklistedBenchmark, NotBlacklistedBenchmark] + tests = perf_data_generator.generate_telemetry_tests( + test_config, benchmarks, None, False, ['blacklisted']) + + generated_test_names = set(t['name'] for t in tests) + self.assertEquals( + generated_test_names, + {'blacklisted', 'not_blacklisted', 'not_blacklisted.reference'})
diff --git a/tools/win/subtract_time.py b/tools/win/subtract_time.py new file mode 100644 index 0000000..4e1559b --- /dev/null +++ b/tools/win/subtract_time.py
@@ -0,0 +1,20 @@ +# Copyright (c) 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +This script converts to %time% compatible strings passed to it into seconds, +subtracts them, and prints the difference. That's it. It's used by timeit.bat. +""" + +import re +import sys + +def ParseTime(time_string): + # Time looks like 15:19:30.32 + match = re.match("(.*):(.*):(.*)\.(.*)", time_string) + hours, minutes, seconds, fraction = map(int, match.groups()) + return hours * 3600 + minutes * 60 + seconds + fraction * .01 + +print "%1.2f seconds elapsed time" % (ParseTime(sys.argv[1]) - + ParseTime(sys.argv[2]))
diff --git a/tools/win/timeit.bat b/tools/win/timeit.bat new file mode 100755 index 0000000..af00372 --- /dev/null +++ b/tools/win/timeit.bat
@@ -0,0 +1,13 @@ +@ECHO off + +REM Copyright (c) 2017 The Chromium Authors. All rights reserved. +REM Use of this source code is governed by a BSD-style license that can be +REM found in the LICENSE file. + +REM This batch file executes the commands passed to it and prints out the +REM elapsed run time. + +SETLOCAL +SET starttime=%time% +CALL %* +CALL python %~dp0subtract_time.py %time% %starttime%
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 3f37fc2..5a6d887 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -1083,7 +1083,7 @@ // to use a compatible config. We expect the client to request RGB565 // onscreen surface also for this to work (with the exception of // fullscreen video). - if (base::SysInfo::IsLowEndDevice()) + if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) format.SetRGB565(); #endif
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm index c77bdf4..ce75522 100644 --- a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm +++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
@@ -5,6 +5,7 @@ #import "ui/views/controls/scrollbar/cocoa_scroll_bar.h" #import "base/mac/sdk_forward_declarations.h" +#include "cc/paint/paint_shader.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "ui/compositor/layer.h"