OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 Google Inc. | |
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 "SkTypes.h" | |
9 #include "SkPoint.h" | |
10 #include "Test.h" | |
11 #include <vector> | |
12 | |
13 #if SK_SUPPORT_GPU | |
14 | |
15 #include "GrRenderTargetPriv.h" | |
16 #include "gl/GrGLGpu.h" | |
17 #include "gl/debug/DebugGLTestContext.h" | |
18 | |
19 typedef std::vector<SkPoint> SamplePattern; | |
20 | |
21 static const SamplePattern kTestPatterns[] = { | |
22 SamplePattern{ // Intel on mac, msaa8, offscreen. | |
23 {0.562500, 0.312500}, | |
24 {0.437500, 0.687500}, | |
25 {0.812500, 0.562500}, | |
26 {0.312500, 0.187500}, | |
27 {0.187500, 0.812500}, | |
28 {0.062500, 0.437500}, | |
29 {0.687500, 0.937500}, | |
30 {0.937500, 0.062500} | |
31 }, | |
32 | |
33 SamplePattern{ // Intel on mac, msaa8, on-screen. | |
34 {0.562500, 0.687500}, | |
35 {0.437500, 0.312500}, | |
36 {0.812500, 0.437500}, | |
37 {0.312500, 0.812500}, | |
38 {0.187500, 0.187500}, | |
39 {0.062500, 0.562500}, | |
40 {0.687500, 0.062500}, | |
41 {0.937500, 0.937500} | |
42 }, | |
43 | |
44 SamplePattern{ // NVIDIA, msaa16. | |
45 {0.062500, 0.000000}, | |
46 {0.250000, 0.125000}, | |
47 {0.187500, 0.375000}, | |
48 {0.437500, 0.312500}, | |
49 {0.500000, 0.062500}, | |
50 {0.687500, 0.187500}, | |
51 {0.750000, 0.437500}, | |
52 {0.937500, 0.250000}, | |
53 {0.000000, 0.500000}, | |
54 {0.312500, 0.625000}, | |
55 {0.125000, 0.750000}, | |
56 {0.375000, 0.875000}, | |
57 {0.562500, 0.562500}, | |
58 {0.812500, 0.687500}, | |
59 {0.625000, 0.812500}, | |
60 {0.875000, 0.937500} | |
61 }, | |
62 | |
63 SamplePattern{ // NVIDIA, mixed samples, 16:1. | |
64 {0.250000, 0.125000}, | |
65 {0.625000, 0.812500}, | |
66 {0.500000, 0.062500}, | |
67 {0.812500, 0.687500}, | |
68 {0.187500, 0.375000}, | |
69 {0.875000, 0.937500}, | |
70 {0.125000, 0.750000}, | |
71 {0.750000, 0.437500}, | |
72 {0.937500, 0.250000}, | |
73 {0.312500, 0.625000}, | |
74 {0.437500, 0.312500}, | |
75 {0.000000, 0.500000}, | |
76 {0.375000, 0.875000}, | |
77 {0.687500, 0.187500}, | |
78 {0.062500, 0.000000}, | |
79 {0.562500, 0.562500} | |
80 } | |
81 }; | |
82 constexpr int numTestPatterns = SK_ARRAY_COUNT(kTestPatterns); | |
83 | |
84 class TestSampleLocationsInterface : public SkNoncopyable { | |
85 public: | |
86 virtual void overrideSamplePattern(const SamplePattern&) = 0; | |
87 virtual ~TestSampleLocationsInterface() {} | |
88 }; | |
89 | |
90 GrRenderTarget* SK_WARN_UNUSED_RESULT create_render_target(GrContext* ctx, GrSur
faceOrigin origin, | |
91 int numSamples) { | |
92 GrSurfaceDesc desc; | |
93 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
94 desc.fOrigin = origin; | |
95 desc.fWidth = 100; | |
96 desc.fHeight = 100; | |
97 desc.fConfig = kBGRA_8888_GrPixelConfig; | |
98 desc.fSampleCnt = numSamples; | |
99 return ctx->textureProvider()->createTexture(desc, SkBudgeted::kNo, 0, 0)->a
sRenderTarget(); | |
100 } | |
101 | |
102 void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern, | |
103 const GrGpu::MultisampleSpecs& specs, bool flipY) { | |
104 GrAlwaysAssert(specs.fSampleLocations); | |
105 if ((int)pattern.size() != specs.fEffectiveSampleCnt) { | |
106 REPORTER_ASSERT_MESSAGE(reporter, false, "Sample pattern has wrong numbe
r of samples."); | |
107 return; | |
108 } | |
109 for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) { | |
110 SkPoint expectedLocation = specs.fSampleLocations[i]; | |
111 if (flipY) { | |
112 expectedLocation.fY = 1 - expectedLocation.fY; | |
113 } | |
114 if (pattern[i] != expectedLocation) { | |
115 REPORTER_ASSERT_MESSAGE(reporter, false, "Sample pattern has wrong s
ample location."); | |
116 return; | |
117 } | |
118 } | |
119 } | |
120 | |
121 void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInter
face* testInterface, | |
122 GrContext* ctx) { | |
123 SkRandom rand; | |
124 SkAutoTUnref<GrRenderTarget> bottomUps[numTestPatterns]; | |
125 SkAutoTUnref<GrRenderTarget> topDowns[numTestPatterns]; | |
126 for (int i = 0; i < numTestPatterns; ++i) { | |
127 int numSamples = (int)kTestPatterns[i].size(); | |
128 GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples)); | |
129 bottomUps[i].reset(create_render_target(ctx, kBottomLeft_GrSurfaceOrigin
, | |
130 rand.nextRangeU(1 + numSamples /
2, numSamples))); | |
131 topDowns[i].reset(create_render_target(ctx, kTopLeft_GrSurfaceOrigin, | |
132 rand.nextRangeU(1 + numSamples /
2, numSamples))); | |
133 } | |
134 | |
135 // Ensure all sample locations get queried and/or cached properly. | |
136 GrStencilSettings dummyStencil; | |
137 for (int repeat = 0; repeat < 2; ++repeat) { | |
138 for (int i = 0; i < numTestPatterns; ++i) { | |
139 testInterface->overrideSamplePattern(kTestPatterns[i]); | |
140 assert_equal(reporter, kTestPatterns[i], | |
141 topDowns[i]->renderTargetPriv().getMultisampleSpecs(dum
myStencil), false); | |
142 assert_equal(reporter, kTestPatterns[i], | |
143 bottomUps[i]->renderTargetPriv().getMultisampleSpecs(du
mmyStencil), true); | |
144 } | |
145 } | |
146 } | |
147 | |
148 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | |
149 | |
150 class GLTestSampleLocationsInterface : public TestSampleLocationsInterface, publ
ic GrGLInterface { | |
151 public: | |
152 GLTestSampleLocationsInterface() : fTestContext(sk_gpu_test::CreateDebugGLTe
stContext()) { | |
153 fStandard = fTestContext->gl()->fStandard; | |
154 fExtensions = fTestContext->gl()->fExtensions; | |
155 fFunctions = fTestContext->gl()->fFunctions; | |
156 | |
157 fFunctions.fGetIntegerv = [&](GrGLenum pname, GrGLint* params) { | |
158 GrAlwaysAssert(GR_GL_EFFECTIVE_RASTER_SAMPLES != pname); | |
159 if (GR_GL_SAMPLES == pname) { | |
160 GrAlwaysAssert(!fSamplePattern.empty()); | |
161 *params = (int)fSamplePattern.size(); | |
162 } else { | |
163 fTestContext->gl()->fFunctions.fGetIntegerv(pname, params); | |
164 } | |
165 }; | |
166 | |
167 fFunctions.fGetMultisamplefv = [&](GrGLenum pname, GrGLuint index, GrGLf
loat* val) { | |
168 GrAlwaysAssert(GR_GL_SAMPLE_POSITION == pname); | |
169 val[0] = fSamplePattern[index].fX; | |
170 val[1] = fSamplePattern[index].fY; | |
171 }; | |
172 } | |
173 | |
174 operator GrBackendContext() { | |
175 return reinterpret_cast<GrBackendContext>(static_cast<GrGLInterface*>(th
is)); | |
176 } | |
177 | |
178 void overrideSamplePattern(const SamplePattern& newPattern) override { | |
179 fSamplePattern = newPattern; | |
180 } | |
181 | |
182 private: | |
183 SkAutoTDelete<sk_gpu_test::GLTestContext> fTestContext; | |
184 SamplePattern fSamplePattern; | |
185 }; | |
186 | |
187 DEF_GPUTEST(GLSampleLocations, reporter, /*factory*/) { | |
188 GLTestSampleLocationsInterface testInterface; | |
189 SkAutoTUnref<GrContext> ctx(GrContext::Create(kOpenGL_GrBackend, testInterfa
ce)); | |
190 test_sampleLocations(reporter, &testInterface, ctx); | |
191 } | |
192 | |
193 #endif | |
OLD | NEW |