diff --git a/DEPS b/DEPS index a945a12..efd816c 100644 --- a/DEPS +++ b/DEPS
@@ -78,7 +78,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': 'c431872866ad9df805408af459fb8c0cbf553068', + 'v8_revision': 'a94bf1a84ab7876bc11a7a7307b77c20d96f58bc', # 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. @@ -639,7 +639,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '9106fb6d23603d47bb8f3d63b45c278ff138d119', # commit position 20628 + Var('webrtc_git') + '/src.git' + '@' + 'da04916bb9ffd832bc239050699bdedfd5efeb53', # commit position 20628 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6a9a566e1..d96cef4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3009,14 +3009,6 @@ SINGLE_VALUE_TYPE(ash::switches::kAshForceEnableStylusTools)}, #endif // defined(OS_CHROMEOS) -#if defined(OS_ANDROID) - {"enable-midi-manager-dynamic-instantiation", - flag_descriptions::kEnableMidiManagerDynamicInstantiationName, - flag_descriptions::kEnableMidiManagerDynamicInstantiationDescription, - kOsAll, - FEATURE_VALUE_TYPE(midi::features::kMidiManagerDynamicInstantiation)}, -#endif // defined(OS_ANDROID) - #if defined(OS_WIN) {"new-usb-backend", flag_descriptions::kNewUsbBackendName, flag_descriptions::kNewUsbBackendDescription, kOsWin,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index ae28b0b..1f81de4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1848,11 +1848,6 @@ const char kEnableExpandedAutofillCreditCardPopupLayoutDescription[] = "If enabled, displays autofill credit card popup using expanded layout."; -const char kEnableMidiManagerDynamicInstantiationName[] = - "MIDIManager dynamic instantiation for Web MIDI."; -const char kEnableMidiManagerDynamicInstantiationDescription[] = - "Enable MIDIManager dynamic instantiation for Web MIDI."; - const char kEnableNtpAssetDownloadSuggestionsName[] = "Show asset downloads on the New Tab page"; const char kEnableNtpAssetDownloadSuggestionsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d9b08af4..2a471056 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1141,9 +1141,6 @@ extern const char kEnableNtpForeignSessionsSuggestionsName[]; extern const char kEnableNtpForeignSessionsSuggestionsDescription[]; -extern const char kEnableMidiManagerDynamicInstantiationName[]; -extern const char kEnableMidiManagerDynamicInstantiationDescription[]; - extern const char kEnableNtpOfflinePageDownloadSuggestionsName[]; extern const char kEnableNtpOfflinePageDownloadSuggestionsDescription[];
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 68c7c0f..a64a0cc 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -914,9 +914,7 @@ "//jingle:jingle_glue", "//third_party/libvpx", "//third_party/opus", - "//third_party/webrtc/api:libjingle_api_deprecated_headers", "//third_party/webrtc/api:libjingle_logging_api", - "//third_party/webrtc/api:libjingle_peerconnection", "//third_party/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/api:optional", "//third_party/webrtc/api:peerconnection_and_implicit_call_api", @@ -946,6 +944,8 @@ "//third_party/webrtc/modules/video_coding:webrtc_h264", "//third_party/webrtc/p2p:libstunprober", "//third_party/webrtc/p2p:rtc_p2p", + "//third_party/webrtc/pc:libjingle_peerconnection", + "//third_party/webrtc/pc:peerconnection", "//third_party/webrtc/pc:rtc_pc", "//third_party/webrtc/pc:rtc_pc_base", "//third_party/webrtc/rtc_base:rtc_base",
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc index 4af35d7..a661434 100644 --- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc +++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -23,7 +23,7 @@ #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" #include "media/base/limits.h" #include "third_party/webrtc/api/videosourceproxy.h" -#include "third_party/webrtc/api/videotracksource.h" +#include "third_party/webrtc/pc/videotracksource.h" namespace content {
diff --git a/content/renderer/media/webrtc/webrtc_audio_sink.h b/content/renderer/media/webrtc/webrtc_audio_sink.h index 00e3af7..d9a1de5 100644 --- a/content/renderer/media/webrtc/webrtc_audio_sink.h +++ b/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -20,7 +20,7 @@ #include "content/renderer/media/media_stream_audio_processor.h" #include "media/base/audio_parameters.h" #include "media/base/audio_push_fifo.h" -#include "third_party/webrtc/api/mediastreamtrack.h" +#include "third_party/webrtc/pc/mediastreamtrack.h" namespace content {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f92337c3..c79bfffe 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -397,12 +397,12 @@ ] deps += [ - "//third_party/webrtc/api:libjingle_peerconnection", "//third_party/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/api:peerconnection_and_implicit_call_api", "//third_party/webrtc/api:rtc_stats_api", "//third_party/webrtc/media:rtc_media_base", "//third_party/webrtc/modules/video_capture", + "//third_party/webrtc/pc:libjingle_peerconnection", "//third_party/webrtc/rtc_base:rtc_base_approved", "//third_party/webrtc/stats:rtc_stats", "//third_party/webrtc_overrides:init_webrtc", @@ -1859,7 +1859,6 @@ "//services/device/public/interfaces", "//third_party/libyuv", "//third_party/opus", - "//third_party/webrtc/api:libjingle_peerconnection", "//third_party/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/api:peerconnection_and_implicit_call_api", "//third_party/webrtc/api:rtc_stats_api", @@ -1869,6 +1868,7 @@ "//third_party/webrtc/media:rtc_media", "//third_party/webrtc/modules/desktop_capture:primitives", "//third_party/webrtc/modules/video_capture", + "//third_party/webrtc/pc:libjingle_peerconnection", "//third_party/webrtc/rtc_base:rtc_base", "//third_party/webrtc/stats:rtc_stats_test_utils", "//third_party/webrtc_overrides",
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 437e0b9..8a2c00c 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <set> +#include <tuple> #include <utility> #include "base/bits.h" @@ -283,21 +284,16 @@ } private: - // TODO(zmo): once std::tuple is allowed, switch over to that. - struct FormatType { - GLenum internal_format; - GLenum format; - GLenum type; - }; - + // FormatType is a tuple of <internal_format, format, type> + typedef std::tuple<GLenum, GLenum, GLenum> FormatType; struct FormatTypeCompare { bool operator() (const FormatType& lhs, const FormatType& rhs) const { - return (lhs.internal_format < rhs.internal_format || - ((lhs.internal_format == rhs.internal_format) && - (lhs.format < rhs.format)) || - ((lhs.internal_format == rhs.internal_format) && - (lhs.format == rhs.format) && - (lhs.type < rhs.type))); + return (std::get<0>(lhs) < std::get<0>(rhs) || + ((std::get<0>(lhs) == std::get<0>(rhs)) && + (std::get<1>(lhs) < std::get<1>(rhs))) || + ((std::get<0>(lhs) == std::get<0>(rhs)) && + (std::get<1>(lhs) == std::get<1>(rhs)) && + (std::get<2>(lhs) < std::get<2>(rhs)))); } };
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h index ff54ce2..b6c7253 100644 --- a/ios/web/public/test/fakes/test_web_state.h +++ b/ios/web/public/test/fakes/test_web_state.h
@@ -82,6 +82,7 @@ void DidChangeVisibleSecurityState() override {} bool HasOpener() const override; void SetHasOpener(bool has_opener) override; + bool CanTakeSnapshot() const override; void TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const override; base::WeakPtr<WebState> AsWeakPtr() override;
diff --git a/ios/web/public/test/fakes/test_web_state.mm b/ios/web/public/test/fakes/test_web_state.mm index 260cd46f..f212f82 100644 --- a/ios/web/public/test/fakes/test_web_state.mm +++ b/ios/web/public/test/fakes/test_web_state.mm
@@ -312,6 +312,10 @@ has_opener_ = has_opener; } +bool TestWebState::CanTakeSnapshot() const { + return view_ != nil; +} + void TestWebState::TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const { callback.Run(gfx::Image([[UIImage alloc] init]));
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h index ddc9bbf..a2859a25 100644 --- a/ios/web/public/web_state/web_state.h +++ b/ios/web/public/web_state/web_state.h
@@ -297,6 +297,11 @@ // Callback used to handle snapshots. The parameter is the snapshot image. typedef base::Callback<void(const gfx::Image&)> SnapshotCallback; + // Returns whether there is a view available to generate a snapshot. If + // this returns false, then TakeSnapshot will takes a snapshot of an empty + // view. + virtual bool CanTakeSnapshot() const = 0; + // Takes a snapshot of this WebState with |target_size|. |callback| is // asynchronously invoked after performing the snapshot. virtual void TakeSnapshot(const SnapshotCallback& callback,
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index db916fa8..dd4f877 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -229,6 +229,7 @@ mojo::ScopedMessagePipeHandle interface_pipe) override; bool HasOpener() const override; void SetHasOpener(bool has_opener) override; + bool CanTakeSnapshot() const override; void TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const override; base::WeakPtr<WebState> AsWeakPtr() override;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 2e142de0..0e8f669 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -713,6 +713,10 @@ created_with_opener_ = has_opener; } +bool WebStateImpl::CanTakeSnapshot() const { + return [web_controller_ canUseViewForGeneratingOverlayPlaceholderView]; +} + void WebStateImpl::TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const { UIView* view = [web_controller_ view];
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index fef4bc4..82ba30f 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -826,4 +826,27 @@ EXPECT_FALSE(observer->update_favicon_url_candidates_info()); } +// Tests that taking a snapshot after disabling web usage or adding an overlay +// will force the creation of the WebState's view. +TEST_F(WebStateImplTest, CanTakeSnapshot) { + // The view is lazily created, so taking a snapshot is not possible initially. + ASSERT_FALSE(web_state_->CanTakeSnapshot()); + + // Enabling overlay does not create the creation of the View. + [web_state_->GetWebController() setOverlayPreviewMode:YES]; + EXPECT_FALSE(web_state_->CanTakeSnapshot()); + + // Loading the page will create the view (and add the placeholder overlay). + [web_state_->GetWebController() loadCurrentURLIfNecessary]; + EXPECT_TRUE(web_state_->CanTakeSnapshot()); + + // Disabling the overlay will remove the view. + [web_state_->GetWebController() setOverlayPreviewMode:NO]; + EXPECT_FALSE(web_state_->CanTakeSnapshot()); + + // Loading the page will create the view again. + [web_state_->GetWebController() loadCurrentURLIfNecessary]; + EXPECT_TRUE(web_state_->CanTakeSnapshot()); +} + } // namespace web
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm index 729a5c5..88aa1cd6 100644 --- a/ios/web/web_state/web_state_unittest.mm +++ b/ios/web/web_state/web_state_unittest.mm
@@ -141,6 +141,28 @@ ASSERT_FALSE(navigation_manager->GetLastCommittedItem()); } +// Tests that taking a snapshot after disabling web usage or adding an overlay +// will force the creation of the WebState's view. +TEST_F(WebStateTest, CanTakeSnapshot) { + // The test fixture forces the creation of the view, so it is initially + // possible to take a snapshot. + ASSERT_TRUE(web_state()->CanTakeSnapshot()); + + // Taking snapshot after disabling web usage will cause a reload. + web_state()->SetWebUsageEnabled(false); + EXPECT_FALSE(web_state()->CanTakeSnapshot()); + + // Even after re-enabling web usage, taking a snapshot will create the + // WebState's view as it is lazily created. + web_state()->SetWebUsageEnabled(true); + EXPECT_FALSE(web_state()->CanTakeSnapshot()); + + // After re-creating the view, it is possible to take a snapshot without + // reloading. + web_state()->GetView(); + EXPECT_TRUE(web_state()->CanTakeSnapshot()); +} + // Tests that the snapshot method returns an image of a rendered html page. TEST_F(WebStateTest, Snapshot) { LoadHtml(
diff --git a/media/blink/watch_time_reporter.cc b/media/blink/watch_time_reporter.cc index 070034d..cddcb77 100644 --- a/media/blink/watch_time_reporter.cc +++ b/media/blink/watch_time_reporter.cc
@@ -18,18 +18,23 @@ return false; } -WatchTimeReporter::WatchTimeReporter(mojom::PlaybackPropertiesPtr properties, - GetMediaTimeCB get_media_time_cb, - mojom::MediaMetricsProvider* provider) +WatchTimeReporter::WatchTimeReporter( + mojom::PlaybackPropertiesPtr properties, + GetMediaTimeCB get_media_time_cb, + mojom::MediaMetricsProvider* provider, + scoped_refptr<base::SequencedTaskRunner> task_runner) : WatchTimeReporter(std::move(properties), false /* is_background */, std::move(get_media_time_cb), - provider) {} + provider, + task_runner) {} -WatchTimeReporter::WatchTimeReporter(mojom::PlaybackPropertiesPtr properties, - bool is_background, - GetMediaTimeCB get_media_time_cb, - mojom::MediaMetricsProvider* provider) +WatchTimeReporter::WatchTimeReporter( + mojom::PlaybackPropertiesPtr properties, + bool is_background, + GetMediaTimeCB get_media_time_cb, + mojom::MediaMetricsProvider* provider, + scoped_refptr<base::SequencedTaskRunner> task_runner) : properties_(std::move(properties)), is_background_(is_background), get_media_time_cb_(std::move(get_media_time_cb)) { @@ -53,7 +58,9 @@ prop_copy->is_background = true; background_reporter_.reset( new WatchTimeReporter(std::move(prop_copy), true /* is_background */, - get_media_time_cb_, provider)); + get_media_time_cb_, provider, task_runner)); + + reporting_timer_.SetTaskRunner(task_runner); } WatchTimeReporter::~WatchTimeReporter() {
diff --git a/media/blink/watch_time_reporter.h b/media/blink/watch_time_reporter.h index 1a37ceb..cf1a2472 100644 --- a/media/blink/watch_time_reporter.h +++ b/media/blink/watch_time_reporter.h
@@ -74,7 +74,8 @@ // the elapsed media time instead? WatchTimeReporter(mojom::PlaybackPropertiesPtr properties, GetMediaTimeCB get_media_time_cb, - mojom::MediaMetricsProvider* provider); + mojom::MediaMetricsProvider* provider, + scoped_refptr<base::SequencedTaskRunner> task_runner); ~WatchTimeReporter() override; // These methods are used to ensure that watch time is only reported for media @@ -144,7 +145,8 @@ WatchTimeReporter(mojom::PlaybackPropertiesPtr properties, bool is_background, GetMediaTimeCB get_media_time_cb, - mojom::MediaMetricsProvider* provider); + mojom::MediaMetricsProvider* provider, + scoped_refptr<base::SequencedTaskRunner> task_runner); // base::PowerObserver implementation. //
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc index f241221..89f9d96 100644 --- a/media/blink/watch_time_reporter_unittest.cc +++ b/media/blink/watch_time_reporter_unittest.cc
@@ -17,6 +17,7 @@ #include "mojo/public/cpp/bindings/strong_binding.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/scheduler/test/renderer_scheduler_test_support.h" namespace media { @@ -227,7 +228,8 @@ is_encrypted, false, initial_video_size), base::Bind(&WatchTimeReporterTest::GetCurrentMediaTime, base::Unretained(this)), - &fake_metrics_provider_)); + &fake_metrics_provider_, + blink::scheduler::GetSequencedTaskRunnerForTesting())); // Setup the reporting interval to be immediate to avoid spinning real time // within the unit test.
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index ba96ebc..f1dffad 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -296,6 +296,9 @@ if (observer_) observer_->SetClient(this); + + memory_usage_reporting_timer_.SetTaskRunner( + frame_->GetTaskRunner(blink::TaskType::kUnthrottled)); } WebMediaPlayerImpl::~WebMediaPlayerImpl() { @@ -2567,7 +2570,8 @@ pipeline_metadata_.natural_size), base::BindRepeating(&WebMediaPlayerImpl::GetCurrentTimeInternal, base::Unretained(this)), - media_metrics_provider_.get())); + media_metrics_provider_.get(), + frame_->GetTaskRunner(blink::TaskType::kUnthrottled))); watch_time_reporter_->OnVolumeChange(volume_); if (delegate_->IsFrameHidden())
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index 63a3d54..8b145b7 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -1023,32 +1023,20 @@ // Recycle buffers. Dequeue(); - // Check and see if we have format info yet. - struct v4l2_format format; - gfx::Size visible_size; - bool again = false; - if (!GetFormatInfo(&format, &visible_size, &again)) - return false; - *endpos = size; - if (again) { - // Need more stream to decode format, return true and schedule next buffer. + // If an initial resolution change event is not done yet, a driver probably + // needs more stream to decode format. + // Return true and schedule next buffer without changing status to kDecoding. + // If the initial resolution change is done and coded size is known, we may + // still have to wait for AssignPictureBuffers() and output buffers to be + // allocated. + if (coded_size_.IsEmpty() || output_buffer_map_.empty()) { return true; } - // Run this initialization only on first startup. - if (output_buffer_map_.empty()) { - DVLOGF(4) << "running initialization"; - // Success! Setup our parameters. - if (!CreateBuffersForFormat(format, visible_size)) - return false; - // We are waiting for AssignPictureBuffers. Do not set the state to - // kDecoding. - } else { - decoder_state_ = kDecoding; - ScheduleDecodeBufferTaskIfNeeded(); - } + decoder_state_ = kDecoding; + ScheduleDecodeBufferTaskIfNeeded(); return true; } @@ -1185,6 +1173,25 @@ bool resolution_change_pending = false; if (event_pending) resolution_change_pending = DequeueResolutionChangeEvent(); + + if (!resolution_change_pending && coded_size_.IsEmpty()) { + // Some platforms do not send an initial resolution change event. + // To work around this, we need to keep checking if the initial resolution + // is known already by explicitly querying the format after each decode, + // regardless of whether we received an event. + // This needs to be done on initial resolution change, + // i.e. when coded_size_.IsEmpty(). + + // Try GetFormatInfo to check if an initial resolution change can be done. + struct v4l2_format format; + gfx::Size visible_size; + bool again; + if (GetFormatInfo(&format, &visible_size, &again) && !again) { + resolution_change_pending = true; + DequeueResolutionChangeEvent(); + } + } + Dequeue(); Enqueue(); @@ -1582,14 +1589,7 @@ DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask"); - // Flush outstanding buffers. - if (decoder_state_ == kInitialized) { - // There's nothing in the pipe, so return done immediately. - VLOGF(2) << "returning flush"; - child_task_runner_->PostTask(FROM_HERE, - base::Bind(&Client::NotifyFlushDone, client_)); - return; - } else if (decoder_state_ == kError) { + if (decoder_state_ == kError) { VLOGF(2) << "early out: kError state"; return; }
diff --git a/media/midi/midi_service.cc b/media/midi/midi_service.cc index 7427330b..6ecd858 100644 --- a/media/midi/midi_service.cc +++ b/media/midi/midi_service.cc
@@ -13,20 +13,6 @@ namespace midi { -namespace { - -// TODO(toyoshim): Support on all platforms. See https://crbug.com/672793. -bool IsDynamicInstantiationEnabled() { -#if defined(OS_ANDROID) - return base::FeatureList::IsEnabled( - features::kMidiManagerDynamicInstantiation); -#else - return true; -#endif -} - -} // namespace - std::unique_ptr<MidiManager> MidiService::ManagerFactory::Create( MidiService* service) { return std::unique_ptr<MidiManager>(MidiManager::Create(service)); @@ -45,8 +31,7 @@ } MidiService::MidiService(void) - : MidiService(std::make_unique<ManagerFactory>(), - IsDynamicInstantiationEnabled()) {} + : MidiService(std::make_unique<ManagerFactory>(), true) {} // TODO(toyoshim): Stop enforcing to disable dynamic instantiation mode for // testing once the mode is enabled by default.
diff --git a/media/midi/midi_switches.cc b/media/midi/midi_switches.cc index 1dc448d..08df596 100644 --- a/media/midi/midi_switches.cc +++ b/media/midi/midi_switches.cc
@@ -8,11 +8,6 @@ namespace midi { namespace features { -#if defined(OS_ANDROID) -const base::Feature kMidiManagerDynamicInstantiation{ - "MidiManagerDynamicInstantiation", base::FEATURE_ENABLED_BY_DEFAULT}; -#endif - #if defined(OS_WIN) const base::Feature kMidiManagerWinrt{"MidiManagerWinrt", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/midi/midi_switches.h b/media/midi/midi_switches.h index 9b377a1d..1c0dbb1d 100644 --- a/media/midi/midi_switches.h +++ b/media/midi/midi_switches.h
@@ -14,10 +14,6 @@ namespace midi { namespace features { -#if defined(OS_ANDROID) -MIDI_EXPORT extern const base::Feature kMidiManagerDynamicInstantiation; -#endif - #if defined(OS_WIN) MIDI_EXPORT extern const base::Feature kMidiManagerWinrt; #endif
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 91b1439..e04368b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1855,37 +1855,6 @@ ] } ], - "MidiManagerDynamicInstantiation": [ - { - "platforms": [ - "chromeos", - "linux", - "mac", - "win" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "MidiManagerDynamicInstantiation" - ] - } - ] - }, - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled_WithFullSupport", - "enable_features": [ - "MidiManagerDynamicInstantiation" - ] - } - ] - } - ], "MojoCdm": [ { "platforms": [
diff --git a/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp index c3bf8fd2..21d8ef7 100644 --- a/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp
@@ -142,6 +142,9 @@ case v8::Isolate::kIndexAccessor: blink_feature = WebFeature::kV8IndexAccessor; break; + case v8::Isolate::kDeoptimizerDisableSpeculation: + blink_feature = WebFeature::kV8DeoptimizerDisableSpeculation; + break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless.
diff --git a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp index 86536ef..3baba84 100644 --- a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp +++ b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
@@ -22,7 +22,7 @@ void InlineStylePropertyMap::SetProperty(CSSPropertyID property_id, const CSSValue* value) { - owner_element_->SetInlineStyleProperty(property_id, value); + owner_element_->SetInlineStyleProperty(property_id, *value); } void InlineStylePropertyMap::RemoveProperty(CSSPropertyID property_id) {
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index a357a5a..24dd166 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -4484,7 +4484,7 @@ void Element::SetInlineStyleProperty(CSSPropertyID property_id, CSSValueID identifier, bool important) { - SetInlineStyleProperty(property_id, CSSIdentifierValue::Create(identifier), + SetInlineStyleProperty(property_id, *CSSIdentifierValue::Create(identifier), important); } @@ -4492,15 +4492,15 @@ double value, CSSPrimitiveValue::UnitType unit, bool important) { - SetInlineStyleProperty(property_id, CSSPrimitiveValue::Create(value, unit), + SetInlineStyleProperty(property_id, *CSSPrimitiveValue::Create(value, unit), important); } void Element::SetInlineStyleProperty(CSSPropertyID property_id, - const CSSValue* value, + const CSSValue& value, bool important) { DCHECK(IsStyledElement()); - EnsureMutableInlineStyle().SetProperty(property_id, *value, important); + EnsureMutableInlineStyle().SetProperty(property_id, value, important); InlineStyleChanged(); }
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h index 86df572..8ae54acd 100644 --- a/third_party/WebKit/Source/core/dom/Element.h +++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -370,9 +370,8 @@ double value, CSSPrimitiveValue::UnitType, bool important = false); - // TODO(sashab): Make this take a const CSSValue&. void SetInlineStyleProperty(CSSPropertyID, - const CSSValue*, + const CSSValue&, bool important = false); bool SetInlineStyleProperty(CSSPropertyID, const String& value,
diff --git a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp index 6ecc8f1d..5ccd7c63 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp
@@ -54,11 +54,8 @@ EXPECT_EQ( LayoutRect(LayoutPoint(745, 0), LayoutSize(39, 26)), ToLayoutInline(GetLayoutObjectByElementId("rtl1"))->LinesBoundingBox()); - // TODO(layout-dev): LayoutNG should have same LayoutRect of legacy. - // See http://crbug.com/785687 EXPECT_EQ( - LayoutNGEnabled() ? LayoutRect(LayoutPoint(745, 0), LayoutSize(65, 13)) - : LayoutRect(LayoutPoint(641, 0), LayoutSize(143, 13)), + LayoutRect(LayoutPoint(641, 0), LayoutSize(143, 13)), ToLayoutInline(GetLayoutObjectByElementId("rtl2"))->LinesBoundingBox()); EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(26, 39)), ToLayoutInline(GetLayoutObjectByElementId("vertical"))
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp index 757064f2..75833f9 100644 --- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp +++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -98,28 +98,49 @@ text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()); if (!text_box->GetEmphasisMarkPosition(style, emphasis_mark_position)) return false; - LineLogicalSide side = style.GetTextEmphasisLineLogicalSide(); - if (IsHorizontal() || !style.IsFlippedLinesWritingMode()) - return side == LineLogicalSide::kOver; - return side == LineLogicalSide::kUnder; + if (IsHorizontal()) { + return emphasis_mark_position == TextEmphasisPosition::kOverRight || + emphasis_mark_position == TextEmphasisPosition::kOverLeft; + } + if (style.IsFlippedLinesWritingMode()) { + return emphasis_mark_position == TextEmphasisPosition::kOverLeft || + emphasis_mark_position == TextEmphasisPosition::kUnderLeft; + } + if (style.IsFlippedBlocksWritingMode()) { + return emphasis_mark_position == TextEmphasisPosition::kOverRight || + emphasis_mark_position == TextEmphasisPosition::kUnderRight; + } + return false; } inline bool InlineFlowBox::HasEmphasisMarkOver( const InlineTextBox* text_box) const { - const auto& style = - text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()); TextEmphasisPosition emphasis_mark_position; - return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) && - style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver; + if (!text_box->GetEmphasisMarkPosition( + text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()), + emphasis_mark_position)) + return false; + + return IsHorizontal() + ? emphasis_mark_position == TextEmphasisPosition::kOverRight || + emphasis_mark_position == TextEmphasisPosition::kOverLeft + : emphasis_mark_position == TextEmphasisPosition::kOverRight || + emphasis_mark_position == TextEmphasisPosition::kUnderRight; } inline bool InlineFlowBox::HasEmphasisMarkUnder( const InlineTextBox* text_box) const { - const auto& style = - text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()); TextEmphasisPosition emphasis_mark_position; - return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) && - style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kUnder; + if (!text_box->GetEmphasisMarkPosition( + text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()), + emphasis_mark_position)) + return false; + + return IsHorizontal() + ? emphasis_mark_position == TextEmphasisPosition::kUnderRight || + emphasis_mark_position == TextEmphasisPosition::kUnderLeft + : emphasis_mark_position == TextEmphasisPosition::kOverLeft || + emphasis_mark_position == TextEmphasisPosition::kUnderLeft; } void InlineFlowBox::AddToLine(InlineBox* child) {
diff --git a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp index cb4312d..8171902b 100644 --- a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp +++ b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
@@ -518,7 +518,12 @@ emphasis_position = style.GetTextEmphasisPosition(); // Ruby text is always over, so it cannot suppress emphasis marks under. - if (style.GetTextEmphasisLineLogicalSide() != LineLogicalSide::kOver) + if ((IsHorizontal() && + (emphasis_position == TextEmphasisPosition::kUnderRight || + emphasis_position == TextEmphasisPosition::kUnderLeft)) || + (!IsHorizontal() && + (emphasis_position == TextEmphasisPosition::kOverLeft || + emphasis_position == TextEmphasisPosition::kUnderLeft))) return true; LineLayoutBox containing_block = GetLineLayoutItem().ContainingBlock();
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc index c35f21a..3d099ac 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc
@@ -85,14 +85,18 @@ else box.metrics = NGLineHeightMetrics(); if (box.needs_box_fragment) { - box.line_left_position = LayoutUnit(); - // Existing box states are wrapped boxes, and hence no left edges. - box.border_edges.line_left = false; + // Existing box states are wrapped before they were closed, and hence + // they do not have start edges. + box.has_start_edge = false; + box.margin_inline_start = LayoutUnit(); + box.margin_border_padding_inline_start = LayoutUnit(); } DCHECK(box.pending_descendants.IsEmpty()); } } + DCHECK(box_data_list_.IsEmpty()); + // Initialize the box state for the line box. NGInlineBoxState& line_box = LineBoxState(); line_box.style = line_style; @@ -108,18 +112,24 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( const NGInlineItem& item, const NGInlineItemResult& item_result, - const NGLineBoxFragmentBuilder::ChildList& line_box, - LayoutUnit position) { + const NGLineBoxFragmentBuilder::ChildList& line_box) { DCHECK(item.Style()); NGInlineBoxState* box = OnOpenTag(*item.Style(), line_box); box->item = &item; // Compute box properties regardless of needs_box_fragment since close tag may // also set needs_box_fragment. - box->line_left_position = - position + item_result.margins.LineLeft(item.Style()->Direction()); - box->borders_paddings_block_start = item_result.borders_paddings_block_start; - box->borders_paddings_block_end = item_result.borders_paddings_block_end; + box->has_start_edge = item_result.has_edge; + if (box->has_start_edge) { + box->margin_inline_start = item_result.margins.inline_start; + // The open tag item has the start margin+border+padding in |inline_size|. + box->margin_border_padding_inline_start = item_result.inline_size; + } else { + DCHECK_EQ(item_result.margins.inline_start, LayoutUnit()); + DCHECK_EQ(item_result.inline_size, LayoutUnit()); + } + box->border_padding_block_start = item_result.borders_paddings_block_start; + box->border_padding_block_end = item_result.borders_paddings_block_end; return box; } @@ -147,16 +157,11 @@ void NGInlineLayoutStateStack::OnEndPlaceItems( NGLineBoxFragmentBuilder::ChildList* line_box, - FontBaseline baseline_type, - LayoutUnit position) { + FontBaseline baseline_type) { for (auto it = stack_.rbegin(); it != stack_.rend(); ++it) { NGInlineBoxState* box = &(*it); - box->line_right_position = position; EndBoxState(box, line_box, baseline_type); } - - if (!box_placeholders_.IsEmpty()) - CreateBoxFragments(line_box); } void NGInlineLayoutStateStack::EndBoxState( @@ -180,28 +185,22 @@ if (!needs_box_fragment) { DCHECK(item); needs_box_fragment = true; - // We have left edge on open tag, and if the box is not a continuation. - // TODO(kojii): Needs review when we change SplitInlines(). - bool has_line_left_edge = item->Style()->IsLeftToRightDirection() - ? item->HasStartEdge() - : item->HasEndEdge(); - border_edges = {true, false, true, has_line_left_edge}; } } void NGInlineBoxState::SetLineRightForBoxFragment( const NGInlineItem& item, - const NGInlineItemResult& item_result, - LayoutUnit position) { + const NGInlineItemResult& item_result) { DCHECK(needs_box_fragment); - line_right_position = - position - item_result.margins.LineRight(item.Style()->Direction()); - // We have right edge on close tag, and if the box does not have a - // continuation. - // TODO(kojii): Needs review when we change SplitInlines(). - border_edges.line_right = item.Style()->IsLeftToRightDirection() - ? item.HasEndEdge() - : item.HasStartEdge(); + has_end_edge = item_result.has_edge; + if (has_end_edge) { + margin_inline_end = item_result.margins.inline_end; + // The close tag item has the end margin+border+padding in |inline_size|. + margin_border_padding_inline_end = item_result.inline_size; + } else { + DCHECK_EQ(item_result.margins.inline_end, LayoutUnit()); + DCHECK_EQ(item_result.inline_size, LayoutUnit()); + } } // Crete a placeholder for a box fragment. @@ -213,8 +212,8 @@ NGLineBoxFragmentBuilder::ChildList* line_box, FontBaseline baseline_type) { DCHECK(box->needs_box_fragment); - LayoutUnit inline_size = box->line_right_position - box->line_left_position; - if (box->fragment_start == line_box->size() && + unsigned fragment_end = line_box->size(); + if (box->fragment_start == fragment_end && !box->needs_box_fragment_when_empty) { // Don't create a box if the inline box is "empty". // Inline boxes with inline margins/borders/paddings are not "empty", @@ -233,71 +232,227 @@ // Extend the block direction of the box by borders and paddings. Inline // direction is already included into positions in NGLineBreaker. - NGLogicalOffset offset(box->line_left_position, - -metrics.ascent - box->borders_paddings_block_start); - NGLogicalSize size(inline_size, metrics.LineHeight() + - box->borders_paddings_block_start + - box->borders_paddings_block_end); - - // The start is marked only in BoxFragmentPlaceholder, while end is marked - // in both BoxFragmentPlaceholder and the list itself. - // With a list of 4 text fragments: - // | 0 | 1 | 2 | 3 | - // |text0|text1|text2|text3| - // By adding a BoxFragmentPlaceholder(2,4) (end is exclusive), it becomes: - // | 0 | 1 | 2 | 3 | 4 | - // |text0|text1|text2|text3|null | - // The "null" is added to the list to compute baseline shift of the box - // separately from text fragments. - unsigned fragment_end = line_box->size(); + NGLogicalOffset offset(LayoutUnit(), + -metrics.ascent - box->border_padding_block_start); + NGLogicalSize size(LayoutUnit(), metrics.LineHeight() + + box->border_padding_block_start + + box->border_padding_block_end); DCHECK(box->item); - box_placeholders_.push_back(BoxFragmentPlaceholder{ - box->fragment_start, fragment_end, box->item, size, box->border_edges}); - line_box->AddChild(nullptr, offset); + box_data_list_.push_back( + BoxData{box->fragment_start, fragment_end, box->item, size}); + BoxData& box_data = box_data_list_.back(); + if (box->has_start_edge) { + box_data.has_line_left_edge = true; + box_data.margin_line_left = box->margin_inline_start; + box_data.margin_border_padding_line_left = + box->margin_border_padding_inline_start; + } + if (box->has_end_edge) { + box_data.has_line_right_edge = true; + box_data.margin_line_right = box->margin_inline_end; + box_data.margin_border_padding_line_right = + box->margin_border_padding_inline_end; + } + if (IsRtl(style.Direction())) { + std::swap(box_data.has_line_left_edge, box_data.has_line_right_edge); + std::swap(box_data.margin_line_left, box_data.margin_line_right); + std::swap(box_data.margin_border_padding_line_left, + box_data.margin_border_padding_line_right); + } + + if (fragment_end > box->fragment_start) { + // The start is marked only in BoxData, while end is marked + // in both BoxData and the list itself. + // With a list of 4 text fragments: + // | 0 | 1 | 2 | 3 | + // |text0|text1|text2|text3| + // By adding a BoxData(2,4) (end is exclusive), it becomes: + // | 0 | 1 | 2 | 3 | 4 | + // |text0|text1|text2|text3|null | + // The "null" is added to the list to compute baseline shift of the box + // separately from text fragments. + line_box->AddChild(offset); + } else { + // Do not defer creating a box fragment if this is an empty inline box. + // An empty box fragment is still flat that we do not have to defer. + // Also, placeholders cannot be reordred if empty. + scoped_refptr<NGLayoutResult> layout_result = + box_data.CreateBoxFragment(line_box); + offset.inline_offset += box_data.margin_line_left; + line_box->AddChild(layout_result, offset, box_data.size.inline_size, 0); + box_data_list_.pop_back(); + } } -// Create box fragments and construct a tree from the placeholders. -void NGInlineLayoutStateStack::CreateBoxFragments( +void NGInlineLayoutStateStack::PrepareForReorder( NGLineBoxFragmentBuilder::ChildList* line_box) { - DCHECK(!box_placeholders_.IsEmpty()); - - // At this point, children is a list of text fragments and box placeholders. - // | 0 | 1 | 2 | 3 | 4 | 5 | - // |text0|text1|text2|text3|null1|text5| - // When there is a BoxFragmentPlaceholder(2,4), this loop creates a box - // fragment with text2 and text3 as its children and changes the list to: - // | 0 | 1 | 2 | 3 | 4 | 5 | - // |text0|text1|null |null | box |text5| - for (const BoxFragmentPlaceholder& placeholder : box_placeholders_) { - const ComputedStyle* style = placeholder.item->Style(); - // Because children are already in the visual order, use LTR for the - // fragment builder so that it should not transform the coordinates for RTL. - NGFragmentBuilder box(placeholder.item->GetLayoutObject(), style, - style->GetWritingMode(), TextDirection::kLtr); - const NGLogicalOffset& box_offset = - (*line_box)[placeholder.fragment_end].offset; - for (unsigned i = placeholder.fragment_start; i < placeholder.fragment_end; - i++) { + // Set indexes of BoxData to the children of the line box. + unsigned box_data_index = 0; + for (const auto& box_data : box_data_list_) { + box_data_index++; + for (unsigned i = box_data.fragment_start; i < box_data.fragment_end; i++) { NGLineBoxFragmentBuilder::Child& child = (*line_box)[i]; - if (child.layout_result) { - box.AddChild(std::move(child.layout_result), child.offset - box_offset); - DCHECK(!child.layout_result); - } else if (child.fragment) { - box.AddChild(std::move(child.fragment), child.offset - box_offset); - DCHECK(!child.fragment); + if (!child.box_data_index) + child.box_data_index = box_data_index; + } + } + + // When boxes are nested, placeholders have indexes to which box it should be + // added. Copy them to BoxData. + for (auto& box_data : box_data_list_) { + const NGLineBoxFragmentBuilder::Child& placeholder = + (*line_box)[box_data.fragment_end]; + DCHECK(!placeholder.HasFragment()); + box_data.offset = placeholder.offset; + box_data.box_data_index = placeholder.box_data_index; + } +} + +void NGInlineLayoutStateStack::UpdateAfterReorder( + NGLineBoxFragmentBuilder::ChildList* line_box) { + // Compute start/end of boxes from the children of the line box. + for (auto& box_data : box_data_list_) + box_data.fragment_start = box_data.fragment_end = 0; + for (unsigned i = 0; i < line_box->size(); i++) { + const auto& child = (*line_box)[i]; + if (!child.HasFragment()) + continue; + if (unsigned box_data_index = child.box_data_index) { + BoxData& box_data = box_data_list_[box_data_index - 1]; + if (!box_data.fragment_end) + box_data.fragment_start = i; + box_data.fragment_end = i + 1; + } + } + + // Extend start/end of boxes when they are nested. + for (auto& box_data : box_data_list_) { + if (box_data.box_data_index) { + BoxData& parent_box_data = box_data_list_[box_data.box_data_index - 1]; + if (!parent_box_data.fragment_end) { + parent_box_data.fragment_start = box_data.fragment_start; + parent_box_data.fragment_end = box_data.fragment_end; + } else { + parent_box_data.fragment_start = + std::min(box_data.fragment_start, parent_box_data.fragment_start); + parent_box_data.fragment_end = + std::max(box_data.fragment_end, parent_box_data.fragment_end); } } - - // Inline boxes have block start/end borders, even when its containing block - // was fragmented. Fragmenting a line box in block direction is not - // supported today. - box.SetBorderEdges(placeholder.border_edges); - box.SetInlineSize(placeholder.size.inline_size); - box.SetBlockSize(placeholder.size.block_size); - DCHECK(!(*line_box)[placeholder.fragment_end].HasFragment()); - (*line_box)[placeholder.fragment_end].layout_result = box.ToBoxFragment(); } - box_placeholders_.clear(); + +#if DCHECK_IS_ON() + // Check all BoxData have ranges. + for (const auto& box_data : box_data_list_) { + DCHECK_NE(box_data.fragment_end, 0u); + DCHECK_GT(box_data.fragment_end, box_data.fragment_start); + } +#endif +} + +LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions( + NGLineBoxFragmentBuilder::ChildList* line_box) { + // At this point, children are in the visual order, and they have their + // origins at (0, 0). Accumulate inline offset from left to right. + LayoutUnit position; + for (auto& child : *line_box) { + child.offset.inline_offset += position; + // Box margins/boders/paddings will be processed later. + // TODO(kojii): we could optimize this if the reordering did not occur. + if (!child.HasFragment()) + continue; + position += child.inline_size; + } + + if (box_data_list_.IsEmpty()) + return position; + + // Create box fragments. + for (auto& box_data : box_data_list_) { + unsigned start = box_data.fragment_start; + unsigned end = box_data.fragment_end; + DCHECK_GT(end, start); + NGLineBoxFragmentBuilder::Child& start_child = (*line_box)[start]; + LayoutUnit line_left_offset = start_child.offset.inline_offset; + LayoutUnit line_right_offset = end < line_box->size() + ? (*line_box)[end].offset.inline_offset + : position; + box_data.offset.inline_offset = line_left_offset; + box_data.size.inline_size = line_right_offset - line_left_offset; + + scoped_refptr<NGLayoutResult> box_fragment = + box_data.CreateBoxFragment(line_box); + NGLogicalOffset offset(line_left_offset + box_data.margin_line_left, + box_data.offset.block_offset); + if (!start_child.HasFragment()) { + start_child.layout_result = std::move(box_fragment); + start_child.offset = offset; + } else { + // In most cases, |start_child| is moved to the children of the box, and + // is empty. It's not empty when it's out-of-flow. Insert in such case. + line_box->InsertChild(start, std::move(box_fragment), offset, + LayoutUnit(), 0); + } + + // Out-of-flow fragments are left in (start + 1, end). Move them by the left + // margin/border/padding. + if (box_data.margin_border_padding_line_left) { + line_box->MoveInInlineDirection(box_data.margin_border_padding_line_left, + start + 1, end); + } + // Move the rest of children by the inline size the box consumes. + LayoutUnit margin_border_padding = + box_data.margin_border_padding_line_left + + box_data.margin_border_padding_line_right; + if (margin_border_padding) { + line_box->MoveInInlineDirection(margin_border_padding, end, + line_box->size()); + position += margin_border_padding; + } + } + + box_data_list_.clear(); + + return position; +} + +scoped_refptr<NGLayoutResult> +NGInlineLayoutStateStack::BoxData::CreateBoxFragment( + NGLineBoxFragmentBuilder::ChildList* line_box) { + DCHECK(item); + DCHECK(item->Style()); + const ComputedStyle& style = *item->Style(); + // Because children are already in the visual order, use LTR for the + // fragment builder so that it should not transform the coordinates for RTL. + NGFragmentBuilder box(item->GetLayoutObject(), &style, style.GetWritingMode(), + TextDirection::kLtr); + + // Inline boxes have block start/end borders, even when its containing block + // was fragmented. Fragmenting a line box in block direction is not + // supported today. + box.SetBorderEdges({true, has_line_right_edge, true, has_line_left_edge}); + LayoutUnit border_padding_line_left = + margin_border_padding_line_left - margin_line_left; + LayoutUnit border_padding_line_right = + margin_border_padding_line_right - margin_line_right; + offset.inline_offset -= border_padding_line_left; + size.inline_size += border_padding_line_left + border_padding_line_right; + box.SetInlineSize(size.inline_size); + box.SetBlockSize(size.block_size); + + for (unsigned i = fragment_start; i < fragment_end; i++) { + NGLineBoxFragmentBuilder::Child& child = (*line_box)[i]; + if (child.layout_result) { + box.AddChild(std::move(child.layout_result), child.offset - offset); + } else if (child.fragment) { + box.AddChild(std::move(child.fragment), child.offset - offset); + } + // Leave out-of-flow fragments. They need to be at the top level so that + // NGInlineLayoutAlgorithm can handle them later. + DCHECK(!child.HasInFlowFragment()); + } + + return box.ToBoxFragment(); } NGInlineLayoutStateStack::PositionPending
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h index 4f317802..fa37027 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h
@@ -56,17 +56,27 @@ // These values are to create a box fragment. Set only when needs_box_fragment // is set. - LayoutUnit line_left_position; - LayoutUnit line_right_position; - LayoutUnit borders_paddings_block_start; - LayoutUnit borders_paddings_block_end; - NGBorderEdges border_edges; + bool has_start_edge = false; + bool has_end_edge = false; + // |CreateBoxFragment()| needs margin, border+padding, and the sum of them. + LayoutUnit margin_inline_start; + LayoutUnit margin_inline_end; + LayoutUnit margin_border_padding_inline_start; + LayoutUnit margin_border_padding_inline_end; + LayoutUnit border_padding_block_start; + LayoutUnit border_padding_block_end; Vector<NGPendingPositions> pending_descendants; bool include_used_fonts = false; bool needs_box_fragment = false; bool needs_box_fragment_when_empty = false; + // True if this box has a metrics, including pending ones. Pending metrics + // will be activated in |EndBoxState()|. + bool HasMetrics() const { + return !metrics.IsEmpty() || !pending_descendants.IsEmpty(); + } + // Compute text metrics for a box. All text in a box share the same // metrics. When line_height_quirk is set, text metrics won't // influence box height until ActivateTextMetrics() is called. @@ -83,8 +93,7 @@ // Create a box fragment for this box. void SetNeedsBoxFragment(bool when_empty); void SetLineRightForBoxFragment(const NGInlineItem&, - const NGInlineItemResult&, - LayoutUnit position); + const NGInlineItemResult&); // Returns if the text style can be added without open-tag. // Text with different font or vertical-align needs to be wrapped with an @@ -108,8 +117,7 @@ // Push a box state stack. NGInlineBoxState* OnOpenTag(const NGInlineItem&, const NGInlineItemResult&, - const NGLineBoxFragmentBuilder::ChildList&, - LayoutUnit position); + const NGLineBoxFragmentBuilder::ChildList&); NGInlineBoxState* OnOpenTag(const ComputedStyle&, const NGLineBoxFragmentBuilder::ChildList&); @@ -119,12 +127,26 @@ FontBaseline); // Compute all the pending positioning at the end of a line. - void OnEndPlaceItems(NGLineBoxFragmentBuilder::ChildList*, - FontBaseline, - LayoutUnit position); + void OnEndPlaceItems(NGLineBoxFragmentBuilder::ChildList*, FontBaseline); LayoutObject* ContainingLayoutObjectForAbsolutePositionObjects() const; + bool HasBoxFragments() const { return !box_data_list_.IsEmpty(); } + + // This class keeps indexes to fragments in the line box, and that only + // appending is allowed. Call this function to move all such data to the line + // box, so that outside of this class can reorder fragments in the line box. + void PrepareForReorder(NGLineBoxFragmentBuilder::ChildList*); + + // When reordering was complete, call this function to re-construct the box + // data from the line box. Callers must call |PrepareForReorder()| before + // reordering. + void UpdateAfterReorder(NGLineBoxFragmentBuilder::ChildList*); + + // Compute inline positions of fragments. Also creates box fragments if + // needed. + LayoutUnit ComputeInlinePositions(NGLineBoxFragmentBuilder::ChildList*); + private: // End of a box state, either explicitly by close tag, or implicitly at the // end of a line. @@ -135,7 +157,6 @@ void AddBoxFragmentPlaceholder(NGInlineBoxState*, NGLineBoxFragmentBuilder::ChildList*, FontBaseline); - void CreateBoxFragments(NGLineBoxFragmentBuilder::ChildList*); enum PositionPending { kPositionNotPending, kPositionPending }; @@ -149,18 +170,31 @@ NGLineBoxFragmentBuilder::ChildList*, FontBaseline); - // Data for a box fragment placeholder. See AddBoxFragmentPlaceholder(). + // Data for a box fragment. See AddBoxFragmentPlaceholder(). // This is a transient object only while building a line box. - struct BoxFragmentPlaceholder { + struct BoxData { unsigned fragment_start; unsigned fragment_end; const NGInlineItem* item; NGLogicalSize size; - NGBorderEdges border_edges; + + bool has_line_left_edge = false; + bool has_line_right_edge = false; + // |CreateBoxFragment()| needs margin, border+padding, and the sum of them. + LayoutUnit margin_line_left; + LayoutUnit margin_line_right; + LayoutUnit margin_border_padding_line_left; + LayoutUnit margin_border_padding_line_right; + + NGLogicalOffset offset; + unsigned box_data_index = 0; + + scoped_refptr<NGLayoutResult> CreateBoxFragment( + NGLineBoxFragmentBuilder::ChildList*); }; Vector<NGInlineBoxState, 4> stack_; - Vector<BoxFragmentPlaceholder, 4> box_placeholders_; + Vector<BoxData, 4> box_data_list_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h index 3d702239..149c68e 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h
@@ -60,6 +60,9 @@ // by default. int expansion = 0; + // Has start/end edge for open/close tags. + bool has_edge = false; + // Create a box when the box is empty, for open/close tags. bool needs_box_when_empty = false;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 3771b93..d0b2f4b 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -70,60 +70,6 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info, NGExclusionSpace* exclusion_space) { - if (Node().IsBidiEnabled()) - BidiReorder(&line_info->Results()); - - PlaceItems(line_info, *exclusion_space); -} - -void NGInlineLayoutAlgorithm::BidiReorder(NGInlineItemResults* line_items) { - // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change - // embedding levels of parts of runs, which requires to split items. - // http://unicode.org/reports/tr9/#L1 - // BidiResolver does not support L1 crbug.com/316409. - - // Create a list of chunk indices in the visual order. - // ICU |ubidi_getVisualMap()| works for a run of characters. Since we can - // handle the direction of each run, we use |ubidi_reorderVisual()| to reorder - // runs instead of characters. - Vector<UBiDiLevel, 32> levels; - levels.ReserveInitialCapacity(line_items->size()); - for (const auto& item_result : *line_items) - levels.push_back(item_result.item->BidiLevelForReorder()); - Vector<int32_t, 32> indices_in_visual_order(line_items->size()); - NGBidiParagraph::IndicesInVisualOrder(levels, &indices_in_visual_order); - - // Reorder to the visual order. - NGInlineItemResults line_items_in_visual_order(line_items->size()); - for (unsigned visual_index = 0; visual_index < indices_in_visual_order.size(); - visual_index++) { - unsigned logical_index = indices_in_visual_order[visual_index]; - line_items_in_visual_order[visual_index] = - std::move((*line_items)[logical_index]); - } - - // Keep Open before Close in the visual order. - HashMap<LayoutObject*, unsigned> first_index; - for (unsigned i = 0; i < line_items_in_visual_order.size(); i++) { - NGInlineItemResult& item_result = line_items_in_visual_order[i]; - const NGInlineItem& item = *item_result.item; - if (item.Type() != NGInlineItem::kOpenTag && - item.Type() != NGInlineItem::kCloseTag) { - continue; - } - auto result = first_index.insert(item.GetLayoutObject(), i); - if (!result.is_new_entry && item.Type() == NGInlineItem::kOpenTag) { - std::swap(line_items_in_visual_order[i], - line_items_in_visual_order[result.stored_value->value]); - } - } - - line_items->swap(line_items_in_visual_order); -} - -void NGInlineLayoutAlgorithm::PlaceItems( - NGLineInfo* line_info, - const NGExclusionSpace& exclusion_space) { NGInlineItemResults* line_items = &line_info->Results(); line_box_.clear(); @@ -151,11 +97,10 @@ // Place items from line-left to line-right along with the baseline. // Items are already bidi-reordered to the visual order. - LayoutUnit position; if (IsRtl(line_info->BaseDirection()) && line_info->LineEndShapeResult()) { PlaceGeneratedContent(std::move(line_info->LineEndShapeResult()), - std::move(line_info->LineEndStyle()), &position, box, + std::move(line_info->LineEndStyle()), box, &text_builder); } @@ -176,7 +121,7 @@ baseline_type_); } } else { - if (quirks_mode_ && line_box_.IsEmpty()) + if (quirks_mode_ && !box->HasMetrics()) box->ActivateTextMetrics(); DCHECK(!item.TextShapeResult()); // kControl or unit tests. } @@ -186,9 +131,10 @@ text_builder.ToTextFragment(item_result.item_index, item_result.start_offset, item_result.end_offset); - line_box_.AddChild(std::move(text_fragment), {position, box->text_top}); + line_box_.AddChild(std::move(text_fragment), box->text_top, + item_result.inline_size, item.BidiLevel()); } else if (item.Type() == NGInlineItem::kOpenTag) { - box = box_states_->OnOpenTag(item, item_result, line_box_, position); + box = box_states_->OnOpenTag(item, item_result, line_box_); // Compute text metrics for all inline boxes since even empty inlines // influence the line height. // https://drafts.csswg.org/css2/visudet.html#line-height @@ -198,39 +144,33 @@ if (ShouldCreateBoxFragment(item, item_result)) box->SetNeedsBoxFragment(item_result.needs_box_when_empty); } else if (item.Type() == NGInlineItem::kCloseTag) { - position += item_result.inline_size; if (box->needs_box_fragment || item_result.needs_box_when_empty) { if (item_result.needs_box_when_empty) box->SetNeedsBoxFragment(true); - box->SetLineRightForBoxFragment(item, item_result, position); + box->SetLineRightForBoxFragment(item, item_result); if (quirks_mode_) box->ActivateTextMetrics(); } box = box_states_->OnCloseTag(&line_box_, box, baseline_type_); - continue; } else if (item.Type() == NGInlineItem::kAtomicInline) { - box = PlaceAtomicInline(item, &item_result, *line_info, position); + box = PlaceAtomicInline(item, &item_result, *line_info); } else if (item.Type() == NGInlineItem::kListMarker) { list_marker_index = line_box_.size(); PlaceListMarker(item, &item_result, *line_info); DCHECK_GT(line_box_.size(), list_marker_index.value()); } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { - NGBlockNode node(ToLayoutBox(item.GetLayoutObject())); - container_builder_.AddInlineOutOfFlowChildCandidate( - node, NGLogicalOffset(position, LayoutUnit()), - line_info->BaseDirection(), - box_states_->ContainingLayoutObjectForAbsolutePositionObjects()); - continue; - } else { - continue; + line_box_.AddChild( + item.GetLayoutObject(), + box_states_->ContainingLayoutObjectForAbsolutePositionObjects(), + item.BidiLevel()); + } else if (item.Type() == NGInlineItem::kBidiControl) { + line_box_.AddChild(item.BidiLevel()); } - - position += item_result.inline_size; } if (line_info->LineEndShapeResult()) { PlaceGeneratedContent(std::move(line_info->LineEndShapeResult()), - std::move(line_info->LineEndStyle()), &position, box, + std::move(line_info->LineEndStyle()), box, &text_builder); } @@ -238,7 +178,40 @@ return; // The line was empty. } - box_states_->OnEndPlaceItems(&line_box_, baseline_type_, position); + box_states_->OnEndPlaceItems(&line_box_, baseline_type_); + + // TODO(kojii): For LTR, we can optimize ComputeInlinePositions() to compute + // without PrepareForReorder() and UpdateAfterReorder() even when + // HasBoxFragments(). We do this to share the logic between LTR and RTL, and + // to get more coverage for RTL, but when we're more stabilized, we could have + // optimized code path for LTR. + box_states_->PrepareForReorder(&line_box_); + BidiReorder(); + box_states_->UpdateAfterReorder(&line_box_); + LayoutUnit inline_size = box_states_->ComputeInlinePositions(&line_box_); + + // Handle out-of-flow positioned objects. They need inline offsets for their + // static positions. + bool has_fragments = false; + for (auto& child : line_box_) { + if (child.out_of_flow_positioned_box) { + NGBlockNode node(ToLayoutBox(child.out_of_flow_positioned_box)); + container_builder_.AddInlineOutOfFlowChildCandidate( + node, NGLogicalOffset(child.offset.inline_offset, LayoutUnit()), + line_info->BaseDirection(), child.out_of_flow_containing_box); + child.out_of_flow_positioned_box = child.out_of_flow_containing_box = + nullptr; + } else if (!has_fragments) { + has_fragments = child.HasFragment(); + } + } + + if (!has_fragments) { + // If we have out-of-flow objects but nothing else, we don't have line box + // metrics nor BFC offset. Exit early. + return; + } + const NGLineHeightMetrics& line_box_metrics = box_states_->LineBoxState().metrics; DCHECK(!line_box_metrics.IsEmpty()); @@ -255,7 +228,7 @@ // Negative margins can make the position negative, but the inline size is // always positive or 0. - LayoutUnit inline_size = position.ClampNegativeToZero(); + inline_size = inline_size.ClampNegativeToZero(); // Other 'text-align' values than 'justify' move line boxes as a whole, but // indivisual items do not change their relative position to the line box. @@ -281,20 +254,17 @@ void NGInlineLayoutAlgorithm::PlaceGeneratedContent( scoped_refptr<const ShapeResult> shape_result, scoped_refptr<const ComputedStyle> style, - LayoutUnit* position, NGInlineBoxState* box, NGTextFragmentBuilder* text_builder) { if (box->CanAddTextOfStyle(*style)) { - PlaceText(std::move(shape_result), std::move(style), position, box, - text_builder); + PlaceText(std::move(shape_result), std::move(style), 0, box, text_builder); } else { scoped_refptr<ComputedStyle> text_style = ComputedStyle::CreateAnonymousStyleWithDisplay(*style, EDisplay::kInline); NGInlineBoxState* box = box_states_->OnOpenTag(*text_style, line_box_); box->ComputeTextMetrics(*text_style, baseline_type_, false); - PlaceText(std::move(shape_result), std::move(style), position, box, - text_builder); + PlaceText(std::move(shape_result), std::move(style), 0, box, text_builder); box_states_->OnCloseTag(&line_box_, box, baseline_type_); } } @@ -302,7 +272,7 @@ void NGInlineLayoutAlgorithm::PlaceText( scoped_refptr<const ShapeResult> shape_result, scoped_refptr<const ComputedStyle> style, - LayoutUnit* position, + UBiDiLevel bidi_level, NGInlineBoxState* box, NGTextFragmentBuilder* text_builder) { unsigned start_offset = shape_result->StartIndexForResult(); @@ -313,38 +283,37 @@ scoped_refptr<NGPhysicalTextFragment> text_fragment = text_builder->ToTextFragment(std::numeric_limits<unsigned>::max(), start_offset, end_offset); - line_box_.AddChild(std::move(text_fragment), {*position, box->text_top}); - *position += inline_size; + line_box_.AddChild(std::move(text_fragment), box->text_top, inline_size, + bidi_level); } NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline( const NGInlineItem& item, NGInlineItemResult* item_result, - const NGLineInfo& line_info, - LayoutUnit position) { + const NGLineInfo& line_info) { DCHECK(item_result->layout_result); // The input |position| is the line-left edge of the margin box. // Adjust it to the border box by adding the line-left margin. - const ComputedStyle& style = *item.Style(); - position += item_result->margins.LineLeft(style.Direction()); + // const ComputedStyle& style = *item.Style(); + // position += item_result->margins.LineLeft(style.Direction()); - NGInlineBoxState* box = - box_states_->OnOpenTag(item, *item_result, line_box_, position); - - PlaceLayoutResult(item_result, position, box); - + item_result->has_edge = true; + NGInlineBoxState* box = box_states_->OnOpenTag(item, *item_result, line_box_); + PlaceLayoutResult(item_result, box, box->margin_inline_start); return box_states_->OnCloseTag(&line_box_, box, baseline_type_); } // Place a NGLayoutResult into the line box. void NGInlineLayoutAlgorithm::PlaceLayoutResult(NGInlineItemResult* item_result, - LayoutUnit position, - NGInlineBoxState* box) { + NGInlineBoxState* box, + LayoutUnit inline_offset) { DCHECK(item_result->layout_result); DCHECK(item_result->layout_result->PhysicalFragment()); - DCHECK(item_result->item->Style()); - const ComputedStyle& style = *item_result->item->Style(); + DCHECK(item_result->item); + const NGInlineItem& item = *item_result->item; + DCHECK(item.Style()); + const ComputedStyle& style = *item.Style(); NGBoxFragment fragment( ConstraintSpace().GetWritingMode(), ToNGPhysicalBoxFragment(*item_result->layout_result->PhysicalFragment())); @@ -366,12 +335,14 @@ text_builder.ToTextFragment(item_result->item_index, item_result->start_offset, item_result->end_offset); - line_box_.AddChild(std::move(text_fragment), {position, line_top}); + line_box_.AddChild(std::move(text_fragment), line_top, LayoutUnit(), + item.BidiLevel()); // We need the box fragment as well to compute VisualRect() correctly. } line_box_.AddChild(std::move(item_result->layout_result), - {position, line_top}); + NGLogicalOffset{inline_offset, line_top}, + item_result->inline_size, item.BidiLevel()); } // Place a list marker. @@ -387,7 +358,7 @@ DCHECK(item_result->layout_result->PhysicalFragment()); // The inline position is adjusted later, when we knew the line width. - PlaceLayoutResult(item_result, LayoutUnit(), nullptr); + PlaceLayoutResult(item_result, nullptr); } // Justify the line. This changes the size of items by adding spacing. @@ -722,4 +693,37 @@ unpositioned_floats_.clear(); } +void NGInlineLayoutAlgorithm::BidiReorder() { + // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change + // embedding levels of parts of runs, which requires to split items. + // http://unicode.org/reports/tr9/#L1 + // BidiResolver does not support L1 crbug.com/316409. + + // Create a list of chunk indices in the visual order. + // ICU |ubidi_getVisualMap()| works for a run of characters. Since we can + // handle the direction of each run, we use |ubidi_reorderVisual()| to reorder + // runs instead of characters. + NGLineBoxFragmentBuilder::ChildList logical_items; + Vector<UBiDiLevel, 32> levels; + logical_items.ReserveInitialCapacity(line_box_.size()); + levels.ReserveInitialCapacity(line_box_.size()); + for (auto& item : line_box_) { + if (!item.HasFragment() && !item.HasBidiLevel()) + continue; + levels.push_back(item.bidi_level); + logical_items.AddChild(std::move(item)); + DCHECK(!item.HasInFlowFragment()); + } + + Vector<int32_t, 32> indices_in_visual_order(levels.size()); + NGBidiParagraph::IndicesInVisualOrder(levels, &indices_in_visual_order); + + // Reorder to the visual order. + line_box_.resize(0); + for (unsigned logical_index : indices_in_visual_order) { + line_box_.AddChild(std::move(logical_items[logical_index])); + DCHECK(!logical_items[logical_index].HasInFlowFragment()); + } +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h index 5c6c5b35..3abeb89 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -52,26 +52,23 @@ bool IsHorizontalWritingMode() const { return is_horizontal_writing_mode_; } - void BidiReorder(NGInlineItemResults*); + void BidiReorder(); - void PlaceItems(NGLineInfo*, const NGExclusionSpace&); void PlaceText(scoped_refptr<const ShapeResult>, scoped_refptr<const ComputedStyle>, - LayoutUnit* position, + UBiDiLevel bidi_level, NGInlineBoxState*, NGTextFragmentBuilder*); void PlaceGeneratedContent(scoped_refptr<const ShapeResult>, scoped_refptr<const ComputedStyle>, - LayoutUnit* position, NGInlineBoxState*, NGTextFragmentBuilder*); NGInlineBoxState* PlaceAtomicInline(const NGInlineItem&, NGInlineItemResult*, - const NGLineInfo&, - LayoutUnit position); + const NGLineInfo&); void PlaceLayoutResult(NGInlineItemResult*, - LayoutUnit position, - NGInlineBoxState*); + NGInlineBoxState*, + LayoutUnit inline_offset = LayoutUnit()); void PlaceListMarker(const NGInlineItem&, NGInlineItemResult*, const NGLineInfo&);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.cc index 9fc764d3..18d22098e 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -55,22 +55,22 @@ : fragment.get(); } -void NGLineBoxFragmentBuilder::ChildList::AddChild( +void NGLineBoxFragmentBuilder::ChildList::InsertChild( + unsigned index, scoped_refptr<NGLayoutResult> layout_result, - const NGLogicalOffset& child_offset) { - children_.push_back(Child{std::move(layout_result), nullptr, child_offset}); + const NGLogicalOffset& offset, + LayoutUnit inline_size, + UBiDiLevel bidi_level) { + children_.insert( + index, Child{std::move(layout_result), offset, inline_size, bidi_level}); } -void NGLineBoxFragmentBuilder::ChildList::AddChild( - scoped_refptr<NGPhysicalFragment> fragment, - const NGLogicalOffset& child_offset) { - children_.push_back(Child{nullptr, std::move(fragment), child_offset}); -} - -void NGLineBoxFragmentBuilder::ChildList::AddChild( - std::nullptr_t, - const NGLogicalOffset& child_offset) { - children_.push_back(Child{nullptr, nullptr, child_offset}); +void NGLineBoxFragmentBuilder::ChildList::MoveInInlineDirection( + LayoutUnit delta, + unsigned start, + unsigned end) { + for (unsigned index = start; index < end; index++) + children_[index].offset.inline_offset += delta; } void NGLineBoxFragmentBuilder::ChildList::MoveInBlockDirection(
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.h index ac5958e..8fb6e88 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -50,9 +50,53 @@ scoped_refptr<NGLayoutResult> layout_result; scoped_refptr<NGPhysicalFragment> fragment; + LayoutObject* out_of_flow_positioned_box = nullptr; + LayoutObject* out_of_flow_containing_box = nullptr; NGLogicalOffset offset; + LayoutUnit inline_size; + unsigned box_data_index = 0; + UBiDiLevel bidi_level = 0xff; - bool HasFragment() const { return layout_result || fragment; } + // Empty constructor needed for |resize()|. + Child() {} + // Create a placeholder. A placeholder does not have a fragment nor a bidi + // level. + Child(NGLogicalOffset offset) : offset(offset) {} + // Crete a bidi control. A bidi control does not have a fragment, but has + // bidi level and affects bidi reordering. + Child(UBiDiLevel bidi_level) : bidi_level(bidi_level) {} + // Create an in-flow |NGLayoutResult|. + Child(scoped_refptr<NGLayoutResult> layout_result, + NGLogicalOffset offset, + LayoutUnit inline_size, + UBiDiLevel bidi_level) + : layout_result(std::move(layout_result)), + offset(offset), + inline_size(inline_size), + bidi_level(bidi_level) {} + // Create an in-flow |NGPhysicalFragment|. + Child(scoped_refptr<NGPhysicalFragment> fragment, + LayoutUnit block_offset, + LayoutUnit inline_size, + UBiDiLevel bidi_level) + : fragment(std::move(fragment)), + offset({LayoutUnit(), block_offset}), + inline_size(inline_size), + bidi_level(bidi_level) {} + // Create an out-of-flow positioned object. + Child(LayoutObject* out_of_flow_positioned_box, + LayoutObject* out_of_flow_containing_box, + UBiDiLevel bidi_level) + : out_of_flow_positioned_box(out_of_flow_positioned_box), + out_of_flow_containing_box(out_of_flow_containing_box), + bidi_level(bidi_level) {} + + bool HasInFlowFragment() const { return layout_result || fragment; } + bool HasOutOfFlowFragment() const { return out_of_flow_positioned_box; } + bool HasFragment() const { + return HasInFlowFragment() || HasOutOfFlowFragment(); + } + bool HasBidiLevel() const { return bidi_level != 0xff; } const NGPhysicalFragment* PhysicalFragment() const; }; @@ -76,6 +120,7 @@ children_.ReserveInitialCapacity(capacity); } void clear() { children_.clear(); } + void resize(size_t size) { children_.resize(size); } using iterator = Vector<Child, 16>::iterator; iterator begin() { return children_.begin(); } @@ -84,13 +129,18 @@ const_iterator begin() const { return children_.begin(); } const_iterator end() const { return children_.end(); } - void AddChild(scoped_refptr<NGLayoutResult>, const NGLogicalOffset&); - void AddChild(scoped_refptr<NGPhysicalFragment>, const NGLogicalOffset&); - // nullptr child is a placeholder until enclosing inline boxes are closed - // and we know the final box structure and their positions. This variant - // helps to avoid needing static_cast when adding a nullptr. - void AddChild(std::nullptr_t, const NGLogicalOffset&); + // Add a child. Accepts all constructor arguments for |Child|. + template <class... Args> + void AddChild(Args&&... args) { + children_.push_back(Child(std::forward<Args>(args)...)); + } + void InsertChild(unsigned, + scoped_refptr<NGLayoutResult>, + const NGLogicalOffset&, + LayoutUnit inline_size, + UBiDiLevel); + void MoveInInlineDirection(LayoutUnit, unsigned start, unsigned end); void MoveInBlockDirection(LayoutUnit); void MoveInBlockDirection(LayoutUnit, unsigned start, unsigned end);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc index 02eaa68..a7ed885 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
@@ -571,15 +571,16 @@ DCHECK(item.Style()); const ComputedStyle& style = *item.Style(); item_result->needs_box_when_empty = false; + item_result->has_edge = item.HasStartEdge(); if (style.HasBorder() || style.HasPadding() || - (style.HasMargin() && item.HasStartEdge())) { + (style.HasMargin() && item_result->has_edge)) { NGBoxStrut borders = ComputeBorders(constraint_space_, style); NGBoxStrut paddings = ComputePadding(constraint_space_, style); item_result->borders_paddings_block_start = borders.block_start + paddings.block_start; item_result->borders_paddings_block_end = borders.block_end + paddings.block_end; - if (item.HasStartEdge()) { + if (item_result->has_edge) { item_result->margins = ComputeMarginsForContainer(constraint_space_, style); item_result->inline_size = item_result->margins.inline_start + @@ -611,7 +612,8 @@ NGInlineItemResult* item_result = &item_results->back(); item_result->needs_box_when_empty = false; - if (item.HasEndEdge()) { + item_result->has_edge = item.HasEndEdge(); + if (item_result->has_edge) { DCHECK(item.Style()); const ComputedStyle& style = *item.Style(); item_result->margins = ComputeMarginsForContainer(constraint_space_, style);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_physical_text_fragment.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_physical_text_fragment.cc index 7a6be610..2c5566e 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_physical_text_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_physical_text_fragment.cc
@@ -14,47 +14,36 @@ if (!shape_result_) return {}; - // Glyph bounds is in logical coordinate, origin at the alphabetic baseline. - LayoutRect visual_rect = EnclosingLayoutRect(shape_result_->Bounds()); + // TODO(kojii): Copying InlineTextBox logic from + // InlineFlowBox::ComputeOverflow(). + // + // InlineFlowBox::ComputeOverflow() computes GlpyhOverflow first + // (ComputeGlyphOverflow) then AddTextBoxVisualOverflow(). We probably don't + // have to keep these two steps separated. + + // Glyph bounds is in logical coordinate, origin at the baseline. + FloatRect visual_float_rect = shape_result_->Bounds(); // Make the origin at the logical top of this fragment. + // ShapeResult::Bounds() is in logical coordinate with alphabetic baseline. const ComputedStyle& style = Style(); - const Font& font = style.GetFont(); - const SimpleFontData* font_data = font.PrimaryFont(); - if (font_data) { - visual_rect.SetY(visual_rect.Y() + font_data->GetFontMetrics().FixedAscent( - kAlphabeticBaseline)); - } + const SimpleFontData* font_data = style.GetFont().PrimaryFont(); + visual_float_rect.SetY( + visual_float_rect.Y() + + font_data->GetFontMetrics().FixedAscent(kAlphabeticBaseline)); + // TODO(kojii): Copying from AddTextBoxVisualOverflow() if (float stroke_width = style.TextStrokeWidth()) { - visual_rect.Inflate(LayoutUnit::FromFloatCeil(stroke_width / 2.0f)); + visual_float_rect.Inflate(stroke_width / 2.0f); } - if (style.GetTextEmphasisMark() != TextEmphasisMark::kNone) { - LayoutUnit emphasis_mark_height = - LayoutUnit(font.EmphasisMarkHeight(style.TextEmphasisMarkString())); - DCHECK_GT(emphasis_mark_height, LayoutUnit()); - if (style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver) { - visual_rect.ShiftYEdgeTo( - std::min(visual_rect.Y(), -emphasis_mark_height)); - } else { - LayoutUnit logical_height = - style.IsHorizontalWritingMode() ? Size().height : Size().width; - visual_rect.ShiftMaxYEdgeTo( - std::max(visual_rect.MaxY(), logical_height + emphasis_mark_height)); - } - } + // TODO(kojii): Implement emphasis marks. if (ShadowList* text_shadow = style.TextShadow()) { - LayoutRectOutsets text_shadow_logical_outsets = - LayoutRectOutsets(text_shadow->RectOutsetsIncludingOriginal()) - .LineOrientationOutsets(style.GetWritingMode()); - text_shadow_logical_outsets.ClampNegativeToZero(); - visual_rect.Expand(text_shadow_logical_outsets); + // TODO(kojii): Implement text shadow. } - visual_rect = LayoutRect(EnclosingIntRect(visual_rect)); - + LayoutRect visual_rect = EnclosingLayoutRect(visual_float_rect); switch (LineOrientation()) { case NGLineOrientation::kHorizontal: return NGPhysicalOffsetRect(visual_rect);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index dbfac9ad..9e8b81a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -275,20 +275,53 @@ inline_container_fragments->at(key); if (!value.start_fragment) { value.start_fragment = descendant.fragment; - value.start_fragment_offset = descendant.offset_to_container_box; + value.start_fragment_union_rect.offset = + descendant.offset_to_container_box; + value.start_fragment_union_rect = + NGPhysicalOffsetRect(descendant.offset_to_container_box, + value.start_fragment->Size()); value.start_linebox_fragment = linebox; value.start_linebox_offset = offsets_.at(i); } - value.end_fragment = descendant.fragment; - value.end_fragment_offset = descendant.offset_to_container_box; - value.end_linebox_fragment = linebox; - value.end_linebox_offset = offsets_.at(i); + if (!value.end_fragment || value.end_linebox_fragment != linebox) { + value.end_fragment = descendant.fragment; + value.end_fragment_union_rect = NGPhysicalOffsetRect( + descendant.offset_to_container_box, value.end_fragment->Size()); + value.end_linebox_fragment = linebox; + value.end_linebox_offset = offsets_.at(i); + } + // Extend the union size + if (value.start_linebox_fragment == linebox) { + // std::max because initial box might have larger extent than its + // descendants. + value.start_fragment_union_rect.size.width = + std::max(descendant.offset_to_container_box.left + + descendant.fragment->Size().width - + value.start_fragment_union_rect.offset.left, + value.start_fragment_union_rect.size.width); + value.start_fragment_union_rect.size.height = + std::max(descendant.offset_to_container_box.top + + descendant.fragment->Size().height - + value.start_fragment_union_rect.offset.top, + value.start_fragment_union_rect.size.width); + } + if (value.end_linebox_fragment == linebox) { + value.end_fragment_union_rect.size.width = + std::max(descendant.offset_to_container_box.left + + descendant.fragment->Size().width - + value.start_fragment_union_rect.offset.left, + value.end_fragment_union_rect.size.width); + value.end_fragment_union_rect.size.height = + std::max(descendant.offset_to_container_box.top + + descendant.fragment->Size().height - + value.start_fragment_union_rect.offset.top, + value.end_fragment_union_rect.size.height); + } inline_container_fragments->Set(key, value); } } } } - // TODO(atotic) need to implement correct RTL handling. } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h index ff57900a8..d386a684 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -6,6 +6,7 @@ #define NGFragmentBuilder_h #include "core/layout/ng/geometry/ng_border_edges.h" +#include "core/layout/ng/geometry/ng_physical_offset_rect.h" #include "core/layout/ng/geometry/ng_physical_rect.h" #include "core/layout/ng/inline/ng_baseline.h" #include "core/layout/ng/ng_break_token.h" @@ -14,7 +15,6 @@ #include "core/layout/ng/ng_out_of_flow_positioned_descendant.h" #include "platform/heap/Handle.h" #include "platform/wtf/Allocator.h" - namespace blink { class NGPhysicalFragment; @@ -111,21 +111,22 @@ // Inline containing block geometry is defined by two fragments: // start and end. FragmentPair holds the information needed to compute // inline containing block geometry wrt enclosing container block. - // - // start_fragment is the start fragment of inline containing block. - // start_fragment_offset is offset wrt start_linebox_fragment - // start_linebox_offset is offset of linebox from inline-cb - // end_fragment/linebox are complementary properties for end fragment. struct FragmentPair { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + // Linebox that contains start_fragment. const NGPhysicalLineBoxFragment* start_linebox_fragment; + // Offset of start_linebox from containing block. NGLogicalOffset start_linebox_offset; + // Start fragment of inline containing block. const NGPhysicalFragment* start_fragment; - NGPhysicalOffset start_fragment_offset; + // Start fragment rect combined with rectangles of all fragments + // generated by same Element as start_fragment. + NGPhysicalOffsetRect start_fragment_union_rect; + // end_** variables are end fragment counterparts to start fragment. const NGPhysicalLineBoxFragment* end_linebox_fragment; NGLogicalOffset end_linebox_offset; const NGPhysicalFragment* end_fragment; - NGPhysicalOffset end_fragment_offset; + NGPhysicalOffsetRect end_fragment_union_rect; }; void ComputeInlineContainerFragments(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc index 79b80a6..8d5a538 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -164,9 +164,10 @@ default_containing_block_.style->Direction(); // Step 1 NGLogicalOffset start_fragment_logical_offset = - block_info.value.start_fragment_offset.ConvertToLogical( + block_info.value.start_fragment_union_rect.offset.ConvertToLogical( container_writing_mode, container_direction, - start_linebox_fragment->Size(), start_fragment->Size()); + start_linebox_fragment->Size(), + block_info.value.start_fragment_union_rect.size); // Text fragments do not include inline-cb borders and padding. if (start_fragment->IsText()) { start_fragment_logical_offset -= inline_cb_borders.StartOffset(); @@ -186,9 +187,10 @@ block_info.value.end_linebox_fragment; const NGPhysicalFragment* end_fragment = block_info.value.end_fragment; NGLogicalOffset end_fragment_logical_offset = - block_info.value.end_fragment_offset.ConvertToLogical( + block_info.value.end_fragment_union_rect.offset.ConvertToLogical( container_writing_mode, container_direction, - end_linebox_fragment->Size(), end_fragment->Size()); + end_linebox_fragment->Size(), + block_info.value.end_fragment_union_rect.size); // Text fragments do not include inline-cb borders and padding. if (end_fragment->IsText()) { end_fragment_logical_offset += NGLogicalOffset( @@ -198,7 +200,8 @@ } NGLogicalOffset end_fragment_bottom_right = end_fragment_logical_offset + - end_fragment->Size().ConvertToLogical(container_writing_mode); + block_info.value.end_fragment_union_rect.size.ConvertToLogical( + container_writing_mode); NGPhysicalOffset end_fragment_physical_offset = end_fragment_bottom_right.ConvertToPhysical( container_writing_mode, container_direction, @@ -249,8 +252,9 @@ NGLogicalOffset default_container_offset; if (RuntimeEnabledFeatures::LayoutNGPaintFragmentsEnabled()) { // NGPaint offset is wrt parent fragment. - default_container_offset = start_fragment_logical_offset - + default_container_offset = start_fragment_logical_offset_wrt_box - default_containing_block_.content_offset; + default_container_offset += inline_cb_borders.StartOffset(); } else { // Legacy offset is wrt inline container. default_container_offset =
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h index aecc67dbd..e30cde11 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -57,7 +57,8 @@ NGLogicalOffset content_offset; // Physical content offset wrt border box. NGPhysicalOffset content_physical_offset; - // Logical offset wrt default containing block. + // Logical offset of container padding box + // wrt default containing block padding box. NGLogicalOffset default_container_offset; };
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 28c47d91..3b563d7e 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1359,26 +1359,6 @@ return g_null_atom; } -LineLogicalSide ComputedStyle::GetTextEmphasisLineLogicalSide() const { - TextEmphasisPosition position = GetTextEmphasisPosition(); - if (IsHorizontalWritingMode()) { - return position == TextEmphasisPosition::kOverRight || - position == TextEmphasisPosition::kOverLeft - ? LineLogicalSide::kOver - : LineLogicalSide::kUnder; - } - if (GetWritingMode() != WritingMode::kSidewaysLr) { - return position == TextEmphasisPosition::kOverRight || - position == TextEmphasisPosition::kUnderRight - ? LineLogicalSide::kOver - : LineLogicalSide::kUnder; - } - return position == TextEmphasisPosition::kOverLeft || - position == TextEmphasisPosition::kUnderLeft - ? LineLogicalSide::kOver - : LineLogicalSide::kUnder; -} - CSSAnimationData& ComputedStyle::AccessAnimations() { if (!AnimationsInternal()) SetAnimationsInternal(CSSAnimationData::Create());
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index 900753764..397c0252 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -876,7 +876,6 @@ SetTextEmphasisMarkInternal(mark); } const AtomicString& TextEmphasisMarkString() const; - LineLogicalSide GetTextEmphasisLineLogicalSide() const; // -webkit-text-emphasis-color (aka -epub-text-emphasis-color) void SetTextEmphasisColor(const StyleColor& color) {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h index 262126d..6473388 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h +++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -253,11 +253,6 @@ kUnderLeft, }; -enum class LineLogicalSide { - kOver, - kUnder, -}; - } // namespace blink #endif // ComputedStyleConstants_h
diff --git a/third_party/WebKit/public/platform/web_feature.mojom b/third_party/WebKit/public/platform/web_feature.mojom index a4d7f0e..38dd4dd 100644 --- a/third_party/WebKit/public/platform/web_feature.mojom +++ b/third_party/WebKit/public/platform/web_feature.mojom
@@ -1783,6 +1783,7 @@ kFileAccessedSessionStorage = 2274, kFileAccessedSharedWorker = 2275, kV8MediaKeys_GetStatusForPolicy_Method = 2276, + kV8DeoptimizerDisableSpeculation = 2277, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn index 7c938eb..8a4f25213 100644 --- a/third_party/webrtc_overrides/BUILD.gn +++ b/third_party/webrtc_overrides/BUILD.gn
@@ -121,11 +121,11 @@ ":webrtc", "//third_party/libsrtp", "//third_party/usrsctp", - "//third_party/webrtc/api:libjingle_peerconnection", "//third_party/webrtc/media:rtc_media", "//third_party/webrtc/media:rtc_media_base", "//third_party/webrtc/modules/media_file", "//third_party/webrtc/modules/video_capture", + "//third_party/webrtc/pc:libjingle_peerconnection", "//third_party/webrtc/pc:rtc_pc", "//third_party/webrtc/system_wrappers", "//third_party/webrtc/voice_engine",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 6a88bbe..7c219c5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -17280,6 +17280,7 @@ <int value="2274" label="FileAccessedSessionStorage"/> <int value="2275" label="FileAccessedSharedWorker"/> <int value="2276" label="V8MediaKeys_GetStatusForPolicy_Method"/> + <int value="2277" label="V8DeoptimizerDisableSpeculation"/> </enum> <enum name="FeedbackSource">
diff --git a/ui/message_center/views/toast_contents_view.cc b/ui/message_center/views/toast_contents_view.cc index e3d5604..1517157 100644 --- a/ui/message_center/views/toast_contents_view.cc +++ b/ui/message_center/views/toast_contents_view.cc
@@ -191,9 +191,15 @@ collection_->IncrementDeferCounter(); fade_animation_->Stop(); - closing_animation_ = (is_closing_ ? fade_animation_.get() : NULL); - fade_animation_->Reset(1); - fade_animation_->Hide(); + closing_animation_ = (is_closing_ ? fade_animation_.get() : nullptr); + if (GetWidget()->GetLayer()->opacity() > 0.0) { + fade_animation_->Reset(1); + fade_animation_->Hide(); + } else { + // If the layer is already transparent, do not trigger animation again. + // It happens when the toast is removed by touch gesture. + OnBoundsAnimationEndedOrCancelled(fade_animation_.get()); + } } void ToastContentsView::OnBoundsAnimationEndedOrCancelled(