Add gl_SampleMask functionality to fragment builders

Adds methods for overriding and masking a fragment's sample mask.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1690963003

Committed: https://skia.googlesource.com/skia/+/533cefe5b9c7cec2592fc7ca00ee4cf69a26c094

Review URL: https://codereview.chromium.org/1690963003
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index 4dab6f2..b9816af 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -67,6 +67,17 @@
     GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
 
     /**
+     * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found
+     * in the mask will not be written out to the framebuffer.
+     *
+     * @param mask      int that contains the sample mask. Bit N corresponds to the Nth sample.
+     * @param invert    perform a bit-wise NOT on the provided mask before applying it?
+     *
+     * Requires GLSL support for sample variables.
+     */
+    virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
+
+    /**
      * Fragment procs with child procs should call these functions before/after calling emitCode
      * on a child proc.
      */
@@ -83,6 +94,20 @@
 public:
     /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
     GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
+
+    /**
+     * Overrides the fragment's sample coverage. The provided mask determines which samples will now
+     * be written out to the framebuffer. Note that this mask can be reduced by a future call to
+     * maskSampleCoverage.
+     *
+     * If a primitive processor uses this method, it must guarantee that every codepath through the
+     * shader overrides the sample mask at some point.
+     *
+     * @param mask    int that contains the new coverage mask. Bit N corresponds to the Nth sample.
+     *
+     * Requires NV_sample_mask_override_coverage.
+     */
+    virtual void overrideSampleCoverage(const char* mask) = 0;
 };
 
 /*
@@ -127,6 +152,8 @@
     const char* fragmentPosition() override;
 
     // GrGLSLFPFragmentBuilder interface.
+    void maskSampleCoverage(const char* mask, bool invert = false) override;
+    void overrideSampleCoverage(const char* mask) override;
     const SkString& getMangleString() const override { return fMangleString; }
     void onBeforeChildProcEmitCode() override;
     void onAfterChildProcEmitCode() override;
@@ -197,6 +224,7 @@
     bool fHasCustomColorOutput;
     int  fCustomColorOutputIndex;
     bool fHasSecondaryOutput;
+    bool fHasInitializedSampleMask;
 
     // some state to verify shaders and effects are consistent, this is reset between effects by
     // the program creator