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:
parent
4080305f57
commit
ca02c0a464
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user