Flutter Engine
The Flutter Engine
Classes | Public Types | Static Public Member Functions | List of all members
skgpu::ganesh::TextureOp Class Reference

#include <TextureOp.h>

Classes

class  BatchSizeLimiter
 

Public Types

enum class  Saturate : bool { kNo = false , kYes = true }
 

Static Public Member Functions

static GrOp::Owner Make (GrRecordingContext *, GrSurfaceProxyView, SkAlphaType srcAlphaType, sk_sp< GrColorSpaceXform >, GrSamplerState::Filter, GrSamplerState::MipmapMode, const SkPMColor4f &, Saturate, SkBlendMode, GrAAType, DrawQuad *, const SkRect *subset=nullptr)
 
static void AddTextureSetOps (skgpu::ganesh::SurfaceDrawContext *, const GrClip *, GrRecordingContext *, GrTextureSetEntry[], int cnt, int proxyRunCnt, GrSamplerState::Filter, GrSamplerState::MipmapMode, Saturate, SkBlendMode, GrAAType, SkCanvas::SrcRectConstraint, const SkMatrix &viewMatrix, sk_sp< GrColorSpaceXform > textureXform)
 

Detailed Description

Definition at line 42 of file TextureOp.h.

Member Enumeration Documentation

◆ Saturate

enum class skgpu::ganesh::TextureOp::Saturate : bool
strong

Controls whether saturate() is called after the texture is color-converted to ensure all color values are in 0..1 range.

Enumerator
kNo 
kYes 

Definition at line 48 of file TextureOp.h.

48: bool { kNo = false, kYes = true };
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.

Member Function Documentation

◆ AddTextureSetOps()

void skgpu::ganesh::TextureOp::AddTextureSetOps ( skgpu::ganesh::SurfaceDrawContext sdc,
const GrClip clip,
GrRecordingContext context,
GrTextureSetEntry  set[],
int  cnt,
int  proxyRunCnt,
GrSamplerState::Filter  filter,
GrSamplerState::MipmapMode  mm,
Saturate  saturate,
SkBlendMode  blendMode,
GrAAType  aaType,
SkCanvas::SrcRectConstraint  constraint,
const SkMatrix viewMatrix,
sk_sp< GrColorSpaceXform textureXform 
)
static

Definition at line 1275 of file TextureOp.cpp.

1288 {
1289 // Ensure that the index buffer limits are lower than the proxy and quad count limits of
1290 // the op's metadata so we don't need to worry about overflow.
1291 SkDEBUGCODE(TextureOpImpl::ValidateResourceLimits();)
1292 SkASSERT(proxy_run_count(set, cnt) == proxyRunCnt);
1293
1294 // First check if we can support batches as a single op
1295 if (blendMode != SkBlendMode::kSrcOver ||
1297 // Append each entry as its own op; these may still be GrTextureOps if the blend mode is
1298 // src-over but the backend doesn't support dynamic state changes. Otherwise Make()
1299 // automatically creates the appropriate FillRectOp to emulate TextureOp.
1300 SkMatrix ctm;
1301 for (int i = 0; i < cnt; ++i) {
1302 ctm = viewMatrix;
1303 if (set[i].fPreViewMatrix) {
1304 ctm.preConcat(*set[i].fPreViewMatrix);
1305 }
1306
1307 DrawQuad quad;
1308 quad.fEdgeFlags = set[i].fAAFlags;
1309 if (set[i].fDstClipQuad) {
1310 quad.fDevice = GrQuad::MakeFromSkQuad(set[i].fDstClipQuad, ctm);
1311
1312 SkPoint srcPts[4];
1313 GrMapRectPoints(set[i].fDstRect, set[i].fSrcRect, set[i].fDstClipQuad, srcPts, 4);
1314 quad.fLocal = GrQuad::MakeFromSkQuad(srcPts, SkMatrix::I());
1315 } else {
1316 quad.fDevice = GrQuad::MakeFromRect(set[i].fDstRect, ctm);
1317 quad.fLocal = GrQuad(set[i].fSrcRect);
1318 }
1319
1320 const SkRect* subset = constraint == SkCanvas::kStrict_SrcRectConstraint
1321 ? &set[i].fSrcRect : nullptr;
1322
1323 auto op = Make(context, set[i].fProxyView, set[i].fSrcAlphaType, textureColorSpaceXform,
1324 filter, mm, set[i].fColor, saturate, blendMode, aaType, &quad, subset);
1325 sdc->addDrawOp(clip, std::move(op));
1326 }
1327 return;
1328 }
1329
1330 // Second check if we can always just make a single op and avoid the extra iteration
1331 // needed to clump things together.
1334 auto op = TextureOpImpl::Make(context, set, cnt, proxyRunCnt, filter, mm, saturate, aaType,
1335 constraint, viewMatrix, std::move(textureColorSpaceXform));
1336 sdc->addDrawOp(clip, std::move(op));
1337 return;
1338 }
1339
1340 BatchSizeLimiter state(sdc, clip, context, cnt, filter, mm, saturate, constraint, viewMatrix,
1341 std::move(textureColorSpaceXform));
1342
1343 // kNone and kMSAA never get altered
1344 if (aaType == GrAAType::kNone || aaType == GrAAType::kMSAA) {
1345 // Clump these into series of MaxNumNonAAQuads-sized GrTextureOps
1346 while (state.numLeft() > 0) {
1347 int clumpSize = std::min(state.numLeft(), GrResourceProvider::MaxNumNonAAQuads());
1348
1349 state.createOp(set, clumpSize, aaType);
1350 }
1351 } else {
1352 // kCoverage can be downgraded to kNone. Note that the following is conservative. kCoverage
1353 // can also get downgraded to kNone if all the quads are on integer coordinates and
1354 // axis-aligned.
1355 SkASSERT(aaType == GrAAType::kCoverage);
1356
1357 while (state.numLeft() > 0) {
1358 GrAAType runningAA = GrAAType::kNone;
1359 bool clumped = false;
1360
1361 for (int i = 0; i < state.numLeft(); ++i) {
1362 int absIndex = state.baseIndex() + i;
1363
1364 if (set[absIndex].fAAFlags != GrQuadAAFlags::kNone ||
1365 runningAA == GrAAType::kCoverage) {
1366
1368 // Here we either need to boost the AA type to kCoverage, but doing so with
1369 // all the accumulated quads would overflow, or we have a set of AA quads
1370 // that has just gotten too large. In either case, calve off the existing
1371 // quads as their own TextureOp.
1372 state.createOp(
1373 set,
1375 runningAA); // maybe downgrading AA here
1376 clumped = true;
1377 break;
1378 }
1379
1380 runningAA = GrAAType::kCoverage;
1381 } else if (runningAA == GrAAType::kNone) {
1382
1384 // Here we've found a consistent batch of non-AA quads that has gotten too
1385 // large. Calve it off as its own TextureOp.
1387 GrAAType::kNone); // definitely downgrading AA here
1388 clumped = true;
1389 break;
1390 }
1391 }
1392 }
1393
1394 if (!clumped) {
1395 // We ran through the above loop w/o hitting a limit. Spit out this last clump of
1396 // quads and call it a day.
1397 state.createOp(set, state.numLeft(), runningAA); // maybe downgrading AA here
1398 }
1399 }
1400 }
1401}
static void GrMapRectPoints(const SkRect &inRect, const SkRect &outRect, const SkPoint inPts[], SkPoint outPts[], int ptCount)
Definition: GrRect.h:37
GrAAType
Definition: GrTypesPriv.h:200
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kSrcOver
r = s + (1-sa)*d
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
const GrCaps * caps() const
bool dynamicStateArrayGeometryProcessorTextureSupport() const
Definition: GrCaps.h:418
Definition: GrQuad.h:30
static GrQuad MakeFromRect(const SkRect &, const SkMatrix &)
Definition: GrQuad.cpp:107
static GrQuad MakeFromSkQuad(const SkPoint pts[4], const SkMatrix &)
Definition: GrQuad.cpp:122
GrRecordingContextPriv priv()
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
SkMatrix & preConcat(const SkMatrix &other)
Definition: SkMatrix.cpp:674
void addDrawOp(const GrClip *, GrOp::Owner, const std::function< WillAddOpFn > &=std::function< WillAddOpFn >())
static GrOp::Owner Make(GrRecordingContext *, GrSurfaceProxyView, SkAlphaType srcAlphaType, sk_sp< GrColorSpaceXform >, GrSamplerState::Filter, GrSamplerState::MipmapMode, const SkPMColor4f &, Saturate, SkBlendMode, GrAAType, DrawQuad *, const SkRect *subset=nullptr)
Definition: TextureOp.cpp:1149
AtkStateType state
static float min(float r, float g, float b)
Definition: hsl.cpp:48
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
GrQuad fLocal
Definition: GrQuad.h:186
GrQuad fDevice
Definition: GrQuad.h:185
GrQuadAAFlags fEdgeFlags
Definition: GrQuad.h:187

◆ Make()

GrOp::Owner skgpu::ganesh::TextureOp::Make ( GrRecordingContext context,
GrSurfaceProxyView  proxyView,
SkAlphaType  srcAlphaType,
sk_sp< GrColorSpaceXform textureXform,
GrSamplerState::Filter  filter,
GrSamplerState::MipmapMode  mm,
const SkPMColor4f color,
Saturate  saturate,
SkBlendMode  blendMode,
GrAAType  aaType,
DrawQuad quad,
const SkRect subset = nullptr 
)
static

Creates an op that draws a sub-quadrilateral of a texture. The passed color is modulated by the texture's color. 'deviceQuad' specifies the device-space coordinates to draw, using 'localQuad' to map into the proxy's texture space. If non-null, 'subset' represents the boundary for the strict src rect constraint. If GrAAType is kCoverage then AA is applied to the edges indicated by GrQuadAAFlags. Otherwise, GrQuadAAFlags is ignored.

This is functionally very similar to FillRectOp::Make, except that the GrPaint has been deconstructed into the texture, filter, modulating color, and blend mode. When blend mode is src over, this will return a FillRectOp with a paint that samples the proxy.

Definition at line 1149 of file TextureOp.cpp.

1160 {
1161 // Apply optimizations that are valid whether or not using TextureOp or FillRectOp
1162 if (subset && subset->contains(proxyView.proxy()->backingStoreBoundsRect())) {
1163 // No need for a shader-based subset if hardware clamping achieves the same effect
1164 subset = nullptr;
1165 }
1166
1168 auto [mustFilter, mustMM] = FilterAndMipmapHaveNoEffect(quad->fLocal, quad->fDevice);
1169 if (!mustFilter) {
1171 }
1172 if (!mustMM) {
1174 }
1175 }
1176
1177 if (blendMode == SkBlendMode::kSrcOver) {
1178 return TextureOpImpl::Make(context, std::move(proxyView), std::move(textureXform), filter,
1179 mm, color, saturate, aaType, std::move(quad), subset);
1180 } else {
1181 // Emulate complex blending using FillRectOp
1182 GrSamplerState samplerState(GrSamplerState::WrapMode::kClamp, filter, mm);
1183 GrPaint paint;
1184 paint.setColor4f(color);
1185 paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
1186
1187 std::unique_ptr<GrFragmentProcessor> fp;
1188 const auto& caps = *context->priv().caps();
1189 if (subset) {
1190 SkRect localRect;
1191 if (quad->fLocal.asRect(&localRect)) {
1192 fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(),
1193 samplerState, *subset, localRect, caps);
1194 } else {
1195 fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(),
1196 samplerState, *subset, caps);
1197 }
1198 } else {
1199 fp = GrTextureEffect::Make(std::move(proxyView), alphaType, SkMatrix::I(), samplerState,
1200 caps);
1201 }
1202 fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(textureXform));
1203 fp = GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(fp), nullptr);
1204 if (saturate == Saturate::kYes) {
1206 }
1207 paint.setColorFragmentProcessor(std::move(fp));
1208 return ganesh::FillRectOp::Make(context, std::move(paint), aaType, quad);
1209 }
1210}
static std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > child, SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
static std::unique_ptr< GrFragmentProcessor > ClampOutput(std::unique_ptr< GrFragmentProcessor >)
bool asRect(SkRect *rect) const
Definition: GrQuad.cpp:141
GrSurfaceProxy * proxy() const
SkRect backingStoreBoundsRect() const
static std::unique_ptr< GrFragmentProcessor > MakeSubset(GrSurfaceProxyView, SkAlphaType, const SkMatrix &, GrSamplerState, const SkRect &subset, const GrCaps &caps, const float border[4]=kDefaultBorder, bool alwaysUseShaderTileMode=false)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static const GrXPFactory * FromBlendMode(SkBlendMode)
static GrOp::Owner Make(GrRecordingContext *, GrPaint &&, GrAAType, DrawQuad *, const GrUserStencilSettings *=nullptr, InputFlags=InputFlags::kNone)
Definition: FillRectOp.cpp:470
const Paint & paint
Definition: color_source.cc:38
DlColor color
const uint32_t fp
std::tuple< bool, bool > FilterAndMipmapHaveNoEffect(const GrQuad &srcQuad, const GrQuad &dstQuad)
Definition: TextureOp.cpp:1114
bool contains(SkScalar x, SkScalar y) const
Definition: extension.cpp:19

The documentation for this class was generated from the following files: