GrCCStroker.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright 2018 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. #ifndef GrCCStroker_DEFINED
  8. #define GrCCStroker_DEFINED
  9. #include "include/private/SkNx.h"
  10. #include "src/gpu/GrAllocator.h"
  11. #include "src/gpu/GrMesh.h"
  12. #include "src/gpu/ccpr/GrCCStrokeGeometry.h"
  13. class GrGpuBuffer;
  14. class GrCCCoverageProcessor;
  15. class GrOnFlushResourceProvider;
  16. class GrOpFlushState;
  17. class GrPipeline;
  18. class GrPrimitiveProcessor;
  19. class SkMatrix;
  20. class SkPath;
  21. class SkStrokeRec;
  22. /**
  23. * This class parses stroked SkPaths into a GPU instance buffer, then issues calls to draw their
  24. * coverage counts.
  25. */
  26. class GrCCStroker {
  27. public:
  28. GrCCStroker(int numPaths, int numSkPoints, int numSkVerbs)
  29. : fGeometry(numSkPoints, numSkVerbs), fPathInfos(numPaths) {}
  30. // Parses a device-space SkPath into the current batch, using the SkPath's original verbs with
  31. // 'deviceSpacePts', and the SkStrokeRec's original settings with 'strokeDevWidth'. Accepts an
  32. // optional post-device-space translate for placement in an atlas.
  33. //
  34. // Strokes intended as hairlines must have a strokeDevWidth of 1. Non-hairline strokes can only
  35. // be drawn with rigid body transforms; affine transformation of the stroke lines themselves is
  36. // not yet supported.
  37. void parseDeviceSpaceStroke(const SkPath&, const SkPoint* deviceSpacePts, const SkStrokeRec&,
  38. float strokeDevWidth, GrScissorTest,
  39. const SkIRect& clippedDevIBounds,
  40. const SkIVector& devToAtlasOffset);
  41. using BatchID = int;
  42. // Compiles the outstanding parsed paths into a batch, and returns an ID that can be used to
  43. // draw their strokes in the future.
  44. BatchID closeCurrentBatch();
  45. // Builds an internal GPU buffer and prepares for calls to drawStrokes(). Caller must close the
  46. // current batch before calling this method, and cannot parse new paths afer.
  47. bool prepareToDraw(GrOnFlushResourceProvider*);
  48. // Called after prepareToDraw(). Draws the given batch of path strokes.
  49. void drawStrokes(
  50. GrOpFlushState*, GrCCCoverageProcessor*, BatchID, const SkIRect& drawBounds) const;
  51. private:
  52. static constexpr int kNumScissorModes = 2;
  53. static constexpr BatchID kEmptyBatchID = -1;
  54. using Verb = GrCCStrokeGeometry::Verb;
  55. using InstanceTallies = GrCCStrokeGeometry::InstanceTallies;
  56. // Every kBeginPath verb has a corresponding PathInfo entry.
  57. struct PathInfo {
  58. SkIVector fDevToAtlasOffset;
  59. float fStrokeRadius;
  60. GrScissorTest fScissorTest;
  61. };
  62. // Defines a sub-batch of stroke instances that have a scissor test and the same scissor rect.
  63. // Start indices are deduced by looking at the previous ScissorSubBatch.
  64. struct ScissorSubBatch {
  65. ScissorSubBatch(GrTAllocator<InstanceTallies>* alloc, const InstanceTallies& startIndices,
  66. const SkIRect& scissor)
  67. : fEndInstances(&alloc->emplace_back(startIndices)), fScissor(scissor) {}
  68. InstanceTallies* fEndInstances;
  69. SkIRect fScissor;
  70. };
  71. // Defines a batch of stroke instances that can be drawn with drawStrokes(). Start indices are
  72. // deduced by looking at the previous Batch in the list.
  73. struct Batch {
  74. Batch(GrTAllocator<InstanceTallies>* alloc, const InstanceTallies& startNonScissorIndices,
  75. int startScissorSubBatch)
  76. : fNonScissorEndInstances(&alloc->emplace_back(startNonScissorIndices))
  77. , fEndScissorSubBatch(startScissorSubBatch) {}
  78. InstanceTallies* fNonScissorEndInstances;
  79. int fEndScissorSubBatch;
  80. };
  81. class InstanceBufferBuilder;
  82. void appendStrokeMeshesToBuffers(int numSegmentsLog2, const Batch&,
  83. const InstanceTallies* startIndices[2],
  84. int startScissorSubBatch, const SkIRect& drawBounds) const;
  85. void flushBufferedMeshesAsStrokes(const GrPrimitiveProcessor&, GrOpFlushState*, const
  86. GrPipeline&, const SkIRect& drawBounds) const;
  87. template<int GrCCStrokeGeometry::InstanceTallies::* InstanceType>
  88. void drawConnectingGeometry(GrOpFlushState*, const GrPipeline&,
  89. const GrCCCoverageProcessor&, const Batch&,
  90. const InstanceTallies* startIndices[2], int startScissorSubBatch,
  91. const SkIRect& drawBounds) const;
  92. GrCCStrokeGeometry fGeometry;
  93. SkSTArray<32, PathInfo> fPathInfos;
  94. SkSTArray<32, Batch> fBatches;
  95. SkSTArray<32, ScissorSubBatch> fScissorSubBatches;
  96. int fMaxNumScissorSubBatches = 0;
  97. bool fHasOpenBatch = false;
  98. const InstanceTallies fZeroTallies = InstanceTallies();
  99. GrSTAllocator<128, InstanceTallies> fTalliesAllocator;
  100. const InstanceTallies* fInstanceCounts[kNumScissorModes] = {&fZeroTallies, &fZeroTallies};
  101. sk_sp<GrGpuBuffer> fInstanceBuffer;
  102. // The indices stored in batches are relative to these base instances.
  103. InstanceTallies fBaseInstances[kNumScissorModes];
  104. mutable SkSTArray<32, GrMesh> fMeshesBuffer;
  105. mutable SkSTArray<32, SkIRect> fScissorsBuffer;
  106. };
  107. #endif