Merge pull request #1059 from vlidholt/master
Improvements to demo game
diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart
index 1983cde..28708fc 100644
--- a/examples/widgets/card_collection.dart
+++ b/examples/widgets/card_collection.dart
@@ -23,8 +23,12 @@
final TextStyle backgroundTextStyle =
typography.white.title.copyWith(textAlign: TextAlign.center);
- MixedViewportLayoutState layoutState = new MixedViewportLayoutState();
- List<CardModel> cardModels;
+ MixedViewportLayoutState _layoutState = new MixedViewportLayoutState();
+ List<CardModel> _cardModels;
+ DismissDirection _dismissDirection = DismissDirection.horizontal;
+ bool _drawerShowing = false;
+ AnimationStatus _drawerStatus = AnimationStatus.dismissed;
+
void initState() {
List<double> cardHeights = <double>[
@@ -32,7 +36,7 @@
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
];
- cardModels = new List.generate(cardHeights.length, (i) {
+ _cardModels = new List.generate(cardHeights.length, (i) {
Color color = Color.lerp(colors.Red[300], colors.Blue[900], i / cardHeights.length);
return new CardModel(i, cardHeights[i], color);
});
@@ -40,20 +44,91 @@
}
void dismissCard(CardModel card) {
- if (cardModels.contains(card)) {
+ if (_cardModels.contains(card)) {
setState(() {
- cardModels.remove(card);
+ _cardModels.remove(card);
});
}
}
- Widget builder(int index) {
- if (index >= cardModels.length)
+ void _handleOpenDrawer() {
+ setState(() {
+ _drawerShowing = true;
+ _drawerStatus = AnimationStatus.forward;
+ });
+ }
+
+ void _handleDrawerDismissed() {
+ setState(() {
+ _drawerStatus = AnimationStatus.dismissed;
+ });
+ }
+
+ String dismissDirectionText(DismissDirection direction) {
+ String s = direction.toString();
+ return "dismiss ${s.substring(s.indexOf('.') + 1)}";
+ }
+
+ void changeDismissDirection(DismissDirection newDismissDirection) {
+ setState(() {
+ _dismissDirection = newDismissDirection;
+ _drawerStatus = AnimationStatus.dismissed;
+ });
+ }
+
+ Widget buildDrawer() {
+ if (_drawerStatus == AnimationStatus.dismissed)
return null;
- CardModel cardModel = cardModels[index];
+ Widget buildDrawerItem(DismissDirection direction, String icon) {
+ return new DrawerItem(
+ icon: icon,
+ onPressed: () { changeDismissDirection(direction); },
+ child: new Row([
+ new Flexible(child: new Text(dismissDirectionText(direction))),
+ new Radio(
+ value: direction,
+ onChanged: changeDismissDirection,
+ groupValue: _dismissDirection
+ )
+ ])
+ );
+ }
+
+ return new IconTheme(
+ data: const IconThemeData(color: IconThemeColor.black),
+ child: new Drawer(
+ level: 3,
+ showing: _drawerShowing,
+ onDismissed: _handleDrawerDismissed,
+ children: [
+ new DrawerHeader(child: new Text('Dismiss Direction')),
+ buildDrawerItem(DismissDirection.horizontal, 'action/code'),
+ buildDrawerItem(DismissDirection.left, 'navigation/arrow_back'),
+ buildDrawerItem(DismissDirection.right, 'navigation/arrow_forward')
+ ]
+ )
+ );
+ }
+
+ Widget buildToolBar() {
+ return new ToolBar(
+ left: new IconButton(icon: "navigation/menu", onPressed: _handleOpenDrawer),
+ center: new Text('Swipe Away'),
+ right: [
+ new Text(dismissDirectionText(_dismissDirection))
+ ]
+ );
+ }
+
+ Widget buildCard(int index) {
+ if (index >= _cardModels.length)
+ return null;
+
+ CardModel cardModel = _cardModels[index];
Widget card = new Dismissable(
- onResized: () { layoutState.invalidate([index]); },
+ direction: _dismissDirection,
+ onResized: () { _layoutState.invalidate([index]); },
onDismissed: () { dismissCard(cardModel); },
child: new Card(
color: cardModel.color,
@@ -65,8 +140,28 @@
)
);
- Widget backgroundText =
- new Text("Swipe in either direction", style: backgroundTextStyle);
+ String backgroundMessage;
+ switch(_dismissDirection) {
+ case DismissDirection.horizontal:
+ backgroundMessage = "Swipe in either direction";
+ break;
+ case DismissDirection.left:
+ backgroundMessage = "Swipe left to dismiss";
+ break;
+ case DismissDirection.right:
+ backgroundMessage = "Swipe right to dismiss";
+ break;
+ default:
+ backgroundMessage = "Unsupported dismissDirection";
+ }
+
+ Widget leftArrowIcon = new Icon(type: 'navigation/arrow_back', size: 36);
+ if (_dismissDirection == DismissDirection.right)
+ leftArrowIcon = new Opacity(opacity: 0.1, child: leftArrowIcon);
+
+ Widget rightArrowIcon = new Icon(type: 'navigation/arrow_forward', size: 36);
+ if (_dismissDirection == DismissDirection.left)
+ rightArrowIcon = new Opacity(opacity: 0.1, child: rightArrowIcon);
// The background Widget appears behind the Dismissable card when the card
// moves to the left or right. The Positioned widget ensures that the
@@ -85,16 +180,20 @@
height: cardModel.height,
decoration: new BoxDecoration(backgroundColor: Theme.of(this).primaryColor),
child: new Row([
- new Icon(type: 'navigation/arrow_back', size: 36),
- new Flexible(child: backgroundText),
- new Icon(type: 'navigation/arrow_forward', size: 36)
+ leftArrowIcon,
+ new Flexible(child: new Text(backgroundMessage, style: backgroundTextStyle)),
+ rightArrowIcon
])
)
)
)
);
- return new Stack([background, card], key: cardModel.key);
+ return new IconTheme(
+ key: cardModel.key,
+ data: const IconThemeData(color: IconThemeColor.white),
+ child: new Stack([background, card])
+ );
}
Widget build() {
@@ -102,26 +201,24 @@
padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
decoration: new BoxDecoration(backgroundColor: Theme.of(this).primarySwatch[50]),
child: new ScrollableMixedWidgetList(
- builder: builder,
- token: cardModels.length,
- layoutState: layoutState
+ builder: buildCard,
+ token: _cardModels.length,
+ layoutState: _layoutState
)
);
- return new IconTheme(
- data: const IconThemeData(color: IconThemeColor.white),
- child: new Theme(
- data: new ThemeData(
- brightness: ThemeBrightness.light,
- primarySwatch: colors.Blue,
- accentColor: colors.RedAccent[200]
- ),
- child: new Title(
- title: 'Cards',
- child: new Scaffold(
- toolbar: new ToolBar(center: new Text('Swipe Away')),
- body: cardCollection
- )
+ return new Theme(
+ data: new ThemeData(
+ brightness: ThemeBrightness.light,
+ primarySwatch: colors.Blue,
+ accentColor: colors.RedAccent[200]
+ ),
+ child: new Title(
+ title: 'Cards',
+ child: new Scaffold(
+ toolbar: buildToolBar(),
+ drawer: buildDrawer(),
+ body: cardCollection
)
)
);
diff --git a/services/sky/document_view.cc b/services/sky/document_view.cc
index 8ce55d3..8632184 100644
--- a/services/sky/document_view.cc
+++ b/services/sky/document_view.cc
@@ -209,7 +209,9 @@
void DocumentView::BeginFrame(base::TimeTicks frame_time) {
if (sky_view_) {
- sky_view_->BeginFrame(frame_time);
+ std::unique_ptr<LayerTree> layer_tree = sky_view_->BeginFrame(frame_time);
+ if (layer_tree)
+ current_layer_tree_ = std::move(layer_tree);
root_layer_->SetSize(sky_view_->display_metrics().physical_size);
}
}
@@ -220,13 +222,8 @@
}
void DocumentView::PaintContents(SkCanvas* canvas, const gfx::Rect& clip) {
- blink::WebRect rect(clip.x(), clip.y(), clip.width(), clip.height());
-
- if (sky_view_) {
- RefPtr<SkPicture> picture = sky_view_->Paint();
- if (picture)
- canvas->drawPicture(picture.get());
- }
+ if (current_layer_tree_)
+ current_layer_tree_->root_layer()->Paint(canvas);
}
float DocumentView::GetDevicePixelRatio() const {
diff --git a/services/sky/document_view.h b/services/sky/document_view.h
index e67faa9..4d7e7e2 100644
--- a/services/sky/document_view.h
+++ b/services/sky/document_view.h
@@ -22,6 +22,7 @@
#include "mojo/services/view_manager/public/cpp/view_observer.h"
#include "services/sky/compositor/layer_client.h"
#include "services/sky/compositor/layer_host_client.h"
+#include "sky/compositor/layer_tree.h"
#include "sky/engine/public/platform/ServiceProvider.h"
#include "sky/engine/public/sky/sky_view.h"
#include "sky/engine/public/sky/sky_view_client.h"
@@ -128,6 +129,7 @@
scoped_ptr<DartLibraryProviderImpl> library_provider_;
scoped_ptr<LayerHost> layer_host_;
scoped_refptr<TextureLayer> root_layer_;
+ std::unique_ptr<LayerTree> current_layer_tree_; // TODO(abarth): Integrate //sky/compositor and //services/sky/compositor.
RasterizerBitmap* bitmap_rasterizer_; // Used for pixel tests.
mojo::ServiceRegistryPtr service_registry_;
scoped_ptr<mojo::StrongBinding<mojo::ServiceProvider>>
diff --git a/sky/compositor/BUILD.gn b/sky/compositor/BUILD.gn
index ffce6c0..c9aeb72 100644
--- a/sky/compositor/BUILD.gn
+++ b/sky/compositor/BUILD.gn
@@ -4,6 +4,8 @@
source_set("compositor") {
sources = [
+ "layer_tree.cc",
+ "layer_tree.h",
"layer.cc",
"layer.h",
]
diff --git a/sky/compositor/layer.h b/sky/compositor/layer.h
index 6dcd36e..60b3ded 100644
--- a/sky/compositor/layer.h
+++ b/sky/compositor/layer.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SKY_COMPOSITOR_H_
-#define SKY_COMPOSITOR_H_
+#ifndef SKY_COMPOSITOR_LAYER_H_
+#define SKY_COMPOSITOR_LAYER_H_
#include <memory>
#include <vector>
@@ -170,4 +170,4 @@
} // namespace sky
-#endif // SKY_COMPOSITOR_H_
+#endif // SKY_COMPOSITOR_LAYER_H_
diff --git a/sky/compositor/layer_tree.cc b/sky/compositor/layer_tree.cc
new file mode 100644
index 0000000..4f1f574
--- /dev/null
+++ b/sky/compositor/layer_tree.cc
@@ -0,0 +1,17 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sky/compositor/layer_tree.h"
+
+#include "sky/compositor/layer.h"
+
+namespace sky {
+
+LayerTree::LayerTree() {
+}
+
+LayerTree::~LayerTree() {
+}
+
+} // namespace sky
diff --git a/sky/compositor/layer_tree.h b/sky/compositor/layer_tree.h
new file mode 100644
index 0000000..f3bde5a
--- /dev/null
+++ b/sky/compositor/layer_tree.h
@@ -0,0 +1,38 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SKY_COMPOSITOR_LAYER_TREE_H_
+#define SKY_COMPOSITOR_LAYER_TREE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "sky/compositor/layer.h"
+#include "third_party/skia/include/core/SkSize.h"
+
+namespace sky {
+
+class LayerTree {
+ public:
+ LayerTree();
+ ~LayerTree();
+
+ Layer* root_layer() const { return root_layer_.get(); }
+ void set_root_layer(std::unique_ptr<Layer> root_layer) {
+ root_layer_ = std::move(root_layer);
+ }
+
+ const SkISize& frame_size() const { return frame_size_; }
+ void set_frame_size(const SkISize& frame_size) { frame_size_ = frame_size; }
+
+ private:
+ SkISize frame_size_; // Physical pixels.
+ std::unique_ptr<Layer> root_layer_;
+
+ DISALLOW_COPY_AND_ASSIGN(LayerTree);
+};
+
+} // namespace sky
+
+#endif // SKY_COMPOSITOR_LAYER_TREE_H_
diff --git a/sky/engine/core/compositing/Scene.cpp b/sky/engine/core/compositing/Scene.cpp
index d58883f..f81cf26 100644
--- a/sky/engine/core/compositing/Scene.cpp
+++ b/sky/engine/core/compositing/Scene.cpp
@@ -16,22 +16,17 @@
}
Scene::Scene(std::unique_ptr<sky::Layer> rootLayer)
- : m_rootLayer(std::move(rootLayer))
+ : m_layerTree(new sky::LayerTree())
{
+ m_layerTree->set_root_layer(std::move(rootLayer));
}
Scene::~Scene()
{
}
-PassRefPtr<SkPicture> Scene::createPicture() const
-{
- SkRTreeFactory rtreeFactory;
- SkPictureRecorder pictureRecorder;
- SkCanvas* canvas = pictureRecorder.beginRecording(m_rootLayer->paint_bounds(),
- &rtreeFactory, SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);
- m_rootLayer->Paint(canvas);
- return adoptRef(pictureRecorder.endRecording());
+std::unique_ptr<sky::LayerTree> Scene::takeLayerTree() {
+ return std::move(m_layerTree);
}
} // namespace blink
diff --git a/sky/engine/core/compositing/Scene.h b/sky/engine/core/compositing/Scene.h
index af2347f..94e4a5aa 100644
--- a/sky/engine/core/compositing/Scene.h
+++ b/sky/engine/core/compositing/Scene.h
@@ -8,6 +8,7 @@
#include <memory>
#include "sky/compositor/layer.h"
+#include "sky/compositor/layer_tree.h"
#include "sky/engine/tonic/dart_wrappable.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/RefCounted.h"
@@ -21,14 +22,12 @@
~Scene() override;
static PassRefPtr<Scene> create(std::unique_ptr<sky::Layer> rootLayer);
- // While bootstraping the compositing system, we use an SkPicture instead
- // of a layer tree to back the scene.
- PassRefPtr<SkPicture> createPicture() const;
+ std::unique_ptr<sky::LayerTree> takeLayerTree();
private:
explicit Scene(std::unique_ptr<sky::Layer> rootLayer);
- std::unique_ptr<sky::Layer> m_rootLayer;
+ std::unique_ptr<sky::LayerTree> m_layerTree;
};
} // namespace blink
diff --git a/sky/engine/core/view/View.cpp b/sky/engine/core/view/View.cpp
index c9dbc07..dcb4b39 100644
--- a/sky/engine/core/view/View.cpp
+++ b/sky/engine/core/view/View.cpp
@@ -65,12 +65,13 @@
m_eventCallback->handleEvent(event.get());
}
-void View::beginFrame(base::TimeTicks frameTime)
+std::unique_ptr<sky::LayerTree> View::beginFrame(base::TimeTicks frameTime)
{
if (!m_frameCallback)
- return;
+ return nullptr;
double frameTimeMS = (frameTime - base::TimeTicks()).InMillisecondsF();
m_frameCallback->handleEvent(frameTimeMS);
+ return m_scene ? m_scene->takeLayerTree() : nullptr;
}
} // namespace blink
diff --git a/sky/engine/core/view/View.h b/sky/engine/core/view/View.h
index d8e7757..aa89a14 100644
--- a/sky/engine/core/view/View.h
+++ b/sky/engine/core/view/View.h
@@ -35,9 +35,6 @@
double width() const;
double height() const;
- Picture* picture() const { return m_picture.get(); }
- void setPicture(Picture* picture) { m_picture = picture; }
-
Scene* scene() const { return m_scene.get(); }
void setScene(Scene* scene) { m_scene = scene; }
@@ -50,7 +47,7 @@
void setDisplayMetrics(const SkyDisplayMetrics& metrics);
void handleInputEvent(PassRefPtr<Event> event);
- void beginFrame(base::TimeTicks frameTime);
+ std::unique_ptr<sky::LayerTree> beginFrame(base::TimeTicks frameTime);
private:
explicit View(const base::Closure& scheduleFrameCallback);
@@ -60,7 +57,6 @@
OwnPtr<EventCallback> m_eventCallback;
OwnPtr<VoidCallback> m_metricsChangedCallback;
OwnPtr<FrameCallback> m_frameCallback;
- RefPtr<Picture> m_picture;
RefPtr<Scene> m_scene;
};
diff --git a/sky/engine/core/view/View.idl b/sky/engine/core/view/View.idl
index 569ed21..3c5e025 100644
--- a/sky/engine/core/view/View.idl
+++ b/sky/engine/core/view/View.idl
@@ -14,7 +14,6 @@
readonly attribute double width;
readonly attribute double height;
- attribute Picture picture;
attribute Scene scene;
void setEventCallback(EventCallback callback);
diff --git a/sky/engine/public/sky/BUILD.gn b/sky/engine/public/sky/BUILD.gn
index 19c32b2..9b7a274 100644
--- a/sky/engine/public/sky/BUILD.gn
+++ b/sky/engine/public/sky/BUILD.gn
@@ -8,6 +8,7 @@
"//mojo/public/cpp/system",
"//mojo/services/network/public/interfaces",
"//skia",
+ "//sky/compositor",
"//sky/engine/core",
"//sky/engine/platform",
"//sky/engine/wtf",
diff --git a/sky/engine/public/sky/sky_view.cc b/sky/engine/public/sky/sky_view.cc
index de5cc2d..54809ac 100644
--- a/sky/engine/public/sky/sky_view.cc
+++ b/sky/engine/public/sky/sky_view.cc
@@ -66,16 +66,8 @@
dart_controller_->RunFromSnapshot(snapshot.Pass());
}
-void SkyView::BeginFrame(base::TimeTicks frame_time) {
- view_->beginFrame(frame_time);
-}
-
-PassRefPtr<SkPicture> SkyView::Paint() {
- if (Scene* scene = view_->scene())
- return scene->createPicture();
- if (Picture* picture = view_->picture())
- return picture->toSkia();
- return nullptr;
+std::unique_ptr<sky::LayerTree> SkyView::BeginFrame(base::TimeTicks frame_time) {
+ return view_->beginFrame(frame_time);
}
void SkyView::HandleInputEvent(const WebInputEvent& inputEvent) {
diff --git a/sky/engine/public/sky/sky_view.h b/sky/engine/public/sky/sky_view.h
index 8eaae79..a5b0231 100644
--- a/sky/engine/public/sky/sky_view.h
+++ b/sky/engine/public/sky/sky_view.h
@@ -11,6 +11,7 @@
#include "base/time/time.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/services/network/public/interfaces/url_loader.mojom.h"
+#include "sky/compositor/layer_tree.h"
#include "sky/engine/public/platform/WebCommon.h"
#include "sky/engine/public/platform/WebURL.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
@@ -33,7 +34,8 @@
const SkyDisplayMetrics& display_metrics() const { return display_metrics_; }
void SetDisplayMetrics(const SkyDisplayMetrics& metrics);
- void BeginFrame(base::TimeTicks frame_time);
+
+ std::unique_ptr<sky::LayerTree> BeginFrame(base::TimeTicks frame_time);
void CreateView(const String& name);
@@ -42,7 +44,6 @@
void RunFromSnapshot(const WebString& name,
mojo::ScopedDataPipeConsumerHandle snapshot);
- PassRefPtr<SkPicture> Paint();
void HandleInputEvent(const WebInputEvent& event);
void StartDartTracing();
diff --git a/sky/packages/sky/lib/painting/box_painter.dart b/sky/packages/sky/lib/painting/box_painter.dart
index 7fb94f5..0cb2efd 100644
--- a/sky/packages/sky/lib/painting/box_painter.dart
+++ b/sky/packages/sky/lib/painting/box_painter.dart
@@ -45,6 +45,8 @@
/// The offset from the left
final double left;
+ bool get isNonNegative => top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0;
+
bool operator ==(other) {
if (identical(this, other))
return true;
diff --git a/sky/packages/sky/lib/src/rendering/shifted_box.dart b/sky/packages/sky/lib/src/rendering/shifted_box.dart
index a7c32f6..1376b83 100644
--- a/sky/packages/sky/lib/src/rendering/shifted_box.dart
+++ b/sky/packages/sky/lib/src/rendering/shifted_box.dart
@@ -79,6 +79,7 @@
EdgeDims get padding => _padding;
void set padding (EdgeDims value) {
assert(value != null);
+ assert(value.isNonNegative);
if (_padding == value)
return;
_padding = value;
diff --git a/sky/packages/sky/lib/src/widgets/basic.dart b/sky/packages/sky/lib/src/widgets/basic.dart
index 956ad20..b986c2a 100644
--- a/sky/packages/sky/lib/src/widgets/basic.dart
+++ b/sky/packages/sky/lib/src/widgets/basic.dart
@@ -393,7 +393,10 @@
this.margin,
this.padding,
this.transform
- }) : super(key: key);
+ }) : super(key: key) {
+ assert(margin == null || margin.isNonNegative);
+ assert(padding == null || padding.isNonNegative);
+ }
final Widget child;
final BoxConstraints constraints;
diff --git a/sky/packages/sky/lib/src/widgets/dismissable.dart b/sky/packages/sky/lib/src/widgets/dismissable.dart
index fa511a7..892dbcf 100644
--- a/sky/packages/sky/lib/src/widgets/dismissable.dart
+++ b/sky/packages/sky/lib/src/widgets/dismissable.dart
@@ -20,6 +20,15 @@
const double _kFlingVelocityScale = 1.0 / 300.0;
const double _kDismissCardThreshold = 0.4;
+enum DismissDirection {
+ vertical,
+ horizontal,
+ left,
+ right,
+ up,
+ down
+}
+
typedef void ResizedCallback();
typedef void DismissedCallback();
@@ -29,41 +38,51 @@
Key key,
this.child,
this.onResized,
- this.onDismissed
- // TODO(hansmuller): direction
+ this.onDismissed,
+ this.direction: DismissDirection.horizontal
}) : super(key: key);
Widget child;
ResizedCallback onResized;
DismissedCallback onDismissed;
+ DismissDirection direction;
AnimationPerformance _fadePerformance;
AnimationPerformance _resizePerformance;
Size _size;
- double _dragX = 0.0;
+ double _dragExtent = 0.0;
bool _dragUnderway = false;
void initState() {
_fadePerformance = new AnimationPerformance(duration: _kCardDismissFadeout);
}
+ void syncConstructorArguments(Dismissable source) {
+ child = source.child;
+ onResized = source.onResized;
+ onDismissed = source.onDismissed;
+ direction = source.direction;
+ }
+
+ bool get _directionIsYAxis {
+ return
+ direction == DismissDirection.vertical ||
+ direction == DismissDirection.up ||
+ direction == DismissDirection.down;
+ }
+
void _handleFadeCompleted() {
if (!_dragUnderway)
_startResizePerformance();
}
- void syncConstructorArguments(Dismissable source) {
- child = source.child;
- onResized = source.onResized;
- onDismissed = source.onDismissed;
- }
-
Point get _activeCardDragEndPoint {
if (!_isActive)
return Point.origin;
assert(_size != null);
- return new Point(_dragX.sign * _size.width * _kDismissCardThreshold, 0.0);
+ double extent = _directionIsYAxis ? _size.height : _size.width;
+ return new Point(_dragExtent.sign * extent * _kDismissCardThreshold, 0.0);
}
bool get _isActive {
@@ -104,19 +123,38 @@
if (_fadePerformance.isAnimating)
return;
_dragUnderway = true;
- _dragX = 0.0;
+ _dragExtent = 0.0;
_fadePerformance.progress = 0.0;
}
void _handleScrollUpdate(double scrollOffset) {
if (!_isActive || _fadePerformance.isAnimating)
return;
- double oldDragX = _dragX;
- _dragX -= scrollOffset;
- if (oldDragX.sign != _dragX.sign)
+
+ double oldDragExtent = _dragExtent;
+ switch(direction) {
+ case DismissDirection.horizontal:
+ case DismissDirection.vertical:
+ _dragExtent -= scrollOffset;
+ break;
+
+ case DismissDirection.up:
+ case DismissDirection.left:
+ if (_dragExtent - scrollOffset < 0)
+ _dragExtent -= scrollOffset;
+ break;
+
+ case DismissDirection.down:
+ case DismissDirection.right:
+ if (_dragExtent - scrollOffset > 0)
+ _dragExtent -= scrollOffset;
+ break;
+ }
+
+ if (oldDragExtent.sign != _dragExtent.sign)
setState(() {}); // Rebuild to update the new drag endpoint.
if (!_fadePerformance.isAnimating)
- _fadePerformance.progress = _dragX.abs() / (_size.width * _kDismissCardThreshold);
+ _fadePerformance.progress = _dragExtent.abs() / (_size.width * _kDismissCardThreshold);
}
_handleScrollEnd() {
@@ -129,10 +167,33 @@
_fadePerformance.reverse();
}
- bool _isHorizontalFlingGesture(sky.GestureEvent event) {
- double vx = event.velocityX.abs();
- double vy = event.velocityY.abs();
- return vx - vy > _kMinFlingVelocityDelta && vx > _kMinFlingVelocity;
+ bool _isFlingGesture(sky.GestureEvent event) {
+ double vx = event.velocityX;
+ double vy = event.velocityY;
+ if (_directionIsYAxis) {
+ if (vy.abs() - vx.abs() < _kMinFlingVelocityDelta)
+ return false;
+ switch(direction) {
+ case DismissDirection.vertical:
+ return vy.abs() > _kMinFlingVelocity;
+ case DismissDirection.up:
+ return -vy > _kMinFlingVelocity;
+ default:
+ return vy > _kMinFlingVelocity;
+ }
+ } else {
+ if (vx.abs() - vy.abs() < _kMinFlingVelocityDelta)
+ return false;
+ switch(direction) {
+ case DismissDirection.horizontal:
+ return vx.abs() > _kMinFlingVelocity;
+ case DismissDirection.left:
+ return -vx > _kMinFlingVelocity;
+ default:
+ return vx > _kMinFlingVelocity;
+ }
+ }
+ return false;
}
EventDisposition _handleFlingStart(sky.GestureEvent event) {
@@ -142,9 +203,10 @@
_dragUnderway = false;
if (_fadePerformance.isCompleted) { // drag then fling
_startResizePerformance();
- } else if (_isHorizontalFlingGesture(event)) {
- _dragX = event.velocityX.sign;
- _fadePerformance.fling(velocity: event.velocityX.abs() * _kFlingVelocityScale);
+ } else if (_isFlingGesture(event)) {
+ double velocity = _directionIsYAxis ? event.velocityY : event.velocityX;
+ _dragExtent = velocity.sign;
+ _fadePerformance.fling(velocity: velocity.abs() * _kFlingVelocityScale);
} else {
_fadePerformance.reverse();
}
@@ -160,8 +222,8 @@
Widget build() {
if (_resizePerformance != null) {
- AnimatedValue<double> dismissHeight = new AnimatedValue<double>(
- _size.height,
+ AnimatedValue<double> squashAxisExtent = new AnimatedValue<double>(
+ _directionIsYAxis ? _size.width : _size.height,
end: 0.0,
curve: ease,
interval: _kCardDismissResizeInterval
@@ -170,13 +232,18 @@
return new SquashTransition(
performance: _resizePerformance,
direction: Direction.forward,
- height: dismissHeight);
+ width: _directionIsYAxis ? squashAxisExtent : null,
+ height: !_directionIsYAxis ? squashAxisExtent : null
+ );
}
return new GestureDetector(
- onHorizontalScrollStart: _handleScrollStart,
- onHorizontalScrollUpdate: _handleScrollUpdate,
- onHorizontalScrollEnd: _handleScrollEnd,
+ onHorizontalScrollStart: _directionIsYAxis ? null : _handleScrollStart,
+ onHorizontalScrollUpdate: _directionIsYAxis ? null : _handleScrollUpdate,
+ onHorizontalScrollEnd: _directionIsYAxis ? null : _handleScrollEnd,
+ onVerticalScrollStart: _directionIsYAxis ? _handleScrollStart : null,
+ onVerticalScrollUpdate: _directionIsYAxis ? _handleScrollUpdate : null,
+ onVerticalScrollEnd: _directionIsYAxis ? _handleScrollEnd : null,
child: new Listener(
onGestureFlingStart: _handleFlingStart,
child: new SizeObserver(
diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn
index 4b8c350..aa417c9 100644
--- a/sky/shell/BUILD.gn
+++ b/sky/shell/BUILD.gn
@@ -18,6 +18,7 @@
"//mojo/services/network/public/interfaces",
"//services/asset_bundle:lib",
"//skia",
+ "//sky/compositor",
"//sky/engine",
"//sky/engine/tonic",
"//sky/engine/wtf",
diff --git a/sky/shell/gpu/rasterizer.cc b/sky/shell/gpu/rasterizer.cc
index d2e930d..391b585 100644
--- a/sky/shell/gpu/rasterizer.cc
+++ b/sky/shell/gpu/rasterizer.cc
@@ -5,6 +5,7 @@
#include "sky/shell/gpu/rasterizer.h"
#include "base/trace_event/trace_event.h"
+#include "sky/compositor/layer.h"
#include "sky/shell/gpu/ganesh_context.h"
#include "sky/shell/gpu/ganesh_surface.h"
#include "sky/shell/gpu/picture_serializer.h"
@@ -35,33 +36,31 @@
CHECK(surface_) << "GLSurface required.";
}
-void Rasterizer::Draw(PassRefPtr<SkPicture> picture, gfx::Size size) {
+void Rasterizer::Draw(scoped_ptr<LayerTree> layer_tree) {
TRACE_EVENT0("sky", "Rasterizer::Draw");
if (!surface_)
return;
+ gfx::Size size(layer_tree->frame_size().width(),
+ layer_tree->frame_size().height());
+
if (surface_->GetSize() != size)
surface_->Resize(size);
EnsureGLContext();
CHECK(context_->MakeCurrent(surface_.get()));
EnsureGaneshSurface(surface_->GetBackingFrameBufferObject(), size);
+ SkCanvas* canvas = ganesh_surface_->canvas();
- DrawPicture(picture.get());
+ canvas->clear(SK_ColorBLACK);
+ layer_tree->root_layer()->Paint(canvas);
+ canvas->flush();
surface_->SwapBuffers();
// SerializePicture("/data/data/org.domokit.sky.shell/cache/layer0.skp", picture.get());
}
-void Rasterizer::DrawPicture(SkPicture* picture) {
- TRACE_EVENT0("sky", "Rasterizer::DrawPicture");
- SkCanvas* canvas = ganesh_surface_->canvas();
- canvas->clear(SK_ColorBLACK);
- canvas->drawPicture(picture);
- canvas->flush();
-}
-
void Rasterizer::OnOutputSurfaceDestroyed() {
if (context_) {
CHECK(context_->MakeCurrent(surface_.get()));
diff --git a/sky/shell/gpu/rasterizer.h b/sky/shell/gpu/rasterizer.h
index ff8b687..21dcd0d 100644
--- a/sky/shell/gpu/rasterizer.h
+++ b/sky/shell/gpu/rasterizer.h
@@ -34,12 +34,11 @@
void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override;
void OnOutputSurfaceDestroyed() override;
- void Draw(PassRefPtr<SkPicture> picture, gfx::Size size) override;
+ void Draw(scoped_ptr<LayerTree> layer_tree) override;
private:
void EnsureGLContext();
void EnsureGaneshSurface(intptr_t window_fbo, const gfx::Size& size);
- void DrawPicture(SkPicture* picture);
scoped_refptr<gfx::GLShareGroup> share_group_;
scoped_refptr<gfx::GLSurface> surface_;
diff --git a/sky/shell/gpu_delegate.h b/sky/shell/gpu_delegate.h
index 43cca28..b3bbe54 100644
--- a/sky/shell/gpu_delegate.h
+++ b/sky/shell/gpu_delegate.h
@@ -5,7 +5,10 @@
#ifndef SKY_SHELL_GPU_DELEGATE_H_
#define SKY_SHELL_GPU_DELEGATE_H_
-#include "sky/engine/wtf/PassRefPtr.h"
+#include <memory>
+
+#include "base/memory/scoped_ptr.h"
+#include "sky/compositor/layer_tree.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_widget_types.h"
@@ -18,7 +21,7 @@
public:
virtual void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) = 0;
virtual void OnOutputSurfaceDestroyed() = 0;
- virtual void Draw(PassRefPtr<SkPicture> picture, gfx::Size size) = 0;
+ virtual void Draw(scoped_ptr<LayerTree> layer_tree) = 0;
protected:
virtual ~GPUDelegate();
diff --git a/sky/shell/ui/animator.cc b/sky/shell/ui/animator.cc
index 1fc3754..9ee517d 100644
--- a/sky/shell/ui/animator.cc
+++ b/sky/shell/ui/animator.cc
@@ -71,13 +71,18 @@
base::TimeTicks frame_time = time_stamp ?
base::TimeTicks::FromInternalValue(time_stamp) : base::TimeTicks::Now();
- engine_->BeginFrame(frame_time);
- RefPtr<SkPicture> picture = engine_->Paint();
+ scoped_ptr<LayerTree> layer_tree =
+ make_scoped_ptr(engine_->BeginFrame(frame_time).release());
+
+ if (!layer_tree) {
+ OnFrameComplete();
+ return;
+ }
config_.gpu_task_runner->PostTaskAndReply(
FROM_HERE,
- base::Bind(&GPUDelegate::Draw, config_.gpu_delegate, picture,
- engine_->physical_size()),
+ base::Bind(&GPUDelegate::Draw, config_.gpu_delegate,
+ base::Passed(&layer_tree)),
base::Bind(&Animator::OnFrameComplete, weak_factory_.GetWeakPtr()));
}
diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc
index b9a3efd..f3f4251 100644
--- a/sky/shell/ui/engine.cc
+++ b/sky/shell/ui/engine.cc
@@ -96,27 +96,18 @@
blink::initialize(g_platform_impl);
}
-void Engine::BeginFrame(base::TimeTicks frame_time) {
+std::unique_ptr<LayerTree> Engine::BeginFrame(base::TimeTicks frame_time) {
TRACE_EVENT0("sky", "Engine::BeginFrame");
- if (sky_view_)
- sky_view_->BeginFrame(frame_time);
-}
+ if (!sky_view_)
+ return nullptr;
-PassRefPtr<SkPicture> Engine::Paint() {
- TRACE_EVENT0("sky", "Engine::Paint");
-
- if (sky_view_) {
- RefPtr<SkPicture> picture = sky_view_->Paint();
- if (picture)
- return picture.release();
+ std::unique_ptr<LayerTree> layer_tree = sky_view_->BeginFrame(frame_time);
+ if (layer_tree) {
+ layer_tree->set_frame_size(SkISize::Make(physical_size_.width(),
+ physical_size_.height()));
}
-
- SkPictureRecorder recorder;
- SkCanvas* canvas = recorder.beginRecording(
- physical_size_.width(), physical_size_.height());
- canvas->clear(SK_ColorBLACK);
- return adoptRef(recorder.endRecordingAsPicture());
+ return layer_tree;
}
void Engine::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
@@ -272,8 +263,6 @@
}
void Engine::SaveFrameToSkPicture(const base::FilePath& destination) {
- PassRefPtr<SkPicture> picture = Paint();
- SerializePicture(destination.AsUTF8Unsafe().c_str(), picture.get());
}
} // namespace shell
diff --git a/sky/shell/ui/engine.h b/sky/shell/ui/engine.h
index 8b68230..794089f 100644
--- a/sky/shell/ui/engine.h
+++ b/sky/shell/ui/engine.h
@@ -55,9 +55,7 @@
static void Init();
- void BeginFrame(base::TimeTicks frame_time);
- PassRefPtr<SkPicture> Paint();
- const gfx::Size& physical_size() { return physical_size_; }
+ std::unique_ptr<LayerTree> BeginFrame(base::TimeTicks frame_time);
void StartDartTracing();
void StopDartTracing(mojo::ScopedDataPipeProducerHandle producer);