1 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #ifndef GrPLSPathRenderer_DEFINED 10 #define GrPLSPathRenderer_DEFINED 11 12 #include "GrPathRenderer.h" 13 14 /* 15 * Renders arbitrary antialiased paths using pixel local storage as a scratch buffer. The overall 16 * technique is very similar to the approach presented in "Resolution independent rendering of 17 * deformable vector objects using graphics hardware" by Kokojima et al. 18 19 * We first render the straight-line portions of the path (essentially pretending as if all segments 20 * were kLine_Verb) as a triangle fan, using a fragment shader which updates the winding counts 21 * appropriately. We then render the curved portions of the path using a Loop-Blinn shader which 22 * calculates which portion of the triangle is covered by the quad (conics and cubics are split down 23 * to quads). Where we diverge from Kokojima is that, instead of rendering into the stencil buffer 24 * and using built-in MSAA to handle straight-line antialiasing, we use the pixel local storage area 25 * and calculate the MSAA ourselves in the fragment shader. Essentially, we manually evaluate the 26 * coverage of each pixel four times, storing four winding counts into the pixel local storage area, 27 * and compute the final coverage based on those winding counts. 28 * 29 * Our approach is complicated by the need to perform antialiasing on straight edges as well, 30 * without relying on hardware MSAA. We instead bloat the triangles to ensure complete coverage, 31 * pass the original (un-bloated) vertices in to the fragment shader, and then have the fragment 32 * shader use these vertices to evaluate whether a given sample is located within the triangle or 33 * not. This gives us MSAA4 edges on triangles which line up nicely with no seams. We similarly face 34 * problems on the back (flat) edges of quads, where we have to ensure that the back edge is 35 * antialiased in the same way. Similar to the triangle case, we pass in the two (unbloated) 36 * vertices defining the back edge of the quad and the fragment shader uses these vertex coordinates 37 * to discard samples falling on the other side of the quad's back edge. 38 */ 39 class GrPLSPathRenderer : public GrPathRenderer { 40 public: 41 GrPLSPathRenderer(); 42 43 bool onCanDrawPath(const CanDrawPathArgs& args) const override; 44 45 protected: 46 bool onDrawPath(const DrawPathArgs& args) override; 47 }; 48 49 #endif 50