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 "include/core/SkM44.h"
12#include "include/core/SkRefCnt.h"
13#include "include/gpu/gl/GrGLTypes.h"
14#include "src/gpu/GrGpu.h"
15#include "src/gpu/GrPathRendering.h"
16#include "src/gpu/GrStencilSettings.h"
17
18class GrGLGpu;
19class GrStyle;
20
21/**
22 * This class wraps the NV_path_rendering extension and manages its various
23 * API versions. If a method is not present in the GrGLInterface of the GrGLGpu
24 * (because the driver version is old), it tries to provide a backup
25 * implementation. But if a backup implementation is not practical, it marks the
26 * method as not supported.
27 */
28class GrGLPathRendering : public GrPathRendering {
29public:
30 /**
31 * Create a new GrGLPathRendering object from a given GrGLGpu.
32 */
33 GrGLPathRendering(GrGLGpu* gpu);
34 ~GrGLPathRendering() override;
35
36 // GrPathRendering implementations.
37 sk_sp<GrPath> createPath(const SkPath&, const GrStyle&) override;
38
39 /* Called when the 3D context state is unknown. */
40 void resetContext();
41
42 /**
43 * Called when the context either is about to be lost or is lost. DisconnectType indicates
44 * whether GPU resources should be cleaned up or abandoned when this is called.
45 */
46 void disconnect(GrGpu::DisconnectType);
47
48 bool shouldBindFragmentInputs() const {
49 return fCaps.bindFragmentInputSupport;
50 }
51
52 // Functions for "separable shader" texturing support.
53 void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
54 GrGLenum genMode, GrGLint components,
55 const SkMatrix&);
56
57 /* Sets the projection matrix for path rendering */
58 void setProjectionMatrix(const SkMatrix& matrix,
59 const SkISize& renderTargetSize,
60 GrSurfaceOrigin renderTargetOrigin);
61
62 GrGLuint genPaths(GrGLsizei range);
63 GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);
64
65protected:
66 void onStencilPath(const StencilPathArgs&, const GrPath*) override;
67 void onDrawPath(const GrStencilSettings&, const GrPath*) override;
68
69private:
70 /**
71 * Mark certain functionality as not supported.
72 */
73 struct Caps {
74 bool bindFragmentInputSupport : 1;
75 };
76
77 void flushPathStencilSettings(const GrStencilSettings&);
78
79 struct MatrixState {
80 SkMatrix fViewMatrix;
81 SkISize fRenderTargetSize;
82 GrSurfaceOrigin fRenderTargetOrigin;
83
84 MatrixState() { this->invalidate(); }
85 void invalidate() {
86 fViewMatrix = SkMatrix::InvalidMatrix();
87 fRenderTargetSize.fWidth = -1;
88 fRenderTargetSize.fHeight = -1;
89 fRenderTargetOrigin = (GrSurfaceOrigin) -1;
90 }
91
92 /**
93 * Gets a matrix that goes from local coordinates to GL normalized device coords.
94 */
95 void getRTAdjustedGLMatrix(float* destMatrix) {
96 SkMatrix combined;
97 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
98 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
99 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
100 0, 0, 1);
101 } else {
102 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
103 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
104 0, 0, 1);
105 }
106 combined.preConcat(fViewMatrix);
107 SkM44 combined44(combined);
108 combined44.getColMajor(destMatrix);
109 }
110 };
111 GrGLGpu* gpu();
112
113 GrGLuint fFirstPreallocatedPathID;
114 GrGLsizei fPreallocatedPathCount;
115 MatrixState fHWProjectionMatrixState;
116 GrStencilSettings fHWPathStencilSettings;
117 Caps fCaps;
118};
119
120#endif
121