skia2/tests/GpuSampleLocationsTest.cpp
Brian Salomon dcfca431e3 Use GrContextFactories that produce a single GrContext in unit tests.
This is to alleviate problems due to the command buffer getting bent out of shape when the current
OpenGL context is switched out from under it (because we ran a test with a native GL context). This,
however is not a full solution. More changes will be required to ensure that after running each
command buffer or native test we bind the null context. This does allow us to take a step in that
direction without breaking anything too badly. Moreover, there is no real benefit to reusing a
GrContextFactory.

Modifies DEF_GPUTEST to take GrContextOptions rather than a factory to use. Tests were already using
their own factories anyway.

In tests that use GrContextFactory the factory instance is moved to the inner loop.

Modifies gpucts and skia_test to not use persistent GrContextFactories.

Change-Id: Ie7a36793545c775f2f30653ead6fec93a3d22717
Reviewed-on: https://skia-review.googlesource.com/71861
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
2017-11-15 22:03:07 +00:00

200 lines
6.9 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkTypes.h"
#include "SkPoint.h"
#include "Test.h"
#include <vector>
#if SK_SUPPORT_GPU
#include "GrAppliedClip.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetPriv.h"
#include "GrTypesPriv.h"
#include "gl/GrGLGpu.h"
#include "gl/debug/DebugGLTestContext.h"
typedef std::vector<SkPoint> SamplePattern;
static const SamplePattern kTestPatterns[] = {
SamplePattern{ // Intel on mac, msaa8, offscreen.
{0.562500, 0.312500},
{0.437500, 0.687500},
{0.812500, 0.562500},
{0.312500, 0.187500},
{0.187500, 0.812500},
{0.062500, 0.437500},
{0.687500, 0.937500},
{0.937500, 0.062500}
},
SamplePattern{ // Intel on mac, msaa8, on-screen.
{0.562500, 0.687500},
{0.437500, 0.312500},
{0.812500, 0.437500},
{0.312500, 0.812500},
{0.187500, 0.187500},
{0.062500, 0.562500},
{0.687500, 0.062500},
{0.937500, 0.937500}
},
SamplePattern{ // NVIDIA, msaa16.
{0.062500, 0.000000},
{0.250000, 0.125000},
{0.187500, 0.375000},
{0.437500, 0.312500},
{0.500000, 0.062500},
{0.687500, 0.187500},
{0.750000, 0.437500},
{0.937500, 0.250000},
{0.000000, 0.500000},
{0.312500, 0.625000},
{0.125000, 0.750000},
{0.375000, 0.875000},
{0.562500, 0.562500},
{0.812500, 0.687500},
{0.625000, 0.812500},
{0.875000, 0.937500}
},
SamplePattern{ // NVIDIA, mixed samples, 16:1.
{0.250000, 0.125000},
{0.625000, 0.812500},
{0.500000, 0.062500},
{0.812500, 0.687500},
{0.187500, 0.375000},
{0.875000, 0.937500},
{0.125000, 0.750000},
{0.750000, 0.437500},
{0.937500, 0.250000},
{0.312500, 0.625000},
{0.437500, 0.312500},
{0.000000, 0.500000},
{0.375000, 0.875000},
{0.687500, 0.187500},
{0.062500, 0.000000},
{0.562500, 0.562500}
}
};
constexpr int numTestPatterns = SK_ARRAY_COUNT(kTestPatterns);
class TestSampleLocationsInterface : public SkNoncopyable {
public:
virtual void overrideSamplePattern(const SamplePattern&) = 0;
virtual ~TestSampleLocationsInterface() {}
};
void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
const GrGpu::MultisampleSpecs& specs, bool flipY) {
GrAlwaysAssert(specs.fSampleLocations);
if ((int)pattern.size() != specs.fEffectiveSampleCnt) {
REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong number of samples."));
return;
}
for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
SkPoint expectedLocation = specs.fSampleLocations[i];
if (flipY) {
expectedLocation.fY = 1 - expectedLocation.fY;
}
if (pattern[i] != expectedLocation) {
REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong sample location."));
return;
}
}
}
void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInterface* testInterface,
GrContext* ctx) {
SkRandom rand;
sk_sp<GrRenderTargetContext> bottomUps[numTestPatterns];
sk_sp<GrRenderTargetContext> topDowns[numTestPatterns];
for (int i = 0; i < numTestPatterns; ++i) {
int numSamples = (int)kTestPatterns[i].size();
GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples));
bottomUps[i] = ctx->makeDeferredRenderTargetContext(
SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo,
kBottomLeft_GrSurfaceOrigin);
topDowns[i] = ctx->makeDeferredRenderTargetContext(
SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo,
kTopLeft_GrSurfaceOrigin);
}
// Ensure all sample locations get queried and/or cached properly.
for (int repeat = 0; repeat < 2; ++repeat) {
for (int i = 0; i < numTestPatterns; ++i) {
testInterface->overrideSamplePattern(kTestPatterns[i]);
for (GrRenderTargetContext* rtc : {bottomUps[i].get(), topDowns[i].get()}) {
GrPipeline dummyPipeline(rtc->asRenderTargetProxy(),
GrPipeline::ScissorState::kDisabled,
SkBlendMode::kSrcOver);
GrRenderTarget* rt = rtc->accessRenderTarget();
assert_equal(reporter, kTestPatterns[i],
rt->renderTargetPriv().getMultisampleSpecs(dummyPipeline),
kBottomLeft_GrSurfaceOrigin == rtc->asSurfaceProxy()->origin());
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
class GLTestSampleLocationsInterface : public TestSampleLocationsInterface, public GrGLInterface {
public:
GLTestSampleLocationsInterface() : fTestContext(sk_gpu_test::CreateDebugGLTestContext()) {
fStandard = fTestContext->gl()->fStandard;
fExtensions = fTestContext->gl()->fExtensions;
fFunctions = fTestContext->gl()->fFunctions;
fFunctions.fGetIntegerv = [&](GrGLenum pname, GrGLint* params) {
GrAlwaysAssert(GR_GL_EFFECTIVE_RASTER_SAMPLES != pname);
if (GR_GL_SAMPLES == pname) {
GrAlwaysAssert(!fSamplePattern.empty());
*params = (int)fSamplePattern.size();
} else {
fTestContext->gl()->fFunctions.fGetIntegerv(pname, params);
}
};
fFunctions.fGetMultisamplefv = [&](GrGLenum pname, GrGLuint index, GrGLfloat* val) {
GrAlwaysAssert(GR_GL_SAMPLE_POSITION == pname);
val[0] = fSamplePattern[index].fX;
val[1] = fSamplePattern[index].fY;
};
}
operator GrBackendContext() {
return reinterpret_cast<GrBackendContext>(static_cast<GrGLInterface*>(this));
}
void overrideSamplePattern(const SamplePattern& newPattern) override {
fSamplePattern = newPattern;
}
private:
std::unique_ptr<sk_gpu_test::GLTestContext> fTestContext;
SamplePattern fSamplePattern;
};
DEF_GPUTEST(GLSampleLocations, reporter, /* options */) {
GLTestSampleLocationsInterface testInterface;
sk_sp<GrContext> ctx(GrContext::MakeGL(&testInterface));
// This test relies on at least 2 samples.
int supportedSample = ctx->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
if (supportedSample < 2) {
return;
}
test_sampleLocations(reporter, &testInterface, ctx.get());
}
#endif