aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLPathRendering.h
blob: b39c866c6f89c3f2620d32af950f33496e4ede58 (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
/*
 * 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/GrGLTypes.h"
#include "glsl/GrGLSLUtil.h"

class GrGLNameAllocator;
class GrGLGpu;

/**
 * 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 GrGLGpu
 * (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 GrGLGpu.
     */
    GrGLPathRendering(GrGLGpu* gpu);
    virtual ~GrGLPathRendering();

    // GrPathRendering implementations.
    GrPath* createPath(const SkPath&, const GrStrokeInfo&) override;
    virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
                                         const GrStrokeInfo&) override;

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

    /**
     * Called when the context either is about to be lost or is lost. DisconnectType indicates
     * whether GPU resources should be cleaned up or abandoned when this is called.
     */
    void disconnect(GrGpu::DisconnectType);

    bool shouldBindFragmentInputs() const {
        return fCaps.bindFragmentInputSupport;
    }

    // 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);

protected:
    void onStencilPath(const StencilPathArgs&, const GrPath*) override;
    void onDrawPath(const GrPipeline&,
                    const GrPrimitiveProcessor&,
                    const GrStencilSettings&,
                    const GrPath*) override;
    void onDrawPaths(const GrPipeline&,
                     const GrPrimitiveProcessor&,
                     const GrStencilSettings&,
                     const GrPathRange*,
                     const void* indices,
                     PathIndexType,
                     const float transformValues[],
                     PathTransformType,
                     int count) override;
private:
    /**
     * Mark certain functionality as not supported.
     */
    struct Caps {
        bool bindFragmentInputSupport : 1;
    };

    void flushPathStencilSettings(const GrStencilSettings&);

    struct MatrixState {
        SkMatrix        fViewMatrix;
        SkISize         fRenderTargetSize;
        GrSurfaceOrigin fRenderTargetOrigin;

        MatrixState() { this->invalidate(); }
        void invalidate() {
            fViewMatrix = SkMatrix::InvalidMatrix();
            fRenderTargetSize.fWidth = -1;
            fRenderTargetSize.fHeight = -1;
            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
        }

        /**
         * Gets a matrix that goes from local coordinates to GL normalized device coords.
         */
        template<int Size> void getRTAdjustedGLMatrix(float* destMatrix) {
            SkMatrix combined;
            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
                                0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
                                0, 0, 1);
            } else {
                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
                                0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
                                0, 0, 1);
            }
            combined.preConcat(fViewMatrix);
            GrGLSLGetMatrix<Size>(destMatrix, combined);
        }
    };
    GrGLGpu* gpu();

    GrGLuint fFirstPreallocatedPathID;
    GrGLsizei fPreallocatedPathCount;
    MatrixState fHWProjectionMatrixState;
    GrStencilSettings fHWPathStencilSettings;
    Caps fCaps;
};

#endif