63static constexpr int kNumOpPositions = 4;
64static constexpr Range kRanges[] = {{0, 4,}, {1, 2}};
65static constexpr int kNumRanges = (
int)std::size(kRanges);
66static constexpr int kNumRepeats = 2;
67static constexpr int kNumOps = kNumRepeats * kNumOpPositions * kNumRanges;
69static constexpr uint64_t fact(
int n) {
71 return n > 1 ? n * fact(n - 1) : 1;
75static constexpr unsigned result_width() {
76 unsigned maxLength = 0;
77 for (
size_t i = 0; i < kNumRanges; ++i) {
78 maxLength = maxLength > kRanges[i].fLength ? maxLength : kRanges[i].fLength;
80 return kNumOpPositions + maxLength - 1;
84static constexpr int kNumCombinableValues = fact(kNumOps) / fact(kNumOps - 2);
85using Combinable = std::array<GrOp::CombineResult, kNumCombinableValues>;
91int64_t combinable_index(
int a,
int b) {
94 int64_t aOffset =
a * (kNumOps - 1);
96 int64_t bIdxInA =
b <
a ?
b :
b - 1;
97 return aOffset + bIdxInA;
104static void init_combinable(
int numGroups, Combinable* combinable,
SkRandom* random) {
108 for (
int i = 0; i < kNumOps; ++i) {
110 for (
int g = 0; g <
group.size(); ++g) {
131class TestOp :
public GrOp {
136 int result[],
const Combinable* combinable) {
137 return GrOp::Make<TestOp>(context, value, range,
result, combinable);
140 const char*
name()
const override {
return "TestOp"; }
142 void writeResult(
int result[])
const {
143 for (
const auto& op : ChainRange<TestOp>(this)) {
144 for (
const auto& vr : op.fValueRanges) {
145 for (
unsigned i = 0; i < vr.fRange.fLength; ++i) {
146 result[vr.fRange.fOffset + i] = vr.fValue;
155 TestOp(
int value,
const Range& range,
int result[],
const Combinable* combinable)
157 fValueRanges.push_back({
value, range});
158 this->setBounds(
SkRect::MakeXYWH(range.fOffset, 0, range.fOffset + range.fLength, 1),
159 HasAABloat::kNo, IsHairline::kNo);
172 for (
auto& op : ChainRange<TestOp>(this)) {
173 op.writeResult(fResult);
181 auto that = t->
cast<TestOp>();
182 int v0 = fValueRanges[0].fValue;
183 int v1 = that->fValueRanges[0].fValue;
184 auto result = (*fCombinable)[combinable_index(v0, v1)];
186 std::move(that->fValueRanges.begin(), that->fValueRanges.end(),
187 std::back_inserter(fValueRanges));
196 std::vector<ValueRange> fValueRanges;
198 const Combinable* fCombinable;
212 const GrCaps* caps = dContext->priv().caps();
213 static constexpr SkISize kDims = {kNumOps + 1, 1};
219 auto proxy = dContext->priv().proxyProvider()->createProxy(
format,
223 skgpu::Mipmapped::kNo,
230 proxy->instantiate(dContext->priv().resourceProvider());
234 int result[result_width()];
235 int validResult[result_width()];
237 int permutation[kNumOps];
238 for (
int i = 0; i < kNumOps; ++i) {
242 static constexpr int kNumPermutations = 100;
245 static constexpr int kNumCombinabilitiesPerGrouping = 20;
248 Combinable combinable;
251 for (
int p = 0; p < kNumPermutations; ++p) {
252 for (
int i = 0; i < kNumOps - 2 && !
repeat; ++i) {
255 std::swap(permutation[i], permutation[j]);
258 for (
int g = 1; g < kNumOps; ++g) {
259 for (
int c = 0; c < kNumCombinabilitiesPerGrouping; ++c) {
260 init_combinable(g, &combinable, &random);
263 dContext->priv().resourceProvider(),
267 dContext->priv().auditTrail(),
270 std::fill_n(
result, result_width(), -1);
271 std::fill_n(validResult, result_width(), -1);
272 for (
int i = 0; i < kNumOps; ++i) {
273 int value = permutation[i];
276 int j =
value % (kNumRanges * kNumOpPositions);
277 int pos = j % kNumOpPositions;
278 Range range = kRanges[j / kNumOpPositions];
279 range.fOffset +=
pos;
280 auto op = TestOp::Make(dContext.
get(),
value, range,
result, &combinable);
281 TestOp* testOp = (TestOp*)op.get();
282 testOp->writeResult(validResult);
283 opsTask.
addOp(drawingMgr, std::move(op),
287 opsTask.makeClosed(dContext.
get());
291 opsTask.
disown(drawingMgr);
293 if (!std::equal(
result,
result + result_width(), validResult)) {
#define DEFINE_OP_CLASS_ID
@ kTopLeft_GrSurfaceOrigin
static unsigned repeat(SkFixed fx, int max)
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
#define DEF_GANESH_TEST(name, reporter, options, ctsEnforcement)
#define REPORTER_ASSERT(r, cond,...)
Type::kYUV Type::kRGBA() int(0.7 *637)
virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const =0
GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
std::unique_ptr< GrOp > Owner
void prepare(GrOpFlushState *flushState)
bool execute(GrOpFlushState *flushState)
virtual void disown(GrDrawingManager *)
uint32_t nextULessThan(uint32_t count)
void endFlush(GrDrawingManager *) override
void addOp(GrDrawingManager *, GrOp::Owner, GrTextureResolveManager, const GrCaps &)
uint32_t uint32_t * format
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)