clean up public m44 and camera api

saveCamera() is no longer experimental

In a separate CL, will stage changes to concat virtual to take M44.

Change-Id: Iaf37ce2f24ab1223c54aeb1e79eaebf18f87fece
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281589
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-04-06 10:41:09 -04:00 committed by Skia Commit-Bot
parent 6d3bc2951d
commit 3ef77ddf9e
20 changed files with 96 additions and 125 deletions

View File

@ -368,7 +368,7 @@ protected:
case kScale_Type: canvas->scale(1.0001f, 0.9999f); break;
case k2x3_Type: canvas->concat(m); break;
case k3x3_Type: canvas->concat(m); break;
case k4x4_Type: canvas->concat44(m4); break;
case k4x4_Type: canvas->concat(m4); break;
}
}
canvas->restore();

View File

@ -21,8 +21,8 @@ public:
for (auto& v : value) {
v = rand.nextF();
}
fM1.setColMajor(value + 0);
fM2.setColMajor(value + 16);
fM1 = SkM44::ColMajor(value + 0);
fM2 = SkM44::ColMajor(value + 16);
}
bool isSuitableFor(Backend backend) override {

View File

@ -50,7 +50,7 @@ static void do_draw(SkCanvas* canvas, SkColor color) {
SkM44 m = SkM44::Rotate({0, 1, 0}, SK_ScalarPI/6);
canvas->concat44(make_ctm(info, m, {300, 300}));
canvas->concat(make_ctm(info, m, {300, 300}));
canvas->translate(150, 150);
SkPaint paint;

View File

@ -88,7 +88,7 @@ protected:
SkM44::Translate(-radius, -radius); // center content
canvas->save();
canvas->concat44(model);
canvas->concat(model);
SkPaint fillPaint;
fillPaint.setAntiAlias(true);

View File

@ -124,7 +124,7 @@ protected:
* SkM44::Translate(0, ringY, 0)
* SkM44::Rotate({0,1,0}, SkDegreesToRadians(yRotation))
* SkM44::Translate(0, 0, kRingRadius);
canvas->concat44(model);
canvas->concat(model);
SkRect poster = SkRect::MakeLTRB(-0.5f * kPosterSize, -0.5f * kPosterSize,
0.5f * kPosterSize, 0.5f * kPosterSize);

View File

@ -756,8 +756,19 @@ public:
*/
int saveLayer(const SaveLayerRec& layerRec);
int experimental_saveCamera(const SkM44& projection, const SkM44& camera);
int experimental_saveCamera(const SkScalar projection[16], const SkScalar camera[16]);
/**
* Save the matrix and clip state (just like save()), but then also concat
* two more matrices: projection and camera. This call is logically similar to:
* save()
* concat(projection)
* concat(camera)
* However, these matrices are tracked by the canvas, so if any shader references
* lights or normals, these can be properly transformed, as they will have access to
* local-to-world and local-to-camera.
*
* returns the current save count (see getSaveCount()).
*/
int saveCamera(const SkM44& projection, const SkM44& camera);
/** Removes changes to SkMatrix and clip since SkCanvas state was
last saved. The state is removed from the stack.
@ -880,8 +891,13 @@ public:
example: https://fiddle.skia.org/c/@Canvas_concat
*/
void concat(const SkMatrix& matrix);
void concat44(const SkM44&);
void concat44(const SkScalar[]); // column-major
void concat(const SkM44&);
// DEPRECATED
#if 1
void concat44(const SkM44& m) { this->concat(m); }
void concat44(const SkScalar cm[]) { this->concat(SkM44::ColMajor(cm)); }
#endif
/** Replaces SkMatrix with matrix.
Unlike concat(), any prior matrix state is overwritten.
@ -2427,15 +2443,13 @@ public:
example: https://fiddle.skia.org/c/@Clip
*/
SkMatrix getTotalMatrix() const;
SkM44 getLocalToDevice() const; // entire matrix stack
void getLocalToDevice(SkScalar colMajor[16]) const;
SkM44 getLocalToDevice() const; // entire matrix stack
// These will go away when we have formal access to these from SkSL
SkM44 experimental_getLocalToWorld() const; // up to but not including top-most camera
SkM44 experimental_getLocalToCamera() const; // up to and including top-most camera
void experimental_getLocalToWorld(SkScalar colMajor[16]) const;
void experimental_getLocalToCamera(SkScalar colMajor[16]) const;
///////////////////////////////////////////////////////////////////////////
// don't call

View File

@ -158,10 +158,10 @@ public:
SkScalar m2, SkScalar m6, SkScalar m10, SkScalar m14,
SkScalar m3, SkScalar m7, SkScalar m11, SkScalar m15)
{
this->set44(m0, m4, m8, m12,
m1, m5, m9, m13,
m2, m6, m10, m14,
m3, m7, m11, m15);
fMat[0] = m0; fMat[4] = m4; fMat[8] = m8; fMat[12] = m12;
fMat[1] = m1; fMat[5] = m5; fMat[9] = m9; fMat[13] = m13;
fMat[2] = m2; fMat[6] = m6; fMat[10] = m10; fMat[14] = m14;
fMat[3] = m3; fMat[7] = m7; fMat[11] = m11; fMat[15] = m15;
}
static SkM44 Rows(const SkV4& r0, const SkV4& r1, const SkV4& r2, const SkV4& r3) {
@ -181,6 +181,19 @@ public:
return m;
}
static SkM44 RowMajor(const SkScalar r[16]) {
return SkM44(r[ 0], r[ 1], r[ 2], r[ 3],
r[ 4], r[ 5], r[ 6], r[ 7],
r[ 8], r[ 9], r[10], r[11],
r[12], r[13], r[14], r[15]);
}
static SkM44 ColMajor(const SkScalar c[16]) {
return SkM44(c[0], c[4], c[ 8], c[12],
c[1], c[5], c[ 9], c[13],
c[2], c[6], c[10], c[14],
c[3], c[7], c[11], c[15]);
}
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z = 0) {
return SkM44(1, 0, 0, x,
0, 1, 0, y,
@ -211,25 +224,6 @@ public:
}
void getRowMajor(SkScalar v[]) const;
SkM44& setColMajor(const SkScalar v[]) {
memcpy(fMat, v, sizeof(fMat));
return *this;
}
SkM44& setRowMajor(const SkScalar v[]);
/* Parameters in same order as constructor.
*/
SkM44& set44(SkScalar m0, SkScalar m4, SkScalar m8, SkScalar m12,
SkScalar m1, SkScalar m5, SkScalar m9, SkScalar m13,
SkScalar m2, SkScalar m6, SkScalar m10, SkScalar m14,
SkScalar m3, SkScalar m7, SkScalar m11, SkScalar m15) {
fMat[0] = m0; fMat[4] = m4; fMat[8] = m8; fMat[12] = m12;
fMat[1] = m1; fMat[5] = m5; fMat[9] = m9; fMat[13] = m13;
fMat[2] = m2; fMat[6] = m6; fMat[10] = m10; fMat[14] = m14;
fMat[3] = m3; fMat[7] = m7; fMat[11] = m11; fMat[15] = m15;
return *this;
}
SkScalar rc(int r, int c) const {
SkASSERT(r >= 0 && r <= 3);
SkASSERT(c >= 0 && c <= 3);
@ -263,24 +257,27 @@ public:
}
SkM44& setIdentity() {
return this->set44(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
*this = { 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
return *this;
}
SkM44& setTranslate(SkScalar x, SkScalar y, SkScalar z = 0) {
return this->set44(1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1);
*this = { 1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1 };
return *this;
}
SkM44& setScale(SkScalar x, SkScalar y, SkScalar z = 1) {
return this->set44(x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1);
*this = { x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1 };
return *this;
}
/**
@ -311,18 +308,14 @@ public:
*/
SkM44& setRotate(SkV3 axis, SkScalar radians);
SkM44& setConcat16(const SkM44& a, const SkScalar colMajor[16]);
SkM44& setConcat(const SkM44& a, const SkM44& b) {
return this->setConcat16(a, b.fMat);
}
SkM44& setConcat(const SkM44& a, const SkM44& b);
friend SkM44 operator*(const SkM44& a, const SkM44& b) {
return SkM44(a, b);
}
SkM44& preConcat16(const SkScalar colMajor[16]) {
return this->setConcat16(*this, colMajor);
SkM44& preConcat(const SkM44& m) {
return this->setConcat(*this, m);
}
/** If this is invertible, return that in inverse and return true. If it is

View File

@ -1051,10 +1051,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
// 4x4 matrix functions
.function("saveCamera", optional_override([](SkCanvas& self,
const SimpleM44& projection, const SimpleM44& camera) {
self.experimental_saveCamera(toSkM44(projection), toSkM44(camera));
self.saveCamera(toSkM44(projection), toSkM44(camera));
}))
.function("concat44", optional_override([](SkCanvas& self, const SimpleM44& m) {
self.concat44(toSkM44(m));
self.concat(toSkM44(m));
}))
.function("getLocalToDevice", optional_override([](const SkCanvas& self)->SimpleM44 {
SkM44 m = self.getLocalToDevice();

View File

@ -179,7 +179,7 @@ TransformEffect::~TransformEffect() {
void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
SkAutoCanvasRestore acr(canvas, true);
canvas->concat44(TransformPriv::As<SkM44>(fTransform));
canvas->concat(TransformPriv::As<SkM44>(fTransform));
this->INHERITED::onRender(canvas, ctx);
}

View File

@ -90,7 +90,7 @@ public:
// want "world" to be in our big coordinates (e.g. area), so apply this inverse
// as part of our "camera".
canvas->experimental_saveCamera(viewport * perspective, camera * inv(viewport));
canvas->saveCamera(viewport * perspective, camera * inv(viewport));
}
};
@ -289,7 +289,7 @@ public:
SkM44 trans = SkM44::Translate(200, 200, 0); // center of the rotation
SkM44 m = fRotateAnimator.rotation() * fRotation * f.asM44(200);
canvas->concat44(trans * m * inv(trans));
canvas->concat(trans * m * inv(trans));
this->drawContent(canvas, f.fColor, index++, drawFront);
}
}

View File

@ -527,7 +527,7 @@ class HalfPlaneView3 : public SampleCameraView {
if (fShowUnclipped) {
canvas->save();
canvas->concat44(mx);
canvas->concat(mx);
paint.setAlphaf(0.33f);
canvas->drawPath(fPath, paint);
paint.setAlphaf(1.f);
@ -542,7 +542,7 @@ class HalfPlaneView3 : public SampleCameraView {
planeColor = SK_ColorRED;
}
canvas->save();
canvas->concat44(mx);
canvas->concat(mx);
canvas->drawPath(*path, paint);
canvas->restore();
@ -585,7 +585,7 @@ class HalfPlaneCoons : public SampleCameraView {
SkPaint paint;
canvas->save();
canvas->concat44(this->get44({0, 0, 300, 300}));
canvas->concat(this->get44({0, 0, 300, 300}));
const SkPoint* tex = nullptr;
const SkColor* col = nullptr;

View File

@ -742,24 +742,16 @@ void SkCanvas::notifyCameraChanged() {
FOR_EACH_TOP_DEVICE(device->setInvCamera(invc));
}
int SkCanvas::experimental_saveCamera(const SkM44& projection, const SkM44& camera) {
int SkCanvas::saveCamera(const SkM44& projection, const SkM44& camera) {
// TODO: add a virtual for this, and update clients (e.g. chrome)
int n = this->save();
this->concat44(projection * camera);
this->concat(projection * camera);
fCameraStack.push_back(CameraRec(fMCRec, camera));
this->notifyCameraChanged();
return n;
}
int SkCanvas::experimental_saveCamera(const SkScalar projection[16],
const SkScalar camera[16]) {
SkM44 proj, cam;
proj.setColMajor(projection);
cam.setColMajor(camera);
return this->experimental_saveCamera(proj, cam);
}
void SkCanvas::restore() {
if (fMCRec->fDeferredSaveCount > 0) {
SkASSERT(fSaveCount > 1);
@ -1532,20 +1524,16 @@ void SkCanvas::concat(const SkMatrix& matrix) {
this->didConcat(matrix);
}
void SkCanvas::concat44(const SkScalar colMajor[16]) {
void SkCanvas::concat(const SkM44& m) {
this->checkForDeferredSave();
fMCRec->fMatrix.preConcat16(colMajor);
fMCRec->fMatrix.preConcat(m);
fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
this->didConcat44(colMajor);
}
void SkCanvas::concat44(const SkM44& m) {
this->concat44(SkMatrixPriv::M44ColMajor(m));
this->didConcat44(SkMatrixPriv::M44ColMajor(m));
}
void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
@ -1896,18 +1884,6 @@ SkM44 SkCanvas::experimental_getLocalToCamera() const {
}
}
void SkCanvas::getLocalToDevice(SkScalar colMajor[16]) const {
this->getLocalToDevice().getColMajor(colMajor);
}
void SkCanvas::experimental_getLocalToWorld(SkScalar colMajor[16]) const {
this->experimental_getLocalToWorld().getColMajor(colMajor);
}
void SkCanvas::experimental_getLocalToCamera(SkScalar colMajor[16]) const {
this->experimental_getLocalToCamera().getColMajor(colMajor);
}
GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() {
SkBaseDevice* dev = this->getTopDevice();
return dev ? dev->accessRenderTargetContext() : nullptr;

View File

@ -41,12 +41,7 @@ void SkM44::getRowMajor(SkScalar v[]) const {
transpose_arrays(v, fMat);
}
SkM44& SkM44::setRowMajor(const SkScalar v[]) {
transpose_arrays(fMat, v);
return *this;
}
SkM44& SkM44::setConcat16(const SkM44& a, const SkScalar b[16]) {
SkM44& SkM44::setConcat(const SkM44& a, const SkM44& b) {
sk4f c0 = sk4f::Load(a.fMat + 0);
sk4f c1 = sk4f::Load(a.fMat + 4);
sk4f c2 = sk4f::Load(a.fMat + 8);
@ -56,10 +51,10 @@ SkM44& SkM44::setConcat16(const SkM44& a, const SkScalar b[16]) {
return skvx::mad(c0, r[0], skvx::mad(c1, r[1], skvx::mad(c2, r[2], c3 * r[3])));
};
sk4f m0 = compute(sk4f::Load(b + 0));
sk4f m1 = compute(sk4f::Load(b + 4));
sk4f m2 = compute(sk4f::Load(b + 8));
sk4f m3 = compute(sk4f::Load(b + 12));
sk4f m0 = compute(sk4f::Load(b.fMat + 0));
sk4f m1 = compute(sk4f::Load(b.fMat + 4));
sk4f m2 = compute(sk4f::Load(b.fMat + 8));
sk4f m3 = compute(sk4f::Load(b.fMat + 12));
m0.store(fMat + 0);
m1.store(fMat + 4);
@ -256,10 +251,11 @@ SkM44& SkM44::setRotateUnitSinCos(SkV3 axis, SkScalar sinAngle, SkScalar cosAngl
SkScalar s = sinAngle;
SkScalar t = 1 - c;
return this->set44(t*x*x + c, t*x*y - s*z, t*x*z + s*y, 0,
t*x*y + s*z, t*y*y + c, t*y*z - s*x, 0,
t*x*z - s*y, t*y*z + s*x, t*z*z + c, 0,
0, 0, 0, 1);
*this = { t*x*x + c, t*x*y - s*z, t*x*z + s*y, 0,
t*x*y + s*z, t*y*y + c, t*y*z - s*x, 0,
t*x*z - s*y, t*y*z + s*x, t*z*z + c, 0,
0, 0, 0, 1 };
return *this;
}
SkM44& SkM44::setRotate(SkV3 axis, SkScalar radians) {

View File

@ -184,7 +184,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
case CONCAT44: {
const SkScalar* colMaj = reader->skipT<SkScalar>(16);
BREAK_ON_READ_ERROR(reader);
canvas->concat44(colMaj);
canvas->concat(SkM44::ColMajor(colMaj));
break;
}
case DRAW_ANNOTATION: {

View File

@ -94,7 +94,7 @@ template <> void Draw::draw(const DrawBehind& r) {
}
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
DRAW(Concat44, concat44(r.matrix));
DRAW(Concat44, concat(r.matrix));
DRAW(Concat, concat(r.matrix));
DRAW(Translate, translate(r.dx, r.dy));
DRAW(Scale, scale(r.sx, r.sy));

View File

@ -332,7 +332,7 @@ void SkRecorder::didRestore() {
}
void SkRecorder::didConcat44(const SkScalar m[16]) {
this->append<SkRecords::Concat44>(m);
this->append<SkRecords::Concat44>(SkM44::ColMajor(m));
}
void SkRecorder::didConcat(const SkMatrix& matrix) {

View File

@ -157,13 +157,6 @@ 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.
@ -203,7 +196,7 @@ RECORD(SetMatrix, 0,
RECORD(Concat, 0,
TypedMatrix matrix);
RECORD(Concat44, 0,
Matrix44 matrix);
SkM44 matrix);
RECORD(Translate, 0,
SkScalar dx;

View File

@ -96,7 +96,7 @@ void SkNWayCanvas::willRestore() {
void SkNWayCanvas::didConcat44(const SkScalar m[16]) {
Iter iter(fList);
while (iter.next()) {
iter->concat44(m);
iter->concat(SkM44::ColMajor(m));
}
}

View File

@ -968,7 +968,7 @@ DEF_TEST(M44, reporter) {
0, 0, 0, 1) == m);
const float f[] = { 1, 0, 0, 2, 3, 1, 2, 5, 0, 5, 3, 0, 0, 1, 0, 2 };
m.setColMajor(f);
m = SkM44::ColMajor(f);
m44.setColMajorf(f);
REPORTER_ASSERT(reporter, eq(m44, m, 0));
@ -980,7 +980,7 @@ DEF_TEST(M44, reporter) {
REPORTER_ASSERT(reporter, tt == m);
}
m.setRowMajor(f);
m = SkM44::RowMajor(f);
m44.setRowMajorf(f);
REPORTER_ASSERT(reporter, eq(m44, m, 0));

View File

@ -368,14 +368,13 @@ DEF_TEST(SkSLInterpreterMatrix, r) {
// M*M
{
SkM44 m;
m.setColMajor(in);
SkM44 m = SkM44::ColMajor(in);
SkM44 m2;
float in2[16];
for (int i = 0; i < 16; ++i) {
in2[i] = (i + 4) % 16;
}
m2.setColMajor(in2);
m2 = SkM44::ColMajor(in2);
m.setConcat(m, m2);
// Rearrange the columns on the RHS so we detect left-hand/right-hand errors
test(r, "float4x4 main(float4x4 m) { return m * float4x4(m[1], m[2], m[3], m[0]); }",