Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / gm / convexpolyeffect.cpp
1
2 /*
3  * Copyright 2014 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 // This test only works with the GPU backend.
10
11 #include "gm.h"
12
13 #if SK_SUPPORT_GPU
14
15 #include "GrContext.h"
16 #include "GrPathUtils.h"
17 #include "GrTest.h"
18 #include "SkColorPriv.h"
19 #include "SkDevice.h"
20 #include "SkGeometry.h"
21 #include "SkTLList.h"
22
23 #include "effects/GrConvexPolyEffect.h"
24
25 namespace {
26 extern const GrVertexAttrib kAttribs[] = {
27     {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
28 };
29 }
30
31 namespace skiagm {
32 /**
33  * This GM directly exercises a GrEffect that draws convex polygons.
34  */
35 class ConvexPolyEffect : public GM {
36 public:
37     ConvexPolyEffect() {
38         this->setBGColor(0xFFFFFFFF);
39     }
40
41 protected:
42     virtual SkString onShortName() SK_OVERRIDE {
43         return SkString("convex_poly_effect");
44     }
45
46     virtual SkISize onISize() SK_OVERRIDE {
47         return SkISize::Make(720, 800);
48     }
49
50     virtual uint32_t onGetFlags() const SK_OVERRIDE {
51         // This is a GPU-specific GM.
52         return kGPUOnly_Flag;
53     }
54
55     virtual void onOnceBeforeDraw() SK_OVERRIDE {
56         SkPath tri;
57         tri.moveTo(5.f, 5.f);
58         tri.lineTo(100.f, 20.f);
59         tri.lineTo(15.f, 100.f);
60
61         fPaths.addToTail(tri);
62         fPaths.addToTail(SkPath())->reverseAddPath(tri);
63
64         tri.close();
65         fPaths.addToTail(tri);
66
67         SkPath ngon;
68         static const SkScalar kRadius = 50.f;
69         const SkPoint center = { kRadius, kRadius };
70         for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
71             SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
72             SkPoint point;
73             point.fY = SkScalarSinCos(angle, &point.fX);
74             point.scale(kRadius);
75             point = center + point;
76             if (0 == i) {
77                 ngon.moveTo(point);
78             } else {
79                 ngon.lineTo(point);
80             }
81         }
82
83         fPaths.addToTail(ngon);
84         SkMatrix scaleM;
85         scaleM.setScale(1.1f, 0.4f);
86         ngon.transform(scaleM);
87         fPaths.addToTail(ngon);
88
89         // integer edges
90         fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
91         // half-integer edges
92         fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
93         // vertically/horizontally thin rects that cover pixel centers
94         fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
95         fRects.addToTail(SkRect::MakeLTRB(5.5f,  0.5f, 29.5f, 0.75f));
96         // vertically/horizontally thin rects that don't cover pixel centers
97         fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
98         fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
99         // small in x and y
100         fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
101         // inverted in x and y
102         fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
103     }
104
105     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
106         GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
107         if (NULL == rt) {
108             return;
109         }
110         GrContext* context = rt->getContext();
111         if (NULL == context) {
112             return;
113         }
114
115         SkScalar y = 0;
116         for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
117              NULL != iter.get();
118              iter.next()) {
119             const SkPath* path = iter.get();
120             SkScalar x = 0;
121
122             for (int et = 0; et < kGrEffectEdgeTypeCnt; ++et) {
123                 GrTestTarget tt;
124                 context->getTestTarget(&tt);
125                 if (NULL == tt.target()) {
126                     SkDEBUGFAIL("Couldn't get Gr test target.");
127                     return;
128                 }
129                 GrDrawState* drawState = tt.target()->drawState();
130                 drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
131
132                 SkMatrix m;
133                 SkPath p;
134                 m.setTranslate(x, y);
135                 path->transform(m, &p);
136
137                 GrEffectEdgeType edgeType = (GrEffectEdgeType) et;
138                 SkAutoTUnref<GrEffect> effect(GrConvexPolyEffect::Create(edgeType, p));
139                 if (!effect) {
140                     continue;
141                 }
142                 drawState->addCoverageEffect(effect, 1);
143                 drawState->setIdentityViewMatrix();
144                 drawState->setRenderTarget(rt);
145                 drawState->setColor(0xff000000);
146
147                 SkPoint verts[4];
148                 SkRect bounds = p.getBounds();
149                 // Make sure any artifacts around the exterior of path are visible by using overly
150                 // conservative bounding geometry.
151                 bounds.outset(5.f, 5.f);
152                 bounds.toQuad(verts);
153
154                 tt.target()->setVertexSourceToArray(verts, 4);
155                 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
156                 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
157
158                 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
159             }
160
161             // Draw AA and non AA paths using normal API for reference.
162             canvas->save();
163             canvas->translate(x, y);
164             SkPaint paint;
165             canvas->drawPath(*path, paint);
166             canvas->translate(path->getBounds().width() + 10.f, 0);
167             paint.setAntiAlias(true);
168             canvas->drawPath(*path, paint);
169             canvas->restore();
170
171             y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
172         }
173
174         for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
175              NULL != iter.get();
176              iter.next()) {
177
178             SkScalar x = 0;
179
180             for (int et = 0; et < kGrEffectEdgeTypeCnt; ++et) {
181                 GrTestTarget tt;
182                 context->getTestTarget(&tt);
183                 if (NULL == tt.target()) {
184                     SkDEBUGFAIL("Couldn't get Gr test target.");
185                     return;
186                 }
187                 SkRect rect = *iter.get();
188                 rect.offset(x, y);
189                 GrEffectEdgeType edgeType = (GrEffectEdgeType) et;
190                 SkAutoTUnref<GrEffect> effect(GrConvexPolyEffect::Create(edgeType, rect));
191                 if (!effect) {
192                     continue;
193                 }
194
195                 GrDrawState* drawState = tt.target()->drawState();
196                 drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
197                 drawState->addCoverageEffect(effect, 1);
198                 drawState->setIdentityViewMatrix();
199                 drawState->setRenderTarget(rt);
200                 drawState->setColor(0xff000000);
201
202                 SkPoint verts[4];
203                 SkRect bounds = rect;
204                 bounds.outset(5.f, 5.f);
205                 bounds.toQuad(verts);
206
207                 tt.target()->setVertexSourceToArray(verts, 4);
208                 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
209                 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
210
211                 x += SkScalarCeilToScalar(rect.width() + 10.f);
212             }
213
214             // Draw rect without and with AA using normal API for reference
215             canvas->save();
216             canvas->translate(x, y);
217             SkPaint paint;
218             canvas->drawRect(*iter.get(), paint);
219             x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
220             paint.setAntiAlias(true);
221             canvas->drawRect(*iter.get(), paint);
222             canvas->restore();
223
224             y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
225         }
226     }
227
228 private:
229     SkTLList<SkPath> fPaths;
230     SkTLList<SkRect> fRects;
231
232     typedef GM INHERITED;
233 };
234
235 DEF_GM( return SkNEW(ConvexPolyEffect); )
236 }
237
238 #endif