Add "sample locations" feature to GrProcessor

Adds a "sample locations" feature to GrProcessor. When enabled, this
allows a processor to know inside the shader where all the samples are
located. Also adds various infastructure to query, cache, and identify
multisample data.

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

Review URL: https://codereview.chromium.org/1717393002
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index 57b8ee9..614b04f 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -68,6 +68,23 @@
     /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
     GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
 
+    enum Coordinates {
+        kSkiaDevice_Coordinates,
+        kGLSLWindow_Coordinates,
+
+        kLast_Coordinates = kGLSLWindow_Coordinates
+    };
+
+    /**
+     * Appends the offset from the center of the pixel to a specified sample.
+     *
+     * @param sampleIdx      GLSL expression of the sample index.
+     * @param Coordinates    Coordinate space in which to emit the offset.
+     *
+     * A processor must call setWillUseSampleLocations in its constructor before using this method.
+     */
+    virtual void appendOffsetToSample(const char* sampleIdx, Coordinates) = 0;
+
     /**
      * 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.
@@ -138,14 +155,11 @@
  */
 class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
 public:
-    typedef uint8_t FragPosKey;
+   /** Returns a nonzero key for a surface's origin. This should only be called if a processor will
+       use the fragment position and/or sample locations. */
+    static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin);
 
-    /** Returns a key for reading the fragment location. This should only be called if there is an
-       effect that will requires the fragment position. If the fragment position is not required,
-       the key is 0. */
-    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
-
-    GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey);
+    GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program);
 
     // Shared GrGLSLFragmentBuilder interface.
     bool enableFeature(GLSLFeature) override;
@@ -154,6 +168,7 @@
     const char* fragmentPosition() override;
 
     // GrGLSLFPFragmentBuilder interface.
+    void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
     void maskSampleCoverage(const char* mask, bool invert = false) override;
     void overrideSampleCoverage(const char* mask) override;
     const SkString& getMangleString() const override { return fMangleString; }
@@ -167,8 +182,6 @@
     void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
 
 private:
-    bool hasFragmentPosition() const;
-
     // Private public interface, used by GrGLProgramBuilder to build a fragment shader
     void enableCustomOutput();
     void enableSecondaryOutput();
@@ -189,19 +202,10 @@
     static const char* DeclaredColorOutputName() { return "fsColorOut"; }
     static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
 
-    /*
-     * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
-     */
-    void addVarying(GrGLSLVarying*, GrSLPrecision);
+    GrSurfaceOrigin getSurfaceOrigin() const;
 
     void onFinalize() override;
-
-    // Interpretation of FragPosKey when generating code
-    enum {
-        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
-        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
-        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
-    };
+    void defineSampleOffsetArray(const char* name, const SkMatrix&);
 
     static const char* kDstTextureColorName;
 
@@ -225,12 +229,12 @@
      */
     SkString fMangleString;
 
-    bool fSetupFragPosition;
-    bool fTopLeftFragPosRead;
-    bool fHasCustomColorOutput;
-    int  fCustomColorOutputIndex;
-    bool fHasSecondaryOutput;
-    bool fHasInitializedSampleMask;
+    bool       fSetupFragPosition;
+    bool       fHasCustomColorOutput;
+    int        fCustomColorOutputIndex;
+    bool       fHasSecondaryOutput;
+    uint8_t    fUsedSampleOffsetArrays;
+    bool       fHasInitializedSampleMask;
 
 #ifdef SK_DEBUG
     // some state to verify shaders and effects are consistent, this is reset between effects by