c0b642ca48
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>
146 lines
5.6 KiB
C++
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
|