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
17class GrGLNameAllocator;
18class GrGpuGL;
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 GrGpuGL
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 */
27class GrGLPathRendering : public GrPathRendering {
28public:
29    /**
30     * Create a new GrGLPathRendering object from a given GrGpuGL.
31     */
32    GrGLPathRendering(GrGpuGL* gpu);
33    virtual ~GrGLPathRendering();
34
35    // GrPathRendering implementations.
36    virtual GrPath* createPath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE;
37    virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
38                                         const SkStrokeRec&) SK_OVERRIDE;
39    virtual GrPathRange* createGlyphs(const SkTypeface*,
40                                      const SkDescriptor*,
41                                      const SkStrokeRec&) SK_OVERRIDE;
42    virtual void stencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
43    virtual void drawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
44    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
45                           const float transforms[], PathTransformType,
46                           SkPath::FillType) SK_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
58    enum TexturingMode {
59        FixedFunction_TexturingMode,
60        SeparableShaders_TexturingMode
61    };
62
63    /** Specifies whether texturing should use fixed fuction pipe or separable shaders
64     * Specifies whether texturing should use fixed fuction pipe or whether
65     * it is ok to use normal vertex and fragment shaders, and for path rendering
66     * populate fragment shaders with setProgramPathFragmentInputTransform.
67     * The fixed function mode will be removed once the other mode is more widely
68     * available.
69     */
70    TexturingMode texturingMode() const  {
71        return caps().fragmentInputGenSupport ?
72            SeparableShaders_TexturingMode : FixedFunction_TexturingMode;
73    }
74
75    // Functions for fixed function texturing support.
76    enum PathTexGenComponents {
77        kS_PathTexGenComponents = 1,
78        kST_PathTexGenComponents = 2,
79        kSTR_PathTexGenComponents = 3
80    };
81    void enablePathTexGen(int unitIdx, PathTexGenComponents, const GrGLfloat* coefficients);
82    void enablePathTexGen(int unitIdx, PathTexGenComponents, const SkMatrix& matrix);
83    void flushPathTexGenSettings(int numUsedTexCoordSets);
84
85    // Functions for "separable shader" texturing support.
86    void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
87                                              GrGLenum genMode, GrGLint components,
88                                              const SkMatrix&);
89
90    /* Sets the projection matrix for path rendering */
91    void setProjectionMatrix(const SkMatrix& matrix,
92                             const SkISize& renderTargetSize,
93                             GrSurfaceOrigin renderTargetOrigin);
94
95    GrGLuint genPaths(GrGLsizei range);
96    GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);
97
98private:
99    /**
100     * Mark certain functionality as not supported if the driver version is too
101     * old and a backup implementation is not practical.
102     */
103    struct Caps {
104        bool stencilThenCoverSupport : 1;
105        bool fragmentInputGenSupport : 1;
106        bool glyphLoadingSupport     : 1;
107    };
108    const Caps& caps() const { return fCaps; }
109
110    void flushPathStencilSettings(SkPath::FillType fill);
111
112    // NV_path_rendering v1.2
113    void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
114                                  GrGLuint mask, GrGLenum coverMode);
115
116    void stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
117                                    GrGLuint mask, GrGLenum coverMode);
118
119    void stencilThenCoverFillPathInstanced(
120        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
121                         GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
122                         GrGLenum transformType, const GrGLfloat *transformValues);
123
124    void stencilThenCoverStrokePathInstanced(
125                         GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
126                         GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
127                         GrGLenum transformType, const GrGLfloat *transformValues);
128
129    GrGpuGL* fGpu;
130    SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
131    Caps fCaps;
132    GrGLProgram::MatrixState fHWProjectionMatrixState;
133    GrStencilSettings fHWPathStencilSettings;
134    struct PathTexGenData {
135        GrGLenum  fMode;
136        GrGLint   fNumComponents;
137        GrGLfloat fCoefficients[3 * 3];
138    };
139    int fHWActivePathTexGenSets;
140    SkTArray<PathTexGenData, true> fHWPathTexGenSettings;
141};
142
143#endif
144