| Index: gm/convexpolyeffect.cpp
|
| diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f438a08b931317373e6560aaec22bb6e4a32017f
|
| --- /dev/null
|
| +++ b/gm/convexpolyeffect.cpp
|
| @@ -0,0 +1,172 @@
|
| +
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +// This test only works with the GPU backend.
|
| +
|
| +#include "gm.h"
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +
|
| +#include "GrContext.h"
|
| +#include "GrPathUtils.h"
|
| +#include "GrTest.h"
|
| +#include "SkColorPriv.h"
|
| +#include "SkDevice.h"
|
| +#include "SkGeometry.h"
|
| +#include "SkTLList.h"
|
| +
|
| +#include "effects/GrConvexPolyEffect.h"
|
| +
|
| +namespace {
|
| +extern const GrVertexAttrib kAttribs[] = {
|
| + {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
| +};
|
| +}
|
| +
|
| +namespace skiagm {
|
| +/**
|
| + * This GM directly exercises a GrEffect that draws convex polygons.
|
| + */
|
| +class ConvexPolyEffect : public GM {
|
| +public:
|
| + ConvexPolyEffect() {
|
| + this->setBGColor(0xFFFFFFFF);
|
| + }
|
| +
|
| +protected:
|
| + virtual SkString onShortName() SK_OVERRIDE {
|
| + return SkString("convex_poly_effect");
|
| + }
|
| +
|
| + virtual SkISize onISize() SK_OVERRIDE {
|
| + return make_isize(475, 530);
|
| + }
|
| +
|
| + virtual uint32_t onGetFlags() const SK_OVERRIDE {
|
| + // This is a GPU-specific GM.
|
| + return kGPUOnly_Flag;
|
| + }
|
| +
|
| + virtual void onOnceBeforeDraw() SK_OVERRIDE {
|
| + SkPath tri;
|
| + tri.moveTo(5.f, 5.f);
|
| + tri.lineTo(100.f, 20.f);
|
| + tri.lineTo(15.f, 100.f);
|
| +
|
| + fPaths.addToTail(tri);
|
| + fPaths.addToTail(SkPath())->reverseAddPath(tri);
|
| +
|
| + tri.close();
|
| + fPaths.addToTail(tri);
|
| +
|
| + SkPath ngon;
|
| + static const SkScalar kRadius = 50.f;
|
| + const SkPoint center = { kRadius, kRadius };
|
| + for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
|
| + SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
|
| + SkPoint point;
|
| + point.fY = SkScalarSinCos(angle, &point.fX);
|
| + point.scale(kRadius);
|
| + point = center + point;
|
| + if (0 == i) {
|
| + ngon.moveTo(point);
|
| + } else {
|
| + ngon.lineTo(point);
|
| + }
|
| + }
|
| +
|
| + fPaths.addToTail(ngon);
|
| + SkMatrix scaleM;
|
| + scaleM.setScale(1.1f, 0.4f);
|
| + ngon.transform(scaleM);
|
| + fPaths.addToTail(ngon);
|
| + }
|
| +
|
| + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
| + SkBaseDevice* device = canvas->getTopDevice();
|
| + GrRenderTarget* rt = device->accessRenderTarget();
|
| + if (NULL == rt) {
|
| + return;
|
| + }
|
| + GrContext* context = rt->getContext();
|
| + if (NULL == context) {
|
| + return;
|
| + }
|
| +
|
| + const SkPath* path;
|
| + SkScalar y = 0;
|
| + for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
|
| + NULL != (path = iter.get());
|
| + iter.next()) {
|
| + SkScalar x = 0;
|
| +
|
| + for (int et = 0; et < GrConvexPolyEffect::kEdgeTypeCnt; ++et) {
|
| + GrTestTarget tt;
|
| + context->getTestTarget(&tt);
|
| + if (NULL == tt.target()) {
|
| + SkDEBUGFAIL("Couldn't get Gr test target.");
|
| + return;
|
| + }
|
| + GrDrawState* drawState = tt.target()->drawState();
|
| + drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
|
| +
|
| + SkMatrix m;
|
| + SkPath p;
|
| + m.setTranslate(x, y);
|
| + path->transform(m, &p);
|
| +
|
| + GrConvexPolyEffect::EdgeType edgeType = (GrConvexPolyEffect::EdgeType) et;
|
| + SkAutoTUnref<GrEffectRef> effect(GrConvexPolyEffect::Create(edgeType, p));
|
| + if (!effect) {
|
| + SkDEBUGFAIL("Couldn't create convex poly effect.");
|
| + return;
|
| + }
|
| + drawState->addCoverageEffect(effect, 1);
|
| + drawState->setIdentityViewMatrix();
|
| + drawState->setRenderTarget(rt);
|
| + drawState->setColor(0xff000000);
|
| +
|
| + SkPoint verts[4];
|
| + SkRect bounds = p.getBounds();
|
| + // Make sure any artifacts around the exterior of path are visible by using overly
|
| + // conservative bounding geometry.
|
| + bounds.outset(5.f, 5.f);
|
| + bounds.toQuad(verts);
|
| +
|
| + tt.target()->setVertexSourceToArray(verts, 4);
|
| + tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
|
| + tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
|
| +
|
| + x += path->getBounds().width() + 10.f;
|
| + }
|
| +
|
| + // Draw AA and non AA paths using normal API for reference.
|
| + canvas->save();
|
| + canvas->translate(x, y);
|
| + SkPaint paint;
|
| + canvas->drawPath(*path, paint);
|
| + canvas->translate(path->getBounds().width() + 10.f, 0);
|
| + paint.setAntiAlias(true);
|
| + canvas->drawPath(*path, paint);
|
| + canvas->restore();
|
| +
|
| + y += path->getBounds().height() + 20.f;
|
| + }
|
| + }
|
| +
|
| +private:
|
| + SkTLList<SkPath> fPaths;
|
| +
|
| + typedef GM INHERITED;
|
| +};
|
| +
|
| +DEF_GM( return SkNEW(ConvexPolyEffect); )
|
| +
|
| +}
|
| +
|
| +#endif
|
|
|