diff --git a/DEPS b/DEPS index e3abd6e..1c592e8d 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '9f6be2e9e4279586cf484b669d1fc701c31a7fe2', + 'v8_revision': '83d9ade42120db9133e0c94d4d193386d69456f8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '012ae898a069bda7afbfdad4eb4c8ba042b68dc7', + 'pdfium_revision': '2bbb55162f0c9490a2085ed6eaa38038a7605609', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -232,7 +232,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '9cdb5386506ddbff3cbb096e9d2292c632ad915c', # commit position 17863 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'ce4e632d4dd043996afe4402d4edf27186b33032', # commit position 17884 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 02f2a6a..c7619a9 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -743,10 +743,15 @@ ProcessId pid = kv.first; // kNullProcessId for the current process. ProcessMemoryDump* process_memory_dump = kv.second.get(); - bool added_to_trace = tracing_observer_->AddDumpToTraceIfEnabled( - &pmd_async_state->req_args, pid, process_memory_dump); + // SUMMARY_ONLY dumps are just return the summarized result in the + // ProcessMemoryDumpCallback. These shouldn't be added to the trace to + // avoid confusing trace consumers. + if (pmd_async_state->req_args.dump_type != MemoryDumpType::SUMMARY_ONLY) { + bool added_to_trace = tracing_observer_->AddDumpToTraceIfEnabled( + &pmd_async_state->req_args, pid, process_memory_dump); - dump_successful = dump_successful && added_to_trace; + dump_successful = dump_successful && added_to_trace; + } // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 // Don't try to fill the struct in detailed mode since it is hard to avoid
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc index 732b5c8..946b5b64 100644 --- a/base/trace_event/memory_dump_manager_unittest.cc +++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -221,6 +221,23 @@ unsigned num_of_post_tasks_; }; +std::unique_ptr<trace_analyzer::TraceAnalyzer> GetDeserializedTrace() { + // Flush the trace into JSON. + trace_event::TraceResultBuffer buffer; + TraceResultBuffer::SimpleOutput trace_output; + buffer.SetOutputCallback(trace_output.GetCallback()); + RunLoop run_loop; + buffer.Start(); + trace_event::TraceLog::GetInstance()->Flush( + Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer))); + run_loop.Run(); + buffer.Finish(); + + // Analyze the JSON. + return WrapUnique( + trace_analyzer::TraceAnalyzer::Create(trace_output.json_output)); +} + } // namespace class MemoryDumpManagerTest : public testing::Test { @@ -1080,20 +1097,8 @@ MemoryDumpLevelOfDetail::DETAILED); DisableTracing(); - // Flush the trace into JSON. - trace_event::TraceResultBuffer buffer; - TraceResultBuffer::SimpleOutput trace_output; - buffer.SetOutputCallback(trace_output.GetCallback()); - RunLoop run_loop; - buffer.Start(); - trace_event::TraceLog::GetInstance()->Flush( - Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer))); - run_loop.Run(); - buffer.Finish(); - - // Analyze the JSON. - std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = WrapUnique( - trace_analyzer::TraceAnalyzer::Create(trace_output.json_output)); + std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = + GetDeserializedTrace(); trace_analyzer::TraceEventVector events; analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), &events); @@ -1107,6 +1112,37 @@ ASSERT_EQ(events[0]->id, events[2]->id); } +TEST_F(MemoryDumpManagerTest, SummaryOnlyDumpsArentAddedToTrace) { + using trace_analyzer::Query; + + InitializeMemoryDumpManager(false /* is_coordinator */); + SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); + + // Standard provider with default options (create dump for current process). + MockMemoryDumpProvider mdp; + RegisterDumpProvider(&mdp, nullptr, kDefaultOptions, kWhitelistedMDPName); + + EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); + EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2); + EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2).WillRepeatedly(Return(true)); + RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, + MemoryDumpLevelOfDetail::BACKGROUND); + RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY, + MemoryDumpLevelOfDetail::BACKGROUND); + DisableTracing(); + + std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = + GetDeserializedTrace(); + trace_analyzer::TraceEventVector events; + analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), + &events); + + ASSERT_EQ(1u, events.size()); + ASSERT_TRUE(trace_analyzer::CountMatches( + events, Query::EventNameIs(MemoryDumpTypeToString( + MemoryDumpType::EXPLICITLY_TRIGGERED)))); +} + // Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the // unregistration should actually delete the providers and not leak them. TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) {
diff --git a/base/trace_event/memory_dump_request_args.cc b/base/trace_event/memory_dump_request_args.cc index 0b525d4..633b535 100644 --- a/base/trace_event/memory_dump_request_args.cc +++ b/base/trace_event/memory_dump_request_args.cc
@@ -18,6 +18,8 @@ return "explicitly_triggered"; case MemoryDumpType::PEAK_MEMORY_USAGE: return "peak_memory_usage"; + case MemoryDumpType::SUMMARY_ONLY: + return "summary_only"; } NOTREACHED(); return "unknown"; @@ -30,6 +32,8 @@ return MemoryDumpType::EXPLICITLY_TRIGGERED; if (str == "peak_memory_usage") return MemoryDumpType::PEAK_MEMORY_USAGE; + if (str == "summary_only") + return MemoryDumpType::SUMMARY_ONLY; NOTREACHED(); return MemoryDumpType::LAST; }
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h index 0f42a1853..bc5cc38e 100644 --- a/base/trace_event/memory_dump_request_args.h +++ b/base/trace_event/memory_dump_request_args.h
@@ -28,7 +28,8 @@ PERIODIC_INTERVAL, // Dumping memory at periodic intervals. EXPLICITLY_TRIGGERED, // Non maskable dump request. PEAK_MEMORY_USAGE, // Dumping memory at detected peak total memory usage. - LAST = PEAK_MEMORY_USAGE // For IPC macros. + SUMMARY_ONLY, // Calculate just the summary & don't add to the trace. + LAST = SUMMARY_ONLY }; // Tells the MemoryDumpProvider(s) how much detailed their dumps should be.
diff --git a/base/trace_event/memory_tracing_observer.cc b/base/trace_event/memory_tracing_observer.cc index 3130b20..a5b60e4 100644 --- a/base/trace_event/memory_tracing_observer.cc +++ b/base/trace_event/memory_tracing_observer.cc
@@ -72,6 +72,8 @@ if (!IsMemoryInfraTracingEnabled()) return false; + CHECK_NE(MemoryDumpType::SUMMARY_ONLY, req_args->dump_type); + const uint64_t dump_guid = req_args->dump_guid; std::unique_ptr<TracedValue> traced_value(new TracedValue);
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 6b7472f4..fa0bd60 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -652,6 +652,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", @@ -769,6 +771,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", @@ -939,6 +942,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 86348f0..e1fa9d0 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -11,19 +11,25 @@ #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: + PaintCanvas() {} 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 @@ -36,7 +42,7 @@ 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; @@ -87,6 +93,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, @@ -180,6 +188,9 @@ protected: friend class PaintSurface; friend class PaintRecorder; + + private: + DISALLOW_COPY_AND_ASSIGN(PaintCanvas); }; class CC_PAINT_EXPORT PaintCanvasAutoRestore {
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..fa62a41 --- /dev/null +++ b/cc/paint/paint_op_buffer.cc
@@ -0,0 +1,566 @@ +// 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) { + PaintOp* single_op = op->record->GetFirstOp(); + // RasterWithAlpha only supported for draw ops. + if (single_op->IsDrawOp()) { + single_op->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); +} + +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( + scoped_refptr<DisplayItemList> list) + : list(list) {} + +size_t DrawDisplayItemListOp::AdditionalBytesUsed() const { + return list->ApproximateMemoryUsage(); +} + +DrawDisplayItemListOp::DrawDisplayItemListOp(const DrawDisplayItemListOp& op) = + default; + +DrawDisplayItemListOp& DrawDisplayItemListOp::operator=( + const DrawDisplayItemListOp& op) = 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..c874590 --- /dev/null +++ b/cc/paint/paint_op_buffer.h
@@ -0,0 +1,799 @@ +// 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 "base/memory/aligned_memory.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 CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix { + public: + explicit ThreadsafeMatrix(const SkMatrix& matrix) : SkMatrix(matrix) { + (void)getType(); + } +}; + +class CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT PaintOpWithDataArrayBase : PaintOpWithData { + // Helper class for static asserts in push functions. + using PaintOpWithData::PaintOpWithData; +}; + +template <typename T> +struct CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT ConcatOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Concat; + explicit ConcatOp(const SkMatrix& matrix) : matrix(matrix) {} + void Raster(SkCanvas* canvas) const; + + ThreadsafeMatrix matrix; +}; + +struct CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT DrawDisplayItemListOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::DrawDisplayItemList; + static constexpr bool kIsDrawOp = true; + explicit DrawDisplayItemListOp(scoped_refptr<DisplayItemList> list); + // Windows wants to generate these when types are exported, so + // provide them here explicitly so that DisplayItemList doesn't have + // to be defined in this header. + DrawDisplayItemListOp(const DrawDisplayItemListOp& op); + DrawDisplayItemListOp& operator=(const DrawDisplayItemListOp& op); + ~DrawDisplayItemListOp(); + void Raster(SkCanvas* canvas) const; + size_t AdditionalBytesUsed() const; + // TODO(enne): DisplayItemList should know number of slow paths. + + scoped_refptr<DisplayItemList> list; +}; + +struct CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT NoopOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Noop; + void Raster(SkCanvas* canvas) const {} +}; + +struct CC_PAINT_EXPORT RestoreOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Restore; + void Raster(SkCanvas* canvas) const; +}; + +struct CC_PAINT_EXPORT RotateOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Rotate; + explicit RotateOp(SkScalar degrees) : degrees(degrees) {} + void Raster(SkCanvas* canvas) const; + + SkScalar degrees; +}; + +struct CC_PAINT_EXPORT SaveOp final : PaintOp { + static constexpr PaintOpType kType = PaintOpType::Save; + void Raster(SkCanvas* canvas) const; +}; + +struct CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 CC_PAINT_EXPORT 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 const_cast<PaintOp*>(first_op_.data_as<PaintOp>()); + } + + 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 { + // |first_op_| is aligned to LargestPaintOp. If T needs a smaller + // alignment, this is okay because it will be a factor of the actual + // alignment being used (as they are always a power of 2). If T needs + // a larger alignment, that is bad and we should use T to choose the + // alignment of |first_op_| instead. + static_assert(ALIGNOF(T) <= ALIGNOF(LargestPaintOp), ""); + auto* op = reinterpret_cast<T*>(first_op_.data_as<T>()); + new (op) T{std::forward<Args>(args)...}; + op->type = static_cast<uint32_t>(T::kType); + op->skip = 0; + AnalyzeAddedOp(op); + 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; + AnalyzeAddedOp(op); + op_count_++; + return op; + } + + template <typename T> + void AnalyzeAddedOp(const T* op) { + num_slow_paths_ += CountSlowPathsFromFlags<T, T::kHasPaintFlags>::Count(op); + num_slow_paths_ += op->CountSlowPaths(); + + subrecord_bytes_used_ += op->AdditionalBytesUsed(); + } + + // 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. + base::AlignedMemory<sizeof(LargestPaintOp), ALIGNOF(LargestPaintOp)> + first_op_; + 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..a962ab9 --- /dev/null +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -0,0 +1,332 @@ +// 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()); +} + +// Verify that the save draw restore code works with a single op +// that's not a draw op, and the optimization does not kick in. +TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpNotADrawOp) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + + buffer.push<NoopOp>(); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.playback(&canvas); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); +} + +// Test that the save/draw/restore optimization applies if the single op +// is a DrawRecord that itself has a single draw op. +TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleOp) { + sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>(); + + 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); + record->push<DrawRectOp>(rect, draw_flags); + EXPECT_EQ(record->approximateOpCount(), 1); + + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + buffer.push<DrawRecordOp>(std::move(record)); + 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_); + + float expected_alpha = alpha * 50 / 255.f; + EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f); +} + +// The same as the above SingleOpRecord test, but the single op is not +// a draw op. So, there's no way to fold in the save layer optimization. +// Verify that the optimization doesn't apply and that this doesn't crash. +// See: http://crbug.com/712093. +TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleNonDrawOp) { + sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>(); + record->push<NoopOp>(); + EXPECT_EQ(record->approximateOpCount(), 1); + EXPECT_FALSE(record->GetFirstOp()->IsDrawOp()); + + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + buffer.push<DrawRecordOp>(std::move(record)); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.playback(&canvas); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); +} + +} // 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..2ed17c74 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()); + 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..935452a3 --- /dev/null +++ b/cc/paint/record_paint_canvas.cc
@@ -0,0 +1,372 @@ +// 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) : buffer_(buffer) { + DCHECK(buffer_); +} + +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 GetCanvas()->getMetaData(); +} + +SkImageInfo RecordPaintCanvas::imageInfo() const { + return GetCanvas()->imageInfo(); +} + +void RecordPaintCanvas::flush() { + // This is a noop when recording. +} + +int RecordPaintCanvas::save() { + buffer_->push<SaveOp>(); + return GetCanvas()->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 GetCanvas()->saveLayer(bounds, &paint); + } + buffer_->push<SaveLayerOp>(bounds, flags); + return GetCanvas()->saveLayer(bounds, nullptr); +} + +int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) { + buffer_->push<SaveLayerAlphaOp>(bounds, alpha); + return GetCanvas()->saveLayerAlpha(bounds, alpha); +} + +void RecordPaintCanvas::restore() { + buffer_->push<RestoreOp>(); + GetCanvas()->restore(); +} + +int RecordPaintCanvas::getSaveCount() const { + return GetCanvas()->getSaveCount(); +} + +void RecordPaintCanvas::restoreToCount(int save_count) { + if (!canvas_) { + DCHECK_EQ(save_count, 1); + return; + } + + DCHECK_GE(save_count, 1); + int diff = GetCanvas()->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); + GetCanvas()->translate(dx, dy); +} + +void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) { + buffer_->push<ScaleOp>(sx, sy); + GetCanvas()->scale(sx, sy); +} + +void RecordPaintCanvas::rotate(SkScalar degrees) { + buffer_->push<RotateOp>(degrees); + GetCanvas()->rotate(degrees); +} + +void RecordPaintCanvas::concat(const SkMatrix& matrix) { + buffer_->push<ConcatOp>(matrix); + GetCanvas()->concat(matrix); +} + +void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) { + buffer_->push<SetMatrixOp>(matrix); + GetCanvas()->setMatrix(matrix); +} + +void RecordPaintCanvas::clipRect(const SkRect& rect, + SkClipOp op, + bool antialias) { + buffer_->push<ClipRectOp>(rect, op, antialias); + GetCanvas()->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); + GetCanvas()->clipRRect(rrect, op, antialias); +} + +void RecordPaintCanvas::clipPath(const SkPath& path, + SkClipOp op, + bool antialias) { + if (!path.isInverseFillType() && + GetCanvas()->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); + GetCanvas()->clipPath(path, op, antialias); + return; +} + +bool RecordPaintCanvas::quickReject(const SkRect& rect) const { + return GetCanvas()->quickReject(rect); +} + +bool RecordPaintCanvas::quickReject(const SkPath& path) const { + return GetCanvas()->quickReject(path); +} + +SkRect RecordPaintCanvas::getLocalClipBounds() const { + return GetCanvas()->getLocalClipBounds(); +} + +bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const { + return GetCanvas()->getLocalClipBounds(bounds); +} + +SkIRect RecordPaintCanvas::getDeviceClipBounds() const { + return GetCanvas()->getDeviceClipBounds(); +} + +bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const { + return GetCanvas()->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 GetCanvas()->isClipEmpty(); +} + +bool RecordPaintCanvas::isClipRect() const { + return GetCanvas()->isClipRect(); +} + +const SkMatrix& RecordPaintCanvas::getTotalMatrix() const { + return GetCanvas()->getTotalMatrix(); +} + +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); +} + +const SkNoDrawCanvas* RecordPaintCanvas::GetCanvas() const { + return const_cast<RecordPaintCanvas*>(this)->GetCanvas(); +} + +SkNoDrawCanvas* RecordPaintCanvas::GetCanvas() { + if (canvas_) + return &*canvas_; + + SkIRect rect = buffer_->cullRect().roundOut(); + canvas_.emplace(rect.right(), rect.bottom()); + + // 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(rect), SkClipOp::kIntersect, false); + return &*canvas_; +} + +} // namespace cc
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h new file mode 100644 index 0000000..4677512 --- /dev/null +++ b/cc/paint/record_paint_canvas.h
@@ -0,0 +1,159 @@ +// 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 "base/optional.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); + ~RecordPaintCanvas() override; + + SkMetaData& getMetaData() override; + SkImageInfo imageInfo() const override; + + void flush() 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 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: + const SkNoDrawCanvas* GetCanvas() const; + SkNoDrawCanvas* GetCanvas(); + + 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. + // + // This is mutable so that const functions (e.g. quickReject) that may + // lazy initialize the canvas can still be const. + mutable base::Optional<SkNoDrawCanvas> canvas_; + + DISALLOW_COPY_AND_ASSIGN(RecordPaintCanvas); +}; + +} // 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 9c1a20a..47953bd 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc
@@ -22,7 +22,6 @@ const SkSurfaceProps& props) : canvas_(new SkCanvas(bitmap, props)), owned_(canvas_) {} -SkiaPaintCanvas::SkiaPaintCanvas(SkiaPaintCanvas&& other) = default; SkiaPaintCanvas::~SkiaPaintCanvas() = default; SkMetaData& SkiaPaintCanvas::getMetaData() { @@ -45,7 +44,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 8e016f0..720104df 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -28,11 +28,8 @@ explicit SkiaPaintCanvas(SkCanvas* canvas); explicit SkiaPaintCanvas(const SkBitmap& bitmap); explicit SkiaPaintCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props); - explicit SkiaPaintCanvas(SkiaPaintCanvas&& other); ~SkiaPaintCanvas() override; - SkiaPaintCanvas& operator=(SkiaPaintCanvas&& other) = default; - SkMetaData& getMetaData() override; SkImageInfo imageInfo() const override; @@ -40,7 +37,7 @@ 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/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 700ebd2..850a28f 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -6658,8 +6658,27 @@ FakeContentLayerClient client_; }; +class LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin + : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin); + LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin); + +class LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin + : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin); class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { protected: @@ -6771,15 +6790,30 @@ FakeContentLayerClient client_; }; +class LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer + : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeTestMaskLayerForSurfaceWithClippedLayer); + LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer); + +class LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer + : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer); class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->layer_transforms_should_scale_layer_contents = true; - } - void SetupTree() override { // Root // | @@ -6895,7 +6929,27 @@ FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling); +class LayerTreeTestSingleTextureMaskLayerWithScaling + : public LayerTreeTestMaskLayerWithScaling { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + settings->layer_transforms_should_scale_layer_contents = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestSingleTextureMaskLayerWithScaling); + +class LayerTreeTestMultiTextureMaskLayerWithScaling + : public LayerTreeTestMaskLayerWithScaling { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + settings->layer_transforms_should_scale_layer_contents = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureMaskLayerWithScaling); class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest { protected: @@ -7000,7 +7054,27 @@ FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds); +class LayerTreeTestSingleTextureMaskLayerWithDifferentBounds + : public LayerTreeTestMaskLayerWithDifferentBounds { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestSingleTextureMaskLayerWithDifferentBounds); + +class LayerTreeTestMultiTextureMaskLayerWithDifferentBounds + : public LayerTreeTestMaskLayerWithDifferentBounds { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerWithDifferentBounds); class LayerTreeTestPageScaleFlags : public LayerTreeTest { protected:
diff --git a/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml b/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml index 3793a52..815da682 100644 --- a/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml +++ b/chrome/android/java/res/layout-sw360dp/preference_spinner_single_line.xml
@@ -21,7 +21,9 @@ android:textAlignment="viewStart" android:layout_height="wrap_content" android:layout_width="0dp" - android:layout_weight="1" /> + android:layout_weight="1" + android:paddingTop="12dp" + android:paddingBottom="12dp"/> <Spinner android:id="@+id/spinner"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index d769f08..c37db14 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -550,6 +550,8 @@ getImageControl().hideCustomImage(true); getSearchBarControl().setSearchTerm(searchTerm); mPanelMetrics.onSearchRequestStarted(); + // Make sure the new Search Term draws. + requestUpdate(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java index 4fdbc1e..752e673 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
@@ -16,6 +16,8 @@ import android.view.View.MeasureSpec; import android.view.View.OnTouchListener; import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.widget.FrameLayout; import android.widget.PopupWindow; import android.widget.PopupWindow.OnDismissListener; import android.widget.TextView; @@ -302,9 +304,15 @@ private void createContentView() { if (mPopupWindow.getContentView() != null) return; + View view = LayoutInflater.from(mContext).inflate(R.layout.textbubble_text, null); ((TextView) view).setText(mStringId); mPopupWindow.setContentView(view); + + // On some versions of Android, the LayoutParams aren't set until after the popup window + // is shown. Explicitly set the LayoutParams to avoid crashing. See crbug.com/713759. + view.setLayoutParams( + new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } // OnTouchListener implementation.
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/OWNERS b/chrome/browser/extensions/api/enterprise_platform_keys/OWNERS index 325f7c3..56eef3e 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/OWNERS +++ b/chrome/browser/extensions/api/enterprise_platform_keys/OWNERS
@@ -1 +1,2 @@ emaxx@chromium.org +drcrash@chromium.org
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/OWNERS b/chrome/browser/extensions/api/enterprise_platform_keys_private/OWNERS index d7df737..19c0042 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys_private/OWNERS +++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/OWNERS
@@ -1,3 +1,5 @@ -dkrahn@chromium.org -mnissler@chromium.org +emaxx@chromium.org +drcrash@chromium.org bartfab@chromium.org +mnissler@chromium.org +dkrahn@chromium.org
diff --git a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc index 822e9ff..9d19714 100644 --- a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc +++ b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
@@ -39,6 +39,7 @@ #include "net/log/net_log_entry.h" #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h" #include "chrome/browser/chromeos/system_logs/debug_log_writer.h" #endif @@ -111,7 +112,15 @@ // will be stored - /home/chronos/<user_profile_dir>/Downloads/log_dumps base::FilePath GetLogDumpDirectory(content::BrowserContext* context) { const DownloadPrefs* const prefs = DownloadPrefs::FromBrowserContext(context); - return prefs->DownloadPath().Append(kLogDumpsSubdir); + base::FilePath path = prefs->DownloadPath(); + +#if defined(OS_CHROMEOS) + Profile* profile = Profile::FromBrowserContext(context); + if (file_manager::util::IsUnderNonNativeLocalPath(profile, path)) + path = prefs->GetDefaultDownloadDirectoryForProfile(); +#endif + + return path.Append(kLogDumpsSubdir); } // Removes direcotry content of |logs_dumps| and |app_logs_dir| (only for the
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc index 94b24b55a..6235a9c 100644 --- a/chrome/browser/net/dns_probe_browsertest.cc +++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -9,7 +9,7 @@ #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" @@ -185,8 +185,12 @@ request, network_delegate, file_path, - BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior( + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN))), should_delay_(should_delay), start_delayed_(false), destruction_callback_(destruction_callback) {}
diff --git a/chrome/browser/net/load_timing_browsertest.cc b/chrome/browser/net/load_timing_browsertest.cc index e6f53d9c..18af0e56 100644 --- a/chrome/browser/net/load_timing_browsertest.cc +++ b/chrome/browser/net/load_timing_browsertest.cc
@@ -14,7 +14,7 @@ #include "base/path_service.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -123,10 +123,15 @@ const base::FilePath& path, const TimingDeltas& load_timing_deltas) : net::URLRequestFileJob( - request, network_delegate, path, - content::BrowserThread::GetBlockingPool()-> - GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), + request, + network_delegate, + path, + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior( + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN))), load_timing_deltas_(load_timing_deltas), weak_factory_(this) {}
diff --git a/chrome/browser/notifications/notification_common.cc b/chrome/browser/notifications/notification_common.cc index 92f44b4..3320f6a 100644 --- a/chrome/browser/notifications/notification_common.cc +++ b/chrome/browser/notifications/notification_common.cc
@@ -14,6 +14,7 @@ void NotificationCommon::OpenNotificationSettings( content::BrowserContext* browser_context) { #if defined(OS_ANDROID) + // Android settings are opened directly from Java NOTIMPLEMENTED(); #else Profile* profile = Profile::FromBrowserContext(browser_context);
diff --git a/chrome/browser/notifications/notification_display_service_factory.cc b/chrome/browser/notifications/notification_display_service_factory.cc index 3e7c4f1..da0e659 100644 --- a/chrome/browser/notifications/notification_display_service_factory.cc +++ b/chrome/browser/notifications/notification_display_service_factory.cc
@@ -39,25 +39,28 @@ // Selection of the implementation works as follows: // - Android always uses the NativeNotificationDisplayService. -// - Mac uses the MessageCenterDisplayService by default, but can use the -// NativeNotificationDisplayService by using the chrome://flags or via -// the --enable-features=NativeNotifications command line flag. +// - Mac uses the NativeNotificationDisplayService by default but +// can revert to MessageCenterDisplayService via +// chrome://flags#enable-native-notifications or Finch +// - Linux uses MessageCenterDisplayService by default but can switch +// to NativeNotificationDisplayService via +// chrome://flags#enable-native-notifications // - All other platforms always use the MessageCenterDisplayService. KeyedService* NotificationDisplayServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) #if defined(OS_ANDROID) + DCHECK(base::FeatureList::IsEnabled(features::kNativeNotifications)); return new NativeNotificationDisplayService( Profile::FromBrowserContext(context), g_browser_process->notification_platform_bridge()); -#else // defined(OS_ANDROID) +#endif if (base::FeatureList::IsEnabled(features::kNativeNotifications) && g_browser_process->notification_platform_bridge()) { return new NativeNotificationDisplayService( Profile::FromBrowserContext(context), g_browser_process->notification_platform_bridge()); } -#endif // defined(OS_ANDROID) #endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) return new MessageCenterDisplayService( Profile::FromBrowserContext(context),
diff --git a/chrome/browser/notifications/platform_notification_service_unittest.cc b/chrome/browser/notifications/platform_notification_service_unittest.cc index a7ed019..808fdd2 100644 --- a/chrome/browser/notifications/platform_notification_service_unittest.cc +++ b/chrome/browser/notifications/platform_notification_service_unittest.cc
@@ -165,11 +165,7 @@ } Notification GetDisplayedNotification() { -#if defined(OS_ANDROID) - return static_cast<StubNotificationPlatformBridge*>( - g_browser_process->notification_platform_bridge()) - ->GetNotificationAt(profile_->GetPath().BaseName().value(), 0); -#elif BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) +#if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) if (base::FeatureList::IsEnabled(features::kNativeNotifications)) { return static_cast<StubNotificationPlatformBridge*>( g_browser_process->notification_platform_bridge())
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc index c77fc39..a6355bb 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -28,12 +28,9 @@ PaymentRequestSheetController::~PaymentRequestSheetController() {} std::unique_ptr<views::View> PaymentRequestSheetController::CreateView() { - // This is owned by its parent. - content_view_ = new views::View; - - FillContentView(content_view_); - - return CreatePaymentView(); + std::unique_ptr<views::View> view = CreatePaymentView(); + UpdateContentView(); + return view; } void PaymentRequestSheetController::UpdateContentView() { @@ -117,6 +114,8 @@ 0, views::GridLayout::SizeType::FIXED, kDialogWidth, kDialogWidth); pane_->SetLayoutManager(pane_layout); pane_layout->StartRow(0, 0); + // This is owned by its parent. It's the container passed to FillContentView. + content_view_ = new views::View; pane_layout->AddView(content_view_); pane_->SizeToPreferredSize();
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 9935918..901375a 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -16,6 +16,7 @@ #include "build/build_config.h" #include "cc/paint/paint_flags.h" #include "cc/paint/paint_recorder.h" +#include "cc/paint/paint_shader.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 6e36f8bd4..dc19f25 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -224,7 +224,7 @@ // Enables the use of native notification centers instead of using the Message // Center for displaying the toasts. #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_ANDROID) const base::Feature kNativeNotifications{"NativeNotifications", base::FEATURE_ENABLED_BY_DEFAULT}; #else
diff --git a/chrome/test/chromedriver/chrome/navigation_tracker.cc b/chrome/test/chromedriver/chrome/navigation_tracker.cc index 0fdceb63..3980478 100644 --- a/chrome/test/chromedriver/chrome/navigation_tracker.cc +++ b/chrome/test/chromedriver/chrome/navigation_tracker.cc
@@ -117,15 +117,26 @@ if (loading_state_ == kUnknown) { // In the case that a http request is sent to server to fetch the page // content and the server hasn't responded at all, a dummy page is created - // for the new window. In such case, the baseURL will be empty. + // for the new window. In such case, the baseURL will be empty for <=M59 ; + // whereas the baseURL will be 'about:blank' for >=M60. See crbug/711562. + // TODO(gmanikpure):Remove condition for <3076 when we stop supporting M59. base::DictionaryValue empty_params; std::unique_ptr<base::DictionaryValue> result; Status status = client_->SendCommandAndGetResultWithTimeout( "DOM.getDocument", empty_params, timeout, &result); std::string base_url; - if (status.IsError() || !result->GetString("root.baseURL", &base_url)) + std::string doc_url; + if (status.IsError() || !result->GetString("root.baseURL", &base_url) || + !result->GetString("root.documentURL", &doc_url)) return MakeNavigationCheckFailedStatus(status); - if (base_url.empty()) { + + bool condition; + if (browser_info_->build_no >= 3076) + condition = doc_url != "about:blank" && base_url == "about:blank"; + else + condition = base_url.empty(); + + if (condition) { *is_pending = true; loading_state_ = kLoading; return Status(kOk);
diff --git a/chrome/test/chromedriver/chrome/navigation_tracker_unittest.cc b/chrome/test/chromedriver/chrome/navigation_tracker_unittest.cc index 91ff255..a66e6175 100644 --- a/chrome/test/chromedriver/chrome/navigation_tracker_unittest.cc +++ b/chrome/test/chromedriver/chrome/navigation_tracker_unittest.cc
@@ -46,10 +46,13 @@ std::unique_ptr<base::DictionaryValue>* result) override { if (method == "DOM.getDocument") { base::DictionaryValue result_dict; - if (has_empty_base_url_) - result_dict.SetString("root.baseURL", std::string()); - else + if (has_empty_base_url_) { + result_dict.SetString("root.baseURL", "about:blank"); + result_dict.SetString("root.documentURL", "http://test"); + } else { result_dict.SetString("root.baseURL", "http://test"); + result_dict.SetString("root.documentURL", "http://test"); + } result->reset(result_dict.DeepCopy()); return Status(kOk); } else if (method == "Runtime.evaluate") {
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index ce5a8453..41eb401 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -73,8 +73,6 @@ _VERSION_SPECIFIC_FILTER = {} _VERSION_SPECIFIC_FILTER['HEAD'] = [ - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1775 - 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', ] _VERSION_SPECIFIC_FILTER['58'] = [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1673
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc index 39b8714..8b930c1 100644 --- a/content/browser/renderer_host/clipboard_message_filter.cc +++ b/content/browser/renderer_host/clipboard_message_filter.cc
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" @@ -180,12 +180,14 @@ IPC::Message* reply_msg) { SkBitmap bitmap = GetClipboard()->ReadImage(type); - BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN) - ->PostTask(FROM_HERE, - base::Bind(&ClipboardMessageFilter::ReadAndEncodeImage, this, - bitmap, reply_msg)); + base::PostTaskWithTraits( + FROM_HERE, + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior(base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN), + base::BindOnce(&ClipboardMessageFilter::ReadAndEncodeImage, this, bitmap, + reply_msg)); } void ClipboardMessageFilter::ReadAndEncodeImage(const SkBitmap& bitmap,
diff --git a/device/bluetooth/bluetooth_adapter_factory.cc b/device/bluetooth/bluetooth_adapter_factory.cc index 8cf0128..21a1216 100644 --- a/device/bluetooth/bluetooth_adapter_factory.cc +++ b/device/bluetooth/bluetooth_adapter_factory.cc
@@ -19,6 +19,9 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" #endif +#if defined(ANDROID) +#include "base/android/build_info.h" +#endif namespace device { @@ -77,8 +80,9 @@ if (default_adapter.Get()) return true; -#if defined(OS_ANDROID) && __ANDROID_API__ >= 23 - return true; +#if defined(OS_ANDROID) + return base::android::BuildInfo::GetInstance()->sdk_int() >= + base::android::SDK_VERSION_MARSHMALLOW; #elif defined(OS_WIN) // Windows 8 supports Low Energy GATT operations but it does not support // scanning, initiating connections and GATT Server. To keep the API
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js index b7ce28c0..bebe55e 100644 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js +++ b/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js
@@ -25,7 +25,7 @@ ExtensionViewImpl.prototype.load = function(src) { return new Promise($Function.bind(function(resolve, reject) { - this.loadQueue.push({src: src, resolve: resolve, reject: reject}); + $Array.push(this.loadQueue, {src: src, resolve: resolve, reject: reject}); this.loadNextSrc(); }, this)) .then($Function.bind(function onLoadResolved() {
diff --git a/extensions/renderer/resources/guest_view/guest_view.js b/extensions/renderer/resources/guest_view/guest_view.js index c8ce3b9..c228dca0 100644 --- a/extensions/renderer/resources/guest_view/guest_view.js +++ b/extensions/renderer/resources/guest_view/guest_view.js
@@ -310,7 +310,7 @@ GuestView.prototype.attach = function( internalInstanceId, viewInstanceId, attachParams, callback) { var internal = privates(this).internal; - internal.actionQueue.push($Function.bind(internal.attachImpl$, + $Array.push(internal.actionQueue, $Function.bind(internal.attachImpl$, internal, internalInstanceId, viewInstanceId, attachParams, callback)); internal.performNextAction(); }; @@ -318,7 +318,7 @@ // Creates the guestview. GuestView.prototype.create = function(createParams, callback) { var internal = privates(this).internal; - internal.actionQueue.push($Function.bind(internal.createImpl$, + $Array.push(internal.actionQueue, $Function.bind(internal.createImpl$, internal, createParams, callback)); internal.performNextAction(); }; @@ -327,7 +327,7 @@ // been destroyed. GuestView.prototype.destroy = function(callback) { var internal = privates(this).internal; - internal.actionQueue.push( + $Array.push(internal.actionQueue, $Function.bind(internal.destroyImpl, internal, callback)); internal.performNextAction(); }; @@ -336,7 +336,7 @@ // Note: This is not currently used. GuestView.prototype.detach = function(callback) { var internal = privates(this).internal; - internal.actionQueue.push( + $Array.push(internal.actionQueue, $Function.bind(internal.detachImpl, internal, callback)); internal.performNextAction(); }; @@ -344,7 +344,7 @@ // Adjusts the guestview's sizing parameters. GuestView.prototype.setSize = function(sizeParams, callback) { var internal = privates(this).internal; - internal.actionQueue.push( + $Array.push(internal.actionQueue, $Function.bind(internal.setSizeImpl, internal, sizeParams, callback)); internal.performNextAction(); };
diff --git a/extensions/renderer/resources/guest_view/guest_view_events.js b/extensions/renderer/resources/guest_view/guest_view_events.js index acb3781e..4a0a7bd 100644 --- a/extensions/renderer/resources/guest_view/guest_view_events.js +++ b/extensions/renderer/resources/guest_view/guest_view_events.js
@@ -69,7 +69,7 @@ // to be removed once this GuestViewEvents object is garbage collected. GuestViewEvents.prototype.addScopedListener = function( evt, listener, listenerOpts) { - this.listenersToBeRemoved.push({ 'evt': evt, 'listener': listener }); + $Array.push(this.listenersToBeRemoved, { 'evt': evt, 'listener': listener }); evt.addListener(listener, listenerOpts); };
diff --git a/gpu/skia_bindings/grcontext_for_gles2_interface.cc b/gpu/skia_bindings/grcontext_for_gles2_interface.cc index 1f16141..ee7516b 100644 --- a/gpu/skia_bindings/grcontext_for_gles2_interface.cc +++ b/gpu/skia_bindings/grcontext_for_gles2_interface.cc
@@ -10,6 +10,7 @@ #include "base/lazy_instance.h" #include "base/macros.h" +#include "base/sys_info.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" @@ -32,10 +33,22 @@ static const int kMaxGaneshResourceCacheCount = 16384; // The limit of the bytes allocated toward GPU resources in the GrContext's // GPU cache. + static const size_t kMaxLowEndGaneshResourceCacheBytes = 48 * 1024 * 1024; static const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024; + static const size_t kMaxHighEndGaneshResourceCacheBytes = 256 * 1024 * 1024; + static const int64_t kHighEndMemoryThreshold = (int64_t)4096 * 1024 * 1024; + static const int64_t kLowEndMemoryThreshold = (int64_t)512 * 1024 * 1024; + + size_t max_ganesh_resource_cache_bytes = kMaxGaneshResourceCacheBytes; + if (base::SysInfo::AmountOfPhysicalMemory() <= kLowEndMemoryThreshold) { + max_ganesh_resource_cache_bytes = kMaxLowEndGaneshResourceCacheBytes; + } else if (base::SysInfo::AmountOfPhysicalMemory() >= + kHighEndMemoryThreshold) { + max_ganesh_resource_cache_bytes = kMaxHighEndGaneshResourceCacheBytes; + } gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount, - kMaxGaneshResourceCacheBytes); + max_ganesh_resource_cache_bytes); } }
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 3922634..454717d 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -224,6 +224,8 @@ "lib/browser/headless_devtools_manager_delegate.cc", "lib/browser/headless_devtools_manager_delegate.h", "lib/browser/headless_macros.h", + "lib/browser/headless_net_log.cc", + "lib/browser/headless_net_log.h", "lib/browser/headless_network_delegate.cc", "lib/browser/headless_network_delegate.h", "lib/browser/headless_permission_manager.cc",
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index b691760..7e6879b 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -18,6 +18,8 @@ #include "headless/grit/headless_lib_resources.h" #include "headless/lib/browser/headless_browser_context_options.h" #include "headless/lib/browser/headless_browser_impl.h" +#include "headless/lib/browser/headless_browser_main_parts.h" +#include "headless/lib/browser/headless_net_log.h" #include "headless/lib/browser/headless_permission_manager.h" #include "headless/lib/browser/headless_url_request_context_getter.h" #include "headless/public/util/black_hole_protocol_handler.h" @@ -223,7 +225,8 @@ content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::FILE), protocol_handlers, context_options_->TakeProtocolHandlers(), - std::move(request_interceptors), context_options_.get())); + std::move(request_interceptors), context_options_.get(), + browser_->browser_main_parts()->net_log())); resource_context_->set_url_request_context_getter(url_request_context_getter); return url_request_context_getter.get(); }
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc index 2ae52c3..6423a44 100644 --- a/headless/lib/browser/headless_browser_main_parts.cc +++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -4,9 +4,12 @@ #include "headless/lib/browser/headless_browser_main_parts.h" +#include "base/command_line.h" +#include "content/public/common/content_switches.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" #include "headless/lib/browser/headless_devtools.h" +#include "headless/lib/browser/headless_net_log.h" #include "headless/lib/browser/headless_screen.h" namespace headless { @@ -18,6 +21,14 @@ HeadlessBrowserMainParts::~HeadlessBrowserMainParts() {} void HeadlessBrowserMainParts::PreMainMessageLoopRun() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kLogNetLog)) { + base::FilePath log_path = + command_line->GetSwitchValuePath(switches::kLogNetLog); + net_log_.reset(new HeadlessNetLog(log_path)); + } + if (browser_->options()->devtools_endpoint.address().IsValid()) { StartLocalDevToolsHttpHandler(browser_->options()); devtools_http_handler_started_ = true;
diff --git a/headless/lib/browser/headless_browser_main_parts.h b/headless/lib/browser/headless_browser_main_parts.h index 0bf44ee..0b8d81f 100644 --- a/headless/lib/browser/headless_browser_main_parts.h +++ b/headless/lib/browser/headless_browser_main_parts.h
@@ -7,11 +7,13 @@ #include <memory> +#include "base/files/file_path.h" #include "content/public/browser/browser_main_parts.h" #include "headless/public/headless_browser.h" namespace headless { +class HeadlessNetLog; class HeadlessBrowserImpl; class HeadlessBrowserMainParts : public content::BrowserMainParts { @@ -26,10 +28,13 @@ void PreMainMessageLoopStart() override; #endif + HeadlessNetLog* net_log() const { return net_log_.get(); } + private: HeadlessBrowserImpl* browser_; // Not owned. bool devtools_http_handler_started_; + std::unique_ptr<HeadlessNetLog> net_log_; DISALLOW_COPY_AND_ASSIGN(HeadlessBrowserMainParts); };
diff --git a/headless/lib/browser/headless_net_log.cc b/headless/lib/browser/headless_net_log.cc new file mode 100644 index 0000000..a64f37ea --- /dev/null +++ b/headless/lib/browser/headless_net_log.cc
@@ -0,0 +1,75 @@ +// 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 "headless/lib/browser/headless_net_log.h" + +#include <stdio.h> +#include <utility> + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/scoped_file.h" +#include "base/values.h" +#include "build/build_config.h" +#include "content/public/common/content_switches.h" +#include "net/log/net_log_util.h" +#include "net/log/write_to_file_net_log_observer.h" + +namespace headless { +namespace { + +std::unique_ptr<base::Value> GetHeadlessConstants() { + std::unique_ptr<base::DictionaryValue> constants_dict = + net::GetNetConstants(); + + // Add a dictionary with client information + base::DictionaryValue* dict = new base::DictionaryValue(); + + dict->SetString("name", "headless"); + dict->SetString( + "command_line", + base::CommandLine::ForCurrentProcess()->GetCommandLineString()); + + constants_dict->Set("clientInfo", dict); + + return std::move(constants_dict); +} + +} // namespace + +HeadlessNetLog::HeadlessNetLog(const base::FilePath& log_path) { + // TODO(mmenke): Other than a different set of constants, this code is + // identical to code in ChromeNetLog. Consider merging the code. + + // Much like logging.h, bypass threading restrictions by using fopen + // directly. Have to write on a thread that's shutdown to handle events on + // shutdown properly, and posting events to another thread as they occur + // would result in an unbounded buffer size, so not much can be gained by + // doing this on another thread. It's only used when debugging, so + // performance is not a big concern. + base::ScopedFILE file; +#if defined(OS_WIN) + file.reset(_wfopen(log_path.value().c_str(), L"w")); +#elif defined(OS_POSIX) + file.reset(fopen(log_path.value().c_str(), "w")); +#endif + + if (!file) { + LOG(ERROR) << "Could not open file " << log_path.value() + << " for net logging"; + } else { + std::unique_ptr<base::Value> constants(GetHeadlessConstants()); + write_to_file_observer_.reset(new net::WriteToFileNetLogObserver()); + write_to_file_observer_->StartObserving(this, std::move(file), + constants.get(), nullptr); + } +} + +HeadlessNetLog::~HeadlessNetLog() { + // Remove the observer we own before we're destroyed. + if (write_to_file_observer_) + write_to_file_observer_->StopObserving(nullptr); +} + +} // namespace headless
diff --git a/headless/lib/browser/headless_net_log.h b/headless/lib/browser/headless_net_log.h new file mode 100644 index 0000000..ac33ee5 --- /dev/null +++ b/headless/lib/browser/headless_net_log.h
@@ -0,0 +1,33 @@ +// 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 HEADLESS_LIB_BROWSER_HEADLESS_NET_LOG_H_ +#define HEADLESS_LIB_BROWSER_HEADLESS_NET_LOG_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "net/log/write_to_file_net_log_observer.h" + +namespace base { +class FilePath; +} + +namespace headless { + +class HeadlessNetLog : public net::NetLog { + public: + explicit HeadlessNetLog(const base::FilePath& log_path); + ~HeadlessNetLog() override; + + private: + std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_; + + DISALLOW_COPY_AND_ASSIGN(HeadlessNetLog); +}; + +} // namespace headless + +#endif // HEADLESS_LIB_BROWSER_HEADLESS_NET_LOG_H_
diff --git a/headless/lib/browser/headless_url_request_context_getter.cc b/headless/lib/browser/headless_url_request_context_getter.cc index 1d26484d..1a0f4327 100644 --- a/headless/lib/browser/headless_url_request_context_getter.cc +++ b/headless/lib/browser/headless_url_request_context_getter.cc
@@ -26,13 +26,15 @@ content::ProtocolHandlerMap* protocol_handlers, ProtocolHandlerMap context_protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors, - HeadlessBrowserContextOptions* options) + HeadlessBrowserContextOptions* options, + net::NetLog* net_log) : io_task_runner_(std::move(io_task_runner)), file_task_runner_(std::move(file_task_runner)), user_agent_(options->user_agent()), host_resolver_rules_(options->host_resolver_rules()), proxy_server_(options->proxy_server()), - request_interceptors_(std::move(request_interceptors)) { + request_interceptors_(std::move(request_interceptors)), + net_log_(net_log) { // Must first be created on the UI thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -78,7 +80,7 @@ if (!host_resolver_rules_.empty()) { std::unique_ptr<net::HostResolver> host_resolver( - net::HostResolver::CreateDefaultResolver(nullptr /* net_log */)); + net::HostResolver::CreateDefaultResolver(net_log_)); std::unique_ptr<net::MappedHostResolver> mapped_host_resolver( new net::MappedHostResolver(std::move(host_resolver))); mapped_host_resolver->SetRulesFromString(host_resolver_rules_); @@ -93,6 +95,7 @@ builder.SetInterceptors(std::move(request_interceptors_)); url_request_context_ = builder.Build(); + url_request_context_->set_net_log(net_log_); } return url_request_context_.get();
diff --git a/headless/lib/browser/headless_url_request_context_getter.h b/headless/lib/browser/headless_url_request_context_getter.h index e1bee1ea..c5ef277 100644 --- a/headless/lib/browser/headless_url_request_context_getter.h +++ b/headless/lib/browser/headless_url_request_context_getter.h
@@ -35,7 +35,8 @@ content::ProtocolHandlerMap* protocol_handlers, ProtocolHandlerMap context_protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors, - HeadlessBrowserContextOptions* options); + HeadlessBrowserContextOptions* options, + net::NetLog* net_log); // net::URLRequestContextGetter implementation: net::URLRequestContext* GetURLRequestContext() override; @@ -62,6 +63,7 @@ std::unique_ptr<net::URLRequestContext> url_request_context_; content::ProtocolHandlerMap protocol_handlers_; content::URLRequestInterceptorScopedVector request_interceptors_; + net::NetLog* net_log_; // Not owned. DISALLOW_COPY_AND_ASSIGN(HeadlessURLRequestContextGetter); };
diff --git a/headless/lib/headless_browser_browsertest.cc b/headless/lib/headless_browser_browsertest.cc index 8b6e20c7..2c85ae0 100644 --- a/headless/lib/headless_browser_browsertest.cc +++ b/headless/lib/headless_browser_browsertest.cc
@@ -789,4 +789,44 @@ content::PermissionType::NOTIFICATIONS, url, url)); } +class HeadlessBrowserTestWithNetLog : public HeadlessBrowserTest { + public: + HeadlessBrowserTestWithNetLog() {} + + void SetUp() override { + base::ThreadRestrictions::SetIOAllowed(true); + EXPECT_TRUE(base::CreateTemporaryFile(&net_log_)); + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII("--log-net-log", + net_log_.value()); + HeadlessBrowserTest::SetUp(); + } + + void TearDown() override { + HeadlessBrowserTest::TearDown(); + base::DeleteFile(net_log_, false); + } + + protected: + base::FilePath net_log_; +}; + +IN_PROC_BROWSER_TEST_F(HeadlessBrowserTestWithNetLog, WriteNetLog) { + EXPECT_TRUE(embedded_test_server()->Start()); + + HeadlessBrowserContext* browser_context = + browser()->CreateBrowserContextBuilder().Build(); + + HeadlessWebContents* web_contents = + browser_context->CreateWebContentsBuilder() + .SetInitialURL(embedded_test_server()->GetURL("/hello.html")) + .Build(); + EXPECT_TRUE(WaitForLoad(web_contents)); + browser()->Shutdown(); + + base::ThreadRestrictions::SetIOAllowed(true); + std::string net_log_data; + EXPECT_TRUE(base::ReadFileToString(net_log_, &net_log_data)); + EXPECT_GE(net_log_data.find("hello.html"), 0u); +} + } // namespace headless
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc index 2d1b2dc..85b5460 100644 --- a/net/log/net_log_util.cc +++ b/net/log/net_log_util.cc
@@ -515,7 +515,7 @@ DCHECK(context->CalledOnValidThread()); // Contexts should all be using the same NetLog. DCHECK_EQ((*contexts.begin())->net_log(), context->net_log()); - for (auto* request : *context->url_requests()) { + for (auto* request : context->url_requests()) { requests.push_back(request); } }
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index ec9d001..bcddd10 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -186,8 +186,7 @@ // on UserData associated with |this| and poke at it during teardown. job_.reset(); - DCHECK_EQ(1u, context_->url_requests()->count(this)); - context_->url_requests()->erase(this); + context_->RemoveURLRequest(this); int net_error = OK; // Log error only on failure, not cancellation, as even successful requests @@ -585,7 +584,7 @@ // Sanity check out environment. DCHECK(base::ThreadTaskRunnerHandle::IsSet()); - context->url_requests()->insert(this); + context->InsertURLRequest(this); net_log_.BeginEvent( NetLogEventType::REQUEST_ALIVE, base::Bind(&NetLogURLRequestConstructorCallback, &url, priority_));
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 0ec1db6..c7e4477 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/debug/alias.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" @@ -48,10 +49,10 @@ sdch_manager_(nullptr), network_quality_estimator_(nullptr), reporting_service_(nullptr), - url_requests_(new std::set<const URLRequest*>), enable_brotli_(false), check_cleartext_permitted_(false), - name_(nullptr) { + name_(nullptr), + largest_outstanding_requests_count_seen_(0) { base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( this, "URLRequestContext", base::ThreadTaskRunnerHandle::Get()); } @@ -122,13 +123,27 @@ cookie_store_ = cookie_store; } +void URLRequestContext::InsertURLRequest(const URLRequest* request) const { + url_requests_.insert(request); + if (url_requests_.size() > largest_outstanding_requests_count_seen_) { + largest_outstanding_requests_count_seen_ = url_requests_.size(); + UMA_HISTOGRAM_COUNTS_1M("Net.URLRequestContext.OutstandingRequests", + largest_outstanding_requests_count_seen_); + } +} + +void URLRequestContext::RemoveURLRequest(const URLRequest* request) const { + DCHECK_EQ(1u, url_requests_.count(request)); + url_requests_.erase(request); +} + void URLRequestContext::AssertNoURLRequests() const { - int num_requests = url_requests_->size(); + int num_requests = url_requests_.size(); if (num_requests != 0) { // We're leaking URLRequests :( Dump the URL of the first one and record how // many we leaked so we have an idea of how bad it is. char url_buf[128]; - const URLRequest* request = *url_requests_->begin(); + const URLRequest* request = *url_requests_.begin(); base::strlcpy(url_buf, request->url().spec().c_str(), arraysize(url_buf)); int load_flags = request->load_flags(); base::debug::Alias(url_buf); @@ -154,7 +169,7 @@ pmd->CreateAllocatorDump(dump_name); dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount, base::trace_event::MemoryAllocatorDump::kUnitsObjects, - url_requests_->size()); + url_requests_.size()); HttpTransactionFactory* transaction_factory = http_transaction_factory(); if (transaction_factory) { HttpNetworkSession* network_session = transaction_factory->GetSession();
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index d34c2fd..206b0105 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h
@@ -221,10 +221,14 @@ // Gets the URLRequest objects that hold a reference to this // URLRequestContext. - std::set<const URLRequest*>* url_requests() const { - return url_requests_.get(); + const std::set<const URLRequest*>& url_requests() const { + return url_requests_; } + void InsertURLRequest(const URLRequest* request) const; + + void RemoveURLRequest(const URLRequest* request) const; + // CHECKs that no URLRequests using this context remain. Subclasses should // additionally call AssertNoURLRequests() within their own destructor, // prior to implicit destruction of subclass-owned state. @@ -312,7 +316,7 @@ // be added to CopyFrom. // --------------------------------------------------------------------------- - std::unique_ptr<std::set<const URLRequest*>> url_requests_; + mutable std::set<const URLRequest*> url_requests_; // Enables Brotli Content-Encoding support. bool enable_brotli_; @@ -325,6 +329,10 @@ // to be unique. const char* name_; + // The largest number of outstanding URLRequests that have been created by + // |this| and are not yet destroyed. This doesn't need to be in CopyFrom. + mutable size_t largest_outstanding_requests_count_seen_; + DISALLOW_COPY_AND_ASSIGN(URLRequestContext); };
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/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc index fcf7e6e..f0458fb 100644 --- a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc +++ b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc
@@ -22,6 +22,8 @@ return memory_instrumentation::mojom::DumpType::EXPLICITLY_TRIGGERED; case base::trace_event::MemoryDumpType::PEAK_MEMORY_USAGE: return memory_instrumentation::mojom::DumpType::PEAK_MEMORY_USAGE; + case base::trace_event::MemoryDumpType::SUMMARY_ONLY: + return memory_instrumentation::mojom::DumpType::SUMMARY_ONLY; default: CHECK(false) << "Invalid type: " << static_cast<uint8_t>(type); // This should not be reached. Just return a random value. @@ -44,6 +46,9 @@ case memory_instrumentation::mojom::DumpType::PEAK_MEMORY_USAGE: *out = base::trace_event::MemoryDumpType::PEAK_MEMORY_USAGE; break; + case memory_instrumentation::mojom::DumpType::SUMMARY_ONLY: + *out = base::trace_event::MemoryDumpType::SUMMARY_ONLY; + break; default: NOTREACHED() << "Invalid type: " << static_cast<uint8_t>(input); return false;
diff --git a/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom b/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom index 80978bc..9afb800 100644 --- a/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom +++ b/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom
@@ -9,7 +9,8 @@ enum DumpType { PERIODIC_INTERVAL, EXPLICITLY_TRIGGERED, - PEAK_MEMORY_USAGE + PEAK_MEMORY_USAGE, + SUMMARY_ONLY }; enum LevelOfDetail {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 425f730..231830b 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -896,7 +896,7 @@ "tab_capture_end2end_tests": { # TODO(dpranke), TODO(crbug.com/714336): What is the right label to # have here (and/or the right way to run this?). - "label": "//chrome/test:tab_capture_end2end_tests", + "label": "//chrome/test:browser_tests", "type": "gpu_browser_test", "gtest_filter": "CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*", },
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index bb2608f..2dcf955 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -84,7 +84,6 @@ # the tests for IndexedDB are skipped. crbug.com/506752 external/wpt/IndexedDB/ [ Skip ] crbug.com/506752 storage/indexeddb/ [ Skip ] -crbug.com/506752 virtual/sharedarraybuffer/storage/indexeddb/ [ Skip ] # ----------------------------------------------------------------- # Untriaged but known leaks of ActiveDOMObject (http).
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index ddf3f1a2..5ff05d4 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -9,9 +9,7 @@ # than 2 seconds in Release mode or 6 seconds in Debug mode should be listed here. crbug.com/24182 storage/indexeddb/objectstore-cursor.html [ Slow ] -crbug.com/24182 virtual/sharedarraybuffer/storage/indexeddb/objectstore-cursor.html [ Slow ] crbug.com/24182 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] -crbug.com/24182 virtual/sharedarraybuffer/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-mac.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-multi-line.html [ Slow ] crbug.com/24182 compositing/culling/filter-occlusion-blur-large.html [ Slow ] @@ -268,9 +266,7 @@ crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/transform-interpolation.html [ Slow ] crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/webkit-transform-interpolation.html [ Slow ] crbug.com/402379 [ Win7 Debug ] storage/indexeddb/cursor-continue-validity.html [ Slow ] -crbug.com/402379 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/cursor-continue-validity.html [ Slow ] crbug.com/402379 [ Win7 Debug ] storage/indexeddb/mozilla/indexes.html [ Slow ] -crbug.com/402379 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/mozilla/indexes.html [ Slow ] crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.html [ Slow ] crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-sorting.html [ Slow ] crbug.com/440452 virtual/display_list_2d_canvas/fast/canvas/canvas-partial-invalidation-zoomed.html [ Slow ] @@ -389,12 +385,9 @@ # IDB Observer tests require multiple browsing contexts/workers interacting with # IndexedDB, which can be slow. crbug.com/660468 [ Linux ] storage/indexeddb/observer-frame.html [ Slow ] -crbug.com/660468 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/observer-frame.html [ Slow ] crbug.com/660468 [ Linux ] storage/indexeddb/observer-workers.html [ Slow ] -crbug.com/660468 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/observer-workers.html [ Slow ] crbug.com/660492 [ Linux ] storage/indexeddb/structured-clone.html [ Slow ] -crbug.com/660492 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/structured-clone.html [ Slow ] # Foreign fetch tests make many requests, and create multiple browsing contexts, # which can be very slow.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index faa6b25..86b8571 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3327,11 +3327,8 @@ crbug.com/678346 [ Win7 Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/index-cursor.html [ Pass Timeout ] -crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/index-cursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] -crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ] -crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/structured-clone.html [ Pass Timeout ] crbug.com/678487 http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ] crbug.com/678487 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 52c8cc84..00bf19d 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -300,12 +300,6 @@ }, { "prefix": "sharedarraybuffer", - "base": "storage/indexeddb", - "args": ["--js-flags=--harmony-sharedarraybuffer", - "--enable-blink-features=SharedArrayBuffer"] - }, - { - "prefix": "sharedarraybuffer", "base": "webaudio", "args": ["--js-flags=--harmony-sharedarraybuffer", "--enable-blink-features=SharedArrayBuffer"]
diff --git a/third_party/WebKit/LayoutTests/bindings/location-lifetime.html b/third_party/WebKit/LayoutTests/bindings/location-lifetime.html new file mode 100644 index 0000000..2fa7c79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/bindings/location-lifetime.html
@@ -0,0 +1,28 @@ +<!doctype html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<iframe id="iframe-for-document.location"></iframe> +<iframe id="iframe-for-window.location"></iframe> +<script> +test(() => { + let observation; + (function() { + let iframe = document.getElementById("iframe-for-document.location"); + let location = iframe.contentDocument.location; + observation = internals.observeGC(location); + })(); + gc(); + assert_false(observation.wasCollected, "Location wrapper object was collected."); +}, "document.location shouldn't be collected by GC."); + +test(() => { + let observation; + (function() { + let iframe = document.getElementById("iframe-for-window.location"); + let location = iframe.contentWindow.location; + observation = internals.observeGC(location); + })(); + gc(); + assert_false(observation.wasCollected, "Location wrapper object was collected."); +}, "window.location shouldn't be collected by GC."); +</script>
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/http/tests/inspector/network/resource-priority-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority-expected.txt index b7db852..efeeca04 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority-expected.txt
@@ -2,31 +2,15 @@ Tests resource priorities. -sendSyncScriptRequest Request: empty-script.js?sync priority: High -sendAsyncScriptRequest Request: empty-script.js?async priority: Low -sendScriptRequestPrecededByImage -Request: abe.png?precedingScript priority: Low -Request: empty-script.js?precededByImage priority: Medium -sendScriptRequestPrecededByPreloadedImage -Request: abe.png?preloaded priority: Low -Request: empty-script.js?precededByPreloadedImage priority: High -Request: abe.png?followingPreload priority: Low -sendXHRSync +Request: abe.png?preceding priority: Low +Request: empty-script.js?preceded priority: Medium +Request: abe.png?precedingPreload priority: Low +Request: empty-script.js?precededByPreload priority: High Request: empty.html?xhr-sync priority: VeryHigh -sendXHRAsync Request: empty.html?xhr-async priority: High -sendImageRequest -Request: abe.png?image priority: Low -sendStyleRequest -Request: style.css?style priority: VeryHigh -createIFrame +Request: abe.png priority: Low +Request: style.css priority: VeryHigh Request: empty.html?iframe priority: VeryHigh -sendScriptsFromDocumentWriteAfterImage -Request: abe.png?precedingDocWrite priority: Low -Request: docwrite.js priority: Medium -Request: empty-script.js?docWritten-1 priority: High -Request: empty-script.js?docWritten-2 priority: High -Request: empty-script.js?docWritten-3 priority: High
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority.html index 025d4399..01023c0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/resource-priority.html
@@ -33,7 +33,7 @@ function sendImageRequest() { var img = document.createElement("img"); - img.src = "resources/abe.png?image"; + img.src = "resources/abe.png"; document.body.appendChild(img); } @@ -41,7 +41,7 @@ { var link = document.createElement("link"); link.rel = "stylesheet"; - link.href = "resources/style.css?style"; + link.href = "resources/style.css"; document.head.appendChild(link); } @@ -49,8 +49,8 @@ { var iframe = document.createElement("iframe"); document.body.appendChild(iframe); - iframe.srcdoc = '<html><body><img src="resources/abe.png?precedingScript">' - + '<script src="http://localhost:8000/inspector/network/resources/empty-script.js?precededByImage"></s' + iframe.srcdoc = '<html><body><img src="resources/abe.png?preceding">' + + '<script src="http://localhost:8000/inspector/network/resources/empty-script.js?preceded"></s' + 'cript>;</body></html>'; } @@ -58,18 +58,9 @@ { var iframe = document.createElement("iframe"); document.body.appendChild(iframe); - iframe.srcdoc = '<html><body><link href="resources/abe.png?preloaded" rel=preload as=image>' - + '<script src="http://localhost:8000/inspector/network/resources/empty-script.js?precededByPreloadedImage"></s' - + 'cript><img src="resources/abe.png?followingPreload"></body></html>'; -} - -function sendScriptsFromDocumentWriteAfterImage() -{ - var iframe = document.createElement("iframe"); - document.body.appendChild(iframe); - iframe.srcdoc = '<html><body><img src="resources/abe.png?precedingDocWrite">' - + '<script src="resources/docwrite.js"></s' - + 'cript></body></html>'; + iframe.srcdoc = '<html><body><link href="resources/abe.png?precedingPreload" rel=preload as=image>' + + '<script src="http://localhost:8000/inspector/network/resources/empty-script.js?precededByPreload"></s' + + 'cript><img src="resources/abe.png?precedingPreload"></body></html>'; } function createIFrame() @@ -82,41 +73,36 @@ function test() { var actions = [ - {"fn": "sendSyncScriptRequest", "requests": 1}, - {"fn": "sendAsyncScriptRequest", "requests": 1}, - {"fn": "sendScriptRequestPrecededByImage", "requests": 2}, - {"fn": "sendScriptRequestPrecededByPreloadedImage", "requests": 3}, - {"fn": "sendXHRSync", "requests": 1}, - {"fn": "sendXHRAsync", "requests": 1}, - {"fn": "sendImageRequest", "requests": 1}, - {"fn": "sendStyleRequest", "requests": 1}, - {"fn": "createIFrame", "requests": 1}, - {"fn": "sendScriptsFromDocumentWriteAfterImage", "requests": 5}, + "sendSyncScriptRequest", + "sendAsyncScriptRequest", + "sendScriptRequestPrecededByImage", + "sendScriptRequestPrecededByPreloadedImage", + "sendXHRSync", + "sendXHRAsync", + "sendImageRequest", + "sendStyleRequest", + "createIFrame" ]; InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, onRequestStarted); var nextAction = 0; - var expectedRequestCount = 0; - performNextAction(); + performNextRequest(); - function performNextAction() + function performNextRequest() { if (nextAction >= actions.length) { InspectorTest.networkManager.removeEventListener(SDK.NetworkManager.Events.RequestStarted, onRequestStarted); InspectorTest.completeTest(); return; } - InspectorTest.addResult(actions[nextAction].fn); - expectedRequestCount = actions[nextAction].requests; - InspectorTest.evaluateInPage(actions[nextAction++].fn + "()"); + InspectorTest.evaluateInPage(actions[nextAction++] + "()"); } function onRequestStarted(event) { var request = event.data; InspectorTest.addResult("Request: " + request.name() + " priority: " + request.initialPriority()); - expectedRequestCount--; - if (expectedRequestCount < 1) - performNextAction(); + if (request.name().indexOf("preceded") == -1) + performNextRequest(); } } </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/resources/docwrite.js b/third_party/WebKit/LayoutTests/http/tests/inspector/network/resources/docwrite.js deleted file mode 100644 index c6dd9f06..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/resources/docwrite.js +++ /dev/null
@@ -1,3 +0,0 @@ -document.write('<script src="http://localhost:8000/inspector/network/resources/empty-script.js?docWritten-1"></s' + 'cript>'); -document.write('<script src="http://localhost:8000/inspector/network/resources/empty-script.js?docWritten-2"></s' + 'cript>'); -document.write('<script src="http://localhost:8000/inspector/network/resources/empty-script.js?docWritten-3"></s' + 'cript>');
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/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.png index 47485d6..ab929655 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/tabgroup-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/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png index 47485d6..ab929655 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-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/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/tabgroup-expected.png index 300a55b1..aa3d62632 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/tabgroup-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..d5d8ba4 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/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/mac/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png index 300a55b1..aa3d62632 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-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/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/tabgroup-expected.png index a281c42..7733c19 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/tabgroup-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/win/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png index a281c42..7733c19 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/tabgroup-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/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html b/third_party/WebKit/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html deleted file mode 100644 index 07a60c8..0000000 --- a/third_party/WebKit/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html +++ /dev/null
@@ -1,28 +0,0 @@ -<!DOCTYPE html> -<title>IndexedDB: Attempting to serialize a SharedArrayBuffer should throw</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="resources/testharness-helpers.js"></script> -<script> - -if (window.SharedArrayBuffer) { - indexeddb_test( - (t, db) => { - db.createObjectStore('store'); - }, - (t, db) => { - const sab = new SharedArrayBuffer(256); - const tx = db.transaction('store', 'readwrite'); - const store = tx.objectStore('store'); - - assert_throws("DataCloneError", () => { - store.put({sab: sab}, 'key'); - }); - t.done(); - }, - 'Serializing SharedArrayBuffer throws DataClone error.'); -} else { - done(); -} - -</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt deleted file mode 100644 index 51001f0f..0000000 --- a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt +++ /dev/null
@@ -1,3 +0,0 @@ -# This suite runs the tests in with --js-flags=--harmony-sharedarraybuffer -# This enables the SharedArrayBuffer language feature in V8. -# See https://github.com/tc39/ecmascript_sharedmem for more information.
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h index 9ee5682..15d211c9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h
@@ -87,9 +87,6 @@ Transferables* transferables = nullptr; WebBlobInfoArray* blob_info = nullptr; bool write_wasm_to_stream = false; - // Set when serializing a value for storage; e.g. when writing to - // IndexedDB. - bool for_storage = false; }; static PassRefPtr<SerializedScriptValue> Serialize(v8::Isolate*, v8::Local<v8::Value>,
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp index 9564753..fbde869 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
@@ -75,8 +75,7 @@ Location* location = window->location(); DCHECK(location); - // Keep the wrapper object for the return value alive as long as |this| - // object is alive in order to save creation time of the wrapper object. + // If we have already created a wrapper object in this world, returns it. if (DOMDataStore::SetReturnValue(info.GetReturnValue(), location)) return; @@ -101,17 +100,6 @@ wrapper = ToV8(location, holder, isolate); } - // Keep the wrapper object for the return value alive as long as |this| - // object is alive in order to save creation time of the wrapper object. - // - // TODO(dcheng): The hidden reference behavior is broken in many ways. We - // should be caching for all DOM attributes. Even if it's not critical for - // remote Location objects, we should clean this up to improve - // maintainability. In the long-term, this will be superseded by wrapper - // tracing. - V8PrivateProperty::GetSymbol(isolate, "KeepAlive#Window#location") - .Set(holder, wrapper); - V8SetReturnValue(info, wrapper); }
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp index dee9be5..bc0cf537 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
@@ -51,8 +51,7 @@ serializer_(script_state_->GetIsolate(), this), transferables_(options.transferables), blob_info_array_(options.blob_info), - inline_wasm_(options.write_wasm_to_stream), - for_storage_(options.for_storage) {} + inline_wasm_(options.write_wasm_to_stream) {} RefPtr<SerializedScriptValue> V8ScriptValueSerializer::Serialize( v8::Local<v8::Value> value, @@ -118,37 +117,32 @@ void V8ScriptValueSerializer::FinalizeTransfer( ExceptionState& exception_state) { + if (!transferables_ && shared_array_buffers_.IsEmpty()) + return; + // TODO(jbroman): Strictly speaking, this is not correct; transfer should // occur in the order of the transfer list. // https://html.spec.whatwg.org/multipage/infrastructure.html#structuredclonewithtransfer - v8::Isolate* isolate = script_state_->GetIsolate(); - - // The order of ArrayBuffers and SharedArrayBuffers matters; we use the index - // into this array for deserialization. ArrayBufferArray array_buffers; - if (transferables_) - array_buffers.AppendVector(transferables_->array_buffers); + array_buffers.AppendVector(transferables_->array_buffers); array_buffers.AppendVector(shared_array_buffers_); - if (!array_buffers.IsEmpty()) { - serialized_script_value_->TransferArrayBuffers(isolate, array_buffers, - exception_state); - if (exception_state.HadException()) - return; - } + v8::Isolate* isolate = script_state_->GetIsolate(); + serialized_script_value_->TransferArrayBuffers(isolate, array_buffers, + exception_state); + if (exception_state.HadException()) + return; - if (transferables_) { - serialized_script_value_->TransferImageBitmaps( - isolate, transferables_->image_bitmaps, exception_state); - if (exception_state.HadException()) - return; + serialized_script_value_->TransferImageBitmaps( + isolate, transferables_->image_bitmaps, exception_state); + if (exception_state.HadException()) + return; - serialized_script_value_->TransferOffscreenCanvas( - isolate, transferables_->offscreen_canvases, exception_state); - if (exception_state.HadException()) - return; - } + serialized_script_value_->TransferOffscreenCanvas( + isolate, transferables_->offscreen_canvases, exception_state); + if (exception_state.HadException()) + return; } void V8ScriptValueSerializer::WriteUTF8String(const String& string) { @@ -405,18 +399,6 @@ v8::Maybe<uint32_t> V8ScriptValueSerializer::GetSharedArrayBufferId( v8::Isolate* isolate, v8::Local<v8::SharedArrayBuffer> v8_shared_array_buffer) { - if (for_storage_) { - DCHECK(exception_state_); - DCHECK_EQ(isolate, script_state_->GetIsolate()); - ExceptionState exception_state(isolate, exception_state_->Context(), - exception_state_->InterfaceName(), - exception_state_->PropertyName()); - exception_state.ThrowDOMException( - kDataCloneError, - "A SharedArrayBuffer can not be serialized for storage."); - return v8::Nothing<uint32_t>(); - } - DOMSharedArrayBuffer* shared_array_buffer = V8SharedArrayBuffer::toImpl(v8_shared_array_buffer);
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h index 8606080..d01afa95 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h
@@ -99,7 +99,6 @@ WebBlobInfoArray* blob_info_array_ = nullptr; ArrayBufferArray shared_array_buffers_; bool inline_wasm_ = false; - bool for_storage_ = false; #if DCHECK_IS_ON() bool serialize_invoked_ = false; #endif
diff --git a/third_party/WebKit/Source/core/css/ActiveStyleSheetsTest.cpp b/third_party/WebKit/Source/core/css/ActiveStyleSheetsTest.cpp index e4da7d3..a63d9fb 100644 --- a/third_party/WebKit/Source/core/css/ActiveStyleSheetsTest.cpp +++ b/third_party/WebKit/Source/core/css/ActiveStyleSheetsTest.cpp
@@ -421,7 +421,7 @@ EXPECT_EQ(0u, changed_rule_sets.size()); CSSStyleSheet* sheet1 = CreateSheet(); - MediaQuerySet* mq = + RefPtr<MediaQuerySet> mq = MediaQueryParser::ParseMediaQuerySet("(min-width: 9000px)"); sheet1->SetMediaQueries(mq); sheet1->MatchesMediaQueries(MediaQueryEvaluator());
diff --git a/third_party/WebKit/Source/core/css/CSSMediaRule.cpp b/third_party/WebKit/Source/core/css/CSSMediaRule.cpp index bba764b72..36d6566 100644 --- a/third_party/WebKit/Source/core/css/CSSMediaRule.cpp +++ b/third_party/WebKit/Source/core/css/CSSMediaRule.cpp
@@ -32,7 +32,7 @@ CSSMediaRule::~CSSMediaRule() {} -MediaQuerySet* CSSMediaRule::MediaQueries() const { +RefPtr<MediaQuerySet> CSSMediaRule::MediaQueries() const { return ToStyleRuleMedia(group_rule_.Get())->MediaQueries(); }
diff --git a/third_party/WebKit/Source/core/css/CSSMediaRule.h b/third_party/WebKit/Source/core/css/CSSMediaRule.h index 8930537..5913849 100644 --- a/third_party/WebKit/Source/core/css/CSSMediaRule.h +++ b/third_party/WebKit/Source/core/css/CSSMediaRule.h
@@ -53,7 +53,7 @@ CSSRule::Type type() const override { return kMediaRule; } - MediaQuerySet* MediaQueries() const; + RefPtr<MediaQuerySet> MediaQueries() const; mutable Member<MediaList> media_cssom_wrapper_; };
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp index a33670b5..887c142 100644 --- a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp +++ b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
@@ -205,8 +205,8 @@ DidMutate(); } -void CSSStyleSheet::SetMediaQueries(MediaQuerySet* media_queries) { - media_queries_ = media_queries; +void CSSStyleSheet::SetMediaQueries(RefPtr<MediaQuerySet> media_queries) { + media_queries_ = std::move(media_queries); if (media_cssom_wrapper_ && media_queries_) media_cssom_wrapper_->Reattach(media_queries_.Get()); } @@ -217,7 +217,7 @@ if (!media_queries_) return true; - return evaluator.Eval(media_queries_, + return evaluator.Eval(*media_queries_, &viewport_dependent_media_query_results_, &device_dependent_media_query_results_); } @@ -442,9 +442,6 @@ DEFINE_TRACE(CSSStyleSheet) { visitor->Trace(contents_); - visitor->Trace(media_queries_); - visitor->Trace(viewport_dependent_media_query_results_); - visitor->Trace(device_dependent_media_query_results_); visitor->Trace(owner_node_); visitor->Trace(owner_rule_); visitor->Trace(media_cssom_wrapper_);
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheet.h b/third_party/WebKit/Source/core/css/CSSStyleSheet.h index d14803fd..eb00fc5 100644 --- a/third_party/WebKit/Source/core/css/CSSStyleSheet.h +++ b/third_party/WebKit/Source/core/css/CSSStyleSheet.h
@@ -99,8 +99,8 @@ void ClearOwnerRule() { owner_rule_ = nullptr; } Document* OwnerDocument() const; - const MediaQuerySet* MediaQueries() const { return media_queries_; } - void SetMediaQueries(MediaQuerySet*); + const MediaQuerySet* MediaQueries() const { return media_queries_.Get(); } + void SetMediaQueries(RefPtr<MediaQuerySet>); bool MatchesMediaQueries(const MediaQueryEvaluator&); bool HasMediaQueryResults() const { return !viewport_dependent_media_query_results_.IsEmpty() || @@ -167,7 +167,7 @@ bool is_disabled_ = false; bool load_completed_ = false; String title_; - Member<MediaQuerySet> media_queries_; + RefPtr<MediaQuerySet> media_queries_; MediaQueryResultList viewport_dependent_media_query_results_; MediaQueryResultList device_dependent_media_query_results_;
diff --git a/third_party/WebKit/Source/core/css/MediaList.cpp b/third_party/WebKit/Source/core/css/MediaList.cpp index f6edcc5..93e67a4 100644 --- a/third_party/WebKit/Source/core/css/MediaList.cpp +++ b/third_party/WebKit/Source/core/css/MediaList.cpp
@@ -22,7 +22,6 @@ #include <memory> #include "bindings/core/v8/ExceptionState.h" #include "core/css/CSSStyleSheet.h" -#include "core/css/MediaQuery.h" #include "core/css/MediaQueryExp.h" #include "core/css/parser/MediaQueryParser.h" #include "platform/wtf/text/StringBuilder.h" @@ -58,7 +57,7 @@ queries_[i] = o.queries_[i]->Copy(); } -MediaQuerySet* MediaQuerySet::Create(const String& media_string) { +RefPtr<MediaQuerySet> MediaQuerySet::Create(const String& media_string) { if (media_string.IsEmpty()) return MediaQuerySet::Create(); @@ -66,7 +65,7 @@ } bool MediaQuerySet::Set(const String& media_string) { - MediaQuerySet* result = Create(media_string); + RefPtr<MediaQuerySet> result = Create(media_string); // TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis for (const auto& query : result->queries_) { CHECK(query); @@ -79,25 +78,25 @@ // To "parse a media query" for a given string means to follow "the parse // a media query list" steps and return "null" if more than one media query // is returned, or else the returned media query. - MediaQuerySet* result = Create(query_string); + RefPtr<MediaQuerySet> result = Create(query_string); // Only continue if exactly one media query is found, as described above. if (result->queries_.size() != 1) return true; - MediaQuery* new_query = result->queries_[0].Release(); + std::unique_ptr<MediaQuery> new_query = std::move(result->queries_[0]); // TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis CHECK(new_query); // If comparing with any of the media queries in the collection of media // queries returns true terminate these steps. for (size_t i = 0; i < queries_.size(); ++i) { - MediaQuery* query = queries_[i].Get(); - if (*query == *new_query) + MediaQuery& query = *queries_[i]; + if (query == *new_query) return true; } - queries_.push_back(new_query); + queries_.push_back(std::move(new_query)); return true; } @@ -105,13 +104,13 @@ // To "parse a media query" for a given string means to follow "the parse // a media query list" steps and return "null" if more than one media query // is returned, or else the returned media query. - MediaQuerySet* result = Create(query_string_to_remove); + RefPtr<MediaQuerySet> result = Create(query_string_to_remove); // Only continue if exactly one media query is found, as described above. if (result->queries_.size() != 1) return true; - MediaQuery* new_query = result->queries_[0].Release(); + std::unique_ptr<MediaQuery> new_query = std::move(result->queries_[0]); // TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis CHECK(new_query); @@ -119,8 +118,8 @@ // comparing with the media query returns true. bool found = false; for (size_t i = 0; i < queries_.size(); ++i) { - MediaQuery* query = queries_[i].Get(); - if (*query == *new_query) { + MediaQuery& query = *queries_[i]; + if (query == *new_query) { queries_.erase(i); --i; found = true; @@ -130,10 +129,10 @@ return found; } -void MediaQuerySet::AddMediaQuery(MediaQuery* media_query) { +void MediaQuerySet::AddMediaQuery(std::unique_ptr<MediaQuery> media_query) { // TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis CHECK(media_query); - queries_.push_back(media_query); + queries_.push_back(std::move(media_query)); } String MediaQuerySet::MediaText() const { @@ -150,16 +149,13 @@ return text.ToString(); } -DEFINE_TRACE(MediaQuerySet) { - visitor->Trace(queries_); -} - -MediaList::MediaList(MediaQuerySet* media_queries, CSSStyleSheet* parent_sheet) +MediaList::MediaList(RefPtr<MediaQuerySet> media_queries, + CSSStyleSheet* parent_sheet) : media_queries_(media_queries), parent_style_sheet_(parent_sheet), parent_rule_(nullptr) {} -MediaList::MediaList(MediaQuerySet* media_queries, CSSRule* parent_rule) +MediaList::MediaList(RefPtr<MediaQuerySet> media_queries, CSSRule* parent_rule) : media_queries_(media_queries), parent_style_sheet_(nullptr), parent_rule_(parent_rule) {} @@ -174,7 +170,8 @@ } String MediaList::item(unsigned index) const { - const HeapVector<Member<MediaQuery>>& queries = media_queries_->QueryVector(); + const Vector<std::unique_ptr<MediaQuery>>& queries = + media_queries_->QueryVector(); if (index < queries.size()) return queries[index]->CssText(); return String(); @@ -210,7 +207,7 @@ parent_style_sheet_->DidMutate(); } -void MediaList::Reattach(MediaQuerySet* media_queries) { +void MediaList::Reattach(RefPtr<MediaQuerySet> media_queries) { // TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis CHECK(media_queries); for (const auto& query : media_queries->QueryVector()) { @@ -220,7 +217,6 @@ } DEFINE_TRACE(MediaList) { - visitor->Trace(media_queries_); visitor->Trace(parent_style_sheet_); visitor->Trace(parent_rule_); }
diff --git a/third_party/WebKit/Source/core/css/MediaList.h b/third_party/WebKit/Source/core/css/MediaList.h index 4942ad1..486bfca3f 100644 --- a/third_party/WebKit/Source/core/css/MediaList.h +++ b/third_party/WebKit/Source/core/css/MediaList.h
@@ -24,6 +24,7 @@ #include "bindings/core/v8/ScriptWrappable.h" #include "core/CoreExport.h" +#include "core/css/MediaQuery.h" #include "core/dom/ExceptionCode.h" #include "platform/heap/Handle.h" #include "platform/wtf/Forward.h" @@ -38,44 +39,49 @@ class MediaList; class MediaQuery; -class CORE_EXPORT MediaQuerySet : public GarbageCollected<MediaQuerySet> { +class CORE_EXPORT MediaQuerySet : public RefCounted<MediaQuerySet> { public: - static MediaQuerySet* Create() { return new MediaQuerySet(); } - static MediaQuerySet* Create(const String& media_string); + static RefPtr<MediaQuerySet> Create() { + return AdoptRef(new MediaQuerySet()); + } + static RefPtr<MediaQuerySet> Create(const String& media_string); bool Set(const String&); bool Add(const String&); bool Remove(const String&); - void AddMediaQuery(MediaQuery*); + void AddMediaQuery(std::unique_ptr<MediaQuery>); - const HeapVector<Member<MediaQuery>>& QueryVector() const { return queries_; } + const Vector<std::unique_ptr<MediaQuery>>& QueryVector() const { + return queries_; + } String MediaText() const; - MediaQuerySet* Copy() const { return new MediaQuerySet(*this); } - - DECLARE_TRACE(); + RefPtr<MediaQuerySet> Copy() const { + return AdoptRef(new MediaQuerySet(*this)); + } private: MediaQuerySet(); MediaQuerySet(const MediaQuerySet&); - HeapVector<Member<MediaQuery>> queries_; + Vector<std::unique_ptr<MediaQuery>> queries_; }; -class MediaList final : public GarbageCollected<MediaList>, +class MediaList final : public GarbageCollectedFinalized<MediaList>, public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - static MediaList* Create(MediaQuerySet* media_queries, + static MediaList* Create(RefPtr<MediaQuerySet> media_queries, CSSStyleSheet* parent_sheet) { - return new MediaList(media_queries, parent_sheet); + return new MediaList(std::move(media_queries), parent_sheet); } - static MediaList* Create(MediaQuerySet* media_queries, CSSRule* parent_rule) { - return new MediaList(media_queries, parent_rule); + static MediaList* Create(RefPtr<MediaQuerySet> media_queries, + CSSRule* parent_rule) { + return new MediaList(std::move(media_queries), parent_rule); } unsigned length() const { return media_queries_->QueryVector().size(); } @@ -92,19 +98,16 @@ const MediaQuerySet* Queries() const { return media_queries_.Get(); } - void Reattach(MediaQuerySet*); + void Reattach(RefPtr<MediaQuerySet>); DECLARE_TRACE(); private: - MediaList(MediaQuerySet*, CSSStyleSheet* parent_sheet); - MediaList(MediaQuerySet*, CSSRule* parent_rule); + MediaList(RefPtr<MediaQuerySet>, CSSStyleSheet* parent_sheet); + MediaList(RefPtr<MediaQuerySet>, CSSRule* parent_rule); - Member<MediaQuerySet> media_queries_; - // Cleared in ~CSSStyleSheet destructor when oilpan is not enabled. + RefPtr<MediaQuerySet> media_queries_; Member<CSSStyleSheet> parent_style_sheet_; - // Cleared in the ~CSSMediaRule and ~CSSImportRule destructors when oilpan is - // not enabled. Member<CSSRule> parent_rule_; };
diff --git a/third_party/WebKit/Source/core/css/MediaQuery.cpp b/third_party/WebKit/Source/core/css/MediaQuery.cpp index 3488aba..b91c5db 100644 --- a/third_party/WebKit/Source/core/css/MediaQuery.cpp +++ b/third_party/WebKit/Source/core/css/MediaQuery.cpp
@@ -61,29 +61,29 @@ result.Append(" and "); } - result.Append(expressions_.at(0)->Serialize()); + result.Append(expressions_.at(0).Serialize()); for (size_t i = 1; i < expressions_.size(); ++i) { result.Append(" and "); - result.Append(expressions_.at(i)->Serialize()); + result.Append(expressions_.at(i).Serialize()); } return result.ToString(); } -static bool ExpressionCompare(const Member<MediaQueryExp>& a, - const Member<MediaQueryExp>& b) { - return CodePointCompare(a->Serialize(), b->Serialize()) < 0; +static bool ExpressionCompare(const MediaQueryExp& a, const MediaQueryExp& b) { + return CodePointCompare(a.Serialize(), b.Serialize()) < 0; } -MediaQuery* MediaQuery::CreateNotAll() { - return new MediaQuery(MediaQuery::kNot, MediaTypeNames::all, - ExpressionHeapVector()); +std::unique_ptr<MediaQuery> MediaQuery::CreateNotAll() { + return WTF::MakeUnique<MediaQuery>(MediaQuery::kNot, MediaTypeNames::all, + ExpressionHeapVector()); } -MediaQuery* MediaQuery::Create(RestrictorType restrictor, - String media_type, - ExpressionHeapVector expressions) { - return new MediaQuery(restrictor, std::move(media_type), - std::move(expressions)); +std::unique_ptr<MediaQuery> MediaQuery::Create( + RestrictorType restrictor, + String media_type, + ExpressionHeapVector expressions) { + return WTF::MakeUnique<MediaQuery>(restrictor, std::move(media_type), + std::move(expressions)); } MediaQuery::MediaQuery(RestrictorType restrictor, @@ -95,11 +95,11 @@ NonCopyingSort(expressions_.begin(), expressions_.end(), ExpressionCompare); // Remove all duplicated expressions. - MediaQueryExp* key = 0; + MediaQueryExp key = MediaQueryExp::Invalid(); for (int i = expressions_.size() - 1; i >= 0; --i) { - MediaQueryExp* exp = expressions_.at(i).Get(); - - if (key && *exp == *key) + MediaQueryExp exp = expressions_.at(i); + CHECK(exp.IsValid()); + if (exp == key) expressions_.erase(i); else key = exp; @@ -112,7 +112,7 @@ serialization_cache_(o.serialization_cache_) { expressions_.ReserveInitialCapacity(o.expressions_.size()); for (unsigned i = 0; i < o.expressions_.size(); ++i) - expressions_.push_back(o.expressions_[i]->Copy()); + expressions_.push_back(o.expressions_[i]); } MediaQuery::~MediaQuery() {} @@ -130,8 +130,4 @@ return serialization_cache_; } -DEFINE_TRACE(MediaQuery) { - visitor->Trace(expressions_); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/MediaQuery.h b/third_party/WebKit/Source/core/css/MediaQuery.h index 9be5c34..8223f50 100644 --- a/third_party/WebKit/Source/core/css/MediaQuery.h +++ b/third_party/WebKit/Source/core/css/MediaQuery.h
@@ -39,17 +39,19 @@ namespace blink { class MediaQueryExp; -using ExpressionHeapVector = HeapVector<Member<MediaQueryExp>>; +using ExpressionHeapVector = Vector<MediaQueryExp>; -class CORE_EXPORT MediaQuery : public GarbageCollectedFinalized<MediaQuery> { +class CORE_EXPORT MediaQuery { public: enum RestrictorType { kOnly, kNot, kNone }; - static MediaQuery* Create(RestrictorType, - String media_type, - ExpressionHeapVector); - static MediaQuery* CreateNotAll(); + static std::unique_ptr<MediaQuery> Create(RestrictorType, + String media_type, + ExpressionHeapVector); + static std::unique_ptr<MediaQuery> CreateNotAll(); + MediaQuery(RestrictorType, String media_type, ExpressionHeapVector); + MediaQuery(const MediaQuery&); ~MediaQuery(); RestrictorType Restrictor() const { return restrictor_; } @@ -58,14 +60,11 @@ bool operator==(const MediaQuery& other) const; String CssText() const; - MediaQuery* Copy() const { return new MediaQuery(*this); } - - DECLARE_TRACE(); + std::unique_ptr<MediaQuery> Copy() const { + return WTF::MakeUnique<MediaQuery>(*this); + } private: - MediaQuery(RestrictorType, String media_type, ExpressionHeapVector); - MediaQuery(const MediaQuery&); - MediaQuery& operator=(const MediaQuery&) = delete; RestrictorType restrictor_;
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp index f8c46e4..a05ca2f9 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
@@ -112,42 +112,41 @@ } bool MediaQueryEvaluator::Eval( - const MediaQuery* query, + const MediaQuery& query, MediaQueryResultList* viewport_dependent_media_query_results, MediaQueryResultList* device_dependent_media_query_results) const { - if (!MediaTypeMatch(query->MediaType())) - return ApplyRestrictor(query->Restrictor(), false); + if (!MediaTypeMatch(query.MediaType())) + return ApplyRestrictor(query.Restrictor(), false); - const ExpressionHeapVector& expressions = query->Expressions(); + const ExpressionHeapVector& expressions = query.Expressions(); // Iterate through expressions, stop if any of them eval to false (AND // semantics). size_t i = 0; for (; i < expressions.size(); ++i) { - bool expr_result = Eval(expressions.at(i).Get()); + bool expr_result = Eval(expressions.at(i)); if (viewport_dependent_media_query_results && - expressions.at(i)->IsViewportDependent()) + expressions.at(i).IsViewportDependent()) { viewport_dependent_media_query_results->push_back( - new MediaQueryResult(*expressions.at(i), expr_result)); + MediaQueryResult(expressions.at(i), expr_result)); + } if (device_dependent_media_query_results && - expressions.at(i)->IsDeviceDependent()) + expressions.at(i).IsDeviceDependent()) { device_dependent_media_query_results->push_back( - new MediaQueryResult(*expressions.at(i), expr_result)); + MediaQueryResult(expressions.at(i), expr_result)); + } if (!expr_result) break; } // Assume true if we are at the end of the list, otherwise assume false. - return ApplyRestrictor(query->Restrictor(), expressions.size() == i); + return ApplyRestrictor(query.Restrictor(), expressions.size() == i); } bool MediaQueryEvaluator::Eval( - const MediaQuerySet* query_set, + const MediaQuerySet& query_set, MediaQueryResultList* viewport_dependent_media_query_results, MediaQueryResultList* device_dependent_media_query_results) const { - if (!query_set) - return true; - - const HeapVector<Member<MediaQuery>>& queries = query_set->QueryVector(); + const Vector<std::unique_ptr<MediaQuery>>& queries = query_set.QueryVector(); if (!queries.size()) return true; // Empty query list evaluates to true. @@ -155,8 +154,8 @@ bool result = false; for (size_t i = 0; i < queries.size() && !result; ++i) { // TODO(sof): CHECK() added for crbug.com/699269 diagnosis, remove sooner. - CHECK_EQ(queries.data(), query_set->QueryVector().data()); - result = Eval(queries[i].Get(), viewport_dependent_media_query_results, + CHECK_EQ(queries.data(), query_set.QueryVector().data()); + result = Eval(*queries[i], viewport_dependent_media_query_results, device_dependent_media_query_results); } @@ -809,7 +808,7 @@ #undef ADD_TO_FUNCTIONMAP } -bool MediaQueryEvaluator::Eval(const MediaQueryExp* expr) const { +bool MediaQueryEvaluator::Eval(const MediaQueryExp& expr) const { if (!media_values_ || !media_values_->HasValues()) return true; @@ -817,9 +816,9 @@ // Call the media feature evaluation function. Assume no prefix and let // trampoline functions override the prefix if prefix is used. - EvalFunc func = g_function_map->at(expr->MediaFeature().Impl()); + EvalFunc func = g_function_map->at(expr.MediaFeature().Impl()); if (func) - return func(expr->ExpValue(), kNoPrefix, *media_values_); + return func(expr.ExpValue(), kNoPrefix, *media_values_); return false; }
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h index 7fe8fe8..4d30601 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h +++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h
@@ -41,7 +41,7 @@ class MediaValues; class MediaValuesInitialViewport; -using MediaQueryResultList = HeapVector<Member<MediaQueryResult>>; +using MediaQueryResultList = Vector<MediaQueryResult>; // Class that evaluates css media queries as defined in // CSS3 Module "Media Queries" (http://www.w3.org/TR/css3-mediaqueries/) @@ -83,17 +83,17 @@ bool MediaTypeMatch(const String& media_type_to_match) const; // Evaluates a list of media queries. - bool Eval(const MediaQuerySet*, + bool Eval(const MediaQuerySet&, MediaQueryResultList* viewport_dependent = nullptr, MediaQueryResultList* device_dependent = nullptr) const; // Evaluates media query. - bool Eval(const MediaQuery*, + bool Eval(const MediaQuery&, MediaQueryResultList* viewport_dependent = nullptr, MediaQueryResultList* device_dependent = nullptr) const; // Evaluates media query subexpression, ie "and (media-feature: value)" part. - bool Eval(const MediaQueryExp*) const; + bool Eval(const MediaQueryExp&) const; DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp index db02731..75372d2 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
@@ -139,11 +139,10 @@ void TestMQEvaluator(TestCase* test_cases, const MediaQueryEvaluator& media_query_evaluator) { - Persistent<MediaQuerySet> query_set = nullptr; + RefPtr<MediaQuerySet> query_set = nullptr; for (unsigned i = 0; test_cases[i].input; ++i) { query_set = MediaQuerySet::Create(test_cases[i].input); - EXPECT_EQ(test_cases[i].output, - media_query_evaluator.Eval(query_set.Get())); + EXPECT_EQ(test_cases[i].output, media_query_evaluator.Eval(*query_set)); } } @@ -194,8 +193,8 @@ page_holder.reset(); ASSERT_EQ(nullptr, frame->View()); MediaQueryEvaluator media_query_evaluator(frame); - MediaQuerySet* query_set = MediaQuerySet::Create("foobar"); - EXPECT_FALSE(media_query_evaluator.Eval(query_set)); + RefPtr<MediaQuerySet> query_set = MediaQuerySet::Create("foobar"); + EXPECT_FALSE(media_query_evaluator.Eval(*query_set)); } TEST(MediaQueryEvaluatorTest, CachedFloatViewport) {
diff --git a/third_party/WebKit/Source/core/css/MediaQueryExp.cpp b/third_party/WebKit/Source/core/css/MediaQueryExp.cpp index b97736c1..334a816 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryExp.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
@@ -218,7 +218,7 @@ const MediaQueryExpValue& exp_value) : media_feature_(media_feature), exp_value_(exp_value) {} -MediaQueryExp* MediaQueryExp::CreateIfValid( +MediaQueryExp MediaQueryExp::Create( const String& media_feature, const Vector<CSSParserToken, 4>& token_list) { DCHECK(!media_feature.IsNull()); @@ -236,7 +236,7 @@ if (token.GetType() == kIdentToken) { CSSValueID ident = token.Id(); if (!FeatureWithValidIdent(lower_media_feature, ident)) - return nullptr; + return Invalid(); exp_value.id = ident; exp_value.is_id = true; } else if (token.GetType() == kNumberToken || @@ -262,10 +262,10 @@ exp_value.unit = CSSPrimitiveValue::UnitType::kNumber; exp_value.is_value = true; } else { - return nullptr; + return Invalid(); } } else { - return nullptr; + return Invalid(); } } else if (token_list.size() == 3 && FeatureWithAspectRatio(lower_media_feature)) { @@ -275,23 +275,23 @@ const CSSParserToken& delimiter = token_list[1]; const CSSParserToken& denominator = token_list[2]; if (delimiter.GetType() != kDelimiterToken || delimiter.Delimiter() != '/') - return nullptr; + return Invalid(); if (numerator.GetType() != kNumberToken || numerator.NumericValue() <= 0 || numerator.GetNumericValueType() != kIntegerValueType) - return nullptr; + return Invalid(); if (denominator.GetType() != kNumberToken || denominator.NumericValue() <= 0 || denominator.GetNumericValueType() != kIntegerValueType) - return nullptr; + return Invalid(); exp_value.numerator = (unsigned)numerator.NumericValue(); exp_value.denominator = (unsigned)denominator.NumericValue(); exp_value.is_ratio = true; } else { - return nullptr; + return Invalid(); } - return new MediaQueryExp(lower_media_feature, exp_value); + return MediaQueryExp(lower_media_feature, exp_value); } MediaQueryExp::~MediaQueryExp() {}
diff --git a/third_party/WebKit/Source/core/css/MediaQueryExp.h b/third_party/WebKit/Source/core/css/MediaQueryExp.h index 20f3fe71..6f962b3 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryExp.h +++ b/third_party/WebKit/Source/core/css/MediaQueryExp.h
@@ -77,17 +77,26 @@ } }; -class CORE_EXPORT MediaQueryExp - : public GarbageCollectedFinalized<MediaQueryExp> { +class CORE_EXPORT MediaQueryExp { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + public: - static MediaQueryExp* CreateIfValid(const String& media_feature, - const Vector<CSSParserToken, 4>&); + // Returns an invalid MediaQueryExp if the arguments are invalid. + static MediaQueryExp Create(const String& media_feature, + const Vector<CSSParserToken, 4>&); + static MediaQueryExp Invalid() { + return MediaQueryExp(String(), MediaQueryExpValue()); + } + + MediaQueryExp(const MediaQueryExp& other); ~MediaQueryExp(); const String& MediaFeature() const { return media_feature_; } MediaQueryExpValue ExpValue() const { return exp_value_; } + bool IsValid() const { return !media_feature_.IsNull(); } + bool operator==(const MediaQueryExp& other) const; bool IsViewportDependent() const; @@ -96,12 +105,6 @@ String Serialize() const; - MediaQueryExp* Copy() const { return new MediaQueryExp(*this); } - - MediaQueryExp(const MediaQueryExp& other); - - DEFINE_INLINE_TRACE() {} - private: MediaQueryExp(const String&, const MediaQueryExpValue&);
diff --git a/third_party/WebKit/Source/core/css/MediaQueryList.cpp b/third_party/WebKit/Source/core/css/MediaQueryList.cpp index c8d8670cb3..5c4f66b6 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryList.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryList.cpp
@@ -29,13 +29,13 @@ MediaQueryList* MediaQueryList::Create(ExecutionContext* context, MediaQueryMatcher* matcher, - MediaQuerySet* media) { - return new MediaQueryList(context, matcher, media); + RefPtr<MediaQuerySet> media) { + return new MediaQueryList(context, matcher, RefPtr<MediaQuerySet>(media)); } MediaQueryList::MediaQueryList(ExecutionContext* context, MediaQueryMatcher* matcher, - MediaQuerySet* media) + RefPtr<MediaQuerySet> media) : ContextLifecycleObserver(context), matcher_(matcher), media_(media), @@ -116,7 +116,6 @@ DEFINE_TRACE(MediaQueryList) { visitor->Trace(matcher_); - visitor->Trace(media_); visitor->Trace(listeners_); EventTargetWithInlineData::Trace(visitor); ContextLifecycleObserver::Trace(visitor);
diff --git a/third_party/WebKit/Source/core/css/MediaQueryList.h b/third_party/WebKit/Source/core/css/MediaQueryList.h index c67b340..aa86b6d 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryList.h +++ b/third_party/WebKit/Source/core/css/MediaQueryList.h
@@ -52,7 +52,7 @@ public: static MediaQueryList* Create(ExecutionContext*, MediaQueryMatcher*, - MediaQuerySet*); + RefPtr<MediaQuerySet>); ~MediaQueryList() override; String media() const; @@ -86,12 +86,12 @@ ExecutionContext* GetExecutionContext() const override; private: - MediaQueryList(ExecutionContext*, MediaQueryMatcher*, MediaQuerySet*); + MediaQueryList(ExecutionContext*, MediaQueryMatcher*, RefPtr<MediaQuerySet>); bool UpdateMatches(); Member<MediaQueryMatcher> matcher_; - Member<MediaQuerySet> media_; + RefPtr<MediaQuerySet> media_; using ListenerList = HeapListHashSet<Member<MediaQueryListListener>>; ListenerList listeners_; bool matches_dirty_;
diff --git a/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp b/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp index b6a4eee..b28d994e 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp
@@ -66,7 +66,7 @@ evaluator_ = CreateEvaluator(); if (evaluator_) - return evaluator_->Eval(media); + return evaluator_->Eval(*media); return false; } @@ -75,7 +75,7 @@ if (!document_) return nullptr; - MediaQuerySet* media = MediaQuerySet::Create(query); + RefPtr<MediaQuerySet> media = MediaQuerySet::Create(query); return MediaQueryList::Create(document_, this, media); }
diff --git a/third_party/WebKit/Source/core/css/MediaQueryMatcherTest.cpp b/third_party/WebKit/Source/core/css/MediaQueryMatcherTest.cpp index ba01d973..6b2d275 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryMatcherTest.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryMatcherTest.cpp
@@ -17,11 +17,11 @@ DummyPageHolder::Create(IntSize(500, 500)); MediaQueryMatcher* matcher = MediaQueryMatcher::Create(page_holder->GetDocument()); - MediaQuerySet* query_set = MediaQuerySet::Create(MediaTypeNames::all); - ASSERT_TRUE(matcher->Evaluate(query_set)); + RefPtr<MediaQuerySet> query_set = MediaQuerySet::Create(MediaTypeNames::all); + ASSERT_TRUE(matcher->Evaluate(query_set.Get())); matcher->DocumentDetached(); - ASSERT_FALSE(matcher->Evaluate(query_set)); + ASSERT_FALSE(matcher->Evaluate(query_set.Get())); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp b/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp index 458f085f..a390c0a3 100644 --- a/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp +++ b/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp
@@ -182,7 +182,8 @@ }; for (unsigned i = 0; test_cases[i].input; ++i) { - MediaQuerySet* query_set = MediaQuerySet::Create(test_cases[i].input); + RefPtr<MediaQuerySet> query_set = + MediaQuerySet::Create(test_cases[i].input); TestMediaQuery(test_cases[i], *query_set); } }
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp index 56a734e..d511aa5c 100644 --- a/third_party/WebKit/Source/core/css/RuleFeature.cpp +++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -1217,8 +1217,6 @@ DEFINE_TRACE(RuleFeatureSet) { visitor->Trace(sibling_rules_); visitor->Trace(uncommon_attribute_rules_); - visitor->Trace(viewport_dependent_media_query_results_); - visitor->Trace(device_dependent_media_query_results_); } void RuleFeatureSet::InvalidationSetFeatures::Add(
diff --git a/third_party/WebKit/Source/core/css/RuleSet.cpp b/third_party/WebKit/Source/core/css/RuleSet.cpp index c69cbae..e19d5d2 100644 --- a/third_party/WebKit/Source/core/css/RuleSet.cpp +++ b/third_party/WebKit/Source/core/css/RuleSet.cpp
@@ -305,7 +305,7 @@ } else if (rule->IsMediaRule()) { StyleRuleMedia* media_rule = ToStyleRuleMedia(rule); if (!media_rule->MediaQueries() || - medium.Eval(media_rule->MediaQueries(), + medium.Eval(*media_rule->MediaQueries(), &features_.ViewportDependentMediaQueryResults(), &features_.DeviceDependentMediaQueryResults())) AddChildRules(media_rule->ChildRules(), medium, add_rule_flags); @@ -336,7 +336,7 @@ CHECK_EQ(import_rules.data(), sheet->ImportRules().data()); if (import_rule->GetStyleSheet() && (!import_rule->MediaQueries() || - medium.Eval(import_rule->MediaQueries(), + medium.Eval(*import_rule->MediaQueries(), &features_.ViewportDependentMediaQueryResults(), &features_.DeviceDependentMediaQueryResults()))) AddRulesFromSheet(import_rule->GetStyleSheet(), medium, add_rule_flags);
diff --git a/third_party/WebKit/Source/core/css/StyleMedia.cpp b/third_party/WebKit/Source/core/css/StyleMedia.cpp index 1dfa898..c08c9ac16 100644 --- a/third_party/WebKit/Source/core/css/StyleMedia.cpp +++ b/third_party/WebKit/Source/core/css/StyleMedia.cpp
@@ -53,12 +53,12 @@ if (!document_element) return false; - MediaQuerySet* media = MediaQuerySet::Create(); + RefPtr<MediaQuerySet> media = MediaQuerySet::Create(); if (!media->Set(query)) return false; MediaQueryEvaluator screen_eval(GetFrame()); - return screen_eval.Eval(media); + return screen_eval.Eval(*media); } DEFINE_TRACE(StyleMedia) {
diff --git a/third_party/WebKit/Source/core/css/StyleRule.cpp b/third_party/WebKit/Source/core/css/StyleRule.cpp index 9756aec..5c5bc6d0 100644 --- a/third_party/WebKit/Source/core/css/StyleRule.cpp +++ b/third_party/WebKit/Source/core/css/StyleRule.cpp
@@ -353,7 +353,7 @@ : StyleRuleGroup(condition_rule), condition_text_(condition_rule.condition_text_) {} -StyleRuleMedia::StyleRuleMedia(MediaQuerySet* media, +StyleRuleMedia::StyleRuleMedia(RefPtr<MediaQuerySet> media, HeapVector<Member<StyleRuleBase>>& adopt_rules) : StyleRuleCondition(kMedia, adopt_rules), media_queries_(media) {} @@ -363,11 +363,6 @@ media_queries_ = media_rule.media_queries_->Copy(); } -DEFINE_TRACE_AFTER_DISPATCH(StyleRuleMedia) { - visitor->Trace(media_queries_); - StyleRuleCondition::TraceAfterDispatch(visitor); -} - StyleRuleSupports::StyleRuleSupports( const String& condition_text, bool condition_is_supported, @@ -375,6 +370,10 @@ : StyleRuleCondition(kSupports, condition_text, adopt_rules), condition_is_supported_(condition_is_supported) {} +DEFINE_TRACE_AFTER_DISPATCH(StyleRuleMedia) { + StyleRuleCondition::TraceAfterDispatch(visitor); +} + StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& supports_rule) : StyleRuleCondition(supports_rule), condition_is_supported_(supports_rule.condition_is_supported_) {}
diff --git a/third_party/WebKit/Source/core/css/StyleRule.h b/third_party/WebKit/Source/core/css/StyleRule.h index 2965c92..aa8dcbc 100644 --- a/third_party/WebKit/Source/core/css/StyleRule.h +++ b/third_party/WebKit/Source/core/css/StyleRule.h
@@ -239,7 +239,7 @@ class CORE_EXPORT StyleRuleMedia : public StyleRuleCondition { public: static StyleRuleMedia* Create( - MediaQuerySet* media, + RefPtr<MediaQuerySet> media, HeapVector<Member<StyleRuleBase>>& adopt_rules) { return new StyleRuleMedia(media, adopt_rules); } @@ -251,11 +251,11 @@ DECLARE_TRACE_AFTER_DISPATCH(); private: - StyleRuleMedia(MediaQuerySet*, + StyleRuleMedia(RefPtr<MediaQuerySet>, HeapVector<Member<StyleRuleBase>>& adopt_rules); StyleRuleMedia(const StyleRuleMedia&); - Member<MediaQuerySet> media_queries_; + RefPtr<MediaQuerySet> media_queries_; }; class StyleRuleSupports : public StyleRuleCondition {
diff --git a/third_party/WebKit/Source/core/css/StyleRuleImport.cpp b/third_party/WebKit/Source/core/css/StyleRuleImport.cpp index 0bb1e09..a236a30 100644 --- a/third_party/WebKit/Source/core/css/StyleRuleImport.cpp +++ b/third_party/WebKit/Source/core/css/StyleRuleImport.cpp
@@ -32,11 +32,12 @@ namespace blink { StyleRuleImport* StyleRuleImport::Create(const String& href, - MediaQuerySet* media) { + RefPtr<MediaQuerySet> media) { return new StyleRuleImport(href, media); } -StyleRuleImport::StyleRuleImport(const String& href, MediaQuerySet* media) +StyleRuleImport::StyleRuleImport(const String& href, + RefPtr<MediaQuerySet> media) : StyleRuleBase(kImport), parent_style_sheet_(nullptr), style_sheet_client_(new ImportedStyleSheetClient(this)), @@ -58,7 +59,6 @@ DEFINE_TRACE_AFTER_DISPATCH(StyleRuleImport) { visitor->Trace(style_sheet_client_); visitor->Trace(parent_style_sheet_); - visitor->Trace(media_queries_); visitor->Trace(style_sheet_); visitor->Trace(resource_); StyleRuleBase::TraceAfterDispatch(visitor);
diff --git a/third_party/WebKit/Source/core/css/StyleRuleImport.h b/third_party/WebKit/Source/core/css/StyleRuleImport.h index 0e2242e..0d8134c 100644 --- a/third_party/WebKit/Source/core/css/StyleRuleImport.h +++ b/third_party/WebKit/Source/core/css/StyleRuleImport.h
@@ -36,7 +36,7 @@ USING_PRE_FINALIZER(StyleRuleImport, Dispose); public: - static StyleRuleImport* Create(const String& href, MediaQuerySet*); + static StyleRuleImport* Create(const String& href, RefPtr<MediaQuerySet>); ~StyleRuleImport(); @@ -96,7 +96,7 @@ const String& charset, const CSSStyleSheetResource*); - StyleRuleImport(const String& href, MediaQuerySet*); + StyleRuleImport(const String& href, RefPtr<MediaQuerySet>); void Dispose(); @@ -104,7 +104,7 @@ Member<ImportedStyleSheetClient> style_sheet_client_; String str_href_; - Member<MediaQuerySet> media_queries_; + RefPtr<MediaQuerySet> media_queries_; Member<StyleSheetContents> style_sheet_; Member<CSSStyleSheetResource> resource_; bool loading_;
diff --git a/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp b/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp index 5883eda..37e023c 100644 --- a/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp +++ b/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp
@@ -38,7 +38,7 @@ // FIXME: We should test comma-seperated media conditions for (unsigned i = 0; test_cases[i].input; ++i) { CSSTokenizer tokenizer(test_cases[i].input); - MediaQuerySet* media_condition_query_set = + RefPtr<MediaQuerySet> media_condition_query_set = MediaQueryParser::ParseMediaCondition(tokenizer.TokenRange()); ASSERT_EQ(media_condition_query_set->QueryVector().size(), (unsigned)1); String query_text = media_condition_query_set->QueryVector()[0]->CssText();
diff --git a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp index 96a40f2..60039b1 100644 --- a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
@@ -10,16 +10,17 @@ namespace blink { -MediaQuerySet* MediaQueryParser::ParseMediaQuerySet( +RefPtr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet( const String& query_string) { return ParseMediaQuerySet(CSSTokenizer(query_string).TokenRange()); } -MediaQuerySet* MediaQueryParser::ParseMediaQuerySet(CSSParserTokenRange range) { +RefPtr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet( + CSSParserTokenRange range) { return MediaQueryParser(kMediaQuerySetParser).ParseImpl(range); } -MediaQuerySet* MediaQueryParser::ParseMediaCondition( +RefPtr<MediaQuerySet> MediaQueryParser::ParseMediaCondition( CSSParserTokenRange range) { return MediaQueryParser(kMediaConditionParser).ParseImpl(range); } @@ -226,7 +227,7 @@ } // The state machine loop -MediaQuerySet* MediaQueryParser::ParseImpl(CSSParserTokenRange range) { +RefPtr<MediaQuerySet> MediaQueryParser::ParseImpl(CSSParserTokenRange range) { while (!range.AtEnd()) ProcessToken(range.Consume()); @@ -257,20 +258,18 @@ expressions_.clear(); } -MediaQuery* MediaQueryData::TakeMediaQuery() { - MediaQuery* media_query = MediaQuery::Create( +std::unique_ptr<MediaQuery> MediaQueryData::TakeMediaQuery() { + std::unique_ptr<MediaQuery> media_query = MediaQuery::Create( restrictor_, std::move(media_type_), std::move(expressions_)); Clear(); return media_query; } bool MediaQueryData::AddExpression() { - MediaQueryExp* expression = - MediaQueryExp::CreateIfValid(media_feature_, value_list_); - bool is_valid = !!expression; + MediaQueryExp expression = MediaQueryExp::Create(media_feature_, value_list_); expressions_.push_back(expression); value_list_.clear(); - return is_valid; + return expression.IsValid(); } bool MediaQueryData::TryAddParserToken(CSSParserTokenType type,
diff --git a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h index 35ba945..69000eb 100644 --- a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h +++ b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
@@ -36,7 +36,7 @@ bool AddExpression(); bool TryAddParserToken(CSSParserTokenType, const CSSParserToken&); void SetMediaType(const String&); - MediaQuery* TakeMediaQuery(); + std::unique_ptr<MediaQuery> TakeMediaQuery(); inline bool CurrentMediaQueryChanged() const { return (restrictor_ != MediaQuery::kNone || media_type_set_ || @@ -56,9 +56,9 @@ WTF_MAKE_NONCOPYABLE(MediaQueryParser); public: - static MediaQuerySet* ParseMediaQuerySet(const String&); - static MediaQuerySet* ParseMediaQuerySet(CSSParserTokenRange); - static MediaQuerySet* ParseMediaCondition(CSSParserTokenRange); + static RefPtr<MediaQuerySet> ParseMediaQuerySet(const String&); + static RefPtr<MediaQuerySet> ParseMediaQuerySet(CSSParserTokenRange); + static RefPtr<MediaQuerySet> ParseMediaCondition(CSSParserTokenRange); private: enum ParserType { @@ -69,7 +69,7 @@ MediaQueryParser(ParserType); virtual ~MediaQueryParser(); - MediaQuerySet* ParseImpl(CSSParserTokenRange); + RefPtr<MediaQuerySet> ParseImpl(CSSParserTokenRange); void ProcessToken(const CSSParserToken&); @@ -95,7 +95,7 @@ State state_; ParserType parser_type_; MediaQueryData media_query_data_; - Member<MediaQuerySet> query_set_; + RefPtr<MediaQuerySet> query_set_; MediaQueryBlockWatcher block_watcher_; const static State kReadRestrictor;
diff --git a/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp b/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp index 5f7d95f..adba378 100644 --- a/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp
@@ -53,7 +53,7 @@ } bool SizesAttributeParser::MediaConditionMatches( - MediaQuerySet* media_condition) { + const MediaQuerySet& media_condition) { // A Media Condition cannot have a media type other then screen. MediaQueryEvaluator media_query_evaluator(*media_values_); return media_query_evaluator.Eval(media_condition); @@ -80,9 +80,10 @@ if (!CalculateLengthInPixels( range.MakeSubRange(length_token_start, length_token_end), length)) continue; - MediaQuerySet* media_condition = MediaQueryParser::ParseMediaCondition( - range.MakeSubRange(media_condition_start, length_token_start)); - if (!media_condition || !MediaConditionMatches(media_condition)) + RefPtr<MediaQuerySet> media_condition = + MediaQueryParser::ParseMediaCondition( + range.MakeSubRange(media_condition_start, length_token_start)); + if (!media_condition || !MediaConditionMatches(*media_condition)) continue; length_ = length; length_was_set_ = true;
diff --git a/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h b/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h index 0407b10..d5fa6b17 100644 --- a/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h +++ b/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h
@@ -26,10 +26,10 @@ bool Parse(CSSParserTokenRange); float EffectiveSize(); bool CalculateLengthInPixels(CSSParserTokenRange, float& result); - bool MediaConditionMatches(MediaQuerySet* media_condition); + bool MediaConditionMatches(const MediaQuerySet& media_condition); float EffectiveSizeDefaultValue(); - Member<MediaQuerySet> media_condition_; + RefPtr<MediaQuerySet> media_condition_; Member<MediaValues> media_values_; float length_; bool length_was_set_;
diff --git a/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h b/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h index 89443ed..9f79077 100644 --- a/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h +++ b/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h
@@ -29,21 +29,19 @@ namespace blink { -class MediaQueryResult : public GarbageCollected<MediaQueryResult> { - WTF_MAKE_NONCOPYABLE(MediaQueryResult); +class MediaQueryResult { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); public: MediaQueryResult(const MediaQueryExp& expr, bool result) - : expression_(&expr), result_(result) {} + : expression_(expr), result_(result) {} - DEFINE_INLINE_TRACE() { visitor->Trace(expression_); } - - const MediaQueryExp* Expression() const { return expression_; } + const MediaQueryExp& Expression() const { return expression_; } bool Result() const { return result_; } private: - Member<const MediaQueryExp> expression_; + const MediaQueryExp expression_; bool result_; };
diff --git a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp index 45b17a2..61b2720 100644 --- a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
@@ -257,8 +257,6 @@ DEFINE_TRACE(ScopedStyleResolver) { visitor->Trace(scope_); visitor->Trace(author_style_sheets_); - visitor->Trace(viewport_dependent_media_query_results_); - visitor->Trace(device_dependent_media_query_results_); visitor->Trace(keyframes_rule_map_); visitor->Trace(tree_boundary_crossing_rule_set_); }
diff --git a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h index 675babd..6a57b4f 100644 --- a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h +++ b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h
@@ -43,7 +43,8 @@ // This class selects a ComputedStyle for a given element based on a collection // of stylesheets. -class ScopedStyleResolver final : public GarbageCollected<ScopedStyleResolver> { +class ScopedStyleResolver final + : public GarbageCollectedFinalized<ScopedStyleResolver> { WTF_MAKE_NONCOPYABLE(ScopedStyleResolver); public:
diff --git a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp index c3614055b..1d81d4c7 100644 --- a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -106,7 +106,7 @@ StyleRuleMedia* media_rule = ToStyleRuleMedia(rule); if (!media_rule->MediaQueries() || initial_viewport_medium_->Eval( - media_rule->MediaQueries(), + *media_rule->MediaQueries(), &viewport_dependent_media_query_results_, &device_dependent_media_query_results_)) CollectViewportChildRules(media_rule->ChildRules(), origin); @@ -126,7 +126,7 @@ if (!import_rule->GetStyleSheet()->HasViewportRule()) continue; if (import_rule->MediaQueries() && - initial_viewport_medium_->Eval(import_rule->MediaQueries(), + initial_viewport_medium_->Eval(*import_rule->MediaQueries(), &viewport_dependent_media_query_results_, &device_dependent_media_query_results_)) CollectViewportRulesFromAuthorSheetContents( @@ -148,7 +148,7 @@ if (!contents.HasViewportRule() && contents.ImportRules().IsEmpty()) return; if (sheet.MediaQueries() && - !initial_viewport_medium_->Eval(sheet.MediaQueries(), + !initial_viewport_medium_->Eval(*sheet.MediaQueries(), &viewport_dependent_media_query_results_, &device_dependent_media_query_results_)) return; @@ -309,8 +309,8 @@ auto& results = viewport_dependent_media_query_results_; for (unsigned i = 0; i < results.size(); i++) { - if (initial_viewport_medium_->Eval(results[i]->Expression()) != - results[i]->Result()) { + if (initial_viewport_medium_->Eval(results[i].Expression()) != + results[i].Result()) { needs_update_ = kCollectRules; break; } @@ -343,8 +343,6 @@ visitor->Trace(document_); visitor->Trace(property_set_); visitor->Trace(initial_viewport_medium_); - visitor->Trace(viewport_dependent_media_query_results_); - visitor->Trace(device_dependent_media_query_results_); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h index 136587a..aa224c6 100644 --- a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h +++ b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h
@@ -43,7 +43,7 @@ class StyleRuleViewport; class CORE_EXPORT ViewportStyleResolver - : public GarbageCollected<ViewportStyleResolver> { + : public GarbageCollectedFinalized<ViewportStyleResolver> { public: static ViewportStyleResolver* Create(Document& document) { return new ViewportStyleResolver(document);
diff --git a/third_party/WebKit/Source/core/dom/StyleElement.cpp b/third_party/WebKit/Source/core/dom/StyleElement.cpp index 71e83c7f..78a431c 100644 --- a/third_party/WebKit/Source/core/dom/StyleElement.cpp +++ b/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -152,11 +152,11 @@ // If type is empty or CSS, this is a CSS style sheet. const AtomicString& type = this->type(); if (IsCSS(element, type) && passes_content_security_policy_checks) { - MediaQuerySet* media_queries = MediaQuerySet::Create(media()); + RefPtr<MediaQuerySet> media_queries = MediaQuerySet::Create(media()); MediaQueryEvaluator screen_eval("screen"); MediaQueryEvaluator print_eval("print"); - if (screen_eval.Eval(media_queries) || print_eval.Eval(media_queries)) { + if (screen_eval.Eval(*media_queries) || print_eval.Eval(*media_queries)) { loading_ = true; TextPosition start_position = start_position_ == TextPosition::BelowRangePosition()
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp index d758f34fb..0634c6e 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp +++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -1136,7 +1136,7 @@ const auto& results = global_rule_set_.GetRuleFeatureSet().ViewportDependentMediaQueryResults(); for (unsigned i = 0; i < results.size(); ++i) { - if (evaluator.Eval(results[i]->Expression()) != results[i]->Result()) + if (evaluator.Eval(results[i].Expression()) != results[i].Result()) return true; } return false; @@ -1147,7 +1147,7 @@ const auto& results = global_rule_set_.GetRuleFeatureSet().DeviceDependentMediaQueryResults(); for (unsigned i = 0; i < results.size(); ++i) { - if (evaluator.Eval(results[i]->Expression()) != results[i]->Result()) + if (evaluator.Eval(results[i].Expression()) != results[i].Result()) return true; } return false;
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp index 64c5d4e..b3ce2ee 100644 --- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -34,6 +34,7 @@ DOMWindow::DOMWindow(Frame& frame) : frame_(frame), window_proxy_manager_(frame.GetWindowProxyManager()), + location_(this, nullptr), window_is_closing_(false) {} DOMWindow::~DOMWindow() { @@ -465,4 +466,9 @@ EventTargetWithInlineData::Trace(visitor); } +DEFINE_TRACE_WRAPPERS(DOMWindow) { + visitor->TraceWrappers(location_); + EventTargetWithInlineData::TraceWrappers(visitor); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.h b/third_party/WebKit/Source/core/frame/DOMWindow.h index 54bda63..be224d4 100644 --- a/third_party/WebKit/Source/core/frame/DOMWindow.h +++ b/third_party/WebKit/Source/core/frame/DOMWindow.h
@@ -5,6 +5,7 @@ #ifndef DOMWindow_h #define DOMWindow_h +#include "bindings/core/v8/TraceWrapperMember.h" #include "bindings/core/v8/Transferables.h" #include "core/CoreExport.h" #include "core/events/EventTarget.h" @@ -51,6 +52,8 @@ // GarbageCollectedFinalized overrides: DECLARE_VIRTUAL_TRACE(); + DECLARE_VIRTUAL_TRACE_WRAPPERS(); + virtual bool IsLocalDOMWindow() const = 0; virtual bool IsRemoteDOMWindow() const = 0; @@ -127,7 +130,7 @@ // of this object. const Member<WindowProxyManager> window_proxy_manager_; Member<InputDeviceCapabilitiesConstants> input_capabilities_; - mutable Member<Location> location_; + mutable TraceWrapperMember<Location> location_; // Set to true when close() has been called. Needed for // |window.closed| determinism; having it return 'true'
diff --git a/third_party/WebKit/Source/core/frame/Location.h b/third_party/WebKit/Source/core/frame/Location.h index d5d506f..f7c32d4 100644 --- a/third_party/WebKit/Source/core/frame/Location.h +++ b/third_party/WebKit/Source/core/frame/Location.h
@@ -39,9 +39,9 @@ namespace blink { class Document; -class LocalDOMWindow; class ExceptionState; class KURL; +class LocalDOMWindow; // This class corresponds to the Location interface. Location is the only // interface besides Window that is accessible cross-origin and must handle
diff --git a/third_party/WebKit/Source/core/frame/Location.idl b/third_party/WebKit/Source/core/frame/Location.idl index 6f62693..ba72bee 100644 --- a/third_party/WebKit/Source/core/frame/Location.idl +++ b/third_party/WebKit/Source/core/frame/Location.idl
@@ -30,6 +30,7 @@ [ CheckSecurity=Receiver, + DependentLifetime, Unforgeable, ] interface Location { // |assign| is *NOT* cross-origin accessible in the spec, but it needs
diff --git a/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp b/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp index 5e4c556..8ef2bc6 100644 --- a/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
@@ -75,7 +75,7 @@ return; } - MediaQuerySet* set = MediaQuerySet::Create(media); + RefPtr<MediaQuerySet> set = MediaQuerySet::Create(media); media_query_list_ = MediaQueryList::Create( &GetDocument(), &GetDocument().GetMediaQueryMatcher(), set); AddMediaQueryListListener();
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.cpp b/third_party/WebKit/Source/core/html/LinkStyle.cpp index 1e70376..37ae854 100644 --- a/third_party/WebKit/Source/core/html/LinkStyle.cpp +++ b/third_party/WebKit/Source/core/html/LinkStyle.cpp
@@ -305,9 +305,9 @@ bool media_query_matches = true; LocalFrame* frame = LoadingFrame(); if (!owner_->Media().IsEmpty() && frame) { - MediaQuerySet* media = MediaQuerySet::Create(owner_->Media()); + RefPtr<MediaQuerySet> media = MediaQuerySet::Create(owner_->Media()); MediaQueryEvaluator evaluator(frame); - media_query_matches = evaluator.Eval(media); + media_query_matches = evaluator.Eval(*media); } // Don't hold up layout tree construction and script execution on
diff --git a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp index 00ead606..eb8af21c 100644 --- a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
@@ -100,8 +100,7 @@ const MediaValuesCached::MediaValuesCachedData& media_values_cached_data) { preload_scanner_.reset(new TokenPreloadScanner( document_url, std::move(cached_document_parameters), - media_values_cached_data, - TokenPreloadScanner::ScannerType::kMainDocument)); + media_values_cached_data)); } BackgroundHTMLParser::Configuration::Configuration()
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp index 379bf39..6ad3557 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -722,8 +722,7 @@ // crbug.com/465478 if (preloader_) { if (!preload_scanner_) { - preload_scanner_ = CreatePreloadScanner( - TokenPreloadScanner::ScannerType::kMainDocument); + preload_scanner_ = CreatePreloadScanner(); preload_scanner_->AppendToEnd(input_.Current()); } ScanAndPreload(preload_scanner_.get()); @@ -798,10 +797,8 @@ if (IsPaused()) { // Check the document.write() output with a separate preload scanner as // the main scanner can't deal with insertions. - if (!insertion_preload_scanner_) { - insertion_preload_scanner_ = - CreatePreloadScanner(TokenPreloadScanner::ScannerType::kInsertion); - } + if (!insertion_preload_scanner_) + insertion_preload_scanner_ = CreatePreloadScanner(); insertion_preload_scanner_->AppendToEnd(source); ScanAndPreload(insertion_preload_scanner_.get()); } @@ -902,10 +899,8 @@ if (GetDocument()->Loader()->GetResponse().AppCacheID() != 0) return; - if (!preload_scanner_) { - preload_scanner_ = - CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument); - } + if (!preload_scanner_) + preload_scanner_ = CreatePreloadScanner(); preload_scanner_->AppendToEnd(source); ScanAndPreload(preload_scanner_.get()); @@ -1261,12 +1256,11 @@ FetchQueuedPreloads(); } -std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::CreatePreloadScanner( - TokenPreloadScanner::ScannerType scanner_type) { +std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::CreatePreloadScanner() { return HTMLPreloadScanner::Create( options_, GetDocument()->Url(), CachedDocumentParameters::Create(GetDocument()), - MediaValuesCached::MediaValuesCachedData(*GetDocument()), scanner_type); + MediaValuesCached::MediaValuesCachedData(*GetDocument())); } void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) { @@ -1312,8 +1306,7 @@ int current_preload_count = GetDocument()->Loader()->Fetcher()->CountPreloads(); - std::unique_ptr<HTMLPreloadScanner> scanner = - CreatePreloadScanner(TokenPreloadScanner::ScannerType::kInsertion); + std::unique_ptr<HTMLPreloadScanner> scanner = CreatePreloadScanner(); scanner->AppendToEnd(SegmentedString(written_source)); ScanAndPreload(scanner.get());
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h index 11ed0f8..28ef5ee 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -223,8 +223,7 @@ IsExecutingScript(); } - std::unique_ptr<HTMLPreloadScanner> CreatePreloadScanner( - TokenPreloadScanner::ScannerType); + std::unique_ptr<HTMLPreloadScanner> CreatePreloadScanner(); // Let the given HTMLPreloadScanner scan the input it has, and then preloads // resources using the resulting PreloadRequests and |m_preloader|.
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp index 8b065f6a..101d5c9 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -127,18 +127,16 @@ static bool MediaAttributeMatches(const MediaValuesCached& media_values, const String& attribute_value) { - MediaQuerySet* media_queries = MediaQuerySet::Create(attribute_value); + RefPtr<MediaQuerySet> media_queries = MediaQuerySet::Create(attribute_value); MediaQueryEvaluator media_query_evaluator(media_values); - return media_query_evaluator.Eval(media_queries); + return media_query_evaluator.Eval(*media_queries); } class TokenPreloadScanner::StartTagScanner { STACK_ALLOCATED(); public: - StartTagScanner(const StringImpl* tag_impl, - MediaValuesCached* media_values, - TokenPreloadScanner::ScannerType scanner_type) + StartTagScanner(const StringImpl* tag_impl, MediaValuesCached* media_values) : tag_impl_(tag_impl), link_is_style_sheet_(false), link_is_preconnect_(false), @@ -153,8 +151,7 @@ cross_origin_(kCrossOriginAttributeNotSet), media_values_(media_values), referrer_policy_set_(false), - referrer_policy_(kReferrerPolicyDefault), - scanner_type_(scanner_type) { + referrer_policy_(kReferrerPolicyDefault) { if (Match(tag_impl_, imgTag) || Match(tag_impl_, sourceTag)) { source_size_ = SizesAttributeParser(media_values_, String()).length(); return; @@ -261,8 +258,6 @@ request->SetCharset(Charset()); request->SetDefer(defer_); request->SetIntegrityMetadata(integrity_metadata_); - if (scanner_type_ == ScannerType::kInsertion) - request->SetFromInsertionScanner(true); return request; } @@ -579,14 +574,12 @@ bool referrer_policy_set_; ReferrerPolicy referrer_policy_; IntegrityMetadataSet integrity_metadata_; - TokenPreloadScanner::ScannerType scanner_type_; }; TokenPreloadScanner::TokenPreloadScanner( const KURL& document_url, std::unique_ptr<CachedDocumentParameters> document_parameters, - const MediaValuesCached::MediaValuesCachedData& media_values_cached_data, - const ScannerType scanner_type) + const MediaValuesCached::MediaValuesCachedData& media_values_cached_data) : document_url_(document_url), in_style_(false), in_picture_(false), @@ -594,7 +587,6 @@ template_count_(0), document_parameters_(std::move(document_parameters)), media_values_(MediaValuesCached::Create(media_values_cached_data)), - scanner_type_(scanner_type), did_rewind_(false) { DCHECK(document_parameters_.get()); DCHECK(media_values_.Get()); @@ -862,7 +854,7 @@ return; } - StartTagScanner scanner(tag_impl, media_values_, scanner_type_); + StartTagScanner scanner(tag_impl, media_values_); scanner.ProcessAttributes(token.Attributes()); // TODO(yoav): ViewportWidth is currently racy and might be zero in some // cases, at least in tests. That problem will go away once @@ -896,12 +888,10 @@ const HTMLParserOptions& options, const KURL& document_url, std::unique_ptr<CachedDocumentParameters> document_parameters, - const MediaValuesCached::MediaValuesCachedData& media_values_cached_data, - const TokenPreloadScanner::ScannerType scanner_type) + const MediaValuesCached::MediaValuesCachedData& media_values_cached_data) : scanner_(document_url, std::move(document_parameters), - media_values_cached_data, - scanner_type), + media_values_cached_data), tokenizer_(HTMLTokenizer::Create(options)) {} HTMLPreloadScanner::~HTMLPreloadScanner() {}
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h index 9971f77b..d5936af 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
@@ -82,12 +82,9 @@ USING_FAST_MALLOC(TokenPreloadScanner); public: - enum class ScannerType { kMainDocument, kInsertion }; - TokenPreloadScanner(const KURL& document_url, std::unique_ptr<CachedDocumentParameters>, - const MediaValuesCached::MediaValuesCachedData&, - const ScannerType); + const MediaValuesCached::MediaValuesCachedData&); ~TokenPreloadScanner(); void Scan(const HTMLToken&, @@ -165,7 +162,6 @@ std::unique_ptr<CachedDocumentParameters> document_parameters_; Persistent<MediaValuesCached> media_values_; ClientHintsPreferences client_hints_preferences_; - ScannerType scanner_type_; bool did_rewind_ = false; @@ -181,11 +177,11 @@ const HTMLParserOptions& options, const KURL& document_url, std::unique_ptr<CachedDocumentParameters> document_parameters, - const MediaValuesCached::MediaValuesCachedData& media_values_cached_data, - const TokenPreloadScanner::ScannerType scanner_type) { + const MediaValuesCached::MediaValuesCachedData& + media_values_cached_data) { return WTF::WrapUnique(new HTMLPreloadScanner( options, document_url, std::move(document_parameters), - media_values_cached_data, scanner_type)); + media_values_cached_data)); } ~HTMLPreloadScanner(); @@ -198,8 +194,7 @@ HTMLPreloadScanner(const HTMLParserOptions&, const KURL& document_url, std::unique_ptr<CachedDocumentParameters>, - const MediaValuesCached::MediaValuesCachedData&, - const TokenPreloadScanner::ScannerType); + const MediaValuesCached::MediaValuesCachedData&); TokenPreloadScanner scanner_; SegmentedString source_;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerFuzzer.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerFuzzer.cpp index 60e5765..794dcd55 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerFuzzer.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerFuzzer.cpp
@@ -64,8 +64,7 @@ MockResourcePreloader preloader; std::unique_ptr<HTMLPreloadScanner> scanner = HTMLPreloadScanner::Create( - options, document_url, std::move(document_parameters), media_data, - TokenPreloadScanner::ScannerType::kMainDocument); + options, document_url, std::move(document_parameters), media_data); TextResourceDecoderForFuzzing decoder(fuzzed_data); CString bytes = fuzzed_data.ConsumeRemainingBytes();
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp index 3e746aad..ca30bb2 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
@@ -189,8 +189,7 @@ scanner_ = HTMLPreloadScanner::Create( options, document_url, CachedDocumentParameters::Create(&dummy_page_holder_->GetDocument()), - CreateMediaValuesData(), - TokenPreloadScanner::ScannerType::kMainDocument); + CreateMediaValuesData()); } void SetUp() override { RunSetUp(kViewportEnabled); }
diff --git a/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp b/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp index 939bbc1..0d559a74 100644 --- a/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp +++ b/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp
@@ -81,13 +81,7 @@ params.SetCharset(charset_.IsEmpty() ? document->characterSet().GetString() : charset_); } - FetchParameters::SpeculativePreloadType speculative_preload_type = - FetchParameters::SpeculativePreloadType::kInDocument; - if (from_insertion_scanner_) { - speculative_preload_type = - FetchParameters::SpeculativePreloadType::kInserted; - } - params.SetSpeculativePreloadType(speculative_preload_type, discovery_time_); + params.SetSpeculativePreload(true, discovery_time_); return document->Loader()->StartPreload(resource_type_, params); }
diff --git a/third_party/WebKit/Source/core/html/parser/PreloadRequest.h b/third_party/WebKit/Source/core/html/parser/PreloadRequest.h index cecfccbf..5ce1490 100644 --- a/third_party/WebKit/Source/core/html/parser/PreloadRequest.h +++ b/third_party/WebKit/Source/core/html/parser/PreloadRequest.h
@@ -98,9 +98,6 @@ const IntegrityMetadataSet& IntegrityMetadata() const { return integrity_metadata_; } - void SetFromInsertionScanner(const bool from_insertion_scanner) { - from_insertion_scanner_ = from_insertion_scanner; - } private: PreloadRequest(const String& initiator_name, @@ -125,8 +122,7 @@ client_hints_preferences_(client_hints_preferences), request_type_(request_type), referrer_policy_(referrer_policy), - referrer_source_(referrer_source), - from_insertion_scanner_(false) {} + referrer_source_(referrer_source) {} KURL CompleteURL(Document*); @@ -146,7 +142,6 @@ ReferrerPolicy referrer_policy_; ReferrerSource referrer_source_; IntegrityMetadataSet integrity_metadata_; - bool from_insertion_scanner_; }; typedef Vector<std::unique_ptr<PreloadRequest>> PreloadRequestStream;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp index 78b1fa9..e580572 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -1612,7 +1612,8 @@ } const MediaQuerySet* queries = media->Queries(); - const HeapVector<Member<MediaQuery>>& query_vector = queries->QueryVector(); + const Vector<std::unique_ptr<MediaQuery>>& query_vector = + queries->QueryVector(); LocalFrame* frame = nullptr; if (parent_style_sheet) { if (Document* document = parent_style_sheet->OwnerDocument()) @@ -1629,15 +1630,15 @@ MediaValues* media_values = MediaValues::CreateDynamicIfFrameExists(frame); bool has_media_query_items = false; for (size_t i = 0; i < query_vector.size(); ++i) { - MediaQuery* query = query_vector.at(i).Get(); - const ExpressionHeapVector& expressions = query->Expressions(); + MediaQuery& query = *query_vector.at(i); + const ExpressionHeapVector& expressions = query.Expressions(); std::unique_ptr<protocol::Array<protocol::CSS::MediaQueryExpression>> expression_array = protocol::Array<protocol::CSS::MediaQueryExpression>::create(); bool has_expression_items = false; for (size_t j = 0; j < expressions.size(); ++j) { - MediaQueryExp* media_query_exp = expressions.at(j).Get(); - MediaQueryExpValue exp_value = media_query_exp->ExpValue(); + const MediaQueryExp& media_query_exp = expressions.at(j); + MediaQueryExpValue exp_value = media_query_exp.ExpValue(); if (!exp_value.is_value) continue; const char* value_name = @@ -1647,7 +1648,7 @@ protocol::CSS::MediaQueryExpression::create() .setValue(exp_value.value) .setUnit(String(value_name)) - .setFeature(media_query_exp->MediaFeature()) + .setFeature(media_query_exp.MediaFeature()) .build(); if (inspector_style_sheet && media->ParentRule())
diff --git a/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/third_party/WebKit/Source/core/loader/LinkLoader.cpp index d93287e..867e8fa 100644 --- a/third_party/WebKit/Source/core/loader/LinkLoader.cpp +++ b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -301,9 +301,9 @@ } // Preload only if media matches - MediaQuerySet* media_queries = MediaQuerySet::Create(media); + RefPtr<MediaQuerySet> media_queries = MediaQuerySet::Create(media); MediaQueryEvaluator evaluator(*media_values); - if (!evaluator.Eval(media_queries)) + if (!evaluator.Eval(*media_queries)) return nullptr; } if (caller == kLinkCalledFromHeader)
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index c72135b..a57d2f7c 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/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp index 6c2834d..e535711 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -381,7 +381,6 @@ options.blob_info = &blob_info; options.write_wasm_to_stream = ExecutionContext::From(script_state)->IsSecureContext(); - options.for_storage = true; RefPtr<SerializedScriptValue> serialized_value = SerializedScriptValue::Serialize(isolate, value.V8Value(), options, exception_state);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp index d588778..f0a5e2f0 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
@@ -90,7 +90,7 @@ ++g_hardware_context_count; #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: AudioContext::AudioContext(): %u #%u\n", - audioContext, audioContext->m_contextId, s_hardwareContextCount); + audio_context, audio_context->context_id_, g_hardware_context_count); #endif DEFINE_STATIC_LOCAL(SparseHistogram, max_channel_count_histogram, @@ -114,7 +114,7 @@ AudioContext::~AudioContext() { #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: AudioContext::~AudioContext(): %u\n", this, - m_contextId); + context_id_); #endif }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp index 3ecee4d..fe8ceac4 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp
@@ -58,9 +58,9 @@ SetInternalChannelInterpretation(AudioBus::kSpeakers); #if DEBUG_AUDIONODE_REFERENCES - if (!s_isNodeCountInitialized) { - s_isNodeCountInitialized = true; - atexit(AudioHandler::printNodeCounts); + if (!is_node_count_initialized_) { + is_node_count_initialized_ = true; + atexit(AudioHandler::PrintNodeCounts); } #endif InstanceCounters::IncrementCounter(InstanceCounters::kAudioHandlerCounter); @@ -72,10 +72,10 @@ DCHECK(!GetNode()); InstanceCounters::DecrementCounter(InstanceCounters::kAudioHandlerCounter); #if DEBUG_AUDIONODE_REFERENCES - --s_nodeCount[getNodeType()]; + --node_count_[GetNodeType()]; fprintf(stderr, "[%16p]: %16p: %2d: AudioHandler::~AudioHandler() %d [%d]\n", - context(), this, getNodeType(), m_connectionRefCount, - s_nodeCount[getNodeType()]); + Context(), this, GetNodeType(), connection_ref_count_, + node_count_[GetNodeType()]); #endif } @@ -169,9 +169,9 @@ node_type_ = type; #if DEBUG_AUDIONODE_REFERENCES - ++s_nodeCount[type]; + ++node_count_[type]; fprintf(stderr, "[%16p]: %16p: %2d: AudioHandler::AudioHandler [%3d]\n", - context(), this, getNodeType(), s_nodeCount[getNodeType()]); + Context(), this, GetNodeType(), node_count_[GetNodeType()]); #endif } @@ -454,8 +454,8 @@ #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: %16p: %2d: AudioHandler::ref %3d [%3d]\n", - context(), this, getNodeType(), m_connectionRefCount, - s_nodeCount[getNodeType()]); + Context(), this, GetNodeType(), connection_ref_count_, + node_count_[GetNodeType()]); #endif // See the disabling code in disableOutputsIfNecessary(). This handles // the case where a node is being re-connected after being used at least @@ -492,8 +492,8 @@ #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: %16p: %2d: AudioHandler::deref %3d [%3d]\n", - context(), this, getNodeType(), m_connectionRefCount, - s_nodeCount[getNodeType()]); + Context(), this, GetNodeType(), connection_ref_count_, + node_count_[GetNodeType()]); #endif if (!connection_ref_count_) @@ -502,17 +502,17 @@ #if DEBUG_AUDIONODE_REFERENCES -bool AudioHandler::s_isNodeCountInitialized = false; -int AudioHandler::s_nodeCount[NodeTypeEnd]; +bool AudioHandler::is_node_count_initialized_ = false; +int AudioHandler::node_count_[kNodeTypeEnd]; -void AudioHandler::printNodeCounts() { +void AudioHandler::PrintNodeCounts() { fprintf(stderr, "\n\n"); fprintf(stderr, "===========================\n"); fprintf(stderr, "AudioNode: reference counts\n"); fprintf(stderr, "===========================\n"); - for (unsigned i = 0; i < NodeTypeEnd; ++i) - fprintf(stderr, "%2d: %d\n", i, s_nodeCount[i]); + for (unsigned i = 0; i < kNodeTypeEnd; ++i) + fprintf(stderr, "%2d: %d\n", i, node_count_[i]); fprintf(stderr, "===========================\n\n\n"); } @@ -546,7 +546,7 @@ DCHECK(IsMainThread()); #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: %16p: %2d: AudioNode::dispose %16p\n", context(), - this, handler().getNodeType(), m_handler.get()); + this, Handler().GetNodeType(), handler_.Get()); #endif BaseAudioContext::AutoLocker locker(context()); Handler().Dispose(); @@ -561,7 +561,7 @@ #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: %16p: %2d: AudioNode::AudioNode %16p\n", context(), - this, m_handler->getNodeType(), m_handler.get()); + this, handler_->GetNodeType(), handler_.Get()); #endif }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.h b/third_party/WebKit/Source/modules/webaudio/AudioNode.h index 292b3388..0a81af0 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.h
@@ -186,7 +186,7 @@ virtual void CheckNumberOfChannelsForInput(AudioNodeInput*); #if DEBUG_AUDIONODE_REFERENCES - static void printNodeCounts(); + static void PrintNodeCounts(); #endif // tailTime() is the length of time (not counting latency time) where @@ -281,8 +281,8 @@ bool is_disabled_; #if DEBUG_AUDIONODE_REFERENCES - static bool s_isNodeCountInitialized; - static int s_nodeCount[NodeTypeEnd]; + static bool is_node_count_initialized_; + static int node_count_[kNodeTypeEnd]; #endif ChannelCountMode channel_count_mode_;
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp index 5d11344..998596b 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp
@@ -104,7 +104,7 @@ #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: OfflineAudioContext::OfflineAudioContext()\n", - audioContext); + audio_context); #endif DEFINE_STATIC_LOCAL(SparseHistogram, offline_context_channel_count_histogram, ("WebAudio.OfflineAudioContext.ChannelCount"));
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..3952c877 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 8691f50c..694762a 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 d88ea7c..6a76f3be 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 fc8ebc1a..9e74558a 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) { @@ -536,7 +538,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(); @@ -555,8 +557,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( @@ -594,7 +596,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 c497fbade..9904efe 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/loader/fetch/FetchParameters.cpp b/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.cpp index 95cbd432..8cbba33 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.cpp
@@ -39,7 +39,7 @@ : resource_request_(resource_request), charset_(charset), options_(ResourceFetcher::DefaultResourceOptions()), - speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), + speculative_preload_(false), preload_discovery_time_(0.0), defer_(kNoDefer), origin_restriction_(kUseDefaultOriginRestrictionForType), @@ -52,7 +52,7 @@ const ResourceLoaderOptions& options) : resource_request_(resource_request), options_(options), - speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), + speculative_preload_(false), preload_discovery_time_(0.0), defer_(kNoDefer), origin_restriction_(kUseDefaultOriginRestrictionForType), @@ -65,7 +65,7 @@ const FetchInitiatorInfo& initiator) : resource_request_(resource_request), options_(ResourceFetcher::DefaultResourceOptions()), - speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), + speculative_preload_(false), preload_discovery_time_(0.0), defer_(kNoDefer), origin_restriction_(kUseDefaultOriginRestrictionForType), @@ -129,10 +129,9 @@ } } -void FetchParameters::SetSpeculativePreloadType( - SpeculativePreloadType speculative_preload_type, - double discovery_time) { - speculative_preload_type_ = speculative_preload_type; +void FetchParameters::SetSpeculativePreload(bool speculative_preload, + double discovery_time) { + speculative_preload_ = speculative_preload; preload_discovery_time_ = discovery_time; }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.h b/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.h index f5b4842..a736299 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.h +++ b/third_party/WebKit/Source/platform/loader/fetch/FetchParameters.h
@@ -47,11 +47,6 @@ public: enum DeferOption { kNoDefer, kLazyLoad, kIdleLoad }; - enum class SpeculativePreloadType { - kNotSpeculative, - kInDocument, // The request was discovered in the main document - kInserted // The request was discovered in a document.write() - }; enum OriginRestriction { kUseDefaultOriginRestrictionForType, kRestrictToSameOrigin, @@ -108,14 +103,9 @@ return client_hint_preferences_; } - bool IsSpeculativePreload() const { - return speculative_preload_type_ != SpeculativePreloadType::kNotSpeculative; - } - SpeculativePreloadType GetSpeculativePreloadType() const { - return speculative_preload_type_; - } - void SetSpeculativePreloadType(SpeculativePreloadType, - double discovery_time = 0); + bool IsSpeculativePreload() const { return speculative_preload_; } + void SetSpeculativePreload(bool speculative_preload, + double discovery_time = 0); double PreloadDiscoveryTime() { return preload_discovery_time_; } @@ -172,7 +162,7 @@ ResourceRequest resource_request_; String charset_; ResourceLoaderOptions options_; - SpeculativePreloadType speculative_preload_type_; + bool speculative_preload_; double preload_discovery_time_; DeferOption defer_; OriginRestriction origin_restriction_;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index 0554a74b..4f4e498 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -158,7 +158,7 @@ const ResourceRequest& resource_request, ResourcePriority::VisibilityStatus visibility, FetchParameters::DeferOption defer_option, - FetchParameters::SpeculativePreloadType speculative_preload_type, + bool is_speculative_preload, bool is_link_preload) { ResourceLoadPriority priority = TypeToPriority(type); @@ -189,9 +189,7 @@ // Preload late in document: Medium if (FetchParameters::kLazyLoad == defer_option) { priority = kResourceLoadPriorityLow; - } else if (speculative_preload_type == - FetchParameters::SpeculativePreloadType::kInDocument && - image_fetched_) { + } else if (is_speculative_preload && image_fetched_) { // Speculative preload is used as a signal for scripts at the bottom of // the document. priority = kResourceLoadPriorityMedium; @@ -517,7 +515,7 @@ resource_request.SetPriority(ComputeLoadPriority( factory.GetType(), params.GetResourceRequest(), ResourcePriority::kNotVisible, params.Defer(), - params.GetSpeculativePreloadType(), params.IsLinkPreload())); + params.IsSpeculativePreload(), params.IsLinkPreload())); InitializeResourceRequest(resource_request, factory.GetType(), params.Defer()); network_instrumentation::resourcePrioritySet(identifier,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h index dafdd00..bd7e918 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h
@@ -168,8 +168,7 @@ const ResourceRequest&, ResourcePriority::VisibilityStatus, FetchParameters::DeferOption = FetchParameters::kNoDefer, - FetchParameters::SpeculativePreloadType = - FetchParameters::SpeculativePreloadType::kNotSpeculative, + bool is_speculative_preload = false, bool is_link_preload = false); enum PrepareRequestResult { kAbort, kContinue, kBlock };
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/Source/platform/scheduler/base/task_queue.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h index de227cc..43a8bc5 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -233,4 +233,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h b/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h index 0257e32..1131f8f 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ #include "base/time/time.h" #include "public/platform/WebCommon.h" @@ -42,4 +42,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/child/compositor_worker_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/compositor_worker_scheduler.h index 65f2f5c7..4e1a370 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/compositor_worker_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/child/compositor_worker_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_ #include "base/macros.h" #include "platform/scheduler/child/worker_scheduler.h" @@ -58,4 +58,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_COMPOSITOR_WORKER_SCHEDULER_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc index cee9b58..5fe0cb1 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc
@@ -52,7 +52,7 @@ new IdleCanceledDelayedTaskSweeper("test", scheduler_helper_.get(), idle_helper_->IdleTaskRunner())), - default_task_runner_(scheduler_helper_->DefaultTaskQueue()) { + default_task_queue_(scheduler_helper_->DefaultTaskQueue()) { clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); } @@ -84,7 +84,7 @@ std::unique_ptr<IdleHelper> idle_helper_; std::unique_ptr<IdleCanceledDelayedTaskSweeper> idle_canceled_delayed_taks_sweeper_; - scoped_refptr<TaskQueue> default_task_runner_; + scoped_refptr<TaskQueue> default_task_queue_; DISALLOW_COPY_AND_ASSIGN(IdleCanceledDelayedTaskSweeperTest); }; @@ -94,28 +94,28 @@ TestClass class2; // Post one task we won't cancel. - default_task_runner_->PostDelayedTask( + default_task_queue_->PostDelayedTask( FROM_HERE, base::Bind(&TestClass::NopTask, class1.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(100)); // And a bunch we will. - default_task_runner_->PostDelayedTask( + default_task_queue_->PostDelayedTask( FROM_HERE, base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(101)); - default_task_runner_->PostDelayedTask( + default_task_queue_->PostDelayedTask( FROM_HERE, base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(102)); - default_task_runner_->PostDelayedTask( + default_task_queue_->PostDelayedTask( FROM_HERE, base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(103)); - default_task_runner_->PostDelayedTask( + default_task_queue_->PostDelayedTask( FROM_HERE, base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(104)); @@ -130,7 +130,7 @@ idle_helper_->EnableLongIdlePeriod(); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(40)); - EXPECT_EQ(1u, default_task_runner_->GetNumberOfPendingTasks()); + EXPECT_EQ(1u, default_task_queue_->GetNumberOfPendingTasks()); } } // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc index 346d8c9..64f18e2 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc
@@ -37,21 +37,20 @@ tracing_category, disabled_by_default_tracing_category, disabled_by_default_verbose_tracing_category)), - control_task_runner_( + control_task_queue_( NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::CONTROL) .SetShouldNotifyObservers(false))), - default_task_runner_(NewTaskQueue(default_task_queue_spec)), + default_task_queue_(NewTaskQueue(default_task_queue_spec)), observer_(nullptr), tracing_category_(tracing_category), disabled_by_default_tracing_category_( disabled_by_default_tracing_category) { - control_task_runner_->SetQueuePriority(TaskQueue::CONTROL_PRIORITY); + control_task_queue_->SetQueuePriority(TaskQueue::CONTROL_PRIORITY); task_queue_manager_->SetWorkBatchSize(4); DCHECK(task_queue_manager_delegate_); - task_queue_manager_delegate_->SetDefaultTaskRunner( - default_task_runner_.get()); + task_queue_manager_delegate_->SetDefaultTaskRunner(default_task_queue_.get()); } SchedulerHelper::~SchedulerHelper() { @@ -83,11 +82,11 @@ scoped_refptr<TaskQueue> SchedulerHelper::DefaultTaskQueue() { CheckOnValidThread(); - return default_task_runner_; + return default_task_queue_; } scoped_refptr<TaskQueue> SchedulerHelper::ControlTaskQueue() { - return control_task_runner_; + return control_task_queue_; } size_t SchedulerHelper::GetNumberOfPendingTasks() const {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h index 0dcdc5cf..46bb9ee 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h +++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h
@@ -119,8 +119,8 @@ base::ThreadChecker thread_checker_; scoped_refptr<SchedulerTqmDelegate> task_queue_manager_delegate_; std::unique_ptr<TaskQueueManager> task_queue_manager_; - scoped_refptr<TaskQueue> control_task_runner_; - scoped_refptr<TaskQueue> default_task_runner_; + scoped_refptr<TaskQueue> control_task_queue_; + scoped_refptr<TaskQueue> default_task_queue_; Observer* observer_; // NOT OWNED const char* tracing_category_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc index 553f8efe..2adcdb1f 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc
@@ -22,7 +22,6 @@ scoped_refptr<TaskQueue> timer_task_runner) : child_scheduler_(child_scheduler), idle_task_runner_(idle_task_runner), - timer_task_runner_(timer_task_runner), loading_web_task_runner_(WebTaskRunnerImpl::Create(loading_task_runner)), timer_web_task_runner_(WebTaskRunnerImpl::Create(timer_task_runner)) {}
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h index c1745d9..29736e0 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h
@@ -56,7 +56,6 @@ ChildScheduler* child_scheduler_; // NOT OWNED scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; - scoped_refptr<TaskQueue> timer_task_runner_; RefPtr<WebTaskRunnerImpl> loading_web_task_runner_; RefPtr<WebTaskRunnerImpl> timer_web_task_runner_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc index 0f8e9c9..706b2f4 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -66,14 +66,14 @@ thread_->message_loop(), base::MakeUnique<base::DefaultTickClock>()); worker_scheduler_ = CreateWorkerScheduler(); worker_scheduler_->Init(); - task_runner_ = worker_scheduler_->DefaultTaskQueue(); + task_queue_ = worker_scheduler_->DefaultTaskQueue(); idle_task_runner_ = worker_scheduler_->IdleTaskRunner(); web_scheduler_.reset(new WebSchedulerImpl( worker_scheduler_.get(), worker_scheduler_->IdleTaskRunner(), worker_scheduler_->DefaultTaskQueue(), worker_scheduler_->DefaultTaskQueue())); base::MessageLoop::current()->AddDestructionObserver(this); - web_task_runner_ = WebTaskRunnerImpl::Create(task_runner_); + web_task_runner_ = WebTaskRunnerImpl::Create(task_queue_); completion->Signal(); } @@ -84,7 +84,7 @@ } void WebThreadImplForWorkerScheduler::WillDestroyCurrentMessageLoop() { - task_runner_ = nullptr; + task_queue_ = nullptr; idle_task_runner_ = nullptr; web_scheduler_.reset(); worker_scheduler_.reset(); @@ -106,7 +106,7 @@ base::SingleThreadTaskRunner* WebThreadImplForWorkerScheduler::GetTaskRunner() const { - return task_runner_.get(); + return task_queue_.get(); } SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::GetIdleTaskRunner()
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h index 47c4e3e..5b9e0057 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ #include "base/threading/thread.h" #include "public/platform/WebPrivatePtr.h" @@ -73,7 +73,7 @@ std::unique_ptr<scheduler::WorkerScheduler> worker_scheduler_; std::unique_ptr<scheduler::WebSchedulerImpl> web_scheduler_; scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_; - scoped_refptr<TaskQueue> task_runner_; + scoped_refptr<TaskQueue> task_queue_; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_; scoped_refptr<SchedulerTqmDelegate> task_runner_delegate_; WebPrivatePtr<WebTaskRunnerImpl> web_task_runner_; @@ -82,4 +82,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.h index 3712cab..99f0d40 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ #include "platform/scheduler/base/task_queue.h" #include "platform/scheduler/child/web_task_runner_impl.h" @@ -46,4 +46,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler.h index e470778..2e34af7 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ #include <memory> @@ -47,4 +47,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc index bd7c08f3..82c1e55 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc
@@ -36,17 +36,17 @@ main_task_runner_, "test.scheduler", "test.scheduler", "test.scheduler.debug"); manager_->AddTaskTimeObserver(&test_task_time_observer_); - task_runner_ = + task_queue_ = manager_->NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::TEST)); initial_time_ = clock_->NowTicks(); auto_advancing_time_domain_.reset( new AutoAdvancingVirtualTimeDomain(initial_time_)); manager_->RegisterTimeDomain(auto_advancing_time_domain_.get()); - task_runner_->SetTimeDomain(auto_advancing_time_domain_.get()); + task_queue_->SetTimeDomain(auto_advancing_time_domain_.get()); } void TearDown() override { - task_runner_->UnregisterTaskQueue(); + task_queue_->UnregisterTaskQueue(); manager_->UnregisterTimeDomain(auto_advancing_time_domain_.get()); } @@ -56,7 +56,7 @@ scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; scoped_refptr<SchedulerTqmDelegate> main_task_runner_; std::unique_ptr<TaskQueueManager> manager_; - scoped_refptr<TaskQueue> task_runner_; + scoped_refptr<TaskQueue> task_queue_; std::unique_ptr<AutoAdvancingVirtualTimeDomain> auto_advancing_time_domain_; TestTaskTimeObserver test_task_time_observer_; }; @@ -70,8 +70,8 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeAdvances) { base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); bool task_run = false; - task_runner_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), - delay); + task_queue_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), + delay); mock_task_runner_->RunUntilIdle(); @@ -84,8 +84,8 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeDoesNotAdvance) { base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); bool task_run = false; - task_runner_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), - delay); + task_queue_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), + delay); auto_advancing_time_domain_->SetCanAdvanceVirtualTime(false);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.cc b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.cc index b40f8e2a..d3d5a8d 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.cc
@@ -14,17 +14,17 @@ base::TickClock* time_source, int sample_count, double estimation_percentile) - : compositor_task_runner_(compositor_task_runner), + : compositor_task_queue_(compositor_task_runner), per_frame_compositor_task_runtime_(sample_count), time_source_(time_source), estimation_percentile_(estimation_percentile), nesting_level_(0), did_commit_(false) { - compositor_task_runner_->AddTaskObserver(this); + compositor_task_queue_->AddTaskObserver(this); } IdleTimeEstimator::~IdleTimeEstimator() { - compositor_task_runner_->RemoveTaskObserver(this); + compositor_task_queue_->RemoveTaskObserver(this); } base::TimeDelta IdleTimeEstimator::GetExpectedIdleDuration(
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.h b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.h index 6074155..5987d914 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator.h
@@ -40,7 +40,7 @@ void DidProcessTask(const base::PendingTask& pending_task) override; private: - scoped_refptr<TaskQueue> compositor_task_runner_; + scoped_refptr<TaskQueue> compositor_task_queue_; cc::RollingTimeDeltaHistory per_frame_compositor_task_runtime_; base::TickClock* time_source_; // NOT OWNED double estimation_percentile_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc index 00b2e06..d116859 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc
@@ -48,10 +48,10 @@ manager_ = base::MakeUnique<TaskQueueManager>( main_task_runner_, "test.scheduler", "test.scheduler", "test.scheduler.debug"); - compositor_task_runner_ = manager_->NewTaskQueue( + compositor_task_queue_ = manager_->NewTaskQueue( TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR)); estimator_.reset(new IdleTimeEstimatorForTest( - compositor_task_runner_, test_time_source_.get(), 10, 50)); + compositor_task_queue_, test_time_source_.get(), 10, 50)); } void SimulateFrameWithOneCompositorTask(int compositor_time) { @@ -91,7 +91,7 @@ scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; scoped_refptr<SchedulerTqmDelegate> main_task_runner_; std::unique_ptr<TaskQueueManager> manager_; - scoped_refptr<TaskQueue> compositor_task_runner_; + scoped_refptr<TaskQueue> compositor_task_queue_; std::unique_ptr<IdleTimeEstimatorForTest> estimator_; const base::TimeDelta frame_length_; TestTaskTimeObserver test_task_time_observer_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc index 4ae63b51..112af82 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -101,12 +101,12 @@ &helper_, idle_helper_.IdleTaskRunner()), render_widget_scheduler_signals_(this), - control_task_runner_(helper_.ControlTaskQueue()), - compositor_task_runner_( + control_task_queue_(helper_.ControlTaskQueue()), + compositor_task_queue_( helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) .SetShouldMonitorQuiescence(true))), - compositor_task_runner_enabled_voter_( - compositor_task_runner_->CreateQueueEnabledVoter()), + compositor_task_queue_enabled_voter_( + compositor_task_queue_->CreateQueueEnabledVoter()), delayed_update_policy_runner_( base::Bind(&RendererSchedulerImpl::UpdatePolicy, base::Unretained(this)), @@ -114,7 +114,7 @@ seqlock_queueing_time_estimator_( QueueingTimeEstimator(this, base::TimeDelta::FromSeconds(1))), main_thread_only_(this, - compositor_task_runner_, + compositor_task_queue_, helper_.scheduler_tqm_delegate().get(), helper_.scheduler_tqm_delegate()->NowTicks()), policy_may_need_update_(&any_thread_lock_), @@ -130,9 +130,9 @@ base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, weak_factory_.GetWeakPtr())); - default_loading_task_runner_ = + default_loading_task_queue_ = NewLoadingTaskQueue(TaskQueue::QueueType::DEFAULT_LOADING); - default_timer_task_runner_ = + default_timer_task_queue_ = NewTimerTaskQueue(TaskQueue::QueueType::DEFAULT_TIMER); TRACE_EVENT_OBJECT_CREATED_WITH_ID( @@ -272,7 +272,7 @@ scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::CompositorTaskRunner() { helper_.CheckOnValidThread(); - return compositor_task_runner_; + return compositor_task_queue_; } scoped_refptr<SingleThreadIdleTaskRunner> @@ -283,13 +283,13 @@ scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::LoadingTaskRunner() { helper_.CheckOnValidThread(); - return default_loading_task_runner_; + return default_loading_task_queue_; } scoped_refptr<base::SingleThreadTaskRunner> RendererSchedulerImpl::TimerTaskRunner() { helper_.CheckOnValidThread(); - return default_timer_task_runner_; + return default_timer_task_queue_; } scoped_refptr<TaskQueue> RendererSchedulerImpl::DefaultTaskQueue() { @@ -298,17 +298,17 @@ scoped_refptr<TaskQueue> RendererSchedulerImpl::CompositorTaskQueue() { helper_.CheckOnValidThread(); - return compositor_task_runner_; + return compositor_task_queue_; } scoped_refptr<TaskQueue> RendererSchedulerImpl::LoadingTaskQueue() { helper_.CheckOnValidThread(); - return default_loading_task_runner_; + return default_loading_task_queue_; } scoped_refptr<TaskQueue> RendererSchedulerImpl::TimerTaskQueue() { helper_.CheckOnValidThread(); - return default_timer_task_runner_; + return default_timer_task_queue_; } scoped_refptr<TaskQueue> RendererSchedulerImpl::ControlTaskQueue() { @@ -491,7 +491,7 @@ // hidden. base::TimeDelta end_idle_when_hidden_delay = base::TimeDelta::FromMilliseconds(kEndIdleWhenHiddenDelayMillis); - control_task_runner_->PostDelayedTask( + control_task_queue_->PostDelayedTask( FROM_HERE, end_renderer_hidden_idle_period_closure_.GetCallback(), end_idle_when_hidden_delay); GetMainThreadOnly().renderer_hidden = true; @@ -540,7 +540,7 @@ base::TimeDelta suspend_timers_when_backgrounded_delay = base::TimeDelta::FromMilliseconds( kSuspendTimersWhenBackgroundedDelayMillis); - control_task_runner_->PostDelayedTask( + control_task_queue_->PostDelayedTask( FROM_HERE, suspend_timers_when_backgrounded_closure_.GetCallback(), suspend_timers_when_backgrounded_delay); } @@ -848,7 +848,7 @@ case UseCase::MAIN_THREAD_GESTURE: case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING: case UseCase::SYNCHRONIZED_GESTURE: - return compositor_task_runner_->HasPendingImmediateWork() || + return compositor_task_queue_->HasPendingImmediateWork() || GetMainThreadOnly().touchstart_expected_soon; case UseCase::TOUCHSTART: @@ -891,7 +891,7 @@ any_thread_lock_.AssertAcquired(); if (!policy_may_need_update_.IsSet()) { policy_may_need_update_.SetWhileLocked(true); - control_task_runner_->PostTask(from_here, update_policy_closure_); + control_task_queue_->PostTask(from_here, update_policy_closure_); } } @@ -1165,8 +1165,7 @@ } ApplyTaskQueuePolicy( - compositor_task_runner_.get(), - compositor_task_runner_enabled_voter_.get(), + compositor_task_queue_.get(), compositor_task_queue_enabled_voter_.get(), GetMainThreadOnly().current_policy.compositor_queue_policy, new_policy.compositor_queue_policy); @@ -1206,7 +1205,7 @@ } } - DCHECK(compositor_task_runner_->IsQueueEnabled()); + DCHECK(compositor_task_queue_->IsQueueEnabled()); GetMainThreadOnly().current_policy = new_policy; } @@ -1361,7 +1360,7 @@ GetMainThreadOnly().timer_queue_suspend_count++; ForceUpdatePolicy(); #ifndef NDEBUG - DCHECK(!default_timer_task_runner_->IsQueueEnabled()); + DCHECK(!default_timer_task_queue_->IsQueueEnabled()); for (const auto& runner : timer_task_runners_) { DCHECK(!runner.first->IsQueueEnabled()); } @@ -1655,11 +1654,11 @@ // // Per-frame task runners (loading, timers, etc.) are configured with a more // specific blame context by WebFrameSchedulerImpl. - control_task_runner_->SetBlameContext(blame_context); + control_task_queue_->SetBlameContext(blame_context); DefaultTaskQueue()->SetBlameContext(blame_context); - default_loading_task_runner_->SetBlameContext(blame_context); - default_timer_task_runner_->SetBlameContext(blame_context); - compositor_task_runner_->SetBlameContext(blame_context); + default_loading_task_queue_->SetBlameContext(blame_context); + default_timer_task_queue_->SetBlameContext(blame_context); + compositor_task_queue_->SetBlameContext(blame_context); idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h index b36150b..1af8c53 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
@@ -400,10 +400,10 @@ std::unique_ptr<TaskQueueThrottler> task_queue_throttler_; RenderWidgetSignals render_widget_scheduler_signals_; - const scoped_refptr<TaskQueue> control_task_runner_; - const scoped_refptr<TaskQueue> compositor_task_runner_; + const scoped_refptr<TaskQueue> control_task_queue_; + const scoped_refptr<TaskQueue> compositor_task_queue_; std::unique_ptr<TaskQueue::QueueEnabledVoter> - compositor_task_runner_enabled_voter_; + compositor_task_queue_enabled_voter_; using TaskQueueVoterMap = std::map<scoped_refptr<TaskQueue>, @@ -412,8 +412,8 @@ TaskQueueVoterMap loading_task_runners_; TaskQueueVoterMap timer_task_runners_; std::set<scoped_refptr<TaskQueue>> unthrottled_task_runners_; - scoped_refptr<TaskQueue> default_loading_task_runner_; - scoped_refptr<TaskQueue> default_timer_task_runner_; + scoped_refptr<TaskQueue> default_loading_task_queue_; + scoped_refptr<TaskQueue> default_timer_task_queue_; // Note |virtual_time_domain_| is lazily created. std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc index 1dfe3798..d37e3f92 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
@@ -75,7 +75,7 @@ TaskQueueThrottler::TaskQueueThrottler( RendererSchedulerImpl* renderer_scheduler, const char* tracing_category) - : task_runner_(renderer_scheduler->ControlTaskQueue()), + : control_task_queue_(renderer_scheduler->ControlTaskQueue()), renderer_scheduler_(renderer_scheduler), tick_clock_(renderer_scheduler->tick_clock()), tracing_category_(tracing_category), @@ -108,7 +108,7 @@ } void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) { - DCHECK_NE(task_queue, task_runner_.get()); + DCHECK_NE(task_queue, control_task_queue_.get()); std::pair<TaskQueueMap::iterator, bool> insert_result = queue_details_.insert(std::make_pair(task_queue, Metadata())); @@ -194,8 +194,8 @@ void TaskQueueThrottler::OnQueueNextWakeUpChanged( TaskQueue* queue, base::TimeTicks next_wake_up) { - if (!task_runner_->RunsTasksOnCurrentThread()) { - task_runner_->PostTask( + if (!control_task_queue_->RunsTasksOnCurrentThread()) { + control_task_queue_->PostTask( FROM_HERE, base::Bind(forward_immediate_work_callback_, queue, next_wake_up)); return; @@ -303,7 +303,7 @@ TRACE_EVENT1(tracing_category_, "TaskQueueThrottler::MaybeSchedulePumpThrottledTasks", "delay_till_next_pump_ms", delay.InMilliseconds()); - task_runner_->PostDelayedTask( + control_task_queue_->PostDelayedTask( from_here, pump_throttled_tasks_closure_.GetCallback(), delay); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h index 8e8567b..a6d1f842 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h
@@ -128,7 +128,9 @@ static base::TimeTicks AlignedThrottledRunTime( base::TimeTicks unthrottled_runtime); - const scoped_refptr<TaskQueue>& task_runner() const { return task_runner_; } + const scoped_refptr<TaskQueue>& task_queue() const { + return control_task_queue_; + } // Returned object is owned by |TaskQueueThrottler|. CPUTimeBudgetPool* CreateCPUTimeBudgetPool(const char* name); @@ -174,7 +176,7 @@ TaskQueueMap queue_details_; base::Callback<void(TaskQueue*, base::TimeTicks)> forward_immediate_work_callback_; - scoped_refptr<TaskQueue> task_runner_; + scoped_refptr<TaskQueue> control_task_queue_; RendererSchedulerImpl* renderer_scheduler_; // NOT OWNED base::TickClock* tick_clock_; // NOT OWNED const char* tracing_category_; // NOT OWNED
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc index 1814fbc..0c9df83 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
@@ -271,14 +271,14 @@ ThrotlingAnEmptyQueueDoesNotPostPumpThrottledTasksLocked) { task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); } TEST_F(TaskQueueThrottlerTest, OnTimeDomainHasImmediateWork_EnabledQueue) { task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), base::TimeTicks()); // Check PostPumpThrottledTasksLocked was called. - EXPECT_FALSE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); } TEST_F(TaskQueueThrottlerTest, OnTimeDomainHasImmediateWork_DisabledQueue) { @@ -289,7 +289,7 @@ task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), base::TimeTicks()); // Check PostPumpThrottledTasksLocked was not called. - EXPECT_TRUE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); } TEST_F(TaskQueueThrottlerTest, @@ -301,11 +301,11 @@ voter->SetQueueEnabled(false); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); // Enabling it should trigger a call to PostPumpThrottledTasksLocked. voter->SetQueueEnabled(true); - EXPECT_FALSE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); } TEST_F(TaskQueueThrottlerTest, @@ -318,11 +318,11 @@ voter->SetQueueEnabled(false); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); // Enabling it should trigger a call to PostPumpThrottledTasksLocked. voter->SetQueueEnabled(true); - EXPECT_FALSE(task_queue_throttler_->task_runner()->IsEmpty()); + EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); } TEST_F(TaskQueueThrottlerTest, WakeUpForNonDelayedTask) {
diff --git a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h index ece38941..3fdb2e9 100644 --- a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h +++ b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_ -#define THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_ #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -38,4 +38,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_PUBLIC_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ed8f2031f..b76c0f6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -39229,6 +39229,14 @@ <summary>True if a URLRequest's referrer is empty or valid when set.</summary> </histogram> +<histogram name="Net.URLRequestContext.OutstandingRequests" units="count"> + <owner>xunjieli@chromium.org</owner> + <summary> + Indicates the number of URLRequests that are handed out by a + URLRequestContext and are not yet destroyed. + </summary> +</histogram> + <histogram name="Net.ValidDNSName" enum="Boolean"> <owner>palmer@chromium.org</owner> <summary>
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index 31ef57f..80eeda5 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc
@@ -584,7 +584,7 @@ // Ensure that the bitmap is zeroed, since the code expects that. memset(bitmap_->getPixels(), 0, bitmap_->getSafeSize()); - owned_canvas_ = cc::SkiaPaintCanvas(bitmap_.value()); + owned_canvas_.emplace(bitmap_.value()); return &owned_canvas_.value(); }
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"