34#if defined(GR_TEST_UTILS)
40 str.
appendf(
"%d: Color: [%.2f, %.2f, %.2f, %.2f], Edge AA: l%u_t%u_r%u_b%u, \n"
41 " device quad: [(%.2f, %2.f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), "
42 "(%.2f, %.2f, %.2f)],\n"
43 " local quad: [(%.2f, %2.f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), "
44 "(%.2f, %.2f, %.2f)]\n",
50 deviceQuad->
x(0), deviceQuad->
y(0), deviceQuad->
w(0),
51 deviceQuad->
x(1), deviceQuad->
y(1), deviceQuad->
w(1),
52 deviceQuad->
x(2), deviceQuad->
y(2), deviceQuad->
w(2),
53 deviceQuad->
x(3), deviceQuad->
y(3), deviceQuad->
w(3),
54 safeLocal.
x(0), safeLocal.
y(0), safeLocal.
w(0),
55 safeLocal.
x(1), safeLocal.
y(1), safeLocal.
w(1),
56 safeLocal.
x(2), safeLocal.
y(2), safeLocal.
w(2),
57 safeLocal.
x(3), safeLocal.
y(3), safeLocal.
w(3));
76 return Helper::FactoryHelper<FillRectOpImpl>(context, std::move(
paint), aaType, quad,
77 stencilSettings, inputFlags);
86 , fHelper(processorSet, aaType, stencil, inputFlags)
87 , fQuads(1, !fHelper.isTrivial()) {
92 hairline ? IsHairline::kYes : IsHairline::kNo);
106 fQuads.append(quad->
fDevice, {paintColor, quad->fEdgeFlags},
109 fQuads.append(extra.
fDevice, { paintColor, extra.fEdgeFlags },
114 const char*
name()
const override {
return "FillRectOp"; }
127 auto iter = fQuads.metadata();
133 if (quadColors.isUnknown()) {
148 iter = fQuads.metadata();
150 if (quadColors.isConstant(&colorOverride)) {
153 iter->fColor = colorOverride;
186#if defined(GR_TEST_UTILS)
187 int numQuads() const final {
return fQuads.count(); }
192 fHelper.
aaType(), fQuads.count());
206 bool usesMSAASurface,
211 const VertexSpec vertexSpec = this->vertexSpec();
217 std::move(appliedClip),
220 renderPassXferBarriers, colorLoadOp);
234 renderPassXferBarriers, colorLoadOp);
238 const VertexSpec vertexSpec = this->vertexSpec();
240 const int totalNumVertices = fQuads.count() * vertexSpec.
verticesPerQuad();
241 const size_t totalVertexSizeInBytes = vertexSpec.
vertexSize() * totalNumVertices;
243 fPrePreparedVertices = arena->
makeArrayDefault<
char>(totalVertexSizeInBytes);
245 this->tessellate(vertexSpec, fPrePreparedVertices);
248 void tessellate(
const VertexSpec& vertexSpec,
char*
dst)
const {
252 auto iter = fQuads.iterator();
253 while (iter.next()) {
257 auto info = iter.metadata();
258 tessellator.append(iter.deviceQuad(), iter.localQuad(),
259 info.fColor, kEmptyDomain,
info.fAAFlags);
266 const VertexSpec vertexSpec = this->vertexSpec();
272 const int totalNumVertices = fQuads.count() * vertexSpec.
verticesPerQuad();
275 void* vdata =
target->makeVertexSpace(vertexSpec.
vertexSize(), totalNumVertices,
278 SkDebugf(
"Could not allocate vertices\n");
282 if (fPrePreparedVertices) {
283 const size_t totalVertexSizeInBytes = vertexSpec.
vertexSize() * totalNumVertices;
285 memcpy(vdata, fPrePreparedVertices, totalVertexSizeInBytes);
287 this->tessellate(vertexSpec, (
char*) vdata);
294 SkDebugf(
"Could not allocate indices\n");
305 const VertexSpec vertexSpec = this->vertexSpec();
315 const int totalNumVertices = fQuads.count() * vertexSpec.
verticesPerQuad();
331 auto that = t->
cast<FillRectOpImpl>();
333 bool upgradeToCoverageAAOnMerge =
false;
334 if (fHelper.
aaType() != that->fHelper.aaType()) {
338 upgradeToCoverageAAOnMerge =
true;
342 fQuads.count() + that->fQuads.count())) {
348 if (!fHelper.
isCompatible(that->fHelper, caps, this->bounds(), that->bounds(),
true)) {
363 if (upgradeToCoverageAAOnMerge) {
367 fQuads.concat(that->fQuads);
371#if defined(GR_TEST_UTILS)
372 SkString onDumpInfo()
const override {
374 str.
appendf(
"Device quad type: %u, local quad type: %u\n",
375 (uint32_t) fQuads.deviceQuadType(), (uint32_t) fQuads.localQuadType());
376 str += fHelper.dumpInfo();
378 auto iter = fQuads.iterator();
380 const ColorAndAA&
info = iter.metadata();
381 str += dump_quad_info(
i, iter.deviceQuad(), iter.localQuad(),
389 bool canAddQuads(
int numQuads,
GrAAType aaType) {
393 int quadCount = fQuads.count() + numQuads;
395 auto indexBufferOption =
408 fHelper.
aaType(), quadCount);
429 }
else if (!this->canAddQuads(
count, aaType)) {
434 fQuads.append(quad->
fDevice, { color, quad->fEdgeFlags },
437 fQuads.append(extra.
fDevice, { color, extra.fEdgeFlags },
454 char* fPrePreparedVertices =
nullptr;
504 paint.setColor4f(quads[0].fColor);
507 auto fillRects = op->cast<FillRectOpImpl>();
511 for (
int i = 1;
i < cnt; ++
i) {
520 if (!fillRects->addQuad(&quad, quads[
i].fColor, resolvedAA)) {
545 &quads[
offset], numLeft, stencilSettings,
549 numLeft -= numConsumed;
559#if defined(GR_TEST_UTILS)
561uint32_t skgpu::ganesh::FillRectOp::ClassID() {
return FillRectOpImpl::ClassID(); }
566GR_DRAW_OP_TEST_DEFINE(FillRectOp) {
567 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
571 if (random->nextBool()) {
575 : GrGetRandomStencil(random, context);
583 if (random->nextBool()) {
584 if (random->nextBool()) {
586 SkMatrix localMatrix = GrTest::TestMatrixInvertible(random);
590 context, std::move(
paint), aaType, &quad, stencil);
593 SkRect localRect = GrTest::TestRect(random);
595 GrQuad(localRect), aaFlags};
597 context, std::move(
paint), aaType, &quad, stencil);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
skgpu::ganesh::QuadPerEdgeAA::VertexSpec VertexSpec
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
#define DEFINE_OP_CLASS_ID
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define INHERITED(method,...)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
sk_sp< const GrBuffer > fIndexBuffer
sk_sp< const GrBuffer > fVertexBuffer
friend class GrSimpleMeshDrawOpHelperWithStencil
virtual FixedFunctionFlags fixedFunctionFlags() const
virtual GrProcessorSet::Analysis finalize(const GrCaps &, const GrAppliedClip *, GrClampType)=0
size_t vertexStride() const
virtual GrProgramInfo * programInfo()=0
void createProgramInfo(const GrCaps *caps, SkArenaAlloc *arena, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&appliedClip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
GrMeshDrawOp(uint32_t classID)
virtual void onPrePrepareDraws(GrRecordingContext *, const GrSurfaceProxyView &writeView, GrAppliedClip *, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
virtual void onCreateProgramInfo(const GrCaps *, SkArenaAlloc *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)=0
virtual void onPrepareDraws(GrMeshDrawTarget *)=0
static bool CanUpgradeAAOnMerge(GrAAType aa1, GrAAType aa2)
static bool CombinedQuadCountWillOverflow(GrAAType aaType, bool willBeUpgradedToAA, int combinedQuadCount)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindBuffers(sk_sp< const GrBuffer > indexBuffer, sk_sp< const GrBuffer > instanceBuffer, sk_sp< const GrBuffer > vertexBuffer, GrPrimitiveRestart primitiveRestart=GrPrimitiveRestart::kNo)
const GrCaps & caps() const final
GrOpsRenderPass * opsRenderPass()
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
virtual void onExecute(GrOpFlushState *, const SkRect &chainBounds)=0
static Owner Make(GrRecordingContext *context, Args &&... args)
std::unique_ptr< GrOp > Owner
virtual const char * name() const =0
const SkRect & bounds() const
virtual void visitProxies(const GrVisitProxyFunc &) const
void setBounds(const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
virtual CombineResult onCombineIfPossible(GrOp *, SkArenaAlloc *, const GrCaps &)
static GrPaint Clone(const GrPaint &src)
static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor &a, const GrProcessorAnalysisColor &b)
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
void visitFPProxies(const GrVisitProxyFunc &func) const
static GrQuad MakeFromRect(const SkRect &, const SkMatrix &)
SkArenaAlloc * recordTimeAllocator()
GrRecordingContextPriv priv()
GrSimpleMeshDrawOpHelper::InputFlags InputFlags
GrProcessorSet::Analysis finalizeProcessors(const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor *geometryColor)
void visitProxies(const GrVisitProxyFunc &func) const
void setAAType(GrAAType aaType)
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const
bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil &that, const GrCaps &, const SkRect &thisBounds, const SkRect &thatBounds, bool ignoreAAType=false) const
bool usesLocalCoords() const
bool compatibleWithCoverageAsAlpha() const
GrProgramInfo * createProgramInfoWithStencil(const GrCaps *, SkArenaAlloc *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&, const GrDstProxyView &, GrGeometryProcessor *, GrPrimitiveType, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
T * makeArrayDefault(size_t count)
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
static GrOp::Owner Make(GrRecordingContext *, GrPaint &&, GrAAType, DrawQuad *, const GrUserStencilSettings *=nullptr, InputFlags=InputFlags::kNone)
static void AddFillRectOps(SurfaceDrawContext *, const GrClip *, GrRecordingContext *, GrPaint &&, GrAAType, const SkMatrix &viewMatrix, const GrQuadSetEntry quads[], int quadCount, const GrUserStencilSettings *=nullptr)
static GrOp::Owner MakeNonAARect(GrRecordingContext *, GrPaint &&, const SkMatrix &view, const SkRect &, const GrUserStencilSettings *=nullptr)
void addDrawOp(const GrClip *, GrOp::Owner, const std::function< WillAddOpFn > &=std::function< WillAddOpFn >())
static float max(float r, float g, float b)
bool WillUseHairline(const GrQuad &quad, GrAAType aaType, GrQuadAAFlags edgeFlags)
void ResolveAAType(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags, const GrQuad &quad, GrAAType *outAAType, GrQuadAAFlags *outEdgeFlags)
int ClipToW0(DrawQuad *quad, DrawQuad *extraVertices)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
sk_sp< SkBlender > blender SkRect rect
int QuadLimit(IndexBufferOption option)
GrGeometryProcessor * MakeProcessor(SkArenaAlloc *arena, const VertexSpec &spec)
IndexBufferOption CalcIndexBufferOption(GrAAType aa, int numQuads)
ColorType MinColorType(SkPMColor4f color)
sk_sp< const GrBuffer > GetIndexBuffer(GrMeshDrawTarget *target, IndexBufferOption indexBufferOption)
void IssueDraw(const GrCaps &caps, GrOpsRenderPass *renderPass, const VertexSpec &spec, int runningQuadCount, int quadsInDraw, int maxVerts, int absVertBufferOffset)
static constexpr SkRect MakeEmpty()
void joinPossiblyEmptyRect(const SkRect &r)
IndexBufferOption indexBufferOption() const
size_t vertexSize() const
bool needsIndexBuffer() const
int verticesPerQuad() const
GrPrimitiveType primitiveType() const
#define TRACE_EVENT0(category_group, name)