Lift calls for setting dynamic state to Ganesh level

Previously, all backends were responsible to check for dynamic state
and update it during their internal draw calls. This CL adds
setScissor() and bindTextures() methods to GrOpsRenderTask, and places
this responsibility to update dynamic state on Ganesh instead. It also
replaces the backend-specific "onDrawMeshes" call, with a singular
"onDrawMesh" call that gets called for each mesh.

For now we keep drawMeshes() on GrOpsRenderPass for convenience, but
it will soon be removed and each call site will be responsible to set
its own dynamic state.

Change-Id: If141feae857b22cbf04416557d0c89986eda2a62
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271976
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrOpsRenderPass.h b/src/gpu/GrOpsRenderPass.h
index 0652b26..0bea996 100644
--- a/src/gpu/GrOpsRenderPass.h
+++ b/src/gpu/GrOpsRenderPass.h
@@ -51,16 +51,35 @@
     virtual void end() = 0;
 
     // Updates the internal pipeline state for drawing with the provided GrProgramInfo.
-    // Returns false if the state could not be set.
+    // Enters an internal "bad" state if the pipeline could not be set.
     void bindPipeline(const GrProgramInfo&, const SkRect& drawBounds);
 
+    // The scissor rect is always dynamic state and therefore not stored on GrPipeline. If scissor
+    // test is enabled on the current pipeline, then the client must call setScissorRect() before
+    // drawing. The scissor rect may also be updated between draws without having to bind a new
+    // pipeline.
+    void setScissorRect(const SkIRect&);
+
+    // Texture bindings are dynamic state and therefore not set during bindPipeline(). If the
+    // current program uses textures, then the client must call bindTextures() before drawing.
+    // The primitive processor textures may also be updated between draws by calling bindTextures()
+    // again with a different array for primProcTextures. (On subsequent calls, if the backend is
+    // capable of updating the primitive processor textures independently, then it will
+    // automatically skip binding textures from GrPipeline.)
+    void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
+                      const GrSurfaceProxy* const primProcTextures[]);
+
     // Draws the given array of meshes using the current pipeline state. The client must call
     // bindPipeline() before using this method.
     //
-    // NOTE: This method will soon be replaced by individual calls for each draw type (indexed,
-    // instanced, indexed-patterned, indirect, etc.).
+    // NOTE: This method will soon be deleted. While it continues to exist, it takes care of calling
+    // setScissor() and bindTextures() on the client's behalf.
     void drawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount);
 
+    // Draws the given mesh using the current pipeline state. The client must call bindPipeline(),
+    // followed setScissor() and/or bindTextures() if necessary, before using this method.
+    void drawMesh(GrPrimitiveType, const GrMesh&);
+
     // Performs an upload of vertex data in the middle of a set of a set of draws
     virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
 
@@ -99,7 +118,10 @@
 
     // overridden by backend-specific derived class to perform the rendering command.
     virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0;
-    virtual void onDrawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount) = 0;
+    virtual void onSetScissorRect(const SkIRect&) = 0;
+    virtual bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
+                                const GrSurfaceProxy* const primProcTextures[] = nullptr) = 0;
+    virtual void onDrawMesh(GrPrimitiveType, const GrMesh&) = 0;
     virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0;
     virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
     virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
@@ -111,6 +133,20 @@
     };
 
     DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
+    GrXferBarrierType fXferBarrierType;
+
+#ifdef SK_DEBUG
+    enum class DynamicStateStatus {
+        kDisabled,
+        kUninitialized,
+        kConfigured
+    };
+
+    DynamicStateStatus fScissorStatus = DynamicStateStatus::kDisabled;
+    DynamicStateStatus fTextureBindingStatus = DynamicStateStatus::kDisabled;
+    bool fHasVertexAttributes = false;
+    bool fHasInstanceAttributes = false;
+#endif
 
     typedef GrOpsRenderPass INHERITED;
 };