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