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