blob: 4ec445861ea65471981095f7ecd4451d51adbf9a [file] [log] [blame]
Robert Phillipse837e612019-11-15 11:02:50 -05001/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/GrClip.h"
9#include "src/gpu/GrContextPriv.h"
10#include "src/gpu/GrRenderTargetContext.h"
11#include "src/gpu/ops/GrFillRectOp.h"
12#include "src/gpu/ops/GrTextureOp.h"
13#include "tests/Test.h"
14
15static std::unique_ptr<GrRenderTargetContext> new_RTC(GrContext* context) {
16 return context->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 128, 128,
17 GrColorType::kRGBA_8888, nullptr);
18}
19
20#if 0
21sk_sp<GrSurfaceProxy> create_proxy(GrContext* context) {
22 GrSurfaceDesc desc;
23 desc.fConfig = kRGBA_8888_GrPixelConfig;
24 desc.fWidth = 128;
25 desc.fHeight = 128;
26
27 const GrBackendFormat format = context->priv().caps()->getDefaultBackendFormat(
28 GrColorType::kRGBA_8888,
29 GrRenderable::kYes);
30
31 return context->priv().proxyProvider()->createProxy(
32 format, desc, GrRenderable::kYes, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
33 SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, GrInternalSurfaceFlags::kNone);
34}
35#endif
36
37typedef GrQuadAAFlags (*PerQuadAAFunc)(int i);
38
39typedef void (*BulkRectTest)(skiatest::Reporter* reporter, GrContext* context,
40 PerQuadAAFunc perQuadAA, GrAAType overallAA,
41 int requestedTotNumQuads, int expectedNumOps);
42
43//-------------------------------------------------------------------------------------------------
44static void bulk_fill_rect_create_test(skiatest::Reporter* reporter, GrContext* context,
45 PerQuadAAFunc perQuadAA, GrAAType overallAA,
46 int requestedTotNumQuads, int expectedNumOps) {
47
48 std::unique_ptr<GrRenderTargetContext> rtc = new_RTC(context);
49
50 auto quads = new GrRenderTargetContext::QuadSetEntry[requestedTotNumQuads];
51
52 for (int i = 0; i < requestedTotNumQuads; ++i) {
53 quads[i].fRect = SkRect::MakeWH(100.5f, 100.5f); // prevent the int non-AA optimization
54 quads[i].fColor = SK_PMColor4fWHITE;
55 quads[i].fLocalMatrix = SkMatrix::I();
56 quads[i].fAAFlags = perQuadAA(i);
57 }
58
59 GrPaint paint;
60
61 GrFillRectOp::AddFillRectOps(rtc.get(), GrNoClip(), context, std::move(paint), overallAA,
62 SkMatrix::I(), quads, requestedTotNumQuads);
63
64 GrOpsTask* opsTask = rtc->testingOnly_PeekLastOpsTask();
65 int actualNumOps = opsTask->numOpChains();
66
67 int actualTotNumQuads = 0;
68
69 for (int i = 0; i < actualNumOps; ++i) {
70 const GrOp* tmp = opsTask->getChain(i);
71 REPORTER_ASSERT(reporter, tmp->classID() == GrFillRectOp::ClassID());
72 REPORTER_ASSERT(reporter, tmp->isChainTail());
73 actualTotNumQuads += ((GrDrawOp*) tmp)->numQuads();
74 }
75
76 REPORTER_ASSERT(reporter, expectedNumOps == actualNumOps);
77 REPORTER_ASSERT(reporter, requestedTotNumQuads == actualTotNumQuads);
78
79 context->flush();
80
81 delete[] quads;
82}
83
84#if 0
85//-------------------------------------------------------------------------------------------------
86static void bulk_texture_rect_create_test(skiatest::Reporter* reporter, GrContext* context,
87 PerQuadAAFunc perQuadAA, GrAAType overallAA,
88 int requestedTotNumQuads, int expectedNumOps) {
89
90 std::unique_ptr<GrRenderTargetContext> rtc = new_RTC(context);
91
92 sk_sp<GrSurfaceProxy> proxy = create_proxy(context);
93
94 GrSurfaceProxyView proxyView(std::move(proxy), kTopLeft_GrSurfaceOrigin, GrSwizzle::RGBA());
95
96 auto set = new GrRenderTargetContext::TextureSetEntry[requestedTotNumQuads];
97
98 for (int i = 0; i < requestedTotNumQuads; ++i) {
99 set[i].fProxyView = proxyView;
100 set[i].fSrcColorType = GrColorType::kRGBA_8888;
101 set[i].fSrcRect = SkRect::MakeWH(100.0f, 100.0f);
102 set[i].fDstRect = SkRect::MakeWH(100.5f, 100.5f); // prevent the int non-AA optimization
103 set[i].fDstClipQuad = nullptr;
104 set[i].fPreViewMatrix = nullptr;
105 set[i].fAlpha = 1.0f;
106 set[i].fAAFlags = perQuadAA(i);
107 }
108
109 GrTextureOp::CreateTextureSetOps(rtc.get(), GrNoClip(), context, set, requestedTotNumQuads,
110 GrSamplerState::Filter::kNearest,
111 GrTextureOp::Saturate::kYes,
112 overallAA,
113 SkCanvas::kStrict_SrcRectConstraint,
114 SkMatrix::I(), nullptr);
115
116 GrOpsTask* opsTask = rtc->testingOnly_PeekLastOpsTask();
117 int actualNumOps = opsTask->numOpChains();
118
119 int actualTotNumQuads = 0;
120
121 for (int i = 0; i < actualNumOps; ++i) {
122 const GrOp* tmp = opsTask->getChain(i);
123 REPORTER_ASSERT(reporter, tmp->classID() == GrTextureOp::ClassID());
124 REPORTER_ASSERT(reporter, tmp->isChainTail());
125 actualTotNumQuads += ((GrDrawOp*) tmp)->numQuads();
126 }
127
128 REPORTER_ASSERT(reporter, expectedNumOps == actualNumOps);
129 REPORTER_ASSERT(reporter, requestedTotNumQuads == actualTotNumQuads);
130
131 context->flush();
132
133 delete[] set;
134}
135#endif
136
137//-------------------------------------------------------------------------------------------------
138static void run_test(GrContext* context, skiatest::Reporter* reporter, BulkRectTest test) {
139
140 if (!context->priv().caps()->dynamicStateArrayGeometryProcessorTextureSupport()) {
141 return;
142 }
143
144 // This is the simple case where there is no AA at all. We expect 2 non-AA clumps of quads.
145 {
146 auto noAA = [](int i) -> GrQuadAAFlags {
147 return GrQuadAAFlags::kNone;
148 };
149
150 static const int kNumExpectedOps = 2;
151
152 test(reporter, context, noAA, GrAAType::kNone,
153 2*GrResourceProvider::MaxNumNonAAQuads(), kNumExpectedOps);
154 }
155
156 // This is the same as the above case except the overall AA is kCoverage. However, since
157 // the per-quad AA is still none, all the quads should be downgraded to non-AA.
158 {
159 auto noAA = [](int i) -> GrQuadAAFlags {
160 return GrQuadAAFlags::kNone;
161 };
162
163 static const int kNumExpectedOps = 2;
164
165 test(reporter, context, noAA, GrAAType::kCoverage,
166 2*GrResourceProvider::MaxNumNonAAQuads(), kNumExpectedOps);
167 }
168
169 // This case has an overall AA of kCoverage but the per-quad AA alternates.
170 // We should end up with several aa-sized clumps
171 {
172 auto alternateAA = [](int i) -> GrQuadAAFlags {
173 return (i % 2) ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone;
174 };
175
176 int numExpectedOps = 2*GrResourceProvider::MaxNumNonAAQuads() /
177 GrResourceProvider::MaxNumAAQuads();
178
179 test(reporter, context, alternateAA, GrAAType::kCoverage,
180 2*GrResourceProvider::MaxNumNonAAQuads(), numExpectedOps);
181 }
182
183 // In this case we have a run of MaxNumAAQuads non-AA quads and then AA quads. This
184 // exercises the case where we have a clump of quads that can't be upgraded to AA bc of
185 // its size. We expect one clump of non-AA quads followed by one clump of AA quads.
186 {
187 auto runOfNonAA = [](int i) -> GrQuadAAFlags {
188 return (i < GrResourceProvider::MaxNumAAQuads()) ? GrQuadAAFlags::kNone
189 : GrQuadAAFlags::kAll;
190 };
191
192 static const int kNumExpectedOps = 2;
193
194 test(reporter, context, runOfNonAA, GrAAType::kCoverage,
195 2*GrResourceProvider::MaxNumAAQuads(), kNumExpectedOps);
196 }
197}
198
199DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BulkFillRectTest, reporter, ctxInfo) {
200 run_test(ctxInfo.grContext(), reporter, bulk_fill_rect_create_test);
201}
202
203#if 0
204DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BulkTextureRectTest, reporter, ctxInfo) {
205 run_test(ctxInfo.grContext(), reporter, bulk_texture_rect_create_test);
206}
207#endif