1 /* 2 * Copyright 2015 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 8 #ifndef SurfaceDrawContext_v1_DEFINED 9 #define SurfaceDrawContext_v1_DEFINED 10 11 #include "include/core/SkCanvas.h" 12 #include "include/core/SkDrawable.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/core/SkSurface.h" 15 #include "include/core/SkSurfaceProps.h" 16 #include "include/private/base/SkTArray.h" 17 #include "include/private/gpu/ganesh/GrTypesPriv.h" 18 #include "src/core/SkDevice.h" 19 #include "src/gpu/ganesh/GrPaint.h" 20 #include "src/gpu/ganesh/GrRenderTargetProxy.h" 21 #include "src/gpu/ganesh/GrSurfaceProxyView.h" 22 #include "src/gpu/ganesh/GrXferProcessor.h" 23 #include "src/gpu/ganesh/SurfaceFillContext.h" 24 #include "src/gpu/ganesh/geometry/GrQuad.h" 25 #include "src/gpu/ganesh/ops/OpsTask.h" 26 27 class GrBackendSemaphore; 28 class GrClip; 29 class GrColorSpaceXform; 30 class GrDrawOp; 31 class GrDstProxyView; 32 class GrHardClip; 33 class GrOp; 34 struct GrQuadSetEntry; 35 class GrRenderTarget; 36 class GrStyledShape; 37 class GrStyle; 38 class GrTextureProxy; 39 struct GrTextureSetEntry; 40 struct GrUserStencilSettings; 41 struct SkDrawShadowRec; 42 struct SkIPoint; 43 struct SkIRect; 44 class SkLatticeIter; 45 class SkMatrix; 46 class SkPaint; 47 class SkPath; 48 struct SkPoint; 49 struct SkRect; 50 class SkRegion; 51 class SkRRect; 52 struct SkRSXform; 53 class SkTextBlob; 54 class SkVertices; 55 56 namespace sktext { 57 class GlyphRunList; 58 } 59 60 namespace skgpu::ganesh { 61 62 /** 63 * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets. 64 */ 65 class SurfaceDrawContext final : public SurfaceFillContext { 66 public: 67 static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*, 68 GrColorType, 69 sk_sp<GrSurfaceProxy>, 70 sk_sp<SkColorSpace>, 71 GrSurfaceOrigin, 72 const SkSurfaceProps&); 73 74 /* Uses the default texture format for the color type */ 75 static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*, 76 GrColorType, 77 sk_sp<SkColorSpace>, 78 SkBackingFit, 79 SkISize dimensions, 80 const SkSurfaceProps&, 81 std::string_view label, 82 int sampleCnt = 1, 83 skgpu::Mipmapped = skgpu::Mipmapped::kNo, 84 skgpu::Protected = skgpu::Protected::kNo, 85 GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin, 86 skgpu::Budgeted = skgpu::Budgeted::kYes); 87 88 /** 89 * Takes custom swizzles rather than determining swizzles from color type and format. 90 * It will have color type kUnknown. 91 */ 92 static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*, 93 sk_sp<SkColorSpace>, 94 SkBackingFit, 95 SkISize dimensions, 96 const GrBackendFormat&, 97 int sampleCnt, 98 skgpu::Mipmapped, 99 skgpu::Protected, 100 skgpu::Swizzle readSwizzle, 101 skgpu::Swizzle writeSwizzle, 102 GrSurfaceOrigin, 103 skgpu::Budgeted, 104 const SkSurfaceProps&, 105 std::string_view label); 106 107 // Same as previous factory but will try to use fallback GrColorTypes if the one passed in 108 // fails. The fallback GrColorType will have at least the number of channels and precision per 109 // channel as the passed in GrColorType. It may also swizzle the changes (e.g., BGRA -> RGBA). 110 // SRGB-ness will be preserved. 111 static std::unique_ptr<SurfaceDrawContext> MakeWithFallback( 112 GrRecordingContext*, 113 GrColorType, 114 sk_sp<SkColorSpace>, 115 SkBackingFit, 116 SkISize dimensions, 117 const SkSurfaceProps&, 118 int sampleCnt, 119 skgpu::Mipmapped, 120 skgpu::Protected, 121 GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin, 122 skgpu::Budgeted = skgpu::Budgeted::kYes); 123 124 // Creates a SurfaceDrawContext that wraps the passed in GrBackendTexture. 125 static std::unique_ptr<SurfaceDrawContext> MakeFromBackendTexture( 126 GrRecordingContext*, 127 GrColorType, 128 sk_sp<SkColorSpace>, 129 const GrBackendTexture&, 130 int sampleCnt, 131 GrSurfaceOrigin, 132 const SkSurfaceProps&, 133 sk_sp<skgpu::RefCntedCallback> releaseHelper); 134 135 SurfaceDrawContext(GrRecordingContext*, 136 GrSurfaceProxyView readView, 137 GrSurfaceProxyView writeView, 138 GrColorType, 139 sk_sp<SkColorSpace>, 140 const SkSurfaceProps&); 141 142 ~SurfaceDrawContext() override; 143 144 /** 145 * Draw everywhere (respecting the clip) with the paint. 146 */ 147 void drawPaint(const GrClip*, GrPaint&&, const SkMatrix& viewMatrix); 148 149 /** 150 * Draw the rect using a paint. 151 * @param paint describes how to color pixels. 152 * @param GrAA Controls whether rect is antialiased 153 * @param viewMatrix transformation matrix 154 * @param style The style to apply. Null means fill. Currently path effects are not 155 * allowed. 156 * The rects coords are used to access the paint (through texture matrix) 157 */ 158 void drawRect(const GrClip*, 159 GrPaint&& paint, 160 GrAA, 161 const SkMatrix& viewMatrix, 162 const SkRect&, 163 const GrStyle* style = nullptr); 164 165 /** 166 * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle. 167 * 168 * @param GrPaint describes how to color pixels. 169 * @param GrAA Controls whether rect is antialiased 170 * @param SkMatrix transformation matrix which applies to rectToDraw 171 * @param rectToDraw the rectangle to draw 172 * @param localRect the rectangle of shader coordinates applied to rectToDraw 173 */ 174 void fillRectToRect(const GrClip*, 175 GrPaint&&, 176 GrAA, 177 const SkMatrix&, 178 const SkRect& rectToDraw, 179 const SkRect& localRect); 180 181 /** 182 * Fills a block of pixels with a paint and a localMatrix, respecting the clip. 183 */ fillPixelsWithLocalMatrix(const GrClip * clip,GrPaint && paint,const SkIRect & bounds,const SkMatrix & localMatrix)184 void fillPixelsWithLocalMatrix(const GrClip* clip, 185 GrPaint&& paint, 186 const SkIRect& bounds, 187 const SkMatrix& localMatrix) { 188 SkRect rect = SkRect::Make(bounds); 189 DrawQuad quad{GrQuad::MakeFromRect(rect, SkMatrix::I()), 190 GrQuad::MakeFromRect(rect, localMatrix), GrQuadAAFlags::kNone}; 191 this->drawFilledQuad(clip, std::move(paint), &quad); 192 } 193 194 /** 195 * Creates an op that draws a fill rect with per-edge control over anti-aliasing. 196 * 197 * This is a specialized version of fillQuadWithEdgeAA, but is kept separate since knowing 198 * the geometry is a rectangle affords more optimizations. 199 */ 200 void fillRectWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA, 201 const SkMatrix& viewMatrix, const SkRect& rect, 202 const SkRect* optionalLocalRect = nullptr) { 203 if (edgeAA == GrQuadAAFlags::kAll) { 204 this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, rect, 205 (optionalLocalRect) ? *optionalLocalRect : rect); 206 return; 207 } 208 const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect; 209 DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect), edgeAA}; 210 this->drawFilledQuad(clip, std::move(paint), &quad); 211 } 212 213 /** 214 * Similar to fillRectWithEdgeAA but draws an arbitrary 2D convex quadrilateral transformed 215 * by 'viewMatrix', with per-edge control over anti-aliasing. The quad should follow the 216 * ordering used by SkRect::toQuad(), which determines how the edge AA is applied: 217 * - "top" = points [0] and [1] 218 * - "right" = points[1] and [2] 219 * - "bottom" = points[2] and [3] 220 * - "left" = points[3] and [0] 221 * 222 * The last argument, 'optionalLocalQuad', can be null if no separate local coordinates are 223 * necessary. 224 */ fillQuadWithEdgeAA(const GrClip * clip,GrPaint && paint,GrQuadAAFlags edgeAA,const SkMatrix & viewMatrix,const SkPoint points[4],const SkPoint optionalLocalPoints[4])225 void fillQuadWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA, 226 const SkMatrix& viewMatrix, const SkPoint points[4], 227 const SkPoint optionalLocalPoints[4]) { 228 const SkPoint* localPoints = optionalLocalPoints ? optionalLocalPoints : points; 229 DrawQuad quad{GrQuad::MakeFromSkQuad(points, viewMatrix), 230 GrQuad::MakeFromSkQuad(localPoints, SkMatrix::I()), edgeAA}; 231 this->drawFilledQuad(clip, std::move(paint), &quad); 232 } 233 234 // TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer 235 void drawQuadSet(const GrClip* clip, GrPaint&& paint, const SkMatrix& viewMatrix, 236 const GrQuadSetEntry[], int cnt); 237 238 /** 239 * Creates an op that draws a subrectangle of a texture. The passed color is modulated by the 240 * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect' 241 * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to 242 * device space. 243 */ 244 void drawTexture(const GrClip*, 245 GrSurfaceProxyView, 246 SkAlphaType, 247 GrSamplerState::Filter, 248 GrSamplerState::MipmapMode, 249 SkBlendMode, 250 const SkPMColor4f&, 251 const SkRect& srcRect, 252 const SkRect& dstRect, 253 GrQuadAAFlags, 254 SkCanvas::SrcRectConstraint, 255 const SkMatrix&, 256 sk_sp<GrColorSpaceXform>); 257 258 /** 259 * Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by 260 * 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'subset'. If 261 * 'subset' is null, it's equivalent to using the fast src rect constraint. If 'subset' is 262 * provided, the strict src rect constraint is applied using 'subset'. 263 */ drawTextureQuad(const GrClip * clip,GrSurfaceProxyView view,GrColorType srcColorType,SkAlphaType srcAlphaType,GrSamplerState::Filter filter,GrSamplerState::MipmapMode mm,SkBlendMode mode,const SkPMColor4f & color,const SkPoint srcQuad[4],const SkPoint dstQuad[4],GrQuadAAFlags edgeAA,const SkRect * subset,const SkMatrix & viewMatrix,sk_sp<GrColorSpaceXform> texXform)264 void drawTextureQuad(const GrClip* clip, 265 GrSurfaceProxyView view, 266 GrColorType srcColorType, 267 SkAlphaType srcAlphaType, 268 GrSamplerState::Filter filter, 269 GrSamplerState::MipmapMode mm, 270 SkBlendMode mode, 271 const SkPMColor4f& color, 272 const SkPoint srcQuad[4], 273 const SkPoint dstQuad[4], 274 GrQuadAAFlags edgeAA, 275 const SkRect* subset, 276 const SkMatrix& viewMatrix, 277 sk_sp<GrColorSpaceXform> texXform) { 278 DrawQuad quad{GrQuad::MakeFromSkQuad(dstQuad, viewMatrix), 279 GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), edgeAA}; 280 this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform), filter, mm, 281 color, mode, &quad, subset); 282 } 283 284 /** 285 * Draws a set of textures with a shared filter, color, view matrix, color xform, and 286 * texture color xform. The textures must all have the same GrTextureType and GrConfig. 287 * 288 * If any entries provide a non-null fDstClip array, it will be read from immediately based on 289 * fDstClipCount, so the pointer can become invalid after this returns. 290 * 291 * 'proxRunCnt' is the number of proxy changes encountered in the entry array. Technically this 292 * can be inferred from the array within this function, but the information is already known 293 * by SkGpuDevice, so no need to incur another iteration over the array. 294 */ 295 void drawTextureSet(const GrClip*, 296 GrTextureSetEntry[], 297 int cnt, 298 int proxyRunCnt, 299 GrSamplerState::Filter, 300 GrSamplerState::MipmapMode, 301 SkBlendMode mode, 302 SkCanvas::SrcRectConstraint, 303 const SkMatrix& viewMatrix, 304 sk_sp<GrColorSpaceXform> texXform); 305 306 /** 307 * Draw a roundrect using a paint. 308 * 309 * @param paint describes how to color pixels. 310 * @param GrAA Controls whether rrect is antialiased. 311 * @param viewMatrix transformation matrix 312 * @param rrect the roundrect to draw 313 * @param style style to apply to the rrect. Currently path effects are not allowed. 314 */ 315 void drawRRect(const GrClip*, 316 GrPaint&&, 317 GrAA, 318 const SkMatrix& viewMatrix, 319 const SkRRect& rrect, 320 const GrStyle& style); 321 322 /** 323 * Use a fast method to render the ambient and spot shadows for a path. 324 * Will return false if not possible for the given path. 325 * 326 * @param viewMatrix transformation matrix 327 * @param path the path to shadow 328 * @param rec parameters for shadow rendering 329 */ 330 bool drawFastShadow(const GrClip*, 331 const SkMatrix& viewMatrix, 332 const SkPath& path, 333 const SkDrawShadowRec& rec); 334 335 /** 336 * Draws a path. 337 * 338 * @param paint describes how to color pixels. 339 * @param GrAA Controls whether the path is antialiased. 340 * @param viewMatrix transformation matrix 341 * @param path the path to draw 342 * @param style style to apply to the path. 343 */ 344 void drawPath(const GrClip*, 345 GrPaint&&, 346 GrAA, 347 const SkMatrix& viewMatrix, 348 const SkPath&, 349 const GrStyle&); 350 351 /** 352 * Draws a shape. 353 * 354 * @param paint describes how to color pixels. 355 * @param GrAA Controls whether the path is antialiased. 356 * @param viewMatrix transformation matrix 357 * @param shape the shape to draw 358 */ 359 void drawShape(const GrClip*, 360 GrPaint&&, 361 GrAA, 362 const SkMatrix& viewMatrix, 363 GrStyledShape&&); 364 365 /** 366 * Draws vertices with a paint. 367 * 368 * @param paint describes how to color pixels. 369 * @param viewMatrix transformation matrix 370 * @param vertices specifies the mesh to draw. 371 * @param overridePrimType primitive type to draw. If NULL, derive prim type from vertices. 372 * @param skipColorXform if true, do not apply a color space transfer function 373 */ 374 void drawVertices(const GrClip*, 375 GrPaint&& paint, 376 const SkMatrix& viewMatrix, 377 sk_sp<SkVertices> vertices, 378 GrPrimitiveType* overridePrimType = nullptr, 379 bool skipColorXform = false); 380 381 /** 382 * Draws a custom mesh with a paint. 383 * 384 * @param paint describes how to color pixels. 385 * @param viewMatrix transformation matrix 386 * @param mesh the mesh to draw. 387 * @param children child effects referenced by SkMesh shaders 388 */ 389 void drawMesh(const GrClip*, 390 GrPaint&& paint, 391 const SkMatrix& viewMatrix, 392 const SkMesh& mesh, 393 skia_private::TArray<std::unique_ptr<GrFragmentProcessor>> children); 394 395 /** 396 * Draws textured sprites from an atlas with a paint. This currently does not support AA for the 397 * sprite rectangle edges. 398 * 399 * @param paint describes how to color pixels. 400 * @param viewMatrix transformation matrix 401 * @param spriteCount number of sprites. 402 * @param xform array of compressed transformation data, required. 403 * @param texRect array of texture rectangles used to access the paint. 404 * @param colors optional array of per-sprite colors, supercedes 405 * the paint's color field. 406 */ 407 void drawAtlas(const GrClip*, 408 GrPaint&& paint, 409 const SkMatrix& viewMatrix, 410 int spriteCount, 411 const SkRSXform xform[], 412 const SkRect texRect[], 413 const SkColor colors[]); 414 415 /** 416 * Draws a region. 417 * 418 * @param paint describes how to color pixels 419 * @param viewMatrix transformation matrix 420 * @param aa should the rects of the region be antialiased. 421 * @param region the region to be drawn 422 * @param style style to apply to the region 423 */ 424 void drawRegion(const GrClip*, 425 GrPaint&& paint, 426 GrAA aa, 427 const SkMatrix& viewMatrix, 428 const SkRegion& region, 429 const GrStyle& style, 430 const GrUserStencilSettings* ss = nullptr); 431 432 /** 433 * Draws an oval. 434 * 435 * @param paint describes how to color pixels. 436 * @param GrAA Controls whether the oval is antialiased. 437 * @param viewMatrix transformation matrix 438 * @param oval the bounding rect of the oval. 439 * @param style style to apply to the oval. Currently path effects are not allowed. 440 */ 441 void drawOval(const GrClip*, 442 GrPaint&& paint, 443 GrAA, 444 const SkMatrix& viewMatrix, 445 const SkRect& oval, 446 const GrStyle& style); 447 448 /** 449 * Draws a partial arc of an oval. 450 * 451 * @param paint describes how to color pixels. 452 * @param GrGrAA Controls whether the arc is antialiased. 453 * @param viewMatrix transformation matrix. 454 * @param oval the bounding rect of the oval. 455 * @param startAngle starting angle in degrees. 456 * @param sweepAngle angle to sweep in degrees. Must be in (-360, 360) 457 * @param useCenter true means that the implied path begins at the oval center, connects as 458 * a line to the point indicated by the start contains the arc indicated by 459 * the sweep angle. If false the line beginning at the center point is 460 * omitted. 461 * @param style style to apply to the oval. 462 */ 463 void drawArc(const GrClip*, 464 GrPaint&& paint, 465 GrAA, 466 const SkMatrix& viewMatrix, 467 const SkArc& arc, 468 const GrStyle& style); 469 470 /** 471 * Draw the image as a set of rects, specified by |iter|. 472 */ 473 void drawImageLattice(const GrClip*, 474 GrPaint&&, 475 const SkMatrix& viewMatrix, 476 GrSurfaceProxyView, 477 SkAlphaType alphaType, 478 sk_sp<GrColorSpaceXform>, 479 GrSamplerState::Filter, 480 std::unique_ptr<SkLatticeIter>, 481 const SkRect& dst); 482 483 /** 484 * Draw the text specified by the GlyphRunList. 485 * 486 * @param viewMatrix transformation matrix 487 * @param glyphRunList text, text positions, and paint. 488 */ 489 void drawGlyphRunList(SkCanvas*, 490 const GrClip*, 491 const SkMatrix& viewMatrix, 492 const sktext::GlyphRunList& glyphRunList, 493 SkStrikeDeviceInfo strikeDeviceInfo, 494 const SkPaint& paint); 495 496 /** 497 * Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the 498 * command stream. 499 */ 500 void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds); 501 502 // called to note the last clip drawn to the stencil buffer. 503 // TODO: remove after clipping overhaul. 504 void setLastClip(uint32_t clipStackGenID, 505 const SkIRect& devClipBounds, 506 int numClipAnalyticElements); 507 508 // called to determine if we have to render the clip into SB. 509 // TODO: remove after clipping overhaul. 510 bool mustRenderClip(uint32_t clipStackGenID, 511 const SkIRect& devClipBounds, 512 int numClipAnalyticElements); 513 clearStencilClip(const SkIRect & scissor,bool insideStencilMask)514 void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) { 515 this->internalStencilClear(&scissor, insideStencilMask); 516 } 517 518 // While this can take a general clip, since ClipStack relies on this function, it must take 519 // care to only provide hard clips or we could get stuck in a loop. The general clip is needed 520 // so that path renderers can use this function. 521 void stencilRect(const GrClip* clip, 522 const GrUserStencilSettings* ss, 523 GrPaint&& paint, 524 GrAA doStencilMSAA, 525 const SkMatrix& viewMatrix, 526 const SkRect& rect, 527 const SkMatrix* localMatrix = nullptr) { 528 // Since this provides stencil settings to drawFilledQuad, it performs a different AA type 529 // resolution compared to regular rect draws, which is the main reason it remains separate. 530 DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), 531 localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect), 532 doStencilMSAA == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone}; 533 this->drawFilledQuad(clip, std::move(paint), &quad, ss); 534 } 535 536 // Fills the user stencil bits with a non-zero value at every sample inside the path. This will 537 // likely be implemented with a Redbook algorithm, but it is not guaranteed. The samples being 538 // rendered to must be zero initially. 539 bool stencilPath(const GrHardClip*, 540 GrAA doStencilMSAA, 541 const SkMatrix& viewMatrix, 542 const SkPath&); 543 544 /** 545 * Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings 546 * for each color sample written. 547 */ 548 bool drawAndStencilPath(const GrHardClip*, 549 const GrUserStencilSettings*, 550 SkRegion::Op op, 551 bool invert, 552 GrAA doStencilMSAA, 553 const SkMatrix& viewMatrix, 554 const SkPath&); 555 556 skgpu::Budgeted isBudgeted() const; 557 558 int maxWindowRectangles() const; 559 560 /* 561 * This unique ID will not change for a given SurfaceDrawContext. However, it is _NOT_ 562 * guaranteed to match the uniqueID of the underlying GrRenderTarget - beware! 563 */ uniqueID()564 GrSurfaceProxy::UniqueID uniqueID() const { return this->asSurfaceProxy()->uniqueID(); } 565 566 // Allows caller of addDrawOp to know which op list an op will be added to. 567 using WillAddOpFn = void(GrOp*, uint32_t opsTaskID); 568 // These perform processing specific to GrDrawOp-derived ops before recording them into an 569 // op list. Before adding the op to an op list the WillAddOpFn is called. Note that it 570 // will not be called in the event that the op is discarded. Moreover, the op may merge into 571 // another op after the function is called (either before addDrawOp returns or some time later). 572 // 573 // If the clip pointer is null, no clipping will be performed. 574 void addDrawOp(const GrClip*, 575 GrOp::Owner, 576 const std::function<WillAddOpFn>& = std::function<WillAddOpFn>()); addDrawOp(GrOp::Owner op)577 void addDrawOp(GrOp::Owner op) { this->addDrawOp(nullptr, std::move(op)); } 578 refsWrappedObjects()579 bool refsWrappedObjects() const { return this->asRenderTargetProxy()->refsWrappedObjects(); } 580 581 /** 582 * The next time this SurfaceDrawContext is flushed, the gpu will wait on the passed in 583 * semaphores before executing any commands. 584 */ 585 bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[], 586 bool deleteSemaphoresAfterWait); 587 numSamples()588 int numSamples() const { return this->asRenderTargetProxy()->numSamples(); } surfaceProps()589 const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } canUseDynamicMSAA()590 bool canUseDynamicMSAA() const { return fCanUseDynamicMSAA; } wrapsVkSecondaryCB()591 bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); } 592 alwaysAntialias()593 bool alwaysAntialias() const { 594 return fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag; 595 } 596 chooseAA(const SkPaint & paint)597 GrAA chooseAA(const SkPaint& paint) { 598 return GrAA(paint.isAntiAlias() || this->alwaysAntialias()); 599 } 600 chooseAAType(GrAA aa)601 GrAAType chooseAAType(GrAA aa) { 602 if (this->numSamples() > 1 || fCanUseDynamicMSAA) { 603 // Always trigger DMSAA when it's available. The coverage ops that know how to handle 604 // both single and multisample targets without popping will do so without calling 605 // chooseAAType. 606 return GrAAType::kMSAA; 607 } 608 return (aa == GrAA::kYes) ? GrAAType::kCoverage : GrAAType::kNone; 609 } 610 611 // This entry point should only be called if the backing GPU object is known to be 612 // instantiated. accessRenderTarget()613 GrRenderTarget* accessRenderTarget() { return this->asSurfaceProxy()->peekRenderTarget(); } 614 615 #if defined(GR_TEST_UTILS) testingOnly_SetPreserveOpsOnFullClear()616 void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; } 617 #endif 618 619 void drawStrokedLine(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, const SkPoint[2], 620 const SkStrokeRec&); 621 622 private: 623 enum class QuadOptimization; 624 625 void willReplaceOpsTask(OpsTask* prevTask, OpsTask* nextTask) override; 626 627 OpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const override; 628 void setNeedsStencil(); 629 630 void internalStencilClear(const SkIRect* scissor, bool insideStencilMask); 631 632 // 'stencilSettings' are provided merely for decision making purposes; When non-null, 633 // optimization strategies that submit special ops are avoided. 634 // 635 // 'quad' should be the original draw request on input, and will be updated as 636 // appropriate depending on the returned optimization level. 637 // 638 // If kSubmitted is returned, the provided paint was consumed. Otherwise it is left unchanged. 639 QuadOptimization attemptQuadOptimization(const GrClip* clip, 640 const GrUserStencilSettings* stencilSettings, 641 DrawQuad* quad, 642 GrPaint* paint); 643 644 // The overall AA policy is determined by the quad's edge flags: kNone is no AA, and anything 645 // else uses some form of anti-aliasing. If 'ss' is non-null, that will be MSAA; otherwise it's 646 // MSAA or analytic coverage per chooseAAType(). This will always attempt to apply 647 // quad optimizations, so all quad/rect public APIs should rely on this function for consistent 648 // clipping behavior. 'quad' will be modified in place to reflect final rendered geometry. 649 void drawFilledQuad(const GrClip* clip, 650 GrPaint&& paint, 651 DrawQuad* quad, 652 const GrUserStencilSettings* ss = nullptr); 653 654 // Like drawFilledQuad but does not require using a GrPaint or FP for texturing. 655 // 'quad' may be modified in place to reflect final geometry. 656 void drawTexturedQuad(const GrClip* clip, 657 GrSurfaceProxyView proxyView, 658 SkAlphaType alphaType, 659 sk_sp<GrColorSpaceXform> textureXform, 660 GrSamplerState::Filter filter, 661 GrSamplerState::MipmapMode, 662 const SkPMColor4f& color, 663 SkBlendMode blendMode, 664 DrawQuad* quad, 665 const SkRect* subset = nullptr); 666 667 // Tries to detect if the given shape is a simple, and draws it without path rendering if 668 // we know how. 669 bool drawSimpleShape(const GrClip*, GrPaint*, GrAA, const SkMatrix&, const GrStyledShape&); 670 671 // If 'attemptDrawSimple' is true, of if the original shape is marked as having been simplfied, 672 // this will attempt to re-route through drawSimpleShape() to see if we can avoid path rendering 673 // one more time. 674 void drawShapeUsingPathRenderer(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, 675 GrStyledShape&&, bool attemptDrawSimple = false); 676 677 // Makes a copy of the proxy if it is necessary for the draw and places the texture that should 678 // be used by GrXferProcessor to access the destination color in 'result'. If the return 679 // value is false then a texture copy could not be made. 680 // 681 // The op should have already had setClippedBounds called on it. 682 [[nodiscard]] bool setupDstProxyView(const SkRect& opBounds, 683 bool opRequiresMSAA, 684 GrDstProxyView* result); 685 686 OpsTask* replaceOpsTaskIfModifiesColor(); 687 688 const SkSurfaceProps fSurfaceProps; 689 const bool fCanUseDynamicMSAA; 690 691 bool fNeedsStencil = false; 692 693 #if defined(GR_TEST_UTILS) 694 bool fPreserveOpsOnFullClear_TestingOnly = false; 695 #endif 696 }; 697 698 } // namespace skgpu::ganesh 699 700 #endif // SurfaceDrawContext_v1_DEFINED 701