| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2012 Google Inc. |    2  * Copyright 2012 Google Inc. | 
|    3  * |    3  * | 
|    4  * Use of this source code is governed by a BSD-style license that can be |    4  * Use of this source code is governed by a BSD-style license that can be | 
|    5  * found in the LICENSE file. |    5  * found in the LICENSE file. | 
|    6  */ |    6  */ | 
|    7  |    7  | 
|    8 #include "GrAARectRenderer.h" |    8 #include "GrAARectRenderer.h" | 
|    9 #include "GrGpu.h" |    9 #include "GrGpu.h" | 
|   10 #include "gl/builders/GrGLProgramBuilder.h" |   10 #include "gl/builders/GrGLProgramBuilder.h" | 
|   11 #include "gl/GrGLProcessor.h" |   11 #include "gl/GrGLProcessor.h" | 
|   12 #include "gl/GrGLGeometryProcessor.h" |   12 #include "gl/GrGLGeometryProcessor.h" | 
|   13 #include "GrTBackendProcessorFactory.h" |   13 #include "GrTBackendProcessorFactory.h" | 
|   14 #include "SkColorPriv.h" |   14 #include "SkColorPriv.h" | 
|   15 #include "GrGeometryProcessor.h" |   15 #include "GrGeometryProcessor.h" | 
|   16  |   16  | 
|   17 /////////////////////////////////////////////////////////////////////////////// |   17 /////////////////////////////////////////////////////////////////////////////// | 
|   18  |   18 class GrGLAlignedRectEffect; | 
 |   19  | 
 |   20 // Axis Aligned special case | 
 |   21 class GrAlignedRectEffect : public GrGeometryProcessor { | 
 |   22 public: | 
 |   23     static GrGeometryProcessor* Create() { | 
 |   24         GR_CREATE_STATIC_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ()); | 
 |   25         gAlignedRectEffect->ref(); | 
 |   26         return gAlignedRectEffect; | 
 |   27     } | 
 |   28  | 
 |   29     virtual ~GrAlignedRectEffect() {} | 
 |   30  | 
 |   31     static const char* Name() { return "AlignedRectEdge"; } | 
 |   32  | 
 |   33     const GrShaderVar& inRect() const { return fInRect; } | 
 |   34  | 
 |   35     virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
     IDE { | 
 |   36         return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInsta
     nce(); | 
 |   37     } | 
 |   38  | 
 |   39     class GLProcessor : public GrGLGeometryProcessor { | 
 |   40     public: | 
 |   41         GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
     ) | 
 |   42         : INHERITED (factory) {} | 
 |   43  | 
 |   44         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 
 |   45             // setup the varying for the Axis aligned rect effect | 
 |   46             //      xy -> interpolated offset | 
 |   47             //      zw -> w/2+0.5, h/2+0.5 | 
 |   48             GrGLVertToFrag v(kVec4f_GrSLType); | 
 |   49             args.fPB->addVarying("Rect", &v); | 
 |   50  | 
 |   51             const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inR
     ect(); | 
 |   52             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 
 |   53             vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str()); | 
 |   54  | 
 |   55             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde
     r(); | 
 |   56             // TODO: compute all these offsets, spans, and scales in the VS | 
 |   57             fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v
     .fsIn()); | 
 |   58             fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v
     .fsIn()); | 
 |   59             fsBuilder->codeAppend("\tfloat outset = 0.5;\n"); | 
 |   60             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0
     ). For rects | 
 |   61             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 
     0 .. 1 range. | 
 |   62             fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n"); | 
 |   63             fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n"); | 
 |   64             // For rects < 1 pixel wide or tall, these scale factors are used to
      cap the maximum | 
 |   65             // value of coverage that is used. In other words it is the coverage
      that is | 
 |   66             // used in the interior of the rect after the ramp. | 
 |   67             fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\
     n"); | 
 |   68             fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\
     n"); | 
 |   69  | 
 |   70             // Compute the coverage for the rect's width | 
 |   71             fsBuilder->codeAppendf( | 
 |   72                 "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.
     0);\n", v.fsIn(), | 
 |   73                 v.fsIn()); | 
 |   74             // Compute the coverage for the rect's height and merge with the wid
     th | 
 |   75             fsBuilder->codeAppendf( | 
 |   76                 "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0,
      1.0);\n", | 
 |   77                 v.fsIn(), v.fsIn()); | 
 |   78  | 
 |   79  | 
 |   80             fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput, | 
 |   81                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("cove
     rage")).c_str()); | 
 |   82         } | 
 |   83  | 
 |   84         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBu
     ilder*) {} | 
 |   85  | 
 |   86         virtual void setData(const GrGLProgramDataManager& pdman, const GrProces
     sor&) SK_OVERRIDE {} | 
 |   87  | 
 |   88     private: | 
 |   89         typedef GrGLGeometryProcessor INHERITED; | 
 |   90     }; | 
 |   91  | 
 |   92  | 
 |   93 private: | 
 |   94     GrAlignedRectEffect() | 
 |   95         : fInRect(this->addVertexAttrib(GrShaderVar("inRect", | 
 |   96                                                     kVec4f_GrSLType, | 
 |   97                                                     GrShaderVar::kAttribute_Type
     Modifier))) { | 
 |   98     } | 
 |   99  | 
 |  100     const GrShaderVar& fInRect; | 
 |  101  | 
 |  102     virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { retur
     n true; } | 
 |  103  | 
 |  104     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR
     IDE { | 
 |  105         inout->mulByUnknownAlpha(); | 
 |  106     } | 
 |  107  | 
 |  108     GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 
 |  109  | 
 |  110     typedef GrGeometryProcessor INHERITED; | 
 |  111 }; | 
 |  112  | 
 |  113  | 
 |  114 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect); | 
 |  115  | 
 |  116 GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random, | 
 |  117                                                      GrContext* context, | 
 |  118                                                      const GrDrawTargetCaps&, | 
 |  119                                                      GrTexture* textures[]) { | 
 |  120     return GrAlignedRectEffect::Create(); | 
 |  121 } | 
 |  122  | 
 |  123 /////////////////////////////////////////////////////////////////////////////// | 
 |  124 class GrGLRectEffect; | 
 |  125  | 
 |  126 /** | 
 |  127  * The output of this effect is a modulation of the input color and coverage | 
 |  128  * for an arbitrarily oriented rect. The rect is specified as: | 
 |  129  *      Center of the rect | 
 |  130  *      Unit vector point down the height of the rect | 
 |  131  *      Half width + 0.5 | 
 |  132  *      Half height + 0.5 | 
 |  133  * The center and vector are stored in a vec4 varying ("RectEdge") with the | 
 |  134  * center in the xy components and the vector in the zw components. | 
 |  135  * The munged width and height are stored in a vec2 varying ("WidthHeight") | 
 |  136  * with the width in x and the height in y. | 
 |  137  */ | 
 |  138  | 
 |  139 class GrRectEffect : public GrGeometryProcessor { | 
 |  140 public: | 
 |  141     static GrGeometryProcessor* Create() { | 
 |  142         GR_CREATE_STATIC_PROCESSOR(gRectEffect, GrRectEffect, ()); | 
 |  143         gRectEffect->ref(); | 
 |  144         return gRectEffect; | 
 |  145     } | 
 |  146  | 
 |  147     virtual ~GrRectEffect() {} | 
 |  148  | 
 |  149     static const char* Name() { return "RectEdge"; } | 
 |  150  | 
 |  151     const GrShaderVar& inRectEdge() const { return fInRectEdge; } | 
 |  152     const GrShaderVar& inWidthHeight() const { return fInWidthHeight; } | 
 |  153  | 
 |  154     virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
     IDE { | 
 |  155         return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance(); | 
 |  156     } | 
 |  157  | 
 |  158     class GLProcessor : public GrGLGeometryProcessor { | 
 |  159     public: | 
 |  160         GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
     ) | 
 |  161         : INHERITED (factory) {} | 
 |  162  | 
 |  163         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 
 |  164             // setup the varying for the center point and the unit vector | 
 |  165             // that points down the height of the rect | 
 |  166             GrGLVertToFrag rectEdge(kVec4f_GrSLType); | 
 |  167             args.fPB->addVarying("RectEdge", &rectEdge); | 
 |  168  | 
 |  169             const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>(); | 
 |  170             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 
 |  171             vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRe
     ctEdge().c_str()); | 
 |  172  | 
 |  173             // setup the varying for width/2+.5 and height/2+.5 | 
 |  174             GrGLVertToFrag widthHeight(kVec2f_GrSLType); | 
 |  175             args.fPB->addVarying("WidthHeight", &widthHeight); | 
 |  176             vsBuilder->codeAppendf("%s = %s;", | 
 |  177                                    widthHeight.vsOut(), | 
 |  178                                    rectEffect.inWidthHeight().c_str()); | 
 |  179  | 
 |  180             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde
     r(); | 
 |  181             // TODO: compute all these offsets, spans, and scales in the VS | 
 |  182             fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", w
     idthHeight.fsIn()); | 
 |  183             fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", w
     idthHeight.fsIn()); | 
 |  184             fsBuilder->codeAppend("\tfloat outset = 0.5;\n"); | 
 |  185             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0
     ). For rects | 
 |  186             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 
     0 .. 1 range. | 
 |  187             fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n"); | 
 |  188             fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n"); | 
 |  189             // For rects < 1 pixel wide or tall, these scale factors are used to
      cap the maximum | 
 |  190             // value of coverage that is used. In other words it is the coverage
      that is | 
 |  191             // used in the interior of the rect after the ramp. | 
 |  192             fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\
     n"); | 
 |  193             fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\
     n"); | 
 |  194  | 
 |  195             // Compute the coverage for the rect's width | 
 |  196             fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n", | 
 |  197                                    fsBuilder->fragmentPosition(), rectEdge.fsIn(
     )); | 
 |  198             fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offs
     et.y * %s.z);\n", | 
 |  199                                    rectEdge.fsIn(), rectEdge.fsIn()); | 
 |  200             fsBuilder->codeAppendf( | 
 |  201                 "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0)
     ;\n", | 
 |  202                 widthHeight.fsIn()); | 
 |  203  | 
 |  204             // Compute the coverage for the rect's height and merge with the wid
     th | 
 |  205             fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n", | 
 |  206                                    rectEdge.fsIn()); | 
 |  207             fsBuilder->codeAppendf( | 
 |  208                     "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.
     0, 1.0);\n", | 
 |  209                     widthHeight.fsIn()); | 
 |  210  | 
 |  211  | 
 |  212             fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput, | 
 |  213                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("cove
     rage")).c_str()); | 
 |  214         } | 
 |  215  | 
 |  216         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBu
     ilder*) {} | 
 |  217  | 
 |  218         virtual void setData(const GrGLProgramDataManager& pdman, const GrProces
     sor&) SK_OVERRIDE {} | 
 |  219  | 
 |  220     private: | 
 |  221         typedef GrGLGeometryProcessor INHERITED; | 
 |  222     }; | 
 |  223  | 
 |  224  | 
 |  225  | 
 |  226 private: | 
 |  227     GrRectEffect() | 
 |  228         : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge", | 
 |  229                                                         kVec4f_GrSLType, | 
 |  230                                                         GrShaderVar::kAttribute_
     TypeModifier))) | 
 |  231         , fInWidthHeight(this->addVertexAttrib( | 
 |  232                 GrShaderVar("inWidthHeight", | 
 |  233                             kVec2f_GrSLType, | 
 |  234                             GrShaderVar::kAttribute_TypeModifier))) { | 
 |  235         this->setWillReadFragmentPosition(); | 
 |  236     } | 
 |  237  | 
 |  238     virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { retur
     n true; } | 
 |  239  | 
 |  240     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR
     IDE { | 
 |  241         inout->mulByUnknownAlpha(); | 
 |  242     } | 
 |  243  | 
 |  244     const GrShaderVar& fInRectEdge; | 
 |  245     const GrShaderVar& fInWidthHeight; | 
 |  246  | 
 |  247     GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 
 |  248  | 
 |  249     typedef GrGeometryProcessor INHERITED; | 
 |  250 }; | 
 |  251  | 
 |  252  | 
 |  253 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect); | 
 |  254  | 
 |  255 GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random, | 
 |  256                                               GrContext* context, | 
 |  257                                               const GrDrawTargetCaps&, | 
 |  258                                               GrTexture* textures[]) { | 
 |  259     return GrRectEffect::Create(); | 
 |  260 } | 
 |  261  | 
 |  262 /////////////////////////////////////////////////////////////////////////////// | 
 |  263  | 
|   19 namespace { |  264 namespace { | 
|   20 extern const GrVertexAttrib gAARectAttribs[] = { |  265 extern const GrVertexAttrib gAARectAttribs[] = { | 
|   21     {kVec2f_GrVertexAttribType,  0,                                 kPosition_Gr
     VertexAttribBinding}, |  266     {kVec2f_GrVertexAttribType,  0,                                 kPosition_Gr
     VertexAttribBinding}, | 
|   22     {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVer
     texAttribBinding}, |  267     {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVer
     texAttribBinding}, | 
|   23     {kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor),  kCoverage_Gr
     VertexAttribBinding}, |  268     {kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor),  kCoverage_Gr
     VertexAttribBinding}, | 
|   24 }; |  269 }; | 
|   25  |  270  | 
|   26 // Should the coverage be multiplied into the color attrib or use a separate att
     rib. |  271 // Should the coverage be multiplied into the color attrib or use a separate att
     rib. | 
|   27 enum CoverageAttribType { |  272 enum CoverageAttribType { | 
|   28     kUseColor_CoverageAttribType, |  273     kUseColor_CoverageAttribType, | 
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  296         } |  541         } | 
|  297     } |  542     } | 
|  298  |  543  | 
|  299     target->setIndexSourceToBuffer(indexBuffer); |  544     target->setIndexSourceToBuffer(indexBuffer); | 
|  300     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, |  545     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, | 
|  301                                  kVertsPerAAFillRect, |  546                                  kVertsPerAAFillRect, | 
|  302                                  kIndicesPerAAFillRect); |  547                                  kIndicesPerAAFillRect); | 
|  303     target->resetIndexSource(); |  548     target->resetIndexSource(); | 
|  304 } |  549 } | 
|  305  |  550  | 
 |  551 namespace { | 
 |  552  | 
 |  553 // Rotated | 
 |  554 struct RectVertex { | 
 |  555     SkPoint fPos; | 
 |  556     SkPoint fCenter; | 
 |  557     SkPoint fDir; | 
 |  558     SkPoint fWidthHeight; | 
 |  559 }; | 
 |  560  | 
 |  561 // Rotated | 
 |  562 extern const GrVertexAttrib gAARectVertexAttribs[] = { | 
 |  563     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBind
     ing }, | 
 |  564     { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexA
     ttribBinding }, | 
 |  565     { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexA
     ttribBinding } | 
 |  566 }; | 
 |  567  | 
 |  568 // Axis Aligned | 
 |  569 struct AARectVertex { | 
 |  570     SkPoint fPos; | 
 |  571     SkPoint fOffset; | 
 |  572     SkPoint fWidthHeight; | 
 |  573 }; | 
 |  574  | 
 |  575 // Axis Aligned | 
 |  576 extern const GrVertexAttrib gAAAARectVertexAttribs[] = { | 
 |  577     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBind
     ing }, | 
 |  578     { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexA
     ttribBinding }, | 
 |  579 }; | 
 |  580  | 
 |  581 }; | 
 |  582  | 
 |  583 void GrAARectRenderer::shaderFillAARect(GrDrawTarget* target, | 
 |  584                                         const SkRect& rect, | 
 |  585                                         const SkMatrix& combinedMatrix) { | 
 |  586     GrDrawState* drawState = target->drawState(); | 
 |  587  | 
 |  588     SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY()); | 
 |  589     combinedMatrix.mapPoints(¢er, 1); | 
 |  590  | 
 |  591     // compute transformed (0, 1) vector | 
 |  592     SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix:
     :kMScaleY] }; | 
 |  593     dir.normalize(); | 
 |  594  | 
 |  595     // compute transformed (width, 0) and (0, height) vectors | 
 |  596     SkVector vec[2] = { | 
 |  597       { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] }, | 
 |  598       { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] } | 
 |  599     }; | 
 |  600  | 
 |  601     SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_Scalar
     Half; | 
 |  602     SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_Scal
     arHalf; | 
 |  603     drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVert
     exAttribs), | 
 |  604                                                       sizeof(RectVertex)); | 
 |  605  | 
 |  606     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 
 |  607     if (!geo.succeeded()) { | 
 |  608         SkDebugf("Failed to get space for vertices!\n"); | 
 |  609         return; | 
 |  610     } | 
 |  611  | 
 |  612     RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices()); | 
 |  613  | 
 |  614     GrGeometryProcessor* gp = GrRectEffect::Create(); | 
 |  615     drawState->setGeometryProcessor(gp)->unref(); | 
 |  616  | 
 |  617     for (int i = 0; i < 4; ++i) { | 
 |  618         verts[i].fCenter = center; | 
 |  619         verts[i].fDir = dir; | 
 |  620         verts[i].fWidthHeight.fX = newWidth; | 
 |  621         verts[i].fWidthHeight.fY = newHeight; | 
 |  622     } | 
 |  623  | 
 |  624     SkRect devRect; | 
 |  625     combinedMatrix.mapRect(&devRect, rect); | 
 |  626  | 
 |  627     SkRect devBounds = { | 
 |  628         devRect.fLeft   - SK_ScalarHalf, | 
 |  629         devRect.fTop    - SK_ScalarHalf, | 
 |  630         devRect.fRight  + SK_ScalarHalf, | 
 |  631         devRect.fBottom + SK_ScalarHalf | 
 |  632     }; | 
 |  633  | 
 |  634     verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); | 
 |  635     verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); | 
 |  636     verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); | 
 |  637     verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); | 
 |  638  | 
 |  639     target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer()); | 
 |  640     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); | 
 |  641     target->resetIndexSource(); | 
 |  642 } | 
 |  643  | 
 |  644 void GrAARectRenderer::shaderFillAlignedAARect(GrDrawTarget* target, | 
 |  645                                                const SkRect& rect, | 
 |  646                                                const SkMatrix& combinedMatrix) { | 
 |  647     GrDrawState* drawState = target->drawState(); | 
 |  648     SkASSERT(combinedMatrix.rectStaysRect()); | 
 |  649  | 
 |  650     drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARect
     VertexAttribs), | 
 |  651                                                         sizeof(AARectVertex)); | 
 |  652  | 
 |  653     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 
 |  654     if (!geo.succeeded()) { | 
 |  655         SkDebugf("Failed to get space for vertices!\n"); | 
 |  656         return; | 
 |  657     } | 
 |  658  | 
 |  659     AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices()); | 
 |  660  | 
 |  661     GrGeometryProcessor* gp = GrAlignedRectEffect::Create(); | 
 |  662     drawState->setGeometryProcessor(gp)->unref(); | 
 |  663  | 
 |  664     SkRect devRect; | 
 |  665     combinedMatrix.mapRect(&devRect, rect); | 
 |  666  | 
 |  667     SkRect devBounds = { | 
 |  668         devRect.fLeft   - SK_ScalarHalf, | 
 |  669         devRect.fTop    - SK_ScalarHalf, | 
 |  670         devRect.fRight  + SK_ScalarHalf, | 
 |  671         devRect.fBottom + SK_ScalarHalf | 
 |  672     }; | 
 |  673  | 
 |  674     SkPoint widthHeight = { | 
 |  675         SkScalarHalf(devRect.width()) + SK_ScalarHalf, | 
 |  676         SkScalarHalf(devRect.height()) + SK_ScalarHalf | 
 |  677     }; | 
 |  678  | 
 |  679     verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); | 
 |  680     verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY); | 
 |  681     verts[0].fWidthHeight = widthHeight; | 
 |  682  | 
 |  683     verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); | 
 |  684     verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY); | 
 |  685     verts[1].fWidthHeight = widthHeight; | 
 |  686  | 
 |  687     verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); | 
 |  688     verts[2].fOffset = widthHeight; | 
 |  689     verts[2].fWidthHeight = widthHeight; | 
 |  690  | 
 |  691     verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); | 
 |  692     verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY); | 
 |  693     verts[3].fWidthHeight = widthHeight; | 
 |  694  | 
 |  695     target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer()); | 
 |  696     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); | 
 |  697     target->resetIndexSource(); | 
 |  698 } | 
 |  699  | 
|  306 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |  700 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 
|  307                                     const SkRect& rect, |  701                                     const SkRect& rect, | 
|  308                                     const SkMatrix& combinedMatrix, |  702                                     const SkMatrix& combinedMatrix, | 
|  309                                     const SkRect& devRect, |  703                                     const SkRect& devRect, | 
|  310                                     const SkStrokeRec& stroke) { |  704                                     const SkStrokeRec& stroke) { | 
|  311     SkVector devStrokeSize; |  705     SkVector devStrokeSize; | 
|  312     SkScalar width = stroke.getWidth(); |  706     SkScalar width = stroke.getWidth(); | 
|  313     if (width > 0) { |  707     if (width > 0) { | 
|  314         devStrokeSize.set(width, width); |  708         devStrokeSize.set(width, width); | 
|  315         combinedMatrix.mapVectors(&devStrokeSize, 1); |  709         combinedMatrix.mapVectors(&devStrokeSize, 1); | 
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  511     // can't call mapRect for devInside since it calls sort |  905     // can't call mapRect for devInside since it calls sort | 
|  512     combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
     ; |  906     combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
     ; | 
|  513  |  907  | 
|  514     if (devInside.isEmpty()) { |  908     if (devInside.isEmpty()) { | 
|  515         this->fillAARect(target, devOutside, SkMatrix::I(), devOutside); |  909         this->fillAARect(target, devOutside, SkMatrix::I(), devOutside); | 
|  516         return; |  910         return; | 
|  517     } |  911     } | 
|  518  |  912  | 
|  519     this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside, 
     true); |  913     this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside, 
     true); | 
|  520 } |  914 } | 
| OLD | NEW |