| 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 |