Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: cc/trees/layer_tree_host_unittest_animation.cc

Issue 1122393003: CC: Plumb LayerSettings parameter for cc::Layer construction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | cc/trees/layer_tree_host_unittest_context.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host.h" 5 #include "cc/trees/layer_tree_host.h"
6 6
7 #include "cc/animation/animation_curve.h" 7 #include "cc/animation/animation_curve.h"
8 #include "cc/animation/layer_animation_controller.h" 8 #include "cc/animation/layer_animation_controller.h"
9 #include "cc/animation/scroll_offset_animation_curve.h" 9 #include "cc/animation/scroll_offset_animation_curve.h"
10 #include "cc/animation/timing_function.h" 10 #include "cc/animation/timing_function.h"
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); 224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
225 225
226 // Ensure that an animation's timing function is respected. 226 // Ensure that an animation's timing function is respected.
227 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction 227 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
228 : public LayerTreeHostAnimationTest { 228 : public LayerTreeHostAnimationTest {
229 public: 229 public:
230 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} 230 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
231 231
232 void SetupTree() override { 232 void SetupTree() override {
233 LayerTreeHostAnimationTest::SetupTree(); 233 LayerTreeHostAnimationTest::SetupTree();
234 content_ = FakeContentLayer::Create(&client_); 234 content_ = FakeContentLayer::Create(layer_settings(), &client_);
235 content_->SetBounds(gfx::Size(4, 4)); 235 content_->SetBounds(gfx::Size(4, 4));
236 layer_tree_host()->root_layer()->AddChild(content_); 236 layer_tree_host()->root_layer()->AddChild(content_);
237 } 237 }
238 238
239 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } 239 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
240 240
241 void AnimateLayers(LayerTreeHostImpl* host_impl, 241 void AnimateLayers(LayerTreeHostImpl* host_impl,
242 base::TimeTicks monotonic_time) override { 242 base::TimeTicks monotonic_time) override {
243 LayerAnimationController* controller_impl = 243 LayerAnimationController* controller_impl =
244 host_impl->active_tree()->root_layer()->children()[0]-> 244 host_impl->active_tree()->root_layer()->children()[0]->
(...skipping 28 matching lines...) Expand all
273 273
274 // Ensures that main thread animations have their start times synchronized with 274 // Ensures that main thread animations have their start times synchronized with
275 // impl thread animations. 275 // impl thread animations.
276 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 276 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
277 : public LayerTreeHostAnimationTest { 277 : public LayerTreeHostAnimationTest {
278 public: 278 public:
279 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {} 279 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
280 280
281 void SetupTree() override { 281 void SetupTree() override {
282 LayerTreeHostAnimationTest::SetupTree(); 282 LayerTreeHostAnimationTest::SetupTree();
283 content_ = FakeContentLayer::Create(&client_); 283 content_ = FakeContentLayer::Create(layer_settings(), &client_);
284 content_->SetBounds(gfx::Size(4, 4)); 284 content_->SetBounds(gfx::Size(4, 4));
285 content_->set_layer_animation_delegate(this); 285 content_->set_layer_animation_delegate(this);
286 layer_tree_host()->root_layer()->AddChild(content_); 286 layer_tree_host()->root_layer()->AddChild(content_);
287 } 287 }
288 288
289 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } 289 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
290 290
291 void NotifyAnimationStarted(base::TimeTicks monotonic_time, 291 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
292 Animation::TargetProperty target_property, 292 Animation::TargetProperty target_property,
293 int group) override { 293 int group) override {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 353
354 SINGLE_AND_MULTI_THREAD_TEST_F( 354 SINGLE_AND_MULTI_THREAD_TEST_F(
355 LayerTreeHostAnimationTestAnimationFinishedEvents); 355 LayerTreeHostAnimationTestAnimationFinishedEvents);
356 356
357 // Ensures that when opacity is being animated, this value does not cause the 357 // Ensures that when opacity is being animated, this value does not cause the
358 // subtree to be skipped. 358 // subtree to be skipped.
359 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 359 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
360 : public LayerTreeHostAnimationTest { 360 : public LayerTreeHostAnimationTest {
361 public: 361 public:
362 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() 362 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
363 : update_check_layer_(FakeContentLayer::Create(&client_)) { 363 : update_check_layer_(
364 } 364 FakeContentLayer::Create(layer_settings(), &client_)) {}
365 365
366 void SetupTree() override { 366 void SetupTree() override {
367 update_check_layer_->SetOpacity(0.f); 367 update_check_layer_->SetOpacity(0.f);
368 layer_tree_host()->SetRootLayer(update_check_layer_); 368 layer_tree_host()->SetRootLayer(update_check_layer_);
369 LayerTreeHostAnimationTest::SetupTree(); 369 LayerTreeHostAnimationTest::SetupTree();
370 } 370 }
371 371
372 void BeginTest() override { 372 void BeginTest() override {
373 PostAddAnimationToMainThread(update_check_layer_.get()); 373 PostAddAnimationToMainThread(update_check_layer_.get());
374 } 374 }
(...skipping 28 matching lines...) Expand all
403 // animation correctly recognized. 403 // animation correctly recognized.
404 class LayerTreeHostAnimationTestLayerAddedWithAnimation 404 class LayerTreeHostAnimationTestLayerAddedWithAnimation
405 : public LayerTreeHostAnimationTest { 405 : public LayerTreeHostAnimationTest {
406 public: 406 public:
407 LayerTreeHostAnimationTestLayerAddedWithAnimation() {} 407 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
408 408
409 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 409 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
410 410
411 void DidCommit() override { 411 void DidCommit() override {
412 if (layer_tree_host()->source_frame_number() == 1) { 412 if (layer_tree_host()->source_frame_number() == 1) {
413 scoped_refptr<Layer> layer = Layer::Create(); 413 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
414 layer->set_layer_animation_delegate(this); 414 layer->set_layer_animation_delegate(this);
415 415
416 // Any valid AnimationCurve will do here. 416 // Any valid AnimationCurve will do here.
417 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); 417 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
418 scoped_ptr<Animation> animation( 418 scoped_ptr<Animation> animation(
419 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY)); 419 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
420 layer->layer_animation_controller()->AddAnimation(animation.Pass()); 420 layer->layer_animation_controller()->AddAnimation(animation.Pass());
421 421
422 // We add the animation *before* attaching the layer to the tree. 422 // We add the animation *before* attaching the layer to the tree.
423 layer_tree_host()->root_layer()->AddChild(layer); 423 layer_tree_host()->root_layer()->AddChild(layer);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 551
552 // Make sure the main thread can still execute animations when CanDraw() is not 552 // Make sure the main thread can still execute animations when CanDraw() is not
553 // true. 553 // true.
554 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw 554 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
555 : public LayerTreeHostAnimationTest { 555 : public LayerTreeHostAnimationTest {
556 public: 556 public:
557 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} 557 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
558 558
559 void SetupTree() override { 559 void SetupTree() override {
560 LayerTreeHostAnimationTest::SetupTree(); 560 LayerTreeHostAnimationTest::SetupTree();
561 content_ = FakeContentLayer::Create(&client_); 561 content_ = FakeContentLayer::Create(layer_settings(), &client_);
562 content_->SetBounds(gfx::Size(4, 4)); 562 content_->SetBounds(gfx::Size(4, 4));
563 content_->set_layer_animation_delegate(this); 563 content_->set_layer_animation_delegate(this);
564 layer_tree_host()->root_layer()->AddChild(content_); 564 layer_tree_host()->root_layer()->AddChild(content_);
565 } 565 }
566 566
567 void BeginTest() override { 567 void BeginTest() override {
568 layer_tree_host()->SetViewportSize(gfx::Size()); 568 layer_tree_host()->SetViewportSize(gfx::Size());
569 PostAddAnimationToMainThread(content_.get()); 569 PostAddAnimationToMainThread(content_.get());
570 } 570 }
571 571
(...skipping 19 matching lines...) Expand all
591 591
592 SINGLE_AND_MULTI_THREAD_TEST_F( 592 SINGLE_AND_MULTI_THREAD_TEST_F(
593 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw); 593 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
594 594
595 // Animations should not be started when frames are being skipped due to 595 // Animations should not be started when frames are being skipped due to
596 // checkerboard. 596 // checkerboard.
597 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations 597 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
598 : public LayerTreeHostAnimationTest { 598 : public LayerTreeHostAnimationTest {
599 void SetupTree() override { 599 void SetupTree() override {
600 LayerTreeHostAnimationTest::SetupTree(); 600 LayerTreeHostAnimationTest::SetupTree();
601 content_ = FakeContentLayer::Create(&client_); 601 content_ = FakeContentLayer::Create(layer_settings(), &client_);
602 content_->SetBounds(gfx::Size(4, 4)); 602 content_->SetBounds(gfx::Size(4, 4));
603 content_->set_layer_animation_delegate(this); 603 content_->set_layer_animation_delegate(this);
604 layer_tree_host()->root_layer()->AddChild(content_); 604 layer_tree_host()->root_layer()->AddChild(content_);
605 } 605 }
606 606
607 void InitializeSettings(LayerTreeSettings* settings) override { 607 void InitializeSettings(LayerTreeSettings* settings) override {
608 // Make sure that drawing many times doesn't cause a checkerboarded 608 // Make sure that drawing many times doesn't cause a checkerboarded
609 // animation to start so we avoid flake in this test. 609 // animation to start so we avoid flake in this test.
610 settings->timeout_and_draw_when_animation_checkerboards = false; 610 settings->timeout_and_draw_when_animation_checkerboards = false;
611 } 611 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 // is supported, and that when scroll offset animations are accepted, 677 // is supported, and that when scroll offset animations are accepted,
678 // scroll offset updates are sent back to the main thread. 678 // scroll offset updates are sent back to the main thread.
679 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated 679 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
680 : public LayerTreeHostAnimationTest { 680 : public LayerTreeHostAnimationTest {
681 public: 681 public:
682 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} 682 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
683 683
684 void SetupTree() override { 684 void SetupTree() override {
685 LayerTreeHostAnimationTest::SetupTree(); 685 LayerTreeHostAnimationTest::SetupTree();
686 686
687 scroll_layer_ = FakeContentLayer::Create(&client_); 687 scroll_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
688 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); 688 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
689 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); 689 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
690 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); 690 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
691 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 691 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
692 } 692 }
693 693
694 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 694 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
695 695
696 void DidCommit() override { 696 void DidCommit() override {
697 switch (layer_tree_host()->source_frame_number()) { 697 switch (layer_tree_host()->source_frame_number()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 // delta. 734 // delta.
735 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval 735 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
736 : public LayerTreeHostAnimationTest { 736 : public LayerTreeHostAnimationTest {
737 public: 737 public:
738 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval() 738 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
739 : final_postion_(50.0, 100.0) {} 739 : final_postion_(50.0, 100.0) {}
740 740
741 void SetupTree() override { 741 void SetupTree() override {
742 LayerTreeHostAnimationTest::SetupTree(); 742 LayerTreeHostAnimationTest::SetupTree();
743 743
744 scroll_layer_ = FakeContentLayer::Create(&client_); 744 scroll_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
745 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); 745 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
746 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 746 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
747 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); 747 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
748 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 748 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
749 749
750 scoped_ptr<ScrollOffsetAnimationCurve> curve( 750 scoped_ptr<ScrollOffsetAnimationCurve> curve(
751 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f), 751 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
752 EaseInOutTimingFunction::Create())); 752 EaseInOutTimingFunction::Create()));
753 scoped_ptr<Animation> animation( 753 scoped_ptr<Animation> animation(
754 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET)); 754 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 853
854 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 854 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
855 855
856 void DidCommit() override { 856 void DidCommit() override {
857 if (layer_tree_host()->source_frame_number() == 1) { 857 if (layer_tree_host()->source_frame_number() == 1) {
858 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1); 858 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
859 } else if (layer_tree_host()->source_frame_number() == 2) { 859 } else if (layer_tree_host()->source_frame_number() == 2) {
860 AddOpacityTransitionToLayer( 860 AddOpacityTransitionToLayer(
861 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true); 861 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
862 862
863 scoped_refptr<Layer> layer = Layer::Create(); 863 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
864 layer_tree_host()->root_layer()->AddChild(layer); 864 layer_tree_host()->root_layer()->AddChild(layer);
865 layer->set_layer_animation_delegate(this); 865 layer->set_layer_animation_delegate(this);
866 layer->SetBounds(gfx::Size(4, 4)); 866 layer->SetBounds(gfx::Size(4, 4));
867 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true); 867 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
868 } 868 }
869 } 869 }
870 870
871 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { 871 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
872 if (host_impl->settings().impl_side_painting) 872 if (host_impl->settings().impl_side_painting)
873 host_impl->BlockNotifyReadyToActivateForTesting(true); 873 host_impl->BlockNotifyReadyToActivateForTesting(true);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 930
931 // When a layer with an animation is removed from the tree and later re-added, 931 // When a layer with an animation is removed from the tree and later re-added,
932 // the animation should resume. 932 // the animation should resume.
933 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded 933 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
934 : public LayerTreeHostAnimationTest { 934 : public LayerTreeHostAnimationTest {
935 public: 935 public:
936 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {} 936 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
937 937
938 void SetupTree() override { 938 void SetupTree() override {
939 LayerTreeHostAnimationTest::SetupTree(); 939 LayerTreeHostAnimationTest::SetupTree();
940 content_ = Layer::Create(); 940 content_ = Layer::Create(layer_settings());
941 content_->SetBounds(gfx::Size(4, 4)); 941 content_->SetBounds(gfx::Size(4, 4));
942 layer_tree_host()->root_layer()->AddChild(content_); 942 layer_tree_host()->root_layer()->AddChild(content_);
943 AddOpacityTransitionToLayer(content_.get(), 10000.0, 0.1f, 0.9f, true); 943 AddOpacityTransitionToLayer(content_.get(), 10000.0, 0.1f, 0.9f, true);
944 } 944 }
945 945
946 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 946 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
947 947
948 void DidCommit() override { 948 void DidCommit() override {
949 switch (layer_tree_host()->source_frame_number()) { 949 switch (layer_tree_host()->source_frame_number()) {
950 case 1: 950 case 1:
(...skipping 30 matching lines...) Expand all
981 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded); 981 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
982 982
983 class LayerTreeHostAnimationTestAddAnimationAfterAnimating 983 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
984 : public LayerTreeHostAnimationTest { 984 : public LayerTreeHostAnimationTest {
985 public: 985 public:
986 LayerTreeHostAnimationTestAddAnimationAfterAnimating() 986 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
987 : num_swap_buffers_(0) {} 987 : num_swap_buffers_(0) {}
988 988
989 void SetupTree() override { 989 void SetupTree() override {
990 LayerTreeHostAnimationTest::SetupTree(); 990 LayerTreeHostAnimationTest::SetupTree();
991 content_ = Layer::Create(); 991 content_ = Layer::Create(layer_settings());
992 content_->SetBounds(gfx::Size(4, 4)); 992 content_->SetBounds(gfx::Size(4, 4));
993 layer_tree_host()->root_layer()->AddChild(content_); 993 layer_tree_host()->root_layer()->AddChild(content_);
994 } 994 }
995 995
996 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 996 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
997 997
998 void DidCommit() override { 998 void DidCommit() override {
999 switch (layer_tree_host()->source_frame_number()) { 999 switch (layer_tree_host()->source_frame_number()) {
1000 case 1: 1000 case 1:
1001 // First frame: add an animation to the root layer. 1001 // First frame: add an animation to the root layer.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 private: 1037 private:
1038 scoped_refptr<Layer> content_; 1038 scoped_refptr<Layer> content_;
1039 int num_swap_buffers_; 1039 int num_swap_buffers_;
1040 }; 1040 };
1041 1041
1042 SINGLE_AND_MULTI_THREAD_TEST_F( 1042 SINGLE_AND_MULTI_THREAD_TEST_F(
1043 LayerTreeHostAnimationTestAddAnimationAfterAnimating); 1043 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1044 1044
1045 } // namespace 1045 } // namespace
1046 } // namespace cc 1046 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | cc/trees/layer_tree_host_unittest_context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698