[ngatoy] Make an explicit ID class and simplify Cmd class
Bug: skia:11837
Change-Id: I44b8f02555c1ed7e2f1bf0872bf41f78d1eb5d25
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417003
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 2aefdaf..48c92e6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2181,6 +2181,7 @@
"experimental/ngatoy/Fake.h",
"experimental/ngatoy/SortKey.h",
"experimental/ngatoy/ngatoy.cpp",
+ "experimental/ngatoy/ngatypes.h",
]
deps = [
":flags",
diff --git a/experimental/ngatoy/Cmds.cpp b/experimental/ngatoy/Cmds.cpp
index 6818e83..34eabad 100644
--- a/experimental/ngatoy/Cmds.cpp
+++ b/experimental/ngatoy/Cmds.cpp
@@ -12,15 +12,16 @@
#include "include/effects/SkGradientShader.h"
//------------------------------------------------------------------------------------------------
-RectCmd::RectCmd(int id,
+RectCmd::RectCmd(ID id,
uint32_t paintersOrder,
SkIRect r,
const FakePaint& p,
sk_sp<FakeMCBlob> state)
- : Cmd(id, p.toID(), std::move(state))
+ : Cmd(id)
, fPaintersOrder(paintersOrder)
, fRect(r)
- , fPaint(p) {
+ , fPaint(p)
+ , fMCState(std::move(state)) {
}
SortKey RectCmd::getKey() {
@@ -96,7 +97,9 @@
return 0xFF == SkColorGetA(c);
}
-void RectCmd::rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM, unsigned int z) const {
+void RectCmd::rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM) const {
+
+ unsigned int z = fPaintersOrder;
for (int y = fRect.fTop; y < fRect.fBottom; ++y) {
for (int x = fRect.fLeft; x < fRect.fRight; ++x) {
diff --git a/experimental/ngatoy/Cmds.h b/experimental/ngatoy/Cmds.h
index a9b685c..d14f15a 100644
--- a/experimental/ngatoy/Cmds.h
+++ b/experimental/ngatoy/Cmds.h
@@ -14,51 +14,48 @@
#include "include/core/SkRect.h"
#include "experimental/ngatoy/Fake.h"
+#include "experimental/ngatoy/ngatypes.h"
class Cmd {
public:
- Cmd(int id, int materialID, sk_sp<FakeMCBlob> state)
- : fID(id)
- , fMaterialID(materialID)
- , fMCState(std::move(state)) {
- }
+ Cmd() : fID(ID::Invalid()) {}
+ Cmd(ID id) : fID(id) {}
virtual ~Cmd() {}
- int id() const { return fID; }
+ ID id() const { return fID; }
virtual SortKey getKey() = 0;
- const FakeMCBlob* state() const { return fMCState.get(); }
+ virtual const FakeMCBlob* state() const { return nullptr; }
// To generate the actual image
virtual void execute(FakeCanvas*) const = 0;
- virtual void rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM, unsigned int z) const = 0;
+ virtual void rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM) const = 0;
// To generate the expected image
virtual void execute(SkCanvas*, const FakeMCBlob* priorState) const = 0;
virtual void dump() const = 0;
protected:
- const int fID;
- int fMaterialID;
- sk_sp<FakeMCBlob> fMCState;
+ const ID fID;
private:
};
class RectCmd : public Cmd {
public:
- RectCmd(int id, uint32_t paintersOrder, SkIRect, const FakePaint&, sk_sp<FakeMCBlob> state);
+ RectCmd(ID id, uint32_t paintersOrder, SkIRect, const FakePaint&, sk_sp<FakeMCBlob> state);
SortKey getKey() override;
+ const FakeMCBlob* state() const override { return fMCState.get(); }
void execute(FakeCanvas*) const override;
void execute(SkCanvas* c, const FakeMCBlob* priorState) const override;
- void rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM, unsigned int z) const override;
+ void rasterize(uint32_t zBuffer[256][256], SkBitmap* dstBM) const override;
void dump() const override {
SkDebugf("%d: drawRect %d %d %d %d -- %d",
- fID,
+ fID.toInt(),
fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom,
fPaintersOrder);
}
@@ -66,9 +63,10 @@
protected:
private:
- uint32_t fPaintersOrder;
- SkIRect fRect;
- FakePaint fPaint;
+ uint32_t fPaintersOrder;
+ SkIRect fRect;
+ FakePaint fPaint;
+ sk_sp<FakeMCBlob> fMCState;
};
#endif // Cmds_DEFINED
diff --git a/experimental/ngatoy/Fake.cpp b/experimental/ngatoy/Fake.cpp
index 1791509..cc597e7 100644
--- a/experimental/ngatoy/Fake.cpp
+++ b/experimental/ngatoy/Fake.cpp
@@ -75,7 +75,7 @@
fTracker.push();
}
-void FakeDevice::drawRect(int id, uint32_t paintersOrder, SkIRect r, FakePaint p) {
+void FakeDevice::drawRect(ID id, uint32_t paintersOrder, SkIRect r, FakePaint p) {
sk_sp<FakeMCBlob> state = fTracker.snapState();
@@ -98,11 +98,11 @@
this->sort();
for (auto c : fSortedCmds) {
- c->rasterize(fZBuffer, &fBM, c->getKey().depth());
+ c->rasterize(fZBuffer, &fBM);
}
}
-void FakeDevice::getOrder(std::vector<int>* ops) const {
+void FakeDevice::getOrder(std::vector<ID>* ops) const {
SkASSERT(fFinalized);
// ops->reserve(fSortedCmds.size());
@@ -126,7 +126,7 @@
}
//-------------------------------------------------------------------------------------------------
-void FakeCanvas::drawRect(int id, SkIRect r, FakePaint p) {
+void FakeCanvas::drawRect(ID id, SkIRect r, FakePaint p) {
SkASSERT(!fFinalized);
fDeviceStack.back()->drawRect(id, this->nextZ(), r, p);
@@ -147,10 +147,10 @@
}
}
-std::vector<int> FakeCanvas::getOrder() const {
+std::vector<ID> FakeCanvas::getOrder() const {
SkASSERT(fFinalized);
- std::vector<int> ops;
+ std::vector<ID> ops;
for (auto& d : fDeviceStack) {
d->getOrder(&ops);
diff --git a/experimental/ngatoy/Fake.h b/experimental/ngatoy/Fake.h
index a3b75e1..296e10a 100644
--- a/experimental/ngatoy/Fake.h
+++ b/experimental/ngatoy/Fake.h
@@ -5,6 +5,7 @@
#define Fake_DEFINED
#include "experimental/ngatoy/SortKey.h"
+#include "experimental/ngatoy/ngatypes.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
@@ -254,7 +255,7 @@
~FakeDevice() {}
void save();
- void drawRect(int id, uint32_t z, SkIRect, FakePaint);
+ void drawRect(ID id, uint32_t z, SkIRect, FakePaint);
void clipRect(SkIRect r);
void translate(SkIPoint trans) {
fTracker.translate(trans);
@@ -264,7 +265,7 @@
void finalize();
- void getOrder(std::vector<int>*) const;
+ void getOrder(std::vector<ID>*) const;
sk_sp<FakeMCBlob> snapState() { return fTracker.snapState(); }
protected:
@@ -297,7 +298,7 @@
fDeviceStack.back()->save();
}
- void drawRect(int id, SkIRect, FakePaint);
+ void drawRect(ID id, SkIRect, FakePaint);
void clipRect(SkIRect);
@@ -314,7 +315,7 @@
void finalize();
- std::vector<int> getOrder() const;
+ std::vector<ID> getOrder() const;
sk_sp<FakeMCBlob> snapState() {
return fDeviceStack.back()->snapState();
}
diff --git a/experimental/ngatoy/ngatoy.cpp b/experimental/ngatoy/ngatoy.cpp
index 53ad24a..3a8e6cb 100644
--- a/experimental/ngatoy/ngatoy.cpp
+++ b/experimental/ngatoy/ngatoy.cpp
@@ -215,8 +215,8 @@
SkASSERT(state0 == state4);
}
-static void check_order(const std::vector<int>& actualOrder,
- const std::vector<int>& expectedOrder) {
+static void check_order(const std::vector<ID>& actualOrder,
+ const std::vector<ID>& expectedOrder) {
if (expectedOrder.size() != actualOrder.size()) {
exitf("Op count mismatch. Expected %d - got %d\n",
expectedOrder.size(),
@@ -227,23 +227,23 @@
SkDebugf("order mismatch:\n");
SkDebugf("E %d: ", expectedOrder.size());
for (auto t : expectedOrder) {
- SkDebugf("%d", t);
+ SkDebugf("%d", t.toInt());
}
SkDebugf("\n");
SkDebugf("A %d: ", actualOrder.size());
for (auto t : actualOrder) {
- SkDebugf("%d", t);
+ SkDebugf("%d", t.toInt());
}
SkDebugf("\n");
}
}
-typedef int (*PFTest)(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder);
+typedef int (*PFTest)(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder);
static void sort_test(PFTest testcase) {
std::vector<const Cmd*> test;
- std::vector<int> expectedOrder;
+ std::vector<ID> expectedOrder;
int testID = testcase(&test, &expectedOrder);
@@ -266,81 +266,81 @@
fake.finalize();
- std::vector<int> actualOrder = fake.getOrder();
+ std::vector<ID> actualOrder = fake.getOrder();
check_order(actualOrder, expectedOrder);
save_files(testID, expectedBM, actualBM);
}
// Simple test - green rect should appear atop the red rect
-static int test1(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test1(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// front-to-back order bc all opaque
- expectedOrder->push_back(1);
- expectedOrder->push_back(0);
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(0));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
return 1;
}
// Simple test - blue rect atop green rect atop red rect
-static int test2(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test2(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// front-to-back order bc all opaque
- expectedOrder->push_back(2);
- expectedOrder->push_back(1);
- expectedOrder->push_back(0);
+ expectedOrder->push_back(ID(2));
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(0));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
- test->push_back(new RectCmd(2, kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
+ test->push_back(new RectCmd(ID(2), kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
return 2;
}
// Transparency test - opaque blue rect atop transparent green rect atop opaque red rect
-static int test3(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test3(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// opaque draws are first and are front-to-back. Transparent draw is last.
- expectedOrder->push_back(2);
- expectedOrder->push_back(0);
- expectedOrder->push_back(1);
+ expectedOrder->push_back(ID(2));
+ expectedOrder->push_back(ID(0));
+ expectedOrder->push_back(ID(1));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(0x8000FF00), state));
- test->push_back(new RectCmd(2, kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(0x8000FF00), state));
+ test->push_back(new RectCmd(ID(2), kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
return 3;
}
// Multi-transparency test - transparent blue rect atop transparent green rect atop
// transparent red rect
-static int test4(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test4(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// All in back-to-front order bc they're all transparent
- expectedOrder->push_back(0);
- expectedOrder->push_back(1);
- expectedOrder->push_back(2);
+ expectedOrder->push_back(ID(0));
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(2));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(0x80FF0000), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(0x8000FF00), state));
- test->push_back(new RectCmd(2, kInvalidZ, r.makeOffset(98, 98), FakePaint(0x800000FF), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(0x80FF0000), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(0x8000FF00), state));
+ test->push_back(new RectCmd(ID(2), kInvalidZ, r.makeOffset(98, 98), FakePaint(0x800000FF), state));
return 4;
}
@@ -350,15 +350,15 @@
// Which gets sorted to:
// normal2, normal1, linear2, linear1, radial2, radial1
// So, front to back w/in each material type.
-static int test5(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test5(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// Note: This pushes sorting by material above sorting by Z. Thus we'll get less front to
// back benefit.
- expectedOrder->push_back(3);
- expectedOrder->push_back(0);
- expectedOrder->push_back(4);
- expectedOrder->push_back(1);
- expectedOrder->push_back(5);
- expectedOrder->push_back(2);
+ expectedOrder->push_back(ID(3));
+ expectedOrder->push_back(ID(0));
+ expectedOrder->push_back(ID(4));
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(5));
+ expectedOrder->push_back(ID(2));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
@@ -367,24 +367,24 @@
FakePaint p;
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
p.setLinear(SK_ColorGREEN, SK_ColorWHITE);
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), p, state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), p, state));
p.setRadial(SK_ColorBLUE, SK_ColorBLACK);
- test->push_back(new RectCmd(2, kInvalidZ, r.makeOffset(98, 98), p, state));
- test->push_back(new RectCmd(3, kInvalidZ, r.makeOffset(148, 148), FakePaint(SK_ColorCYAN), state));
+ test->push_back(new RectCmd(ID(2), kInvalidZ, r.makeOffset(98, 98), p, state));
+ test->push_back(new RectCmd(ID(3), kInvalidZ, r.makeOffset(148, 148), FakePaint(SK_ColorCYAN), state));
p.setLinear(SK_ColorMAGENTA, SK_ColorWHITE);
- test->push_back(new RectCmd(4, kInvalidZ, r.makeOffset(148, 8), p, state));
+ test->push_back(new RectCmd(ID(4), kInvalidZ, r.makeOffset(148, 8), p, state));
p.setRadial(SK_ColorYELLOW, SK_ColorBLACK);
- test->push_back(new RectCmd(5, kInvalidZ, r.makeOffset(8, 148), p, state));
+ test->push_back(new RectCmd(ID(5), kInvalidZ, r.makeOffset(8, 148), p, state));
return 5;
}
// simple clipping test - 1 clip w/ two opaque rects
-static int test6(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test6(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// The expected is front to back after the clip
- expectedOrder->push_back(1);
- expectedOrder->push_back(0);
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(0));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
@@ -393,22 +393,22 @@
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
return 6;
}
// more complicated clipping w/ opaque draws -> should reorder
-static int test7(std::vector<const Cmd*>* test, std::vector<int>* expectedOrder) {
+static int test7(std::vector<const Cmd*>* test, std::vector<ID>* expectedOrder) {
// The expected is front to back modulated by the two clip states
- expectedOrder->push_back(5);
- expectedOrder->push_back(4);
- expectedOrder->push_back(1);
- expectedOrder->push_back(0);
+ expectedOrder->push_back(ID(5));
+ expectedOrder->push_back(ID(4));
+ expectedOrder->push_back(ID(1));
+ expectedOrder->push_back(ID(0));
- expectedOrder->push_back(3);
- expectedOrder->push_back(2);
+ expectedOrder->push_back(ID(3));
+ expectedOrder->push_back(ID(2));
//---------------------------------------------------------------------------------------------
FakeStateTracker s;
@@ -417,21 +417,21 @@
sk_sp<FakeMCBlob> state = s.snapState();
SkIRect r{0, 0, 100, 100};
- test->push_back(new RectCmd(0, kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
- test->push_back(new RectCmd(1, kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
+ test->push_back(new RectCmd(ID(0), kInvalidZ, r.makeOffset(8, 8), FakePaint(SK_ColorRED), state));
+ test->push_back(new RectCmd(ID(1), kInvalidZ, r.makeOffset(48, 48), FakePaint(SK_ColorGREEN), state));
s.push();
s.clipRect(SkIRect::MakeXYWH(0, 85, 256, 86)); // intersect w/ the middle third in y
state = s.snapState();
- test->push_back(new RectCmd(2, kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
- test->push_back(new RectCmd(3, kInvalidZ, r.makeOffset(148, 148), FakePaint(SK_ColorCYAN), state));
+ test->push_back(new RectCmd(ID(2), kInvalidZ, r.makeOffset(98, 98), FakePaint(SK_ColorBLUE), state));
+ test->push_back(new RectCmd(ID(3), kInvalidZ, r.makeOffset(148, 148), FakePaint(SK_ColorCYAN), state));
s.pop();
state = s.snapState();
- test->push_back(new RectCmd(4, kInvalidZ, r.makeOffset(148, 8), FakePaint(SK_ColorMAGENTA), state));
- test->push_back(new RectCmd(5, kInvalidZ, r.makeOffset(8, 148), FakePaint(SK_ColorYELLOW), state));
+ test->push_back(new RectCmd(ID(4), kInvalidZ, r.makeOffset(148, 8), FakePaint(SK_ColorMAGENTA), state));
+ test->push_back(new RectCmd(ID(5), kInvalidZ, r.makeOffset(8, 148), FakePaint(SK_ColorYELLOW), state));
return 7;
}
diff --git a/experimental/ngatoy/ngatypes.h b/experimental/ngatoy/ngatypes.h
new file mode 100644
index 0000000..bc1c22c
--- /dev/null
+++ b/experimental/ngatoy/ngatypes.h
@@ -0,0 +1,35 @@
+// Copyright 2021 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+
+#ifndef NGATypes_DEFINED
+#define NGATypes_DEFINED
+
+#include "include/gpu/GrTypes.h"
+
+// This is strictly used to check if we get the order of draw operations we expected. It is
+// pretty much the same as painters order though.
+class ID {
+public:
+ explicit ID(int id) : fID(id) {
+ SkASSERT(id != -1);
+ }
+
+ static ID Invalid() {
+ return ID();
+ }
+
+ bool isValid() const { return fID != -1; }
+
+ bool operator==(ID other) const { return fID == other.fID; }
+
+ int toInt() const { return fID; }
+
+private:
+ ID() : fID(-1) {}
+
+ int fID;
+};
+
+#endif
+
+