Convert SVGPong sample to sksg

Use the new scene graph impl instead of old SVG DOM.

TBR=
Change-Id: I590798b362e953aa3554e85669193f7501ba46de
Reviewed-on: https://skia-review.googlesource.com/98441
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-01-22 16:48:22 -05:00 committed by Skia Commit-Bot
parent 4080305f57
commit ca02c0a464

View File

@ -10,11 +10,14 @@
#include "SkColor.h" #include "SkColor.h"
#include "SkRandom.h" #include "SkRandom.h"
#include "SkRRect.h" #include "SkRRect.h"
#include "SkSVGDOM.h"
#include "SkSVGG.h" #include "SkSGColor.h"
#include "SkSVGPath.h" #include "SkSGDraw.h"
#include "SkSVGRect.h" #include "SkSGGroup.h"
#include "SkSVGSVG.h" #include "SkSGPath.h"
#include "SkSGRect.h"
#include "SkSGScene.h"
#include "SkSGTransform.h"
namespace { namespace {
@ -61,23 +64,20 @@ std::tuple<SkScalar, SkScalar> find_yintercept(const SkPoint& pos, const SkVecto
return std::make_tuple(t, box_reflect(pos.fY + dY, box.fTop, box.fBottom)); return std::make_tuple(t, box_reflect(pos.fY + dY, box.fTop, box.fBottom));
} }
sk_sp<SkSVGRect> make_svg_rrect(const SkRRect& rrect) { void update_pos(const sk_sp<sksg::RRect>& rr, const SkPoint& pos) {
sk_sp<SkSVGRect> node = SkSVGRect::Make(); // TODO: position setters on RRect?
node->setX(SkSVGLength(rrect.rect().x()));
node->setY(SkSVGLength(rrect.rect().y()));
node->setWidth(SkSVGLength(rrect.width()));
node->setHeight(SkSVGLength(rrect.height()));
node->setRx(SkSVGLength(rrect.getSimpleRadii().x()));
node->setRy(SkSVGLength(rrect.getSimpleRadii().y()));
return node; const auto r = rr->getRRect().rect();
const auto offsetX = pos.x() - r.x(),
offsetY = pos.y() - r.y();
rr->setRRect(rr->getRRect().makeOffset(offsetX, offsetY));
} }
} // anonymous ns } // anonymous ns
class SVGPongView final : public SampleView { class PongView final : public SampleView {
public: public:
SVGPongView() {} PongView() = default;
protected: protected:
void onOnceBeforeDraw() override { void onOnceBeforeDraw() override {
@ -88,17 +88,14 @@ protected:
kPaddleSize.width() / 2, kPaddleSize.width() / 2,
kPaddleSize.width() / 2); kPaddleSize.width() / 2);
fBall.initialize(ball, fBall.initialize(ball,
SK_ColorGREEN,
SkPoint::Make(kBounds.centerX(), kBounds.centerY()), SkPoint::Make(kBounds.centerX(), kBounds.centerY()),
SkVector::Make(fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax), SkVector::Make(fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax),
fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax))); fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax)));
fPaddle0.initialize(paddle, fPaddle0.initialize(paddle,
SK_ColorBLUE,
SkPoint::Make(fieldBounds.left() - kPaddleSize.width() / 2, SkPoint::Make(fieldBounds.left() - kPaddleSize.width() / 2,
fieldBounds.centerY()), fieldBounds.centerY()),
SkVector::Make(0, 0)); SkVector::Make(0, 0));
fPaddle1.initialize(paddle, fPaddle1.initialize(paddle,
SK_ColorRED,
SkPoint::Make(fieldBounds.right() + kPaddleSize.width() / 2, SkPoint::Make(fieldBounds.right() + kPaddleSize.width() / 2,
fieldBounds.centerY()), fieldBounds.centerY()),
SkVector::Make(0, 0)); SkVector::Make(0, 0));
@ -117,28 +114,38 @@ protected:
kBounds.top() + (i + 0.75f) * kBounds.height() / kBackgroundDashCount); kBounds.top() + (i + 0.75f) * kBounds.height() / kBackgroundDashCount);
} }
sk_sp<SkSVGPath> bg = SkSVGPath::Make(); auto bg_path = sksg::Path::Make(bgPath);
bg->setPath(bgPath); auto bg_paint = sksg::Color::Make(SK_ColorBLACK);
bg->setFill(SkSVGPaint(SkSVGPaint::Type::kNone)); bg_paint->setStyle(SkPaint::kStroke_Style);
bg->setStroke(SkSVGPaint(SkSVGColorType(SK_ColorBLACK))); bg_paint->setStrokeWidth(kBackgroundStroke);
bg->setStrokeWidth(SkSVGLength(kBackgroundStroke));
// Build the SVG DOM tree. auto ball_paint = sksg::Color::Make(SK_ColorGREEN),
sk_sp<SkSVGSVG> root = SkSVGSVG::Make(); paddle0_paint = sksg::Color::Make(SK_ColorBLUE),
root->appendChild(std::move(bg)); paddle1_paint = sksg::Color::Make(SK_ColorRED),
root->appendChild(fPaddle0.shadowNode); shadow_paint = sksg::Color::Make(SK_ColorBLACK);
root->appendChild(fPaddle1.shadowNode); ball_paint->setAntiAlias(true);
root->appendChild(fBall.shadowNode); paddle0_paint->setAntiAlias(true);
root->appendChild(fPaddle0.objectNode); paddle1_paint->setAntiAlias(true);
root->appendChild(fPaddle1.objectNode); shadow_paint->setAntiAlias(true);
root->appendChild(fBall.objectNode); shadow_paint->setOpacity(kShadowOpacity);
// Build the scene graph.
auto group = sksg::Group::Make();
group->addChild(sksg::Draw::Make(std::move(bg_path), std::move(bg_paint)));
group->addChild(sksg::Draw::Make(fPaddle0.shadowNode, shadow_paint));
group->addChild(sksg::Draw::Make(fPaddle1.shadowNode, shadow_paint));
group->addChild(sksg::Draw::Make(fBall.shadowNode, shadow_paint));
group->addChild(sksg::Draw::Make(fPaddle0.objectNode, paddle0_paint));
group->addChild(sksg::Draw::Make(fPaddle1.objectNode, paddle1_paint));
group->addChild(sksg::Draw::Make(fBall.objectNode, ball_paint));
// Handle everything in a normalized 1x1 space. // Handle everything in a normalized 1x1 space.
root->setViewBox(SkSVGViewBoxType(SkRect::MakeWH(1, 1))); fContentMatrix = sksg::Matrix::Make(
SkMatrix::MakeRectToRect(SkRect::MakeWH(1, 1),
fDom = sk_sp<SkSVGDOM>(new SkSVGDOM()); SkRect::MakeIWH(this->width(), this->height()),
fDom->setContainerSize(SkSize::Make(this->width(), this->height())); SkMatrix::kFill_ScaleToFit));
fDom->setRoot(std::move(root)); auto root = sksg::Transform::Make(std::move(group), fContentMatrix);
fScene = sksg::Scene::Make(std::move(root), sksg::Scene::AnimatorList());
// Off we go. // Off we go.
this->updatePaddleStrategy(); this->updatePaddleStrategy();
@ -146,7 +153,7 @@ protected:
bool onQuery(SkEvent* evt) override { bool onQuery(SkEvent* evt) override {
if (SampleCode::TitleQ(*evt)) { if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "SVGPong"); SampleCode::TitleR(evt, "SGPong");
return true; return true;
} }
@ -159,6 +166,10 @@ protected:
case ']': case ']':
fTimeScale = SkTPin(fTimeScale + 0.1f, kTimeScaleMin, kTimeScaleMax); fTimeScale = SkTPin(fTimeScale + 0.1f, kTimeScaleMin, kTimeScaleMax);
return true; return true;
case 'I':
fShowInval = !fShowInval;
fScene->setShowInval(fShowInval);
return true;
default: default:
break; break;
} }
@ -167,20 +178,23 @@ protected:
} }
void onSizeChange() override { void onSizeChange() override {
if (fDom) { if (fContentMatrix) {
fDom->setContainerSize(SkSize::Make(this->width(), this->height())); fContentMatrix->setMatrix(SkMatrix::MakeRectToRect(SkRect::MakeWH(1, 1),
SkRect::MakeIWH(this->width(),
this->height()),
SkMatrix::kFill_ScaleToFit));
} }
this->INHERITED::onSizeChange(); this->INHERITED::onSizeChange();
} }
void onDrawContent(SkCanvas* canvas) override { void onDrawContent(SkCanvas* canvas) override {
fDom->render(canvas); fScene->render(canvas);
} }
bool onAnimate(const SkAnimTimer& timer) override { bool onAnimate(const SkAnimTimer& timer) override {
// onAnimate may fire before the first draw. // onAnimate may fire before the first draw.
if (fDom) { if (fScene) {
SkScalar dt = (timer.msec() - fLastTick) * fTimeScale; SkScalar dt = (timer.msec() - fLastTick) * fTimeScale;
fLastTick = timer.msec(); fLastTick = timer.msec();
@ -199,13 +213,9 @@ protected:
private: private:
struct Object { struct Object {
void initialize(const SkRRect& rrect, SkColor color, void initialize(const SkRRect& rrect, const SkPoint& p, const SkVector& s) {
const SkPoint& p, const SkVector& s) { objectNode = sksg::RRect::Make(rrect);
objectNode = make_svg_rrect(rrect); shadowNode = sksg::RRect::Make(rrect);
objectNode->setFill(SkSVGPaint(SkSVGColorType(color)));
shadowNode = make_svg_rrect(rrect);
shadowNode->setFillOpacity(SkSVGNumberType(kShadowOpacity));
pos = p; pos = p;
spd = s; spd = s;
@ -218,23 +228,21 @@ private:
void updateDom() { void updateDom() {
const SkPoint corner = pos - SkPoint::Make(size.width() / 2, size.height() / 2); const SkPoint corner = pos - SkPoint::Make(size.width() / 2, size.height() / 2);
objectNode->setX(SkSVGLength(corner.x())); update_pos(objectNode, corner);
objectNode->setY(SkSVGLength(corner.y()));
// Simulate parallax shadow for a centered light source. // Simulate parallax shadow for a centered light source.
SkPoint shadowOffset = pos - SkPoint::Make(kBounds.centerX(), kBounds.centerY()); SkPoint shadowOffset = pos - SkPoint::Make(kBounds.centerX(), kBounds.centerY());
shadowOffset.scale(kShadowParallax); shadowOffset.scale(kShadowParallax);
const SkPoint shadowCorner = corner + shadowOffset; const SkPoint shadowCorner = corner + shadowOffset;
shadowNode->setX(SkSVGLength(shadowCorner.x())); update_pos(shadowNode, shadowCorner);
shadowNode->setY(SkSVGLength(shadowCorner.y()));
} }
sk_sp<SkSVGRect> objectNode; sk_sp<sksg::RRect> objectNode,
sk_sp<SkSVGRect> shadowNode; shadowNode;
SkPoint pos; SkPoint pos;
SkVector spd; SkVector spd;
SkSize size; SkSize size;
}; };
void enforceConstraints() { void enforceConstraints() {
@ -275,15 +283,17 @@ private:
catcher->spd.fY = (yIntercept - catcher->pos.fY) / t; catcher->spd.fY = (yIntercept - catcher->pos.fY) / t;
} }
sk_sp<SkSVGDOM> fDom; std::unique_ptr<sksg::Scene> fScene;
Object fPaddle0, fPaddle1, fBall; sk_sp<sksg::Matrix> fContentMatrix;
SkRandom fRand; Object fPaddle0, fPaddle1, fBall;
SkRandom fRand;
SkMSec fLastTick = 0; SkMSec fLastTick = 0;
SkScalar fTimeScale = 1.0f; SkScalar fTimeScale = 1.0f;
bool fShowInval = false;
typedef SampleView INHERITED; typedef SampleView INHERITED;
}; };
static SkView* SVGPongFactory() { return new SVGPongView; } static SkView* PongFactory() { return new PongView; }
static SkViewRegister reg(SVGPongFactory); static SkViewRegister reg(PongFactory);