Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrAARectRenderer.cpp
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "GrAARectRenderer.h"
9 #include "GrGpu.h"
10 #include "gl/builders/GrGLFullProgramBuilder.h"
11 #include "gl/GrGLProcessor.h"
12 #include "gl/GrGLGeometryProcessor.h"
13 #include "GrTBackendProcessorFactory.h"
14 #include "SkColorPriv.h"
15 #include "GrGeometryProcessor.h"
16
17 ///////////////////////////////////////////////////////////////////////////////
18 class GrGLAlignedRectEffect;
19
20 // Axis Aligned special case
21 class GrAlignedRectEffect : public GrGeometryProcessor {
22 public:
23     static GrGeometryProcessor* Create() {
24         GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ());
25         gAlignedRectEffect->ref();
26         return gAlignedRectEffect;
27     }
28
29     virtual ~GrAlignedRectEffect() {}
30
31     static const char* Name() { return "AlignedRectEdge"; }
32
33     virtual void getConstantColorComponents(GrColor* color,
34                                             uint32_t* validFlags) const SK_OVERRIDE {
35         *validFlags = 0;
36     }
37
38     const GrShaderVar& inRect() const { return fInRect; }
39
40     virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
41         return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInstance();
42     }
43
44     class GLProcessor : public GrGLGeometryProcessor {
45     public:
46         GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
47         : INHERITED (factory) {}
48
49         virtual void emitCode(GrGLFullProgramBuilder* builder,
50                               const GrGeometryProcessor& geometryProcessor,
51                               const GrProcessorKey& key,
52                               const char* outputColor,
53                               const char* inputColor,
54                               const TransformedCoordsArray&,
55                               const TextureSamplerArray& samplers) SK_OVERRIDE {
56             // setup the varying for the Axis aligned rect effect
57             //      xy -> interpolated offset
58             //      zw -> w/2+0.5, h/2+0.5
59             const char *vsRectName, *fsRectName;
60             builder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName);
61
62             const GrShaderVar& inRect = geometryProcessor.cast<GrAlignedRectEffect>().inRect();
63             GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
64             vsBuilder->codeAppendf("\t%s = %s;\n", vsRectName, inRect.c_str());
65
66             GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
67             // TODO: compute all these offsets, spans, and scales in the VS
68             fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
69             fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
70             fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
71             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
72             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
73             fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
74             fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
75             // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
76             // value of coverage that is used. In other words it is the coverage that is
77             // used in the interior of the rect after the ramp.
78             fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
79             fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
80
81             // Compute the coverage for the rect's width
82             fsBuilder->codeAppendf(
83                 "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", fsRectName,
84                 fsRectName);
85             // Compute the coverage for the rect's height and merge with the width
86             fsBuilder->codeAppendf(
87                 "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
88                 fsRectName, fsRectName);
89
90
91             fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
92                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
93         }
94
95         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
96
97         virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
98
99     private:
100         typedef GrGLGeometryProcessor INHERITED;
101     };
102
103
104 private:
105     GrAlignedRectEffect()
106         : fInRect(this->addVertexAttrib(GrShaderVar("inRect",
107                                                     kVec4f_GrSLType,
108                                                     GrShaderVar::kAttribute_TypeModifier))) {
109     }
110
111     const GrShaderVar& fInRect;
112
113     virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
114
115     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
116
117     typedef GrGeometryProcessor INHERITED;
118 };
119
120
121 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect);
122
123 GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random,
124                                                      GrContext* context,
125                                                      const GrDrawTargetCaps&,
126                                                      GrTexture* textures[]) {
127     return GrAlignedRectEffect::Create();
128 }
129
130 ///////////////////////////////////////////////////////////////////////////////
131 class GrGLRectEffect;
132
133 /**
134  * The output of this effect is a modulation of the input color and coverage
135  * for an arbitrarily oriented rect. The rect is specified as:
136  *      Center of the rect
137  *      Unit vector point down the height of the rect
138  *      Half width + 0.5
139  *      Half height + 0.5
140  * The center and vector are stored in a vec4 varying ("RectEdge") with the
141  * center in the xy components and the vector in the zw components.
142  * The munged width and height are stored in a vec2 varying ("WidthHeight")
143  * with the width in x and the height in y.
144  */
145
146 class GrRectEffect : public GrGeometryProcessor {
147 public:
148     static GrGeometryProcessor* Create() {
149         GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gRectEffect, GrRectEffect, ());
150         gRectEffect->ref();
151         return gRectEffect;
152     }
153
154     virtual ~GrRectEffect() {}
155
156     static const char* Name() { return "RectEdge"; }
157
158     virtual void getConstantColorComponents(GrColor* color,
159                                             uint32_t* validFlags) const SK_OVERRIDE {
160         *validFlags = 0;
161     }
162
163     const GrShaderVar& inRectEdge() const { return fInRectEdge; }
164     const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
165
166     virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
167         return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance();
168     }
169
170     class GLProcessor : public GrGLGeometryProcessor {
171     public:
172         GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
173         : INHERITED (factory) {}
174
175         virtual void emitCode(GrGLFullProgramBuilder* builder,
176                               const GrGeometryProcessor& geometryProcessor,
177                               const GrProcessorKey& key,
178                               const char* outputColor,
179                               const char* inputColor,
180                               const TransformedCoordsArray&,
181                               const TextureSamplerArray& samplers) SK_OVERRIDE {
182             // setup the varying for the center point and the unit vector
183             // that points down the height of the rect
184             const char *vsRectEdgeName, *fsRectEdgeName;
185             builder->addVarying(kVec4f_GrSLType, "RectEdge",
186                                 &vsRectEdgeName, &fsRectEdgeName);
187
188             const GrRectEffect& rectEffect = geometryProcessor.cast<GrRectEffect>();
189             GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
190             vsBuilder->codeAppendf("%s = %s;", vsRectEdgeName, rectEffect.inRectEdge().c_str());
191
192             // setup the varying for width/2+.5 and height/2+.5
193             const char *vsWidthHeightName, *fsWidthHeightName;
194             builder->addVarying(kVec2f_GrSLType, "WidthHeight",
195                                 &vsWidthHeightName, &fsWidthHeightName);
196             vsBuilder->codeAppendf("%s = %s;",
197                                    vsWidthHeightName,
198                                    rectEffect.inWidthHeight().c_str());
199
200             GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
201             // TODO: compute all these offsets, spans, and scales in the VS
202             fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
203             fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
204             fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
205             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
206             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
207             fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
208             fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
209             // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
210             // value of coverage that is used. In other words it is the coverage that is
211             // used in the interior of the rect after the ramp.
212             fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
213             fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
214
215             // Compute the coverage for the rect's width
216             fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
217                                    fsBuilder->fragmentPosition(), fsRectEdgeName);
218             fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
219                                    fsRectEdgeName, fsRectEdgeName);
220             fsBuilder->codeAppendf(
221                 "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
222                 fsWidthHeightName);
223
224             // Compute the coverage for the rect's height and merge with the width
225             fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
226                                    fsRectEdgeName);
227             fsBuilder->codeAppendf(
228                     "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
229                     fsWidthHeightName);
230
231
232             fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
233                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
234         }
235
236         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
237
238         virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
239
240     private:
241         typedef GrGLGeometryProcessor INHERITED;
242     };
243
244
245
246 private:
247     GrRectEffect()
248         : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge",
249                                                         kVec4f_GrSLType,
250                                                         GrShaderVar::kAttribute_TypeModifier)))
251         , fInWidthHeight(this->addVertexAttrib(
252                 GrShaderVar("inWidthHeight",
253                             kVec2f_GrSLType,
254                             GrShaderVar::kAttribute_TypeModifier))) {
255         this->setWillReadFragmentPosition();
256     }
257
258     virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
259
260     const GrShaderVar& fInRectEdge;
261     const GrShaderVar& fInWidthHeight;
262
263     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
264
265     typedef GrGeometryProcessor INHERITED;
266 };
267
268
269 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect);
270
271 GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random,
272                                               GrContext* context,
273                                               const GrDrawTargetCaps&,
274                                               GrTexture* textures[]) {
275     return GrRectEffect::Create();
276 }
277
278 ///////////////////////////////////////////////////////////////////////////////
279
280 namespace {
281 extern const GrVertexAttrib gAARectAttribs[] = {
282     {kVec2f_GrVertexAttribType,  0,                                 kPosition_GrVertexAttribBinding},
283     {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding},
284     {kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor), kCoverage_GrVertexAttribBinding},
285 };
286
287 // Should the coverage be multiplied into the color attrib or use a separate attrib.
288 enum CoverageAttribType {
289     kUseColor_CoverageAttribType,
290     kUseCoverage_CoverageAttribType,
291 };
292 }
293
294 static CoverageAttribType set_rect_attribs(GrDrawState* drawState) {
295     if (drawState->canTweakAlphaForCoverage()) {
296         drawState->setVertexAttribs<gAARectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
297         return kUseColor_CoverageAttribType;
298     } else {
299         drawState->setVertexAttribs<gAARectAttribs>(3, sizeof(SkPoint) + 2 * sizeof(SkColor));
300         return kUseCoverage_CoverageAttribType;
301     }
302 }
303
304 static void set_inset_fan(SkPoint* pts, size_t stride,
305                           const SkRect& r, SkScalar dx, SkScalar dy) {
306     pts->setRectFan(r.fLeft + dx, r.fTop + dy,
307                     r.fRight - dx, r.fBottom - dy, stride);
308 }
309
310 void GrAARectRenderer::reset() {
311     SkSafeSetNull(fAAFillRectIndexBuffer);
312     SkSafeSetNull(fAAMiterStrokeRectIndexBuffer);
313     SkSafeSetNull(fAABevelStrokeRectIndexBuffer);
314 }
315
316 static const uint16_t gFillAARectIdx[] = {
317     0, 1, 5, 5, 4, 0,
318     1, 2, 6, 6, 5, 1,
319     2, 3, 7, 7, 6, 2,
320     3, 0, 4, 4, 7, 3,
321     4, 5, 6, 6, 7, 4,
322 };
323
324 static const int kIndicesPerAAFillRect = SK_ARRAY_COUNT(gFillAARectIdx);
325 static const int kVertsPerAAFillRect = 8;
326 static const int kNumAAFillRectsInIndexBuffer = 256;
327
328 GrIndexBuffer* GrAARectRenderer::aaFillRectIndexBuffer(GrGpu* gpu) {
329     static const size_t kAAFillRectIndexBufferSize = kIndicesPerAAFillRect *
330                                                      sizeof(uint16_t) *
331                                                      kNumAAFillRectsInIndexBuffer;
332
333     if (NULL == fAAFillRectIndexBuffer) {
334         fAAFillRectIndexBuffer = gpu->createIndexBuffer(kAAFillRectIndexBufferSize, false);
335         if (fAAFillRectIndexBuffer) {
336             uint16_t* data = (uint16_t*) fAAFillRectIndexBuffer->map();
337             bool useTempData = (NULL == data);
338             if (useTempData) {
339                 data = SkNEW_ARRAY(uint16_t, kNumAAFillRectsInIndexBuffer * kIndicesPerAAFillRect);
340             }
341             for (int i = 0; i < kNumAAFillRectsInIndexBuffer; ++i) {
342                 // Each AA filled rect is drawn with 8 vertices and 10 triangles (8 around
343                 // the inner rect (for AA) and 2 for the inner rect.
344                 int baseIdx = i * kIndicesPerAAFillRect;
345                 uint16_t baseVert = (uint16_t)(i * kVertsPerAAFillRect);
346                 for (int j = 0; j < kIndicesPerAAFillRect; ++j) {
347                     data[baseIdx+j] = baseVert + gFillAARectIdx[j];
348                 }
349             }
350             if (useTempData) {
351                 if (!fAAFillRectIndexBuffer->updateData(data, kAAFillRectIndexBufferSize)) {
352                     SkFAIL("Can't get AA Fill Rect indices into buffer!");
353                 }
354                 SkDELETE_ARRAY(data);
355             } else {
356                 fAAFillRectIndexBuffer->unmap();
357             }
358         }
359     }
360
361     return fAAFillRectIndexBuffer;
362 }
363
364 static const uint16_t gMiterStrokeAARectIdx[] = {
365     0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
366     1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
367     2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
368     3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0,
369
370     0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4,
371     1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4,
372     2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4,
373     3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4,
374
375     0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8,
376     1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8,
377     2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8,
378     3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8,
379 };
380
381 /**
382  * As in miter-stroke, index = a + b, and a is the current index, b is the shift
383  * from the first index. The index layout:
384  * outer AA line: 0~3, 4~7
385  * outer edge:    8~11, 12~15
386  * inner edge:    16~19
387  * inner AA line: 20~23
388  * Following comes a bevel-stroke rect and its indices:
389  *
390  *           4                                 7
391  *            *********************************
392  *          *   ______________________________  *
393  *         *  / 12                          15 \  *
394  *        *  /                                  \  *
395  *     0 *  |8     16_____________________19  11 |  * 3
396  *       *  |       |                    |       |  *
397  *       *  |       |  ****************  |       |  *
398  *       *  |       |  * 20        23 *  |       |  *
399  *       *  |       |  *              *  |       |  *
400  *       *  |       |  * 21        22 *  |       |  *
401  *       *  |       |  ****************  |       |  *
402  *       *  |       |____________________|       |  *
403  *     1 *  |9    17                      18   10|  * 2
404  *        *  \                                  /  *
405  *         *  \13 __________________________14/  *
406  *          *                                   *
407  *           **********************************
408  *          5                                  6
409  */
410 static const uint16_t gBevelStrokeAARectIdx[] = {
411     // Draw outer AA, from outer AA line to outer edge, shift is 0.
412     0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0,
413     1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0,
414     5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0,
415     6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0,
416     2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0,
417     3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0,
418     7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0,
419     4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0,
420
421     // Draw the stroke, from outer edge to inner edge, shift is 8.
422     0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8,
423     1 + 8, 5 + 8, 9 + 8,
424     5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8,
425     6 + 8, 2 + 8, 10 + 8,
426     2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8,
427     3 + 8, 7 + 8, 11 + 8,
428     7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8,
429     4 + 8, 0 + 8, 8 + 8,
430
431     // Draw the inner AA, from inner edge to inner AA line, shift is 16.
432     0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16,
433     1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16,
434     2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16,
435     3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16,
436 };
437
438 int GrAARectRenderer::aaStrokeRectIndexCount(bool miterStroke) {
439     return miterStroke ? SK_ARRAY_COUNT(gMiterStrokeAARectIdx) :
440                          SK_ARRAY_COUNT(gBevelStrokeAARectIdx);
441 }
442
443 GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu, bool miterStroke) {
444     if (miterStroke) {
445         if (NULL == fAAMiterStrokeRectIndexBuffer) {
446             fAAMiterStrokeRectIndexBuffer =
447                 gpu->createIndexBuffer(sizeof(gMiterStrokeAARectIdx), false);
448             if (fAAMiterStrokeRectIndexBuffer) {
449 #ifdef SK_DEBUG
450                 bool updated =
451 #endif
452                 fAAMiterStrokeRectIndexBuffer->updateData(gMiterStrokeAARectIdx,
453                                                           sizeof(gMiterStrokeAARectIdx));
454                 GR_DEBUGASSERT(updated);
455             }
456         }
457         return fAAMiterStrokeRectIndexBuffer;
458     } else {
459         if (NULL == fAABevelStrokeRectIndexBuffer) {
460             fAABevelStrokeRectIndexBuffer =
461                 gpu->createIndexBuffer(sizeof(gBevelStrokeAARectIdx), false);
462             if (fAABevelStrokeRectIndexBuffer) {
463 #ifdef SK_DEBUG
464                 bool updated =
465 #endif
466                 fAABevelStrokeRectIndexBuffer->updateData(gBevelStrokeAARectIdx,
467                                                           sizeof(gBevelStrokeAARectIdx));
468                 GR_DEBUGASSERT(updated);
469             }
470         }
471         return fAABevelStrokeRectIndexBuffer;
472     }
473 }
474
475 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
476                                           GrDrawTarget* target,
477                                           const SkRect& rect,
478                                           const SkMatrix& combinedMatrix,
479                                           const SkRect& devRect) {
480     GrDrawState* drawState = target->drawState();
481
482     GrColor color = drawState->getColor();
483
484     CoverageAttribType covAttribType = set_rect_attribs(drawState);
485     if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
486         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
487     }
488
489     GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
490     if (!geo.succeeded()) {
491         GrPrintf("Failed to get space for vertices!\n");
492         return;
493     }
494
495     GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(gpu);
496     if (NULL == indexBuffer) {
497         GrPrintf("Failed to create index buffer!\n");
498         return;
499     }
500
501     intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
502     size_t vstride = drawState->getVertexStride();
503
504     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
505     SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
506
507     SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
508     inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
509
510     if (combinedMatrix.rectStaysRect()) {
511         // Temporarily #if'ed out. We don't want to pass in the devRect but
512         // right now it is computed in GrContext::apply_aa_to_rect and we don't
513         // want to throw away the work
514 #if 0
515         SkRect devRect;
516         combinedMatrix.mapRect(&devRect, rect);
517 #endif
518
519         set_inset_fan(fan0Pos, vstride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
520         set_inset_fan(fan1Pos, vstride, devRect, inset,  inset);
521     } else {
522         // compute transformed (1, 0) and (0, 1) vectors
523         SkVector vec[2] = {
524           { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
525           { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] }
526         };
527
528         vec[0].normalize();
529         vec[0].scale(SK_ScalarHalf);
530         vec[1].normalize();
531         vec[1].scale(SK_ScalarHalf);
532
533         // create the rotated rect
534         fan0Pos->setRectFan(rect.fLeft, rect.fTop,
535                             rect.fRight, rect.fBottom, vstride);
536         combinedMatrix.mapPointsWithStride(fan0Pos, vstride, 4);
537
538         // Now create the inset points and then outset the original
539         // rotated points
540
541         // TL
542         *((SkPoint*)((intptr_t)fan1Pos + 0 * vstride)) =
543             *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) + vec[0] + vec[1];
544         *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) -= vec[0] + vec[1];
545         // BL
546         *((SkPoint*)((intptr_t)fan1Pos + 1 * vstride)) =
547             *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) + vec[0] - vec[1];
548         *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) -= vec[0] - vec[1];
549         // BR
550         *((SkPoint*)((intptr_t)fan1Pos + 2 * vstride)) =
551             *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) - vec[0] - vec[1];
552         *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) += vec[0] + vec[1];
553         // TR
554         *((SkPoint*)((intptr_t)fan1Pos + 3 * vstride)) =
555             *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) - vec[0] + vec[1];
556         *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) += vec[0] - vec[1];
557     }
558
559     // Make verts point to vertex color and then set all the color and coverage vertex attrs values.
560     verts += sizeof(SkPoint);
561     for (int i = 0; i < 4; ++i) {
562         if (kUseCoverage_CoverageAttribType == covAttribType) {
563             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
564             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
565         } else {
566             *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
567         }
568     }
569
570     int scale;
571     if (inset < SK_ScalarHalf) {
572         scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
573         SkASSERT(scale >= 0 && scale <= 255);
574     } else {
575         scale = 0xff;
576     }
577
578     GrColor innerCoverage;
579     if (kUseCoverage_CoverageAttribType == covAttribType) {
580         innerCoverage = GrColorPackRGBA(scale, scale, scale, scale); 
581     } else {
582         innerCoverage = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
583     }
584     verts += 4 * vstride;
585     for (int i = 0; i < 4; ++i) {
586         if (kUseCoverage_CoverageAttribType == covAttribType) {
587             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
588             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
589         } else {
590             *reinterpret_cast<GrColor*>(verts + i * vstride) = innerCoverage;
591         }
592     }
593
594     target->setIndexSourceToBuffer(indexBuffer);
595     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
596                                  kVertsPerAAFillRect,
597                                  kIndicesPerAAFillRect);
598     target->resetIndexSource();
599 }
600
601 namespace {
602
603 // Rotated
604 struct RectVertex {
605     SkPoint fPos;
606     SkPoint fCenter;
607     SkPoint fDir;
608     SkPoint fWidthHeight;
609 };
610
611 // Rotated
612 extern const GrVertexAttrib gAARectVertexAttribs[] = {
613     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
614     { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
615     { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
616 };
617
618 // Axis Aligned
619 struct AARectVertex {
620     SkPoint fPos;
621     SkPoint fOffset;
622     SkPoint fWidthHeight;
623 };
624
625 // Axis Aligned
626 extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
627     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
628     { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
629 };
630
631 };
632
633 void GrAARectRenderer::shaderFillAARect(GrGpu* gpu,
634                                         GrDrawTarget* target,
635                                         const SkRect& rect,
636                                         const SkMatrix& combinedMatrix) {
637     GrDrawState* drawState = target->drawState();
638
639     SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
640     combinedMatrix.mapPoints(&center, 1);
641
642     // compute transformed (0, 1) vector
643     SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] };
644     dir.normalize();
645
646     // compute transformed (width, 0) and (0, height) vectors
647     SkVector vec[2] = {
648       { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
649       { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] }
650     };
651
652     SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_ScalarHalf;
653     SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_ScalarHalf;
654     drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs),
655                                                       sizeof(RectVertex));
656
657     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
658     if (!geo.succeeded()) {
659         GrPrintf("Failed to get space for vertices!\n");
660         return;
661     }
662
663     RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
664
665     GrGeometryProcessor* gp = GrRectEffect::Create();
666     drawState->setGeometryProcessor(gp)->unref();
667
668     for (int i = 0; i < 4; ++i) {
669         verts[i].fCenter = center;
670         verts[i].fDir = dir;
671         verts[i].fWidthHeight.fX = newWidth;
672         verts[i].fWidthHeight.fY = newHeight;
673     }
674
675     SkRect devRect;
676     combinedMatrix.mapRect(&devRect, rect);
677
678     SkRect devBounds = {
679         devRect.fLeft   - SK_ScalarHalf,
680         devRect.fTop    - SK_ScalarHalf,
681         devRect.fRight  + SK_ScalarHalf,
682         devRect.fBottom + SK_ScalarHalf
683     };
684
685     verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
686     verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
687     verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
688     verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
689
690     target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
691     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
692     target->resetIndexSource();
693 }
694
695 void GrAARectRenderer::shaderFillAlignedAARect(GrGpu* gpu,
696                                                GrDrawTarget* target,
697                                                const SkRect& rect,
698                                                const SkMatrix& combinedMatrix) {
699     GrDrawState* drawState = target->drawState();
700     SkASSERT(combinedMatrix.rectStaysRect());
701
702     drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs),
703                                                         sizeof(AARectVertex));
704
705     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
706     if (!geo.succeeded()) {
707         GrPrintf("Failed to get space for vertices!\n");
708         return;
709     }
710
711     AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
712
713     GrGeometryProcessor* gp = GrAlignedRectEffect::Create();
714     drawState->setGeometryProcessor(gp)->unref();
715
716     SkRect devRect;
717     combinedMatrix.mapRect(&devRect, rect);
718
719     SkRect devBounds = {
720         devRect.fLeft   - SK_ScalarHalf,
721         devRect.fTop    - SK_ScalarHalf,
722         devRect.fRight  + SK_ScalarHalf,
723         devRect.fBottom + SK_ScalarHalf
724     };
725
726     SkPoint widthHeight = {
727         SkScalarHalf(devRect.width()) + SK_ScalarHalf,
728         SkScalarHalf(devRect.height()) + SK_ScalarHalf
729     };
730
731     verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
732     verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
733     verts[0].fWidthHeight = widthHeight;
734
735     verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
736     verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
737     verts[1].fWidthHeight = widthHeight;
738
739     verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
740     verts[2].fOffset = widthHeight;
741     verts[2].fWidthHeight = widthHeight;
742
743     verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
744     verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
745     verts[3].fWidthHeight = widthHeight;
746
747     target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
748     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
749     target->resetIndexSource();
750 }
751
752 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
753                                     GrDrawTarget* target,
754                                     const SkRect& rect,
755                                     const SkMatrix& combinedMatrix,
756                                     const SkRect& devRect,
757                                     const SkStrokeRec& stroke) {
758     SkVector devStrokeSize;
759     SkScalar width = stroke.getWidth();
760     if (width > 0) {
761         devStrokeSize.set(width, width);
762         combinedMatrix.mapVectors(&devStrokeSize, 1);
763         devStrokeSize.setAbs(devStrokeSize);
764     } else {
765         devStrokeSize.set(SK_Scalar1, SK_Scalar1);
766     }
767
768     const SkScalar dx = devStrokeSize.fX;
769     const SkScalar dy = devStrokeSize.fY;
770     const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
771     const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
772
773     // Temporarily #if'ed out. We don't want to pass in the devRect but
774     // right now it is computed in GrContext::apply_aa_to_rect and we don't
775     // want to throw away the work
776 #if 0
777     SkRect devRect;
778     combinedMatrix.mapRect(&devRect, rect);
779 #endif
780
781     SkScalar spare;
782     {
783         SkScalar w = devRect.width() - dx;
784         SkScalar h = devRect.height() - dy;
785         spare = SkTMin(w, h);
786     }
787
788     SkRect devOutside(devRect);
789     devOutside.outset(rx, ry);
790
791     bool miterStroke = true;
792     // For hairlines, make bevel and round joins appear the same as mitered ones.
793     // small miter limit means right angles show bevel...
794     if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
795                         stroke.getMiter() < SK_ScalarSqrt2)) {
796         miterStroke = false;
797     }
798
799     if (spare <= 0 && miterStroke) {
800         this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside);
801         return;
802     }
803
804     SkRect devInside(devRect);
805     devInside.inset(rx, ry);
806
807     SkRect devOutsideAssist(devRect);
808
809     // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist)
810     // to draw the outer of the rect. Because there are 8 vertices on the outer
811     // edge, while vertex number of inner edge is 4, the same as miter-stroke.
812     if (!miterStroke) {
813         devOutside.inset(0, ry);
814         devOutsideAssist.outset(0, ry);
815     }
816
817     this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devInside, miterStroke);
818 }
819
820 void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu,
821                                             GrDrawTarget* target,
822                                             const SkRect& devOutside,
823                                             const SkRect& devOutsideAssist,
824                                             const SkRect& devInside,
825                                             bool miterStroke) {
826     GrDrawState* drawState = target->drawState();
827
828     CoverageAttribType covAttribType = set_rect_attribs(drawState);
829
830     GrColor color = drawState->getColor();
831     if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
832         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
833     }
834
835     int innerVertexNum = 4;
836     int outerVertexNum = miterStroke ? 4 : 8;
837     int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
838
839     GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, 0);
840     if (!geo.succeeded()) {
841         GrPrintf("Failed to get space for vertices!\n");
842         return;
843     }
844     GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu, miterStroke);
845     if (NULL == indexBuffer) {
846         GrPrintf("Failed to create index buffer!\n");
847         return;
848     }
849
850     intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
851     size_t vstride = drawState->getVertexStride();
852
853     // We create vertices for four nested rectangles. There are two ramps from 0 to full
854     // coverage, one on the exterior of the stroke and the other on the interior.
855     // The following pointers refer to the four rects, from outermost to innermost.
856     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
857     SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * vstride);
858     SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * vstride);
859     SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + (2 * outerVertexNum + innerVertexNum) * vstride);
860
861 #ifndef SK_IGNORE_THIN_STROKED_RECT_FIX
862     // TODO: this only really works if the X & Y margins are the same all around
863     // the rect
864     SkScalar inset = SkMinScalar(SK_Scalar1, devOutside.fRight - devInside.fRight);
865     inset = SkMinScalar(inset, devInside.fLeft - devOutside.fLeft);
866     inset = SkMinScalar(inset, devInside.fTop - devOutside.fTop);
867     if (miterStroke) {
868         inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInside.fBottom);
869     } else {
870         inset = SK_ScalarHalf * SkMinScalar(inset, devOutsideAssist.fBottom - devInside.fBottom);
871     }
872     SkASSERT(inset >= 0);
873 #else
874     SkScalar inset = SK_ScalarHalf;
875 #endif
876
877     if (miterStroke) {
878         // outermost
879         set_inset_fan(fan0Pos, vstride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
880         // inner two
881         set_inset_fan(fan1Pos, vstride, devOutside,  inset,  inset);
882         set_inset_fan(fan2Pos, vstride, devInside,  -inset, -inset);
883         // innermost
884         set_inset_fan(fan3Pos, vstride, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
885     } else {
886         SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
887         SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + (outerVertexNum + 4) * vstride);
888         // outermost
889         set_inset_fan(fan0Pos, vstride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
890         set_inset_fan(fan0AssistPos, vstride, devOutsideAssist, -SK_ScalarHalf, -SK_ScalarHalf);
891         // outer one of the inner two
892         set_inset_fan(fan1Pos, vstride, devOutside,  inset,  inset);
893         set_inset_fan(fan1AssistPos, vstride, devOutsideAssist,  inset,  inset);
894         // inner one of the inner two
895         set_inset_fan(fan2Pos, vstride, devInside,  -inset, -inset);
896         // innermost
897         set_inset_fan(fan3Pos, vstride, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
898     }
899
900     // Make verts point to vertex color and then set all the color and coverage vertex attrs values.
901     // The outermost rect has 0 coverage
902     verts += sizeof(SkPoint);
903     for (int i = 0; i < outerVertexNum; ++i) {
904         if (kUseCoverage_CoverageAttribType == covAttribType) {
905             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
906             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
907         } else {
908             *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
909         }
910     }
911
912     // scale is the coverage for the the inner two rects.
913     int scale;
914     if (inset < SK_ScalarHalf) {
915         scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
916         SkASSERT(scale >= 0 && scale <= 255);
917     } else {
918         scale = 0xff;
919     }
920
921     verts += outerVertexNum * vstride;
922     GrColor innerCoverage;
923     if (kUseCoverage_CoverageAttribType == covAttribType) {
924         innerCoverage = GrColorPackRGBA(scale, scale, scale, scale);
925     } else {
926         innerCoverage = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
927     }
928
929     for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
930         if (kUseCoverage_CoverageAttribType == covAttribType) {
931             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
932             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
933         } else {
934             *reinterpret_cast<GrColor*>(verts + i * vstride) = innerCoverage;
935         }
936     }
937
938     // The innermost rect has 0 coverage
939     verts += (outerVertexNum + innerVertexNum) * vstride;
940     for (int i = 0; i < innerVertexNum; ++i) {
941         if (kUseCoverage_CoverageAttribType == covAttribType) {
942             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
943             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
944         } else {
945             *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
946         }
947     }
948
949     target->setIndexSourceToBuffer(indexBuffer);
950     target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0,
951                         totalVertexNum, aaStrokeRectIndexCount(miterStroke));
952 }
953
954 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu,
955                                          GrDrawTarget* target,
956                                          const SkRect rects[2],
957                                          const SkMatrix& combinedMatrix) {
958     SkASSERT(combinedMatrix.rectStaysRect());
959     SkASSERT(!rects[1].isEmpty());
960
961     SkRect devOutside, devOutsideAssist, devInside;
962     combinedMatrix.mapRect(&devOutside, rects[0]);
963     // can't call mapRect for devInside since it calls sort
964     combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
965
966     if (devInside.isEmpty()) {
967         this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside);
968         return;
969     }
970
971     this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devInside, true);
972 }