| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2014 Google Inc. | 2  * Copyright 2014 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 "gl/GrGLPathRendering.h" | 8 #include "gl/GrGLPathRendering.h" | 
| 9 #include "gl/GrGLInterface.h" |  | 
| 10 #include "gl/GrGLNameAllocator.h" | 9 #include "gl/GrGLNameAllocator.h" | 
| 11 #include "gl/GrGLUtil.h" | 10 #include "gl/GrGLUtil.h" | 
|  | 11 #include "gl/GrGpuGL.h" | 
| 12 | 12 | 
| 13 #define GL_CALL(X) GR_GL_CALL(fGLInterface.get(), X) | 13 #include "GrGLPath.h" | 
| 14 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGLInterface.get(), RET, X) | 14 #include "GrGLPathRange.h" | 
|  | 15 #include "GrGLPathRendering.h" | 
|  | 16 | 
|  | 17 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) | 
|  | 18 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X) | 
|  | 19 | 
|  | 20 | 
|  | 21 static const GrGLenum gXformType2GLType[] = { | 
|  | 22     GR_GL_NONE, | 
|  | 23     GR_GL_TRANSLATE_X, | 
|  | 24     GR_GL_TRANSLATE_Y, | 
|  | 25     GR_GL_TRANSLATE_2D, | 
|  | 26     GR_GL_TRANSPOSE_AFFINE_2D | 
|  | 27 }; | 
|  | 28 | 
|  | 29 GR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType); | 
|  | 30 GR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType); | 
|  | 31 GR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType); | 
|  | 32 GR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType); | 
|  | 33 GR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType); | 
|  | 34 GR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::
     kLast_PathTransformType); | 
|  | 35 | 
|  | 36 static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) { | 
|  | 37     switch (op) { | 
|  | 38         default: | 
|  | 39             SkFAIL("Unexpected path fill."); | 
|  | 40             /* fallthrough */; | 
|  | 41         case kIncClamp_StencilOp: | 
|  | 42             return GR_GL_COUNT_UP; | 
|  | 43         case kInvert_StencilOp: | 
|  | 44             return GR_GL_INVERT; | 
|  | 45     } | 
|  | 46 } | 
| 15 | 47 | 
| 16 class GrGLPathRenderingV12 : public GrGLPathRendering { | 48 class GrGLPathRenderingV12 : public GrGLPathRendering { | 
| 17 public: | 49 public: | 
| 18     GrGLPathRenderingV12(const GrGLInterface* glInterface) | 50     GrGLPathRenderingV12(GrGpuGL* gpu) | 
| 19         : GrGLPathRendering(glInterface) { | 51         : GrGLPathRendering(gpu) { | 
| 20     } | 52     } | 
| 21 | 53 | 
| 22     virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, | 54     virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, | 
| 23                                               GrGLuint mask, GrGLenum coverMode)
      SK_OVERRIDE; | 55                                               GrGLuint mask, GrGLenum coverMode)
      SK_OVERRIDE; | 
| 24     virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference
     , | 56     virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference
     , | 
| 25                                                 GrGLuint mask, GrGLenum coverMod
     e) SK_OVERRIDE; | 57                                                 GrGLuint mask, GrGLenum coverMod
     e) SK_OVERRIDE; | 
| 26     virtual GrGLvoid stencilThenCoverFillPathInstanced( | 58     virtual GrGLvoid stencilThenCoverFillPathInstanced( | 
| 27                          GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
     id *paths, | 59                          GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
     id *paths, | 
| 28                          GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, Gr
     GLenum coverMode, | 60                          GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, Gr
     GLenum coverMode, | 
| 29                          GrGLenum transformType, const GrGLfloat *transformValue
     s) SK_OVERRIDE; | 61                          GrGLenum transformType, const GrGLfloat *transformValue
     s) SK_OVERRIDE; | 
| 30     virtual GrGLvoid stencilThenCoverStrokePathInstanced( | 62     virtual GrGLvoid stencilThenCoverStrokePathInstanced( | 
| 31                          GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
     id *paths, | 63                          GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
     id *paths, | 
| 32                          GrGLuint pathBase, GrGLint reference, GrGLuint mask, Gr
     GLenum coverMode, | 64                          GrGLuint pathBase, GrGLint reference, GrGLuint mask, Gr
     GLenum coverMode, | 
| 33                          GrGLenum transformType, const GrGLfloat *transformValue
     s) SK_OVERRIDE; | 65                          GrGLenum transformType, const GrGLfloat *transformValue
     s) SK_OVERRIDE; | 
| 34 }; | 66 }; | 
| 35 | 67 | 
| 36 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 { | 68 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 { | 
| 37 public: | 69 public: | 
| 38     GrGLPathRenderingV13(const GrGLInterface* glInterface) | 70     GrGLPathRenderingV13(GrGpuGL* gpu) | 
| 39         : GrGLPathRenderingV12(glInterface) { | 71         : GrGLPathRenderingV12(gpu) { | 
| 40         fCaps.fragmentInputGenSupport = true; | 72         fCaps.fragmentInputGenSupport = true; | 
| 41     } | 73     } | 
| 42 | 74 | 
| 43     virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint locat
     ion, | 75     virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint locat
     ion, | 
| 44                                                  GrGLenum genMode, GrGLint compo
     nents, | 76                                                  GrGLenum genMode, GrGLint compo
     nents, | 
| 45                                                  const GrGLfloat *coeffs) SK_OVE
     RRIDE; | 77                                                  const GrGLfloat *coeffs) SK_OVE
     RRIDE; | 
| 46 }; | 78 }; | 
| 47 | 79 | 
| 48 | 80 | 
| 49 GrGLPathRendering* GrGLPathRendering::Create(const GrGLInterface* glInterface) { | 81 GrGLPathRendering* GrGLPathRendering::Create(GrGpuGL* gpu) { | 
|  | 82     const GrGLInterface* glInterface = gpu->glInterface(); | 
| 50     if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath || | 83     if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath || | 
| 51         NULL == glInterface->fFunctions.fStencilThenCoverStrokePath || | 84         NULL == glInterface->fFunctions.fStencilThenCoverStrokePath || | 
| 52         NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced || | 85         NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced || | 
| 53         NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) { | 86         NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) { | 
| 54         return new GrGLPathRendering(glInterface); | 87         return new GrGLPathRendering(gpu); | 
| 55     } | 88     } | 
| 56 | 89 | 
| 57     if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) { | 90     if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) { | 
| 58         return new GrGLPathRenderingV12(glInterface); | 91         return new GrGLPathRenderingV12(gpu); | 
| 59     } | 92     } | 
| 60 | 93 | 
| 61     return new GrGLPathRenderingV13(glInterface); | 94     return new GrGLPathRenderingV13(gpu); | 
| 62 } | 95 } | 
| 63 | 96 | 
| 64 GrGLPathRendering::GrGLPathRendering(const GrGLInterface* glInterface) | 97 GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu) | 
| 65     : fGLInterface(SkRef(glInterface)) { | 98     : fGpu(gpu) { | 
| 66     memset(&fCaps, 0, sizeof(fCaps)); | 99     memset(&fCaps, 0, sizeof(fCaps)); | 
|  | 100     fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords()); | 
| 67 } | 101 } | 
| 68 | 102 | 
| 69 GrGLPathRendering::~GrGLPathRendering() { | 103 GrGLPathRendering::~GrGLPathRendering() { | 
| 70 } | 104 } | 
| 71 | 105 | 
| 72 void GrGLPathRendering::abandonGpuResources() { | 106 void GrGLPathRendering::abandonGpuResources() { | 
| 73     fPathNameAllocator.reset(NULL); | 107     fPathNameAllocator.reset(NULL); | 
| 74 } | 108 } | 
| 75 | 109 | 
|  | 110 void GrGLPathRendering::resetContext() { | 
|  | 111     fHWProjectionMatrixState.invalidate(); | 
|  | 112     // we don't use the model view matrix. | 
|  | 113     GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); | 
|  | 114 | 
|  | 115     for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { | 
|  | 116         this->pathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL); | 
|  | 117         fHWPathTexGenSettings[i].fMode = GR_GL_NONE; | 
|  | 118         fHWPathTexGenSettings[i].fNumComponents = 0; | 
|  | 119     } | 
|  | 120     fHWActivePathTexGenSets = 0; | 
|  | 121     fHWPathStencilSettings.invalidate(); | 
|  | 122 } | 
|  | 123 | 
|  | 124 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& s
     troke) { | 
|  | 125     return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke)); | 
|  | 126 } | 
|  | 127 | 
|  | 128 GrPathRange* GrGLPathRendering::createPathRange(size_t size, const SkStrokeRec& 
     stroke) { | 
|  | 129     return SkNEW_ARGS(GrGLPathRange, (fGpu, size, stroke)); | 
|  | 130 } | 
|  | 131 | 
|  | 132 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
     nents, | 
|  | 133                                          const GrGLfloat* coefficients) { | 
|  | 134     SkASSERT(components >= kS_PathTexGenComponents && | 
|  | 135              components <= kSTR_PathTexGenComponents); | 
|  | 136     SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx); | 
|  | 137 | 
|  | 138     if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode && | 
|  | 139         components == fHWPathTexGenSettings[unitIdx].fNumComponents && | 
|  | 140         !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients, | 
|  | 141                 3 * components * sizeof(GrGLfloat))) { | 
|  | 142         return; | 
|  | 143     } | 
|  | 144 | 
|  | 145     fGpu->setTextureUnit(unitIdx); | 
|  | 146 | 
|  | 147     fHWPathTexGenSettings[unitIdx].fNumComponents = components; | 
|  | 148     this->pathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components, 
     coefficients); | 
|  | 149 | 
|  | 150     memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, | 
|  | 151            3 * components * sizeof(GrGLfloat)); | 
|  | 152 } | 
|  | 153 | 
|  | 154 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
     nents, | 
|  | 155                                          const SkMatrix& matrix) { | 
|  | 156     GrGLfloat coefficients[3 * 3]; | 
|  | 157     SkASSERT(components >= kS_PathTexGenComponents && | 
|  | 158              components <= kSTR_PathTexGenComponents); | 
|  | 159 | 
|  | 160     coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); | 
|  | 161     coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); | 
|  | 162     coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); | 
|  | 163 | 
|  | 164     if (components >= kST_PathTexGenComponents) { | 
|  | 165         coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); | 
|  | 166         coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); | 
|  | 167         coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); | 
|  | 168     } | 
|  | 169 | 
|  | 170     if (components >= kSTR_PathTexGenComponents) { | 
|  | 171         coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); | 
|  | 172         coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); | 
|  | 173         coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); | 
|  | 174     } | 
|  | 175 | 
|  | 176     this->enablePathTexGen(unitIdx, components, coefficients); | 
|  | 177 } | 
|  | 178 | 
|  | 179 void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) { | 
|  | 180     SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSe
     ts); | 
|  | 181 | 
|  | 182     // Only write the inactive path tex gens, since active path tex gens were | 
|  | 183     // written when they were enabled. | 
|  | 184 | 
|  | 185     SkDEBUGCODE( | 
|  | 186         for (int i = 0; i < numUsedTexCoordSets; i++) { | 
|  | 187             SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); | 
|  | 188         } | 
|  | 189     ); | 
|  | 190 | 
|  | 191     for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) { | 
|  | 192         SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); | 
|  | 193 | 
|  | 194         fGpu->setTextureUnit(i); | 
|  | 195         GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); | 
|  | 196         fHWPathTexGenSettings[i].fNumComponents = 0; | 
|  | 197     } | 
|  | 198 | 
|  | 199     fHWActivePathTexGenSets = numUsedTexCoordSets; | 
|  | 200 } | 
|  | 201 | 
|  | 202 void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { | 
|  | 203     GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); | 
|  | 204     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); | 
|  | 205     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); | 
|  | 206 | 
|  | 207     this->flushPathStencilSettings(fill); | 
|  | 208     SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 
|  | 209 | 
|  | 210     GrGLenum fillMode = | 
|  | 211         gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
     Op(GrStencilSettings::kFront_Face)); | 
|  | 212     GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
     nt_Face); | 
|  | 213     this->stencilFillPath(id, fillMode, writeMask); | 
|  | 214 } | 
|  | 215 | 
|  | 216 void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { | 
|  | 217     GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); | 
|  | 218     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); | 
|  | 219     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); | 
|  | 220     SkASSERT(!fGpu->fCurrentProgram->hasVertexShader()); | 
|  | 221 | 
|  | 222     this->flushPathStencilSettings(fill); | 
|  | 223     SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 
|  | 224 | 
|  | 225     const SkStrokeRec& stroke = path->getStroke(); | 
|  | 226 | 
|  | 227     SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill)
     ; | 
|  | 228 | 
|  | 229     GrGLenum fillMode = | 
|  | 230         gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
     Op(GrStencilSettings::kFront_Face)); | 
|  | 231     GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
     nt_Face); | 
|  | 232 | 
|  | 233     if (nonInvertedFill == fill) { | 
|  | 234         if (stroke.needToApply()) { | 
|  | 235             if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { | 
|  | 236                 this->stencilFillPath(id, fillMode, writeMask); | 
|  | 237             } | 
|  | 238             this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDI
     NG_BOX); | 
|  | 239         } else { | 
|  | 240             this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDI
     NG_BOX); | 
|  | 241         } | 
|  | 242     } else { | 
|  | 243         if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
     getStyle()) { | 
|  | 244             this->stencilFillPath(id, fillMode, writeMask); | 
|  | 245         } | 
|  | 246         if (stroke.needToApply()) { | 
|  | 247             this->stencilStrokePath(id, 0xffff, writeMask); | 
|  | 248         } | 
|  | 249 | 
|  | 250         GrDrawState* drawState = fGpu->drawState(); | 
|  | 251         GrDrawState::AutoViewMatrixRestore avmr; | 
|  | 252         SkRect bounds = SkRect::MakeLTRB(0, 0, | 
|  | 253                                          SkIntToScalar(drawState->getRenderTarge
     t()->width()), | 
|  | 254                                          SkIntToScalar(drawState->getRenderTarge
     t()->height())); | 
|  | 255         SkMatrix vmi; | 
|  | 256         // mapRect through persp matrix may not be correct | 
|  | 257         if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
     verse(&vmi)) { | 
|  | 258             vmi.mapRect(&bounds); | 
|  | 259             // theoretically could set bloat = 0, instead leave it because of ma
     trix inversion | 
|  | 260             // precision. | 
|  | 261             SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
     rHalf; | 
|  | 262             bounds.outset(bloat, bloat); | 
|  | 263         } else { | 
|  | 264             avmr.setIdentity(drawState); | 
|  | 265         } | 
|  | 266 | 
|  | 267         fGpu->drawSimpleRect(bounds); | 
|  | 268     } | 
|  | 269 } | 
|  | 270 | 
|  | 271 void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i
     ndices[], int count, | 
|  | 272                                   const float transforms[], PathTransformType tr
     ansformsType, | 
|  | 273                                   SkPath::FillType fill) { | 
|  | 274     SkASSERT(fGpu->caps()->pathRenderingSupport()); | 
|  | 275     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); | 
|  | 276     SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); | 
|  | 277     SkASSERT(!fGpu->fCurrentProgram->hasVertexShader()); | 
|  | 278 | 
|  | 279     GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID()
     ; | 
|  | 280 | 
|  | 281     this->flushPathStencilSettings(fill); | 
|  | 282     SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 
|  | 283 | 
|  | 284     const SkStrokeRec& stroke = pathRange->getStroke(); | 
|  | 285 | 
|  | 286     SkPath::FillType nonInvertedFill = | 
|  | 287         SkPath::ConvertToNonInverseFillType(fill); | 
|  | 288 | 
|  | 289     GrGLenum fillMode = | 
|  | 290         gr_stencil_op_to_gl_path_rendering_fill_mode( | 
|  | 291             fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); | 
|  | 292     GrGLint writeMask = | 
|  | 293         fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); | 
|  | 294 | 
|  | 295     if (nonInvertedFill == fill) { | 
|  | 296         if (stroke.needToApply()) { | 
|  | 297             if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { | 
|  | 298                 this->stencilFillPathInstanced( | 
|  | 299                                     count, GR_GL_UNSIGNED_INT, indices, baseID, 
     fillMode, | 
|  | 300                                     writeMask, gXformType2GLType[transformsType]
     , | 
|  | 301                                     transforms); | 
|  | 302             } | 
|  | 303             this->stencilThenCoverStrokePathInstanced( | 
|  | 304                                 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
     ff, writeMask, | 
|  | 305                                 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, | 
|  | 306                                 gXformType2GLType[transformsType], transforms); | 
|  | 307         } else { | 
|  | 308             this->stencilThenCoverFillPathInstanced( | 
|  | 309                                 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
     Mode, writeMask, | 
|  | 310                                 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, | 
|  | 311                                 gXformType2GLType[transformsType], transforms); | 
|  | 312         } | 
|  | 313     } else { | 
|  | 314         if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
     getStyle()) { | 
|  | 315             this->stencilFillPathInstanced( | 
|  | 316                                 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
     Mode, | 
|  | 317                                 writeMask, gXformType2GLType[transformsType], | 
|  | 318                                 transforms); | 
|  | 319         } | 
|  | 320         if (stroke.needToApply()) { | 
|  | 321             this->stencilStrokePathInstanced( | 
|  | 322                                 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
     ff, | 
|  | 323                                 writeMask, gXformType2GLType[transformsType], | 
|  | 324                                 transforms); | 
|  | 325         } | 
|  | 326 | 
|  | 327         GrDrawState* drawState = fGpu->drawState(); | 
|  | 328         GrDrawState::AutoViewMatrixRestore avmr; | 
|  | 329         SkRect bounds = SkRect::MakeLTRB(0, 0, | 
|  | 330                                          SkIntToScalar(drawState->getRenderTarge
     t()->width()), | 
|  | 331                                          SkIntToScalar(drawState->getRenderTarge
     t()->height())); | 
|  | 332         SkMatrix vmi; | 
|  | 333         // mapRect through persp matrix may not be correct | 
|  | 334         if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
     verse(&vmi)) { | 
|  | 335             vmi.mapRect(&bounds); | 
|  | 336             // theoretically could set bloat = 0, instead leave it because of ma
     trix inversion | 
|  | 337             // precision. | 
|  | 338             SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
     rHalf; | 
|  | 339             bounds.outset(bloat, bloat); | 
|  | 340         } else { | 
|  | 341             avmr.setIdentity(drawState); | 
|  | 342         } | 
|  | 343 | 
|  | 344         fGpu->drawSimpleRect(bounds); | 
|  | 345     } | 
|  | 346 } | 
|  | 347 | 
|  | 348 void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { | 
|  | 349     GrStencilSettings pathStencilSettings; | 
|  | 350     fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); | 
|  | 351     if (fHWPathStencilSettings != pathStencilSettings) { | 
|  | 352         // Just the func, ref, and mask is set here. The op and write mask are p
     arams to the call | 
|  | 353         // that draws the path to the SB (glStencilFillPath) | 
|  | 354         GrGLenum func = | 
|  | 355             GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront
     _Face)); | 
|  | 356         this->pathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSetting
     s::kFront_Face), | 
|  | 357                               pathStencilSettings.funcMask(GrStencilSettings::kF
     ront_Face)); | 
|  | 358 | 
|  | 359         fHWPathStencilSettings = pathStencilSettings; | 
|  | 360     } | 
|  | 361 } | 
|  | 362 | 
|  | 363 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, | 
|  | 364                                   const SkISize& renderTargetSize, | 
|  | 365                                   GrSurfaceOrigin renderTargetOrigin) { | 
|  | 366 | 
|  | 367     SkASSERT(fGpu->glCaps().pathRenderingSupport()); | 
|  | 368 | 
|  | 369     if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && | 
|  | 370         renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && | 
|  | 371         matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { | 
|  | 372         return; | 
|  | 373     } | 
|  | 374 | 
|  | 375     fHWProjectionMatrixState.fViewMatrix = matrix; | 
|  | 376     fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; | 
|  | 377     fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; | 
|  | 378 | 
|  | 379     GrGLfloat glMatrix[4 * 4]; | 
|  | 380     fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); | 
|  | 381     GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix)); | 
|  | 382 } | 
|  | 383 | 
|  | 384 | 
| 76 | 385 | 
| 77 // NV_path_rendering | 386 // NV_path_rendering | 
| 78 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { | 387 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { | 
| 79     if (range > 1) { | 388     if (range > 1) { | 
| 80         GrGLuint name; | 389         GrGLuint name; | 
| 81         GL_CALL_RET(name, GenPaths(range)); | 390         GL_CALL_RET(name, GenPaths(range)); | 
| 82         return name; | 391         return name; | 
| 83     } | 392     } | 
| 84 | 393 | 
| 85     if (NULL == fPathNameAllocator.get()) { | 394     if (NULL == fPathNameAllocator.get()) { | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 149     GrGLboolean ret; | 458     GrGLboolean ret; | 
| 150     GL_CALL_RET(ret, IsPath(path)); | 459     GL_CALL_RET(ret, IsPath(path)); | 
| 151     return ret; | 460     return ret; | 
| 152 } | 461 } | 
| 153 | 462 | 
| 154 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint
      mask) { | 463 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint
      mask) { | 
| 155     GL_CALL(PathStencilFunc(func, ref, mask)); | 464     GL_CALL(PathStencilFunc(func, ref, mask)); | 
| 156 } | 465 } | 
| 157 | 466 | 
| 158 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, Gr
     GLuint mask) { | 467 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, Gr
     GLuint mask) { | 
|  | 468     // Decide how to manipulate the stencil buffer based on the fill rule. | 
| 159     GL_CALL(StencilFillPath(path, fillMode, mask)); | 469     GL_CALL(StencilFillPath(path, fillMode, mask)); | 
| 160 } | 470 } | 
| 161 | 471 | 
| 162 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference, 
     GrGLuint mask) { | 472 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference, 
     GrGLuint mask) { | 
| 163     GL_CALL(StencilStrokePath(path, reference, mask)); | 473     GL_CALL(StencilStrokePath(path, reference, mask)); | 
| 164 } | 474 } | 
| 165 | 475 | 
| 166 GrGLvoid GrGLPathRendering::stencilFillPathInstanced( | 476 GrGLvoid GrGLPathRendering::stencilFillPathInstanced( | 
| 167              GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | 477              GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | 
| 168              GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, | 478              GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 272                                                 mask, coverMode, transformType, 
     transformValues)); | 582                                                 mask, coverMode, transformType, 
     transformValues)); | 
| 273 } | 583 } | 
| 274 | 584 | 
| 275 | 585 | 
| 276 // NV_path_rendering v1.3 | 586 // NV_path_rendering v1.3 | 
| 277 GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen( | 587 GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen( | 
| 278              GrGLuint program, GrGLint location, GrGLenum genMode, | 588              GrGLuint program, GrGLint location, GrGLenum genMode, | 
| 279              GrGLint components, const GrGLfloat *coeffs) { | 589              GrGLint components, const GrGLfloat *coeffs) { | 
| 280     GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, 
     coeffs)); | 590     GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, 
     coeffs)); | 
| 281 } | 591 } | 
| OLD | NEW | 
|---|