aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLPathRendering.h
blob: 5133506a427bb1ad244c0d31cb039cbbb5314f4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrGLPathRendering_DEFINED
#define GrGLPathRendering_DEFINED

#include "SkRefCnt.h"
#include "GrPathRendering.h"
#include "GrStencil.h"
#include "gl/GrGLFunctions.h"
#include "gl/GrGLProgram.h"

class GrGLNameAllocator;
class GrGpuGL;

/**
 * This class wraps the NV_path_rendering extension and manages its various
 * API versions. If a method is not present in the GrGLInterface of the GrGpuGL
 * (because the driver version is old), it tries to provide a backup
 * implementation. But if a backup implementation is not practical, it marks the
 * method as not supported.
 */
class GrGLPathRendering : public GrPathRendering {
public:
    /**
     * Create a new GrGLPathRendering object from a given GrGpuGL.
     */
    GrGLPathRendering(GrGpuGL* gpu);
    virtual ~GrGLPathRendering();

    // GrPathRendering implementations.
    virtual GrPath* createPath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE;
    virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
                                         const SkStrokeRec&) SK_OVERRIDE;
    virtual GrPathRange* createGlyphs(const SkTypeface*,
                                      const SkDescriptor*,
                                      const SkStrokeRec&) SK_OVERRIDE;
    virtual void stencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
    virtual void drawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
                           const float transforms[], PathTransformType,
                           SkPath::FillType) SK_OVERRIDE;

    /* Called when the 3D context state is unknown. */
    void resetContext();

    /**
     * Called when the GPU resources have been lost and need to be abandoned
     * (for example after a context loss).
     */
    void abandonGpuResources();


    enum TexturingMode {
        FixedFunction_TexturingMode,
        SeparableShaders_TexturingMode
    };

    /** Specifies whether texturing should use fixed fuction pipe or separable shaders
     * Specifies whether texturing should use fixed fuction pipe or whether
     * it is ok to use normal vertex and fragment shaders, and for path rendering
     * populate fragment shaders with setProgramPathFragmentInputTransform.
     * The fixed function mode will be removed once the other mode is more widely
     * available.
     */
    TexturingMode texturingMode() const  {
        return caps().fragmentInputGenSupport ?
            SeparableShaders_TexturingMode : FixedFunction_TexturingMode;
    }

    // Functions for fixed function texturing support.
    enum PathTexGenComponents {
        kS_PathTexGenComponents = 1,
        kST_PathTexGenComponents = 2,
        kSTR_PathTexGenComponents = 3
    };
    void enablePathTexGen(int unitIdx, PathTexGenComponents, const GrGLfloat* coefficients);
    void enablePathTexGen(int unitIdx, PathTexGenComponents, const SkMatrix& matrix);
    void flushPathTexGenSettings(int numUsedTexCoordSets);

    // Functions for "separable shader" texturing support.
    void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
                                              GrGLenum genMode, GrGLint components,
                                              const SkMatrix&);

    /* Sets the projection matrix for path rendering */
    void setProjectionMatrix(const SkMatrix& matrix,
                             const SkISize& renderTargetSize,
                             GrSurfaceOrigin renderTargetOrigin);

    GrGLuint genPaths(GrGLsizei range);
    GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);

private:
    /**
     * Mark certain functionality as not supported if the driver version is too
     * old and a backup implementation is not practical.
     */
    struct Caps {
        bool stencilThenCoverSupport : 1;
        bool fragmentInputGenSupport : 1;
        bool glyphLoadingSupport     : 1;
    };
    const Caps& caps() const { return fCaps; }

    void flushPathStencilSettings(SkPath::FillType fill);

    // NV_path_rendering v1.2
    void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
                                  GrGLuint mask, GrGLenum coverMode);

    void stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
                                    GrGLuint mask, GrGLenum coverMode);

    void stencilThenCoverFillPathInstanced(
        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
                         GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
                         GrGLenum transformType, const GrGLfloat *transformValues);

    void stencilThenCoverStrokePathInstanced(
                         GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
                         GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
                         GrGLenum transformType, const GrGLfloat *transformValues);

    GrGpuGL* fGpu;
    SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
    Caps fCaps;
    GrGLProgram::MatrixState fHWProjectionMatrixState;
    GrStencilSettings fHWPathStencilSettings;
    struct PathTexGenData {
        GrGLenum  fMode;
        GrGLint   fNumComponents;
        GrGLfloat fCoefficients[3 * 3];
    };
    int fHWActivePathTexGenSets;
    SkTArray<PathTexGenData, true> fHWPathTexGenSettings;
};

#endif