42 return arena->
make([&](
void* ptr) {
43 return new (ptr) LatticeGP(view, std::move(csxf), filter, wideColor);
47 const char*
name()
const override {
return "LatticeGP"; }
53 std::unique_ptr<ProgramImpl> makeProgramImpl(
const GrShaderCaps&)
const override {
59 const auto& latticeGP = geomProc.
cast<LatticeGP>();
60 fColorSpaceXformHelper.setData(pdman, latticeGP.fColorSpaceXform.get());
64 void onEmitCode(EmitArgs&
args, GrGPArgs* gpArgs)
override {
66 const auto& latticeGP =
args.fGeomProc.cast<LatticeGP>();
67 fColorSpaceXformHelper.emitCode(
args.fUniformHandler,
68 latticeGP.fColorSpaceXform.get());
70 args.fVaryingHandler->emitAttributes(latticeGP);
71 WriteOutputPosition(
args.fVertBuilder, gpArgs, latticeGP.fInPosition.name());
72 gpArgs->fLocalCoordVar = latticeGP.fInTextureCoords.asShaderVar();
74 args.fFragBuilder->codeAppend(
"float2 textureCoords;");
75 args.fVaryingHandler->addPassThroughAttribute(
76 latticeGP.fInTextureCoords.asShaderVar(),
78 args.fFragBuilder->codeAppend(
"float4 textureDomain;");
79 args.fVaryingHandler->addPassThroughAttribute(
80 latticeGP.fInTextureDomain.asShaderVar(),
82 Interpolation::kCanBeFlat);
83 args.fFragBuilder->codeAppendf(
"half4 %s;",
args.fOutputColor);
84 args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInColor.asShaderVar(),
86 Interpolation::kCanBeFlat);
87 args.fFragBuilder->codeAppendf(
"%s = ",
args.fOutputColor);
88 args.fFragBuilder->appendTextureLookupAndBlend(
92 "clamp(textureCoords, textureDomain.xy, textureDomain.zw)",
93 &fColorSpaceXformHelper);
94 args.fFragBuilder->codeAppend(
";");
95 args.fFragBuilder->codeAppendf(
"const half4 %s = half4(1);",
args.fOutputCoverage);
101 return std::make_unique<Impl>();
108 , fColorSpaceXform(std::move(csxf)) {
112 this->setTextureSamplerCnt(1);
116 fInColor = MakeColorAttribute(
"color", wideColor);
117 this->setVertexAttributesWithImplicitOffsets(&fInPosition, 4);
120 const TextureSampler& onTextureSampler(
int)
const override {
return fSampler; }
128 TextureSampler fSampler;
147 std::unique_ptr<SkLatticeIter> iter,
150 return Helper::FactoryHelper<NonAALatticeOp>(context, std::move(
paint), viewMatrix,
151 std::move(view), alphaType,
152 std::move(colorSpaceXForm), filter,
153 std::move(iter),
dst);
163 , fView(std::move(view))
165 , fColorSpaceXform(std::move(colorSpaceXform))
167 Patch& patch = fPatches.push_back();
168 patch.fViewMatrix = viewMatrix;
169 patch.fColor =
color;
170 patch.fIter = std::move(iter);
174 this->setTransformedBounds(patch.fDst, viewMatrix, HasAABloat::kNo, IsHairline::kNo);
177 const char*
name()
const override {
return "NonAALatticeOp"; }
188 FixedFunctionFlags fixedFunctionFlags()
const override {
return fHelper.
fixedFunctionFlags(); }
199 analysisColor.isConstant(&fPatches[0].
fColor);
200 fWideColor = !fPatches[0].fColor.fitsInBytes();
205 GrProgramInfo* programInfo()
override {
return fProgramInfo; }
207 void onCreateProgramInfo(
const GrCaps* caps,
210 bool usesMSAASurface,
216 auto gp =
LatticeGP::Make(arena, fView, fColorSpaceXform, fFilter, fWideColor);
223 std::move(appliedClip),
227 renderPassXferBarriers,
235 this->createProgramInfo(
target);
241 int patchCnt = fPatches.size();
243 for (
int i = 0;
i < patchCnt;
i++) {
244 numRects += fPatches[
i].fIter->numRectsToDraw();
253 QuadHelper helper(
target, kVertexStride, numRects);
257 SkDebugf(
"Could not allocate vertices\n");
261 for (
int i = 0;
i < patchCnt;
i++) {
262 const Patch& patch = fPatches[
i];
268 bool isScaleTranslate = patch.fViewMatrix.isScaleTranslate();
269 if (isScaleTranslate) {
270 patch.fIter->mapDstScaleTranslate(patch.fViewMatrix);
277 static const skvx::float4 kDomainOffsets(0.5f, 0.5f, -0.5f, -0.5f);
278 static const skvx::float4 kFlipOffsets(0.f, 1.f, 0.f, 1.f);
279 static const skvx::float4 kFlipMuls(1.f, -1.f, 1.f, -1.f);
280 while (patch.fIter->next(&srcR, &dstR)) {
287 coords = kFlipMuls * coords + kFlipOffsets;
288 domain = skvx::shuffle<0, 3, 2, 1>(kFlipMuls * domain + kFlipOffsets);
292 domain.
store(&texDomain);
293 coords.
store(&texCoords);
295 if (isScaleTranslate) {
302 patch.fViewMatrix.mapRectToQuad(mappedPts, dstR);
308 vertices << mappedPts[0]
312 vertices << mappedPts[3]
316 vertices << mappedPts[1]
320 vertices << mappedPts[2]
328 fMesh = helper.mesh();
332 if (!fProgramInfo || !fMesh) {
344 NonAALatticeOp* that = t->
cast<NonAALatticeOp>();
345 if (fView != that->fView) {
346 return CombineResult::kCannotCombine;
348 if (fFilter != that->fFilter) {
349 return CombineResult::kCannotCombine;
352 return CombineResult::kCannotCombine;
354 if (!fHelper.
isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
355 return CombineResult::kCannotCombine;
358 fPatches.move_back_n(that->fPatches.size(), that->fPatches.begin());
359 fWideColor |= that->fWideColor;
360 return CombineResult::kMerged;
363#if defined(GR_TEST_UTILS)
364 SkString onDumpInfo()
const override {
367 for (
int i = 0;
i < fPatches.size(); ++
i) {
368 str.
appendf(
"%d: Color: 0x%08x Dst [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
i,
370 fPatches[
i].fDst.fTop, fPatches[
i].fDst.fRight, fPatches[
i].fDst.fBottom);
373 str += fHelper.dumpInfo();
380 std::unique_ptr<SkLatticeIter>
fIter;
408 std::unique_ptr<SkLatticeIter> iter,
411 std::move(colorSpaceXform), filter, std::move(iter),
dst);
416#if defined(GR_TEST_UTILS)
422static void init_random_divs(
int divs[],
int count,
int subsetStart,
int subsetStop,
439 int subsetLength = subsetStop - subsetStart;
440 for (
int i = 0;
i < subsetLength -
count; ++
i) {
456GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) {
461 std::unique_ptr<int[]> xdivs;
462 std::unique_ptr<int[]> ydivs;
463 std::unique_ptr<SkCanvas::Lattice::RectType[]>
flags;
464 std::unique_ptr<SkColor[]>
colors;
475 auto proxy = context->priv().proxyProvider()->createProxy(
format,
499 xdivs.reset(
new int[lattice.
fXCount]);
500 ydivs.reset(
new int[lattice.
fYCount]);
503 lattice.
fXDivs = xdivs.get();
504 lattice.
fYDivs = ydivs.get();
510 for (
int i = 0;
i < n; ++
i) {
527 SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
528 auto csxf = GrTest::TestColorXform(random);
533 std::move(proxy), origin,
#define DEFINE_OP_CLASS_ID
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
@ kFloat2_GrVertexAttribType
@ kFloat4_GrVertexAttribType
@ kBottomLeft_GrSurfaceOrigin
@ kTopLeft_GrSurfaceOrigin
std::unique_ptr< SkLatticeIter > fIter
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define INHERITED(method,...)
size_t vertexStride() const
void drawMesh(const GrSimpleMesh &mesh)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
std::unique_ptr< GrOp > Owner
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
void visitFPProxies(const GrVisitProxyFunc &func) const
GrProcessorSet detachProcessorSet()
void visitProxies(const GrVisitProxyFunc &func) const
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const
GrPipeline::InputFlags pipelineFlags() const
GrProcessorSet::Analysis finalizeProcessors(const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor *geometryColor)
static GrProgramInfo * CreateProgramInfo(const GrCaps *, SkArenaAlloc *, const GrPipeline *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrGeometryProcessor *, GrPrimitiveType, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp, const GrUserStencilSettings *=&GrUserStencilSettings::kUnused)
bool isCompatible(const GrSimpleMeshDrawOpHelper &that, const GrCaps &, const SkRect &thisBounds, const SkRect &thatBounds, bool ignoreAAType=false) const
skgpu::Swizzle swizzle() const
GrSurfaceOrigin origin() const
GrSurfaceProxy * proxy() const
const GrBackendFormat & backendFormat() const
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
static bool Valid(int imageWidth, int imageHeight, const SkCanvas::Lattice &lattice)
SkScalar nextRangeScalar(SkScalar min, SkScalar max)
uint32_t nextULessThan(uint32_t count)
uint32_t nextRangeU(uint32_t min, uint32_t max)
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
PODArray< SkColor > colors
DEF_SWITCHES_START aot vmservice shared library name
GrOp::Owner MakeNonAA(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, GrSurfaceProxyView view, SkAlphaType alphaType, sk_sp< GrColorSpaceXform > colorSpaceXform, GrSamplerState::Filter filter, std::unique_ptr< SkLatticeIter > iter, const SkRect &dst)
static const GrUserStencilSettings & kUnused
int fYCount
number of y-coordinates
const SkIRect * fBounds
source bounds to draw from
@ kDefault
draws SkBitmap into lattice rectangle
@ kTransparent
skips lattice rectangle by making it transparent
const int * fYDivs
y-axis values dividing bitmap
int fXCount
number of x-coordinates
const RectType * fRectTypes
array of fill types
const SkColor * fColors
array of colors
const int * fXDivs
x-axis values dividing bitmap
int32_t fBottom
larger y-axis bounds
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static constexpr SkPoint Make(float x, float y)
uint32_t toBytes_RGBA() const
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
SkScalar fTop
smaller y-axis bounds
static TriStrip< float > TriStripFromRect(const SkRect &r)
SKVX_ALWAYS_INLINE void store(void *ptr) const