1 /*
2  * Copyright 2014 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 #ifndef GrGLPathRendering_DEFINED
9 #define GrGLPathRendering_DEFINED
10 
11 #include "SkRefCnt.h"
12 #include "GrPathRendering.h"
13 #include "GrStencil.h"
14 #include "gl/GrGLFunctions.h"
15 #include "gl/GrGLProgram.h"
16 
17 class GrGLNameAllocator;
18 class GrGLGpu;
19 
20 /**
21  * This class wraps the NV_path_rendering extension and manages its various
22  * API versions. If a method is not present in the GrGLInterface of the GrGLGpu
23  * (because the driver version is old), it tries to provide a backup
24  * implementation. But if a backup implementation is not practical, it marks the
25  * method as not supported.
26  */
27 class GrGLPathRendering : public GrPathRendering {
28 public:
29     /**
30      * Create a new GrGLPathRendering object from a given GrGLGpu.
31      */
32     GrGLPathRendering(GrGLGpu* gpu);
33     virtual ~GrGLPathRendering();
34 
35     // GrPathRendering implementations.
36     GrPath* createPath(const SkPath&, const SkStrokeRec&) override;
37     virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
38                                          const SkStrokeRec&) override;
39     virtual GrPathRange* createGlyphs(const SkTypeface*,
40                                       const SkDescriptor*,
41                                       const SkStrokeRec&) override;
42     void stencilPath(const GrPath*, const GrStencilSettings&) override;
43     void drawPath(const GrPath*, const GrStencilSettings&) override;
44     virtual void drawPaths(const GrPathRange*, const void* indices, PathIndexType,
45                            const float transformValues[], PathTransformType, int count,
46                            const GrStencilSettings&) override;
47 
48     /* Called when the 3D context state is unknown. */
49     void resetContext();
50 
51     /**
52      * Called when the GPU resources have been lost and need to be abandoned
53      * (for example after a context loss).
54      */
55     void abandonGpuResources();
56 
57     // Functions for "separable shader" texturing support.
58     void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
59                                               GrGLenum genMode, GrGLint components,
60                                               const SkMatrix&);
61 
62     /* Sets the projection matrix for path rendering */
63     void setProjectionMatrix(const SkMatrix& matrix,
64                              const SkISize& renderTargetSize,
65                              GrSurfaceOrigin renderTargetOrigin);
66 
67     GrGLuint genPaths(GrGLsizei range);
68     GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);
69 
70 private:
71     /**
72      * Mark certain functionality as not supported if the driver version is too
73      * old and a backup implementation is not practical.
74      */
75     struct Caps {
76         bool stencilThenCoverSupport : 1;
77         bool fragmentInputGenSupport : 1;
78         bool glyphLoadingSupport     : 1;
79     };
caps()80     const Caps& caps() const { return fCaps; }
81 
82     void flushPathStencilSettings(const GrStencilSettings&);
83 
84     // NV_path_rendering v1.2
85     void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
86                                   GrGLuint mask, GrGLenum coverMode);
87 
88     void stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
89                                     GrGLuint mask, GrGLenum coverMode);
90 
91     void stencilThenCoverFillPathInstanced(
92         GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
93                          GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
94                          GrGLenum transformType, const GrGLfloat *transformValues);
95 
96     void stencilThenCoverStrokePathInstanced(
97                          GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
98                          GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
99                          GrGLenum transformType, const GrGLfloat *transformValues);
100 
101     struct MatrixState {
102         SkMatrix        fViewMatrix;
103         SkISize         fRenderTargetSize;
104         GrSurfaceOrigin fRenderTargetOrigin;
105 
MatrixStateMatrixState106         MatrixState() { this->invalidate(); }
invalidateMatrixState107         void invalidate() {
108             fViewMatrix = SkMatrix::InvalidMatrix();
109             fRenderTargetSize.fWidth = -1;
110             fRenderTargetSize.fHeight = -1;
111             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
112         }
113 
114         /**
115          * Gets a matrix that goes from local coordinates to GL normalized device coords.
116          */
getRTAdjustedGLMatrixMatrixState117         template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) {
118             SkMatrix combined;
119             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
120                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
121                                 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
122                                 0, 0, 1);
123             } else {
124                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
125                                 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
126                                 0, 0, 1);
127             }
128             combined.preConcat(fViewMatrix);
129             GrGLGetMatrix<Size>(destMatrix, combined);
130         }
131     };
132 
133     GrGLGpu* fGpu;
134     SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
135     Caps fCaps;
136     MatrixState fHWProjectionMatrixState;
137     GrStencilSettings fHWPathStencilSettings;
138     struct PathTexGenData {
139         GrGLenum  fMode;
140         GrGLint   fNumComponents;
141         GrGLfloat fCoefficients[3 * 3];
142     };
143 };
144 
145 #endif
146