Override didTranslate, and add virtual for didScale

This completes pushing through the new virtual didConcat44() to our
subclasses, and introduces didScale() for future optimizations. We
don't call didScale yet, until external subclasses are also updated.

This was derived from https://skia-review.googlesource.com/c/skia/+/263349

bug: skia: 9768
Change-Id: Ia26b48e76e323037082e8f2ee83673c26b99ebed
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/263702
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-01-10 17:21:40 -05:00 committed by Skia Commit-Bot
parent cab1c2dfe6
commit a3a704afa3
18 changed files with 193 additions and 5 deletions

81
gm/3d.cpp Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/utils/Sk3D.h"
struct Info {
float fNear = 0.05f;
float fFar = 4;
float fAngle = SK_ScalarPI / 4;
SkPoint3 fEye { 0, 0, 1.0f/tan(fAngle/2) - 1 };
SkPoint3 fCOA { 0, 0, 0 };
SkPoint3 fUp { 0, 1, 0 };
};
static SkMatrix44 inv(const SkMatrix44& m) {
SkMatrix44 inverse;
m.invert(&inverse);
return inverse;
}
static SkMatrix44 make_ctm(const Info& info, const SkMatrix44& model, SkSize size) {
SkMatrix44 camera,
perspective,
viewport;
SkScalar w = size.width();
SkScalar h = size.height();
Sk3Perspective(&perspective, info.fNear, info.fFar, info.fAngle);
Sk3LookAt(&camera, info.fEye, info.fCOA, info.fUp);
viewport.setScale(w*0.5f, h*0.5f, 1);//.postTranslate(r.centerX(), r.centerY(), 0);
return viewport * perspective * camera * model * inv(viewport);
}
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
static void do_draw(SkCanvas* canvas, SkColor color) {
SkAutoCanvasRestore acr(canvas, true);
Info info;
SkMatrix44 m;
m.setRotateDegreesAbout(0, 1, 0, 30);
canvas->concat(make_ctm(info, m, {300, 300}));
canvas->translate(150, 150);
SkPaint paint;
paint.setColor(color);
canvas->drawRect({-100, -100, 100, 100}, paint);
}
/*
* Test calling drawables w/ translate and matrices
*/
DEF_SIMPLE_GM(sk3d_simple, real_canvas, 300, 300) {
do_draw(real_canvas, 0xFFFF0000);
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(300, 300);
do_draw(canvas, 0x880000FF);
auto pic = recorder.finishRecordingAsPicture();
if (true) {
real_canvas->drawPicture(pic);
} else {
auto data = pic->serialize();
auto pic2 = SkPicture::MakeFromData(data.get());
real_canvas->drawPicture(pic2);
}
}

View File

@ -7,6 +7,7 @@
_gm = get_path_info("../gm", "abspath")
gm_sources = [
"$_gm/3d.cpp",
"$_gm/aaa.cpp",
"$_gm/aaclip.cpp",
"$_gm/aarectmodes.cpp",

View File

@ -2557,10 +2557,13 @@ protected:
virtual void didConcat(const SkMatrix& ) {}
virtual void didSetMatrix(const SkMatrix& ) {}
virtual void didTranslate(SkScalar dx, SkScalar dy) {
// TODO: update all subclasses to override this, so we can remove default impl.
this->didConcat(SkMatrix::MakeTrans(dx, dy));
}
// just pass an array for now, until we decide on the "public" form for the matrix
virtual void didConcat44(const SkScalar[]) {}
// This is not called by SkCanvas yet. Waiting for subclasses to override it first.
virtual void didScale(SkScalar, SkScalar) {}
// NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
// SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using

View File

@ -159,6 +159,9 @@ public:
SkM44& preTranslate(SkScalar x, SkScalar y);
SkM44& preConcat(const SkMatrix&);
const SkScalar* asColMajor() const { return fMat; }
SkScalar* asColMajor() { return fMat; }
private:
/* Stored in column-major.
* Indices

View File

@ -27,8 +27,11 @@ protected:
bool onDoSaveBehind(const SkRect*) override;
void willRestore() override;
void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,

View File

@ -32,8 +32,9 @@ protected:
void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
void didTranslate(SkScalar x, SkScalar y) override;
void didSetMatrix(const SkMatrix&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,

View File

@ -104,8 +104,9 @@ enum DrawType {
DRAW_EDGEAA_QUAD,
DRAW_BEHIND_PAINT,
CONCAT44,
LAST_DRAWTYPE_ENUM = DRAW_BEHIND_PAINT,
LAST_DRAWTYPE_ENUM = CONCAT44,
};
enum DrawVertexFlags {

View File

@ -174,6 +174,16 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
canvas->concat(matrix);
break;
}
case CONCAT44: {
const SkScalar* colMaj = reader->skipT<SkScalar>(16);
BREAK_ON_READ_ERROR(reader);
canvas->concat44(colMaj);
SkMatrix44 m;
m.setColMajor(colMaj);
m.dump();
break;
}
case DRAW_ANNOTATION: {
SkRect rect;
reader->readRect(&rect);

View File

@ -219,6 +219,25 @@ void SkPictureRecord::recordScale(const SkMatrix& m) {
this->validate(initialOffset, size);
}
void SkPictureRecord::didConcat44(const SkScalar m[16]) {
this->validate(fWriter.bytesWritten(), 0);
// op + matrix
size_t size = kUInt32Size + 16 * sizeof(SkScalar);
size_t initialOffset = this->addDraw(CONCAT44, &size);
fWriter.write(m, 16 * sizeof(SkScalar));
this->validate(initialOffset, size);
this->INHERITED::didConcat44(m);
}
void SkPictureRecord::didScale(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeScale(x, y));
}
void SkPictureRecord::didTranslate(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeTrans(x, y));
}
void SkPictureRecord::didConcat(const SkMatrix& matrix) {
switch (matrix.getType()) {
case SkMatrix::kTranslate_Mask:

View File

@ -162,8 +162,11 @@ protected:
bool onDoSaveBehind(const SkRect*) override;
void willRestore() override;
void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;

View File

@ -93,8 +93,10 @@ template <> void Draw::draw(const DrawBehind& r) {
}
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
DRAW(Concat44, concat44(r.matrix.asColMajor()));
DRAW(Concat, concat(r.matrix));
DRAW(Translate, translate(r.dx, r.dy));
DRAW(Scale, scale(r.sx, r.sy));
DRAW(ClipPath, clipPath(r.path, r.opAA.op(), r.opAA.aa()));
DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op(), r.opAA.aa()));
@ -246,7 +248,9 @@ private:
template <typename T> void updateCTM(const T&) {}
void updateCTM(const Restore& op) { fCTM = op.matrix; }
void updateCTM(const SetMatrix& op) { fCTM = op.matrix; }
void updateCTM(const Concat44& op) { fCTM.preConcat(op.matrix.asM33()); }
void updateCTM(const Concat& op) { fCTM.preConcat(op.matrix); }
void updateCTM(const Scale& op) { fCTM.preScale(op.sx, op.sy); }
void updateCTM(const Translate& op) { fCTM.preTranslate(op.dx, op.dy); }
// The bounds of these ops must be calculated when we hit the Restore
@ -258,6 +262,8 @@ private:
void trackBounds(const SetMatrix&) { this->pushControl(); }
void trackBounds(const Concat&) { this->pushControl(); }
void trackBounds(const Concat44&) { this->pushControl(); }
void trackBounds(const Scale&) { this->pushControl(); }
void trackBounds(const Translate&) { this->pushControl(); }
void trackBounds(const ClipRect&) { this->pushControl(); }
void trackBounds(const ClipRRect&) { this->pushControl(); }

View File

@ -370,6 +370,10 @@ void SkRecorder::didRestore() {
this->append<SkRecords::Restore>(this->getTotalMatrix());
}
void SkRecorder::didConcat44(const SkScalar m[16]) {
this->append<SkRecords::Concat44>(m);
}
void SkRecorder::didConcat(const SkMatrix& matrix) {
this->append<SkRecords::Concat>(matrix);
}
@ -378,6 +382,10 @@ void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
this->append<SkRecords::SetMatrix>(matrix);
}
void SkRecorder::didScale(SkScalar sx, SkScalar sy) {
this->append<SkRecords::Scale>(sx, sy);
}
void SkRecorder::didTranslate(SkScalar dx, SkScalar dy) {
this->append<SkRecords::Translate>(dx, dy);
}

View File

@ -67,8 +67,10 @@ public:
void willRestore() override {}
void didRestore() override;
void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;

View File

@ -23,6 +23,7 @@
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkVertices.h"
#include "include/private/SkM44.h"
#include "src/core/SkDrawShadowInfo.h"
namespace SkRecords {
@ -46,7 +47,9 @@ namespace SkRecords {
M(SaveBehind) \
M(SetMatrix) \
M(Translate) \
M(Scale) \
M(Concat) \
M(Concat44) \
M(ClipPath) \
M(ClipRRect) \
M(ClipRect) \
@ -153,6 +156,13 @@ struct TypedMatrix : public SkMatrix {
TypedMatrix(const SkMatrix& matrix);
};
struct Matrix44 : public SkM44 {
Matrix44() {}
Matrix44(const SkScalar m[16]) {
this->setColMajor(m);
}
};
enum Tags {
kDraw_Tag = 1, // May draw something (usually named DrawFoo).
kHasImage_Tag = 2, // Contains an SkImage or SkBitmap.
@ -191,11 +201,17 @@ RECORD(SetMatrix, 0,
TypedMatrix matrix);
RECORD(Concat, 0,
TypedMatrix matrix);
RECORD(Concat44, 0,
Matrix44 matrix);
RECORD(Translate, 0,
SkScalar dx;
SkScalar dy);
RECORD(Scale, 0,
SkScalar sx;
SkScalar sy);
struct ClipOpAndAA {
ClipOpAndAA() {}
ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast<unsigned>(op)), fAA(aa) {}

View File

@ -110,6 +110,15 @@ void SkLuaCanvas::willRestore() {
this->INHERITED::willRestore();
}
void SkLuaCanvas::didConcat44(const SkScalar m[16]) {
// TODO
}
void SkLuaCanvas::didScale(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeScale(x, y));
}
void SkLuaCanvas::didTranslate(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeTrans(x, y));
}
void SkLuaCanvas::didConcat(const SkMatrix& matrix) {
switch (matrix.getType()) {
case SkMatrix::kTranslate_Mask: {

View File

@ -106,6 +106,13 @@ void SkNWayCanvas::didConcat(const SkMatrix& matrix) {
}
}
void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) {
Iter iter(fList);
while (iter.next()) {
iter->setMatrix(matrix);
}
}
void SkNWayCanvas::didTranslate(SkScalar x, SkScalar y) {
Iter iter(fList);
while (iter.next()) {
@ -113,10 +120,10 @@ void SkNWayCanvas::didTranslate(SkScalar x, SkScalar y) {
}
}
void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) {
void SkNWayCanvas::didScale(SkScalar x, SkScalar y) {
Iter iter(fList);
while (iter.next()) {
iter->setMatrix(matrix);
iter->scale(x, y);
}
}

View File

@ -312,6 +312,19 @@ void DebugCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
this->addDrawCommand(new ClipRegionCommand(region, op));
}
void DebugCanvas::didConcat44(const SkScalar m[16]) {
// TODO
this->INHERITED::didConcat44(m);
}
void DebugCanvas::didScale(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeScale(x, y));
}
void DebugCanvas::didTranslate(SkScalar x, SkScalar y) {
this->didConcat(SkMatrix::MakeTrans(x, y));
}
void DebugCanvas::didConcat(const SkMatrix& matrix) {
this->addDrawCommand(new ConcatCommand(matrix));
this->INHERITED::didConcat(matrix);

View File

@ -129,9 +129,11 @@ protected:
bool onDoSaveBehind(const SkRect*) override;
void willRestore() override;
void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;