Update To 11.40.268.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 skiagm {
26 /**
27  * This GM directly exercises a GrProcessor that draws convex polygons.
28  */
29 class ConvexPolyEffect : public GM {
30 public:
31     ConvexPolyEffect() {
32         this->setBGColor(0xFFFFFFFF);
33     }
34
35 protected:
36     virtual SkString onShortName() SK_OVERRIDE {
37         return SkString("convex_poly_effect");
38     }
39
40     virtual SkISize onISize() SK_OVERRIDE {
41         return SkISize::Make(720, 800);
42     }
43
44     virtual uint32_t onGetFlags() const SK_OVERRIDE {
45         // This is a GPU-specific GM.
46         return kGPUOnly_Flag;
47     }
48
49     virtual void onOnceBeforeDraw() SK_OVERRIDE {
50         SkPath tri;
51         tri.moveTo(5.f, 5.f);
52         tri.lineTo(100.f, 20.f);
53         tri.lineTo(15.f, 100.f);
54
55         fPaths.addToTail(tri);
56         fPaths.addToTail(SkPath())->reverseAddPath(tri);
57
58         tri.close();
59         fPaths.addToTail(tri);
60
61         SkPath ngon;
62         static const SkScalar kRadius = 50.f;
63         const SkPoint center = { kRadius, kRadius };
64         for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
65             SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
66             SkPoint point;
67             point.fY = SkScalarSinCos(angle, &point.fX);
68             point.scale(kRadius);
69             point = center + point;
70             if (0 == i) {
71                 ngon.moveTo(point);
72             } else {
73                 ngon.lineTo(point);
74             }
75         }
76
77         fPaths.addToTail(ngon);
78         SkMatrix scaleM;
79         scaleM.setScale(1.1f, 0.4f);
80         ngon.transform(scaleM);
81         fPaths.addToTail(ngon);
82
83         // integer edges
84         fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
85         // half-integer edges
86         fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
87         // vertically/horizontally thin rects that cover pixel centers
88         fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
89         fRects.addToTail(SkRect::MakeLTRB(5.5f,  0.5f, 29.5f, 0.75f));
90         // vertically/horizontally thin rects that don't cover pixel centers
91         fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
92         fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
93         // small in x and y
94         fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
95         // inverted in x and y
96         fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
97     }
98
99     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
100         GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
101         if (NULL == rt) {
102             return;
103         }
104         GrContext* context = rt->getContext();
105         if (NULL == context) {
106             return;
107         }
108
109         SkScalar y = 0;
110         for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
111              iter.get();
112              iter.next()) {
113             const SkPath* path = iter.get();
114             SkScalar x = 0;
115
116             for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
117                 GrTestTarget tt;
118                 context->getTestTarget(&tt);
119                 if (NULL == tt.target()) {
120                     SkDEBUGFAIL("Couldn't get Gr test target.");
121                     return;
122                 }
123                 GrDrawState* drawState = tt.target()->drawState();
124
125                 SkMatrix m;
126                 SkPath p;
127                 m.setTranslate(x, y);
128                 path->transform(m, &p);
129
130                 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
131                 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
132                 if (!fp) {
133                     continue;
134                 }
135                 drawState->addCoverageProcessor(fp);
136                 drawState->setIdentityViewMatrix();
137                 drawState->setRenderTarget(rt);
138                 drawState->setColor(0xff000000);
139
140                 // TODO hack
141                 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
142                 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
143
144                 //SkPoint verts[4];
145                 SkRect bounds = p.getBounds();
146                 // Make sure any artifacts around the exterior of path are visible by using overly
147                 // conservative bounding geometry.
148                 bounds.outset(5.f, 5.f);
149                 bounds.toQuad(verts);
150
151                 //tt.target()->setVertexSourceToArray(verts, 4);
152                 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
153                 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
154
155                 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
156             }
157
158             // Draw AA and non AA paths using normal API for reference.
159             canvas->save();
160             canvas->translate(x, y);
161             SkPaint paint;
162             canvas->drawPath(*path, paint);
163             canvas->translate(path->getBounds().width() + 10.f, 0);
164             paint.setAntiAlias(true);
165             canvas->drawPath(*path, paint);
166             canvas->restore();
167
168             y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
169         }
170
171         for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
172              iter.get();
173              iter.next()) {
174
175             SkScalar x = 0;
176
177             for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
178                 GrTestTarget tt;
179                 context->getTestTarget(&tt);
180                 if (NULL == tt.target()) {
181                     SkDEBUGFAIL("Couldn't get Gr test target.");
182                     return;
183                 }
184                 SkRect rect = *iter.get();
185                 rect.offset(x, y);
186                 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
187                 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
188                 if (!fp) {
189                     continue;
190                 }
191
192                 GrDrawState* drawState = tt.target()->drawState();
193                 drawState->addCoverageProcessor(fp);
194                 drawState->setIdentityViewMatrix();
195                 drawState->setRenderTarget(rt);
196                 drawState->setColor(0xff000000);
197
198                 // TODO hack
199                 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
200                 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
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