238 {
240 "SoftwarePathRenderer::onDrawPath");
241
242 if (!fProxyProvider) {
243 return false;
244 }
245
247
248
249 bool inverseFilled =
args.fShape->inverseFilled() &&
251 *
args.fViewMatrix,
nullptr);
252
253 SkIRect unclippedDevShapeBounds, clippedDevShapeBounds, devClipBounds;
254
255
256 bool useCache = fAllowCaching && !inverseFilled &&
args.fViewMatrix->preservesAxisAlignment() &&
258
261 *
args.fViewMatrix, &unclippedDevShapeBounds,
262 &clippedDevShapeBounds,
263 &devClipBounds)) {
264 if (inverseFilled) {
265 DrawAroundInvPath(
args.fSurfaceDrawContext, std::move(
args.fPaint),
266 *
args.fUserStencilSettings,
args.fClip, *
args.fViewMatrix,
267 devClipBounds, unclippedDevShapeBounds);
268 }
269 return true;
270 }
271
272 const SkIRect* boundsForMask = &clippedDevShapeBounds;
273 if (useCache) {
274
275 int unclippedWidth = unclippedDevShapeBounds.
width();
276 int unclippedHeight = unclippedDevShapeBounds.
height();
277 int64_t unclippedArea =
sk_64_mul(unclippedWidth, unclippedHeight);
279 clippedDevShapeBounds.
height());
280 int maxTextureSize =
args.fSurfaceDrawContext->caps()->maxTextureSize();
281 if (unclippedArea > 2 * clippedArea || unclippedWidth > maxTextureSize ||
282 unclippedHeight > maxTextureSize) {
283 useCache = false;
284 } else {
285 boundsForMask = &unclippedDevShapeBounds;
286 }
287 }
288
290 if (useCache) {
291
298 "SW Path Mask");
301
302#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
303
304
305
308#else
311
314#endif
319
320
321
322
323 uint32_t styleBits =
args.fShape->style().isSimpleHairline() ?
324 ((
args.fShape->style().strokeRec().getCap() << 1) | 1) : 0;
325 builder[6] = fracX | (fracY >> 8) | (styleBits << 16);
326 args.fShape->writeUnstyledKey(&builder[7]);
327 }
328
330 if (useCache) {
332 if (proxy) {
336 args.fContext->priv().stats()->incNumPathMasksCacheHits();
337 }
338 }
339 if (!view) {
342
344 if (
auto direct =
args.fContext->asDirectContext()) {
345 taskGroup = direct->priv().getTaskGroup();
346 }
347
348 if (taskGroup) {
349 view = make_deferred_mask_texture_view(
args.fContext, fit, boundsForMask->
size());
350 if (!view) {
351 return false;
352 }
353
354 auto uploader = std::make_unique<GrTDeferredProxyUploader<SoftwarePathData>>(
355 *boundsForMask, *
args.fViewMatrix, *
args.fShape, aa);
357
358 auto drawAndUploadMask = [uploaderRaw] {
361 if (helper.init(uploaderRaw->data().getMaskBounds())) {
362 helper.drawShape(uploaderRaw->data().getShape(),
363 *uploaderRaw->data().getViewMatrix(),
364 uploaderRaw->data().getAA(), 0xFF);
365 } else {
367 }
368 uploaderRaw->signalAndFreeData();
369 };
370 taskGroup->
add(std::move(drawAndUploadMask));
372 } else {
374 if (!helper.
init(*boundsForMask)) {
375 return false;
376 }
379 }
380
381 if (!view) {
382 return false;
383 }
384 if (useCache) {
386
387
388
390 args.fContext->priv().contextID());
392 args.fShape->addGenIDChangeListener(std::move(listener));
393 }
394
395 args.fContext->priv().stats()->incNumPathMasksGenerated();
396 }
398 if (inverseFilled) {
400 *
args.fUserStencilSettings,
args.fClip, *
args.fViewMatrix, devClipBounds,
401 unclippedDevShapeBounds);
402 }
403 DrawToTargetWithShapeMask(std::move(view),
args.fSurfaceDrawContext, std::move(
args.fPaint),
404 *
args.fUserStencilSettings,
args.fClip, *
args.fViewMatrix,
405 SkIPoint{boundsForMask->fLeft, boundsForMask->fTop}, *boundsForMask);
406
407 return true;
408}
#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename)
@ kTopLeft_GrSurfaceOrigin
bool GrIsStrokeHairlineOrEquivalent(const GrStyle &style, const SkMatrix &matrix, SkScalar *outCoverage)
#define SkDEBUGFAIL(message)
#define SkScalarToFixed(x)
static uint32_t SkFloat2Bits(float value)
sk_sp< SkIDChangeListener > GrMakeUniqueKeyInvalidationListener(skgpu::UniqueKey *key, uint32_t contextID)
static int64_t sk_64_mul(int64_t a, int64_t b)
static SkScalar SkScalarFraction(SkScalar x)
static GrPaint Clone(const GrPaint &src)
bool assignUniqueKeyToProxy(const skgpu::UniqueKey &, GrTextureProxy *)
sk_sp< GrTextureProxy > findOrCreateProxyByUniqueKey(const skgpu::UniqueKey &, UseAllocator=UseAllocator::kYes)
void drawShape(const GrStyledShape &, const SkMatrix &matrix, GrAA, uint8_t alpha)
bool init(const SkIRect &resultBounds)
GrSurfaceProxyView toTextureView(GrRecordingContext *, SkBackingFit fit)
GrTextureProxy * asTextureProxy() const
GrSurfaceOrigin origin() const
void setDeferredUploader(std::unique_ptr< GrDeferredProxyUploader >)
GrTextureProxyPriv texPriv()
static constexpr int kMScaleX
horizontal scale factor
static constexpr int kMTransY
vertical translation
static constexpr int kMTransX
horizontal translation
static constexpr int kMSkewY
vertical skew factor
static constexpr int kMScaleY
vertical scale factor
static constexpr int kMSkewX
horizontal skew factor
void add(std::function< void(void)> fn)
static Domain GenerateDomain()
static bool GetShapeAndClipBounds(SurfaceDrawContext *, const GrClip *, const GrStyledShape &, const SkMatrix &viewMatrix, SkIRect *unclippedDevShapeBounds, SkIRect *clippedDevShapeBounds, SkIRect *devClipBounds)
constexpr SkISize size() const
constexpr int32_t height() const
constexpr int32_t width() const
#define TRACE_EVENT0(category_group, name)