skia2/tests/PrimitiveProcessorTest.cpp
Brian Salomon c0b642ca48 Split GrPipelineInput into separate color and coverage types, the latter of which is just an enum.
Assign names that indicate that they aren't just for the input phase since I plan to use them at the boundary between FPs and XPs as well.

Renamed GrProcOptInfo to GrColorFragmentProcessorAnalysis. This is now only used on the color side and the new name seems clearer to me.

Change GrMeshDrawOp::getFragmentProcessorAnalysisInputs to use the new color/coverage types directly rather than a class that has been reduced to simply bundling them together.

Change-Id: If93bae74c9d590486eecdf63f302418c96deab65
Reviewed-on: https://skia-review.googlesource.com/10161
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
2017-03-27 17:45:29 +00:00

146 lines
5.6 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.
*/
// This is a GPU-backend specific test. It relies on static intializers to work
#include "SkTypes.h"
#include "Test.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "GrGeometryProcessor.h"
#include "GrGpu.h"
#include "GrOpFlushState.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrResourceProvider.h"
#include "SkString.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLVarying.h"
#include "ops/GrMeshDrawOp.h"
namespace {
class Op : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
const char* name() const override { return "Dummy Op"; }
static std::unique_ptr<GrMeshDrawOp> Make(int numAttribs) {
return std::unique_ptr<GrMeshDrawOp>(new Op(numAttribs));
}
private:
Op(int numAttribs) : INHERITED(ClassID()), fNumAttribs(numAttribs) {
this->setBounds(SkRect::MakeWH(1.f, 1.f), HasAABloat::kNo, IsZeroArea::kNo);
}
void getFragmentProcessorAnalysisInputs(GrPipelineAnalysisColor* color,
GrPipelineAnalysisCoverage* coverage) const override {
color->setToUnknown();
*coverage = GrPipelineAnalysisCoverage::kSingleChannel;
}
void applyPipelineOptimizations(const GrPipelineOptimizations&) override {}
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
void onPrepareDraws(Target* target) const override {
class GP : public GrGeometryProcessor {
public:
GP(int numAttribs) {
this->initClassID<GP>();
SkASSERT(numAttribs > 1);
for (auto i = 0; i < numAttribs; ++i) {
fAttribNames.push_back().printf("attr%d", i);
}
for (auto i = 0; i < numAttribs; ++i) {
this->addVertexAttrib(fAttribNames[i].c_str(), kVec2f_GrVertexAttribType);
}
}
const char* name() const override { return "Dummy GP"; }
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
class GLSLGP : public GrGLSLGeometryProcessor {
public:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const GP& gp = args.fGP.cast<GP>();
args.fVaryingHandler->emitAttributes(gp);
this->setupPosition(args.fVertBuilder, gpArgs, gp.fAttribs[0].fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputColor);
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc,
FPCoordTransformIter&&) override {}
};
return new GLSLGP();
}
void getGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* builder) const override {
builder->add32(this->numAttribs());
}
private:
SkTArray<SkString> fAttribNames;
};
sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs));
QuadHelper helper;
size_t vertexStride = gp->getVertexStride();
SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
vertices->setRectFan(0.f, 0.f, 1.f, 1.f, vertexStride);
helper.recordDraw(target, gp.get());
}
int fNumAttribs;
typedef GrMeshDrawOp INHERITED;
};
}
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeRenderTargetContext(
SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig,
nullptr));
if (!renderTargetContext) {
ERRORF(reporter, "Could not create render target context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
GrPaint grPaint;
// This one should succeed.
renderTargetContext->priv().testingOnly_addMeshDrawOp(GrPaint(grPaint), GrAAType::kNone,
Op::Make(attribCnt));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
renderTargetContext->priv().testingOnly_addMeshDrawOp(std::move(grPaint), GrAAType::kNone,
Op::Make(attribCnt + 1));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
#endif