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