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/GrGLTypes.h"
15 #include "glsl/GrGLSLUtil.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 GrStrokeInfo&) override;
37     virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
38                                          const GrStrokeInfo&) override;
39 
40     /* Called when the 3D context state is unknown. */
41     void resetContext();
42 
43     /**
44      * Called when the GPU resources have been lost and need to be abandoned
45      * (for example after a context loss).
46      */
47     void abandonGpuResources();
48 
shouldBindFragmentInputs()49     bool shouldBindFragmentInputs() const {
50         return fCaps.bindFragmentInputSupport;
51     }
52 
53     // Functions for "separable shader" texturing support.
54     void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
55                                               GrGLenum genMode, GrGLint components,
56                                               const SkMatrix&);
57 
58     /* Sets the projection matrix for path rendering */
59     void setProjectionMatrix(const SkMatrix& matrix,
60                              const SkISize& renderTargetSize,
61                              GrSurfaceOrigin renderTargetOrigin);
62 
63     GrGLuint genPaths(GrGLsizei range);
64     GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);
65 
66 protected:
67     void onStencilPath(const StencilPathArgs&, const GrPath*) override;
68     void onDrawPath(const DrawPathArgs&, const GrPath*) override;
69     void onDrawPaths(const DrawPathArgs&, const GrPathRange*, const void* indices, PathIndexType,
70                      const float transformValues[], PathTransformType, int count) override;
71 private:
72     /**
73      * Mark certain functionality as not supported.
74      */
75     struct Caps {
76         bool bindFragmentInputSupport : 1;
77     };
78 
79     void flushPathStencilSettings(const GrStencilSettings&);
80 
81     struct MatrixState {
82         SkMatrix        fViewMatrix;
83         SkISize         fRenderTargetSize;
84         GrSurfaceOrigin fRenderTargetOrigin;
85 
MatrixStateMatrixState86         MatrixState() { this->invalidate(); }
invalidateMatrixState87         void invalidate() {
88             fViewMatrix = SkMatrix::InvalidMatrix();
89             fRenderTargetSize.fWidth = -1;
90             fRenderTargetSize.fHeight = -1;
91             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
92         }
93 
94         /**
95          * Gets a matrix that goes from local coordinates to GL normalized device coords.
96          */
getRTAdjustedGLMatrixMatrixState97         template<int Size> void getRTAdjustedGLMatrix(float* destMatrix) {
98             SkMatrix combined;
99             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
100                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
101                                 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
102                                 0, 0, 1);
103             } else {
104                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
105                                 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
106                                 0, 0, 1);
107             }
108             combined.preConcat(fViewMatrix);
109             GrGLSLGetMatrix<Size>(destMatrix, combined);
110         }
111     };
112     GrGLGpu* gpu();
113 
114     GrGLuint fFirstPreallocatedPathID;
115     GrGLsizei fPreallocatedPathCount;
116     MatrixState fHWProjectionMatrixState;
117     GrStencilSettings fHWPathStencilSettings;
118     Caps fCaps;
119 };
120 
121 #endif
122