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 |