skia2/tests/PrimitiveProcessorTest.cpp
Brian Salomon 62563deb6b Revert "Make GPU backend triangulate rects such that they are rendered as tri strips rather than tri fans."
This reverts commit fa2d604a7d.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> Make GPU backend triangulate rects such that they are rendered as tri strips rather than tri fans.
> 
> Right now when we turn rects into quads we use a vertex order compatible with a tri fan rather than a tri strip.
> 
> I wanted it to be the case that the same code could be used to generate a non-indexed mesh for a single rect or indexed using the quad index buffer when batching. Triangle fanning is not available in all APIS (e.g. is emulated in ANGLE and not supported in Metal) so it seems better to use a triangle strip over a fan in the single rect case.
> 
> 
> Change-Id: I31eebd794e7328f4b39e3ec3377bf2ec556360ca
> Reviewed-on: https://skia-review.googlesource.com/60081
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>

TBR=bsalomon@google.com,robertphillips@google.com

Change-Id: I7c4c23aa418da09c9708b28cce64ab58e282dd3a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/60683
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
2017-10-17 19:14:15 +00:00

150 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 "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<GrDrawOp> Make(int numAttribs) {
return std::unique_ptr<GrDrawOp>(new Op(numAttribs));
}
FixedFunctionFlags fixedFunctionFlags() const override {
return FixedFunctionFlags::kNone;
}
RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,\
GrPixelConfigIsClamped) override {
return RequiresDstTexture::kNo;
}
private:
Op(int numAttribs) : INHERITED(ClassID()), fNumAttribs(numAttribs) {
this->setBounds(SkRect::MakeWH(1.f, 1.f), HasAABloat::kNo, IsZeroArea::kNo);
}
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
void onPrepareDraws(Target* target) override {
class GP : public GrGeometryProcessor {
public:
GP(int numAttribs)
: INHERITED(kGP_ClassID) {
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(), kFloat2_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->writeOutputPosition(args.fVertBuilder, gpArgs, gp.getAttrib(0).fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(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;
typedef GrGeometryProcessor INHERITED;
};
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(),
target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
target->detachAppliedClip()));
}
int fNumAttribs;
typedef GrMeshDrawOp INHERITED;
};
}
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
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_addDrawOp(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_addDrawOp(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