1 /* 2 * Copyright 2011 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 GrGpu_DEFINED 9 #define GrGpu_DEFINED 10 11 #include "include/core/SkPath.h" 12 #include "include/core/SkSpan.h" 13 #include "include/core/SkSurface.h" 14 #include "include/gpu/GrTypes.h" 15 #include "include/private/SkTArray.h" 16 #include "src/core/SkTInternalLList.h" 17 #include "src/gpu/GrAttachment.h" 18 #include "src/gpu/GrCaps.h" 19 #include "src/gpu/GrOpsRenderPass.h" 20 #include "src/gpu/GrPixmap.h" 21 #include "src/gpu/GrSwizzle.h" 22 #include "src/gpu/GrXferProcessor.h" 23 24 class GrAttachment; 25 class GrBackendRenderTarget; 26 class GrBackendSemaphore; 27 struct GrContextOptions; 28 class GrDirectContext; 29 class GrGpuBuffer; 30 class GrGLContext; 31 class GrPath; 32 class GrPathRenderer; 33 class GrPathRendererChain; 34 class GrPipeline; 35 class GrGeometryProcessor; 36 class GrRenderTarget; 37 class GrRingBuffer; 38 class GrSemaphore; 39 class GrStagingBufferManager; 40 class GrStencilSettings; 41 class GrSurface; 42 class GrTexture; 43 class GrThreadSafePipelineBuilder; 44 struct GrVkDrawableInfo; 45 class SkJSONWriter; 46 47 namespace SkSL { 48 class Compiler; 49 } 50 51 class GrGpu : public SkRefCnt { 52 public: 53 GrGpu(GrDirectContext* direct); 54 ~GrGpu() override; 55 getContext()56 GrDirectContext* getContext() { return fContext; } getContext()57 const GrDirectContext* getContext() const { return fContext; } 58 59 /** 60 * Gets the capabilities of the draw target. 61 */ caps()62 const GrCaps* caps() const { return fCaps.get(); } refCaps()63 sk_sp<const GrCaps> refCaps() const { return fCaps; } 64 stagingBufferManager()65 virtual GrStagingBufferManager* stagingBufferManager() { return nullptr; } 66 uniformsRingBuffer()67 virtual GrRingBuffer* uniformsRingBuffer() { return nullptr; } 68 shaderCompiler()69 SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); } 70 71 enum class DisconnectType { 72 // No cleanup should be attempted, immediately cease making backend API calls 73 kAbandon, 74 // Free allocated resources (not known by GrResourceCache) before returning and 75 // ensure no backend backend 3D API calls will be made after disconnect() returns. 76 kCleanup, 77 }; 78 79 // Called by context when the underlying backend context is already or will be destroyed 80 // before GrDirectContext. 81 virtual void disconnect(DisconnectType); 82 83 virtual GrThreadSafePipelineBuilder* pipelineBuilder() = 0; 84 virtual sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() = 0; 85 86 // Called by GrDirectContext::isContextLost. Returns true if the backend Gpu object has gotten 87 // into an unrecoverable, lost state. isDeviceLost()88 virtual bool isDeviceLost() const { return false; } 89 90 /** 91 * The GrGpu object normally assumes that no outsider is setting state 92 * within the underlying 3D API's context/device/whatever. This call informs 93 * the GrGpu that the state was modified and it shouldn't make assumptions 94 * about the state. 95 */ 96 void markContextDirty(uint32_t state = kAll_GrBackendState) { fResetBits |= state; } 97 98 /** 99 * Creates a texture object. If renderable is kYes then the returned texture can 100 * be used as a render target by calling GrTexture::asRenderTarget(). Not all 101 * pixel configs can be used as render targets. Support for configs as textures 102 * or render targets can be checked using GrCaps. 103 * 104 * @param dimensions dimensions of the texture to be created. 105 * @param format the format for the texture (not currently used). 106 * @param renderable should the resulting texture be renderable 107 * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is 108 * kYes. If renderable is kNo then this must be 1. 109 * @param budgeted does this texture count against the resource cache budget? 110 * @param isProtected should the texture be created as protected. 111 * @param texels array of mipmap levels containing texel data to load. 112 * If level i has pixels then it is assumed that its dimensions are 113 * max(1, floor(dimensions.fWidth / 2)) by 114 * max(1, floor(dimensions.fHeight / 2)). 115 * If texels[i].fPixels == nullptr for all i <= mipLevelCount or 116 * mipLevelCount is 0 then the texture's contents are uninitialized. 117 * If a level has non-null pixels, its row bytes must be a multiple of the 118 * config's bytes-per-pixel. The row bytes must be tight to the 119 * level width if !caps->writePixelsRowBytesSupport(). 120 * If mipLevelCount > 1 and texels[i].fPixels != nullptr for any i > 0 121 * then all levels must have non-null pixels. All levels must have 122 * non-null pixels if GrCaps::createTextureMustSpecifyAllLevels() is true. 123 * @param textureColorType The color type interpretation of the texture for the purpose of 124 * of uploading texel data. 125 * @param srcColorType The color type of data in texels[]. 126 * @param texelLevelCount the number of levels in 'texels'. May be 0, 1, or 127 * floor(max((log2(dimensions.fWidth), log2(dimensions.fHeight)))). It 128 * must be the latter if GrCaps::createTextureMustSpecifyAllLevels() is 129 * true. 130 * @return The texture object if successful, otherwise nullptr. 131 */ 132 sk_sp<GrTexture> createTexture(SkISize dimensions, 133 const GrBackendFormat& format, 134 GrTextureType textureType, 135 GrRenderable renderable, 136 int renderTargetSampleCnt, 137 SkBudgeted budgeted, 138 GrProtected isProtected, 139 GrColorType textureColorType, 140 GrColorType srcColorType, 141 const GrMipLevel texels[], 142 int texelLevelCount); 143 144 /** 145 * Simplified createTexture() interface for when there is no initial texel data to upload. 146 */ 147 sk_sp<GrTexture> createTexture(SkISize dimensions, 148 const GrBackendFormat& format, 149 GrTextureType textureType, 150 GrRenderable renderable, 151 int renderTargetSampleCnt, 152 GrMipmapped mipMapped, 153 SkBudgeted budgeted, 154 GrProtected isProtected); 155 156 sk_sp<GrTexture> createCompressedTexture(SkISize dimensions, 157 const GrBackendFormat& format, 158 SkBudgeted budgeted, 159 GrMipmapped mipMapped, 160 GrProtected isProtected, 161 const void* data, size_t dataSize); 162 163 /** 164 * Implements GrResourceProvider::wrapBackendTexture 165 */ 166 sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&, 167 GrWrapOwnership, 168 GrWrapCacheable, 169 GrIOType); 170 171 sk_sp<GrTexture> wrapCompressedBackendTexture(const GrBackendTexture&, 172 GrWrapOwnership, 173 GrWrapCacheable); 174 175 /** 176 * Implements GrResourceProvider::wrapRenderableBackendTexture 177 */ 178 sk_sp<GrTexture> wrapRenderableBackendTexture(const GrBackendTexture&, 179 int sampleCnt, 180 GrWrapOwnership, 181 GrWrapCacheable); 182 183 /** 184 * Implements GrResourceProvider::wrapBackendRenderTarget 185 */ 186 sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTarget&); 187 188 /** 189 * Implements GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget 190 */ 191 sk_sp<GrRenderTarget> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 192 const GrVkDrawableInfo&); 193 194 /** 195 * Creates a buffer in GPU memory. For a client-side buffer use GrBuffer::CreateCPUBacked. 196 * 197 * @param size size of buffer to create. 198 * @param intendedType hint to the graphics subsystem about what the buffer will be used for. 199 * @param accessPattern hint to the graphics subsystem about how the data will be accessed. 200 * @param data optional data with which to initialize the buffer. 201 * 202 * @return the buffer if successful, otherwise nullptr. 203 */ 204 sk_sp<GrGpuBuffer> createBuffer(size_t size, GrGpuBufferType intendedType, 205 GrAccessPattern accessPattern, const void* data = nullptr); 206 207 /** 208 * Resolves MSAA. The resolveRect must already be in the native destination space. 209 */ 210 void resolveRenderTarget(GrRenderTarget*, const SkIRect& resolveRect); 211 212 /** 213 * Uses the base of the texture to recompute the contents of the other levels. 214 */ 215 bool regenerateMipMapLevels(GrTexture*); 216 217 /** 218 * If the backend API has stateful texture bindings, this resets them back to defaults. 219 */ 220 void resetTextureBindings(); 221 222 /** 223 * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed. 224 * 225 * @param surface the surface to read from 226 * @param rect the rectangle of pixels to read 227 * @param surfaceColorType the color type for this use of the surface. 228 * @param dstColorType the color type of the destination buffer. 229 * @param buffer memory to read the rectangle into. 230 * @param rowBytes the number of bytes between consecutive rows. Must be a multiple of 231 * dstColorType's bytes-per-pixel. Must be tight to width if 232 * !caps->readPixelsRowBytesSupport(). 233 * 234 * @return true if the read succeeded, false if not. The read can fail 235 * because of the surface doesn't support reading, the color type 236 * is not allowed for the format of the surface or if the rectangle 237 * read is not contained in the surface. 238 */ 239 bool readPixels(GrSurface* surface, 240 SkIRect rect, 241 GrColorType surfaceColorType, 242 GrColorType dstColorType, 243 void* buffer, 244 size_t rowBytes); 245 246 /** 247 * Updates the pixels in a rectangle of a surface. No sRGB/linear conversions are performed. 248 * 249 * @param surface the surface to write to. 250 * @param rect the rectangle of pixels to overwrite 251 * @param surfaceColorType the color type for this use of the surface. 252 * @param srcColorType the color type of the source buffer. 253 * @param texels array of mipmap levels containing texture data. Row bytes must be a 254 * multiple of srcColorType's bytes-per-pixel. Must be tight to level 255 * width if !caps->writePixelsRowBytesSupport(). 256 * @param mipLevelCount number of levels in 'texels' 257 * @param prepForTexSampling After doing write pixels should the surface be prepared for texture 258 * sampling. This is currently only used by Vulkan for inline uploads 259 * to set that layout back to sampled after doing the upload. Inline 260 * uploads currently can happen between draws in a single op so it is 261 * not trivial to break up the OpsTask into two tasks when we see 262 * an inline upload. However, once we are able to support doing that 263 * we can remove this parameter. 264 * 265 * @return true if the write succeeded, false if not. The read can fail 266 * because of the surface doesn't support writing (e.g. read only), 267 * the color type is not allowed for the format of the surface or 268 * if the rectangle written is not contained in the surface. 269 */ 270 bool writePixels(GrSurface* surface, 271 SkIRect rect, 272 GrColorType surfaceColorType, 273 GrColorType srcColorType, 274 const GrMipLevel texels[], 275 int mipLevelCount, 276 bool prepForTexSampling = false); 277 278 /** 279 * Helper for the case of a single level. 280 */ 281 bool writePixels(GrSurface* surface, 282 SkIRect rect, 283 GrColorType surfaceColorType, 284 GrColorType srcColorType, 285 const void* buffer, 286 size_t rowBytes, 287 bool prepForTexSampling = false) { 288 GrMipLevel mipLevel = {buffer, rowBytes, nullptr}; 289 return this->writePixels(surface, 290 rect, 291 surfaceColorType, 292 srcColorType, 293 &mipLevel, 294 1, 295 prepForTexSampling); 296 } 297 298 /** 299 * Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped, 300 * the base level is written to. 301 * 302 * @param texture the texture to write to. 303 * @param rect the rectangle of pixels in the texture to overwrite 304 * @param textureColorType the color type for this use of the surface. 305 * @param bufferColorType the color type of the transfer buffer's pixel data 306 * @param transferBuffer GrBuffer to read pixels from (type must be "kXferCpuToGpu") 307 * @param offset offset from the start of the buffer 308 * @param rowBytes number of bytes between consecutive rows in the buffer. Must be a 309 * multiple of bufferColorType's bytes-per-pixel. Must be tight to 310 * rect.width() if !caps->writePixelsRowBytesSupport(). 311 */ 312 bool transferPixelsTo(GrTexture* texture, 313 SkIRect rect, 314 GrColorType textureColorType, 315 GrColorType bufferColorType, 316 sk_sp<GrGpuBuffer> transferBuffer, 317 size_t offset, 318 size_t rowBytes); 319 320 /** 321 * Reads the pixels from a rectangle of a surface into a buffer. Use 322 * GrCaps::SupportedRead::fOffsetAlignmentForTransferBuffer to determine the requirements for 323 * the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read. 324 * 325 * If successful the row bytes in the buffer is always: 326 * GrColorTypeBytesPerPixel(bufferColorType) * rect.width() 327 * 328 * Asserts that the caller has passed a properly aligned offset and that the buffer is 329 * large enough to hold the result 330 * 331 * @param surface the surface to read from. 332 * @param rect the rectangle of pixels to read 333 * @param surfaceColorType the color type for this use of the surface. 334 * @param bufferColorType the color type of the transfer buffer's pixel data 335 * @param transferBuffer GrBuffer to write pixels to (type must be "kXferGpuToCpu") 336 * @param offset offset from the start of the buffer 337 */ 338 bool transferPixelsFrom(GrSurface* surface, 339 SkIRect rect, 340 GrColorType surfaceColorType, 341 GrColorType bufferColorType, 342 sk_sp<GrGpuBuffer> transferBuffer, 343 size_t offset); 344 345 // Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst 346 // take place at higher levels and this function implement faster copy paths. The rect 347 // and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the 348 // src/dst bounds and non-empty. They must also be in their exact device space coords, including 349 // already being transformed for origin if need be. If canDiscardOutsideDstRect is set to true 350 // then we don't need to preserve any data on the dst surface outside of the copy. 351 bool copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 352 const SkIPoint& dstPoint); 353 354 // Returns a GrOpsRenderPass which OpsTasks send draw commands to instead of directly 355 // to the Gpu object. The 'bounds' rect is the content rect of the renderTarget. 356 // If a 'stencil' is provided it will be the one bound to 'renderTarget'. If one is not 357 // provided but 'renderTarget' has a stencil buffer then that is a signal that the 358 // render target's stencil buffer should be ignored. 359 GrOpsRenderPass* getOpsRenderPass(GrRenderTarget* renderTarget, 360 bool useMSAASurface, 361 GrAttachment* stencil, 362 GrSurfaceOrigin, 363 const SkIRect& bounds, 364 const GrOpsRenderPass::LoadAndStoreInfo&, 365 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 366 const SkTArray<GrSurfaceProxy*, true>& sampledProxies, 367 GrXferBarrierFlags renderPassXferBarriers); 368 369 // Called by GrDrawingManager when flushing. 370 // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also 371 // insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the 372 // inserted semaphores. 373 void executeFlushInfo(SkSpan<GrSurfaceProxy*>, 374 SkSurface::BackendSurfaceAccess access, 375 const GrFlushInfo&, 376 const GrBackendSurfaceMutableState* newState); 377 378 bool submitToGpu(bool syncCpu); 379 380 virtual void submit(GrOpsRenderPass*) = 0; 381 382 virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0; 383 virtual bool waitFence(GrFence) = 0; 384 virtual void deleteFence(GrFence) const = 0; 385 386 virtual std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore( 387 bool isOwned = true) = 0; 388 virtual std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&, 389 GrSemaphoreWrapType, 390 GrWrapOwnership) = 0; 391 virtual void insertSemaphore(GrSemaphore* semaphore) = 0; 392 virtual void waitSemaphore(GrSemaphore* semaphore) = 0; 393 394 virtual void addFinishedProc(GrGpuFinishedProc finishedProc, 395 GrGpuFinishedContext finishedContext) = 0; 396 virtual void checkFinishProcs() = 0; 397 virtual void finishOutstandingGpuWork() = 0; 398 takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>)399 virtual void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) {} 400 401 /** 402 * Checks if we detected an OOM from the underlying 3D API and if so returns true and resets 403 * the internal OOM state to false. Otherwise, returns false. 404 */ 405 bool checkAndResetOOMed(); 406 407 /** 408 * Put this texture in a safe and known state for use across multiple contexts. Depending on 409 * the backend, this may return a GrSemaphore. If so, other contexts should wait on that 410 * semaphore before using this texture. 411 */ 412 virtual std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) = 0; 413 414 /** 415 * Frees any backend specific objects that are not currently in use by the GPU. This is called 416 * when the client is trying to free up as much GPU memory as possible. We will not release 417 * resources connected to programs/pipelines since the cost to recreate those is significantly 418 * higher that other resources. 419 */ releaseUnlockedBackendObjects()420 virtual void releaseUnlockedBackendObjects() {} 421 422 /////////////////////////////////////////////////////////////////////////// 423 // Debugging and Stats 424 425 class Stats { 426 public: 427 #if GR_GPU_STATS 428 Stats() = default; 429 reset()430 void reset() { *this = {}; } 431 textureCreates()432 int textureCreates() const { return fTextureCreates; } incTextureCreates()433 void incTextureCreates() { fTextureCreates++; } 434 textureUploads()435 int textureUploads() const { return fTextureUploads; } incTextureUploads()436 void incTextureUploads() { fTextureUploads++; } 437 transfersToTexture()438 int transfersToTexture() const { return fTransfersToTexture; } incTransfersToTexture()439 void incTransfersToTexture() { fTransfersToTexture++; } 440 transfersFromSurface()441 int transfersFromSurface() const { return fTransfersFromSurface; } incTransfersFromSurface()442 void incTransfersFromSurface() { fTransfersFromSurface++; } 443 stencilAttachmentCreates()444 int stencilAttachmentCreates() const { return fStencilAttachmentCreates; } incStencilAttachmentCreates()445 void incStencilAttachmentCreates() { fStencilAttachmentCreates++; } 446 msaaAttachmentCreates()447 int msaaAttachmentCreates() const { return fMSAAAttachmentCreates; } incMSAAAttachmentCreates()448 void incMSAAAttachmentCreates() { fMSAAAttachmentCreates++; } 449 numDraws()450 int numDraws() const { return fNumDraws; } incNumDraws()451 void incNumDraws() { fNumDraws++; } 452 numFailedDraws()453 int numFailedDraws() const { return fNumFailedDraws; } incNumFailedDraws()454 void incNumFailedDraws() { ++fNumFailedDraws; } 455 numSubmitToGpus()456 int numSubmitToGpus() const { return fNumSubmitToGpus; } incNumSubmitToGpus()457 void incNumSubmitToGpus() { ++fNumSubmitToGpus; } 458 numScratchTexturesReused()459 int numScratchTexturesReused() const { return fNumScratchTexturesReused; } incNumScratchTexturesReused()460 void incNumScratchTexturesReused() { ++fNumScratchTexturesReused; } 461 numScratchMSAAAttachmentsReused()462 int numScratchMSAAAttachmentsReused() const { return fNumScratchMSAAAttachmentsReused; } incNumScratchMSAAAttachmentsReused()463 void incNumScratchMSAAAttachmentsReused() { ++fNumScratchMSAAAttachmentsReused; } 464 renderPasses()465 int renderPasses() const { return fRenderPasses; } incRenderPasses()466 void incRenderPasses() { fRenderPasses++; } 467 numReorderedDAGsOverBudget()468 int numReorderedDAGsOverBudget() const { return fNumReorderedDAGsOverBudget; } incNumReorderedDAGsOverBudget()469 void incNumReorderedDAGsOverBudget() { fNumReorderedDAGsOverBudget++; } 470 471 #if GR_TEST_UTILS 472 void dump(SkString*); 473 void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values); 474 #endif 475 private: 476 int fTextureCreates = 0; 477 int fTextureUploads = 0; 478 int fTransfersToTexture = 0; 479 int fTransfersFromSurface = 0; 480 int fStencilAttachmentCreates = 0; 481 int fMSAAAttachmentCreates = 0; 482 int fNumDraws = 0; 483 int fNumFailedDraws = 0; 484 int fNumSubmitToGpus = 0; 485 int fNumScratchTexturesReused = 0; 486 int fNumScratchMSAAAttachmentsReused = 0; 487 int fRenderPasses = 0; 488 int fNumReorderedDAGsOverBudget = 0; 489 490 #else // !GR_GPU_STATS 491 492 #if GR_TEST_UTILS 493 void dump(SkString*) {} 494 void dumpKeyValuePairs(SkTArray<SkString>*, SkTArray<double>*) {} 495 #endif 496 void incTextureCreates() {} 497 void incTextureUploads() {} 498 void incTransfersToTexture() {} 499 void incTransfersFromSurface() {} 500 void incStencilAttachmentCreates() {} 501 void incMSAAAttachmentCreates() {} 502 void incNumDraws() {} 503 void incNumFailedDraws() {} 504 void incNumSubmitToGpus() {} 505 void incNumScratchTexturesReused() {} 506 void incNumScratchMSAAAttachmentsReused() {} 507 void incRenderPasses() {} 508 void incNumReorderedDAGsOverBudget() {} 509 #endif 510 }; 511 stats()512 Stats* stats() { return &fStats; } 513 void dumpJSON(SkJSONWriter*) const; 514 515 516 /** 517 * Creates a texture directly in the backend API without wrapping it in a GrTexture. 518 * Must be matched with a call to deleteBackendTexture(). 519 * 520 * If data is null the texture is uninitialized. 521 * 522 * If data represents a color then all texture levels are cleared to that color. 523 * 524 * If data represents pixmaps then it must have a either one pixmap or, if mipmapping 525 * is specified, a complete MIP hierarchy of pixmaps. Additionally, if provided, the mip 526 * levels must be sized correctly according to the MIP sizes implied by dimensions. They 527 * must all have the same color type and that color type must be compatible with the 528 * texture format. 529 */ 530 GrBackendTexture createBackendTexture(SkISize dimensions, 531 const GrBackendFormat&, 532 GrRenderable, 533 GrMipmapped, 534 GrProtected); 535 536 bool clearBackendTexture(const GrBackendTexture&, 537 sk_sp<GrRefCntedCallback> finishedCallback, 538 std::array<float, 4> color); 539 540 /** 541 * Same as the createBackendTexture case except compressed backend textures can 542 * never be renderable. 543 */ 544 GrBackendTexture createCompressedBackendTexture(SkISize dimensions, 545 const GrBackendFormat&, 546 GrMipmapped, 547 GrProtected); 548 549 bool updateCompressedBackendTexture(const GrBackendTexture&, 550 sk_sp<GrRefCntedCallback> finishedCallback, 551 const void* data, 552 size_t length); 553 setBackendTextureState(const GrBackendTexture &,const GrBackendSurfaceMutableState &,GrBackendSurfaceMutableState * previousState,sk_sp<GrRefCntedCallback> finishedCallback)554 virtual bool setBackendTextureState(const GrBackendTexture&, 555 const GrBackendSurfaceMutableState&, 556 GrBackendSurfaceMutableState* previousState, 557 sk_sp<GrRefCntedCallback> finishedCallback) { 558 return false; 559 } 560 setBackendRenderTargetState(const GrBackendRenderTarget &,const GrBackendSurfaceMutableState &,GrBackendSurfaceMutableState * previousState,sk_sp<GrRefCntedCallback> finishedCallback)561 virtual bool setBackendRenderTargetState(const GrBackendRenderTarget&, 562 const GrBackendSurfaceMutableState&, 563 GrBackendSurfaceMutableState* previousState, 564 sk_sp<GrRefCntedCallback> finishedCallback) { 565 return false; 566 } 567 568 /** 569 * Frees a texture created by createBackendTexture(). If ownership of the backend 570 * texture has been transferred to a context using adopt semantics this should not be called. 571 */ 572 virtual void deleteBackendTexture(const GrBackendTexture&) = 0; 573 574 /** 575 * In this case we have a program descriptor and a program info but no render target. 576 */ 577 virtual bool compile(const GrProgramDesc&, const GrProgramInfo&) = 0; 578 precompileShader(const SkData & key,const SkData & data)579 virtual bool precompileShader(const SkData& key, const SkData& data) { return false; } 580 581 #if GR_TEST_UTILS 582 /** Check a handle represents an actual texture in the backend API that has not been freed. */ 583 virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0; 584 585 /** 586 * Creates a GrBackendRenderTarget that can be wrapped using 587 * SkSurface::MakeFromBackendRenderTarget. Ideally this is a non-textureable allocation to 588 * differentiate from testing with SkSurface::MakeFromBackendTexture. When sampleCnt > 1 this 589 * is used to test client wrapped allocations with MSAA where Skia does not allocate a separate 590 * buffer for resolving. If the color is non-null the backing store should be cleared to the 591 * passed in color. 592 */ 593 virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget( 594 SkISize dimensions, 595 GrColorType, 596 int sampleCount = 1, 597 GrProtected = GrProtected::kNo) = 0; 598 599 /** 600 * Deletes a GrBackendRenderTarget allocated with the above. Synchronization to make this safe 601 * is up to the caller. 602 */ 603 virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0; 604 605 // This is only to be used in GL-specific tests. glContextForTesting()606 virtual const GrGLContext* glContextForTesting() const { return nullptr; } 607 608 // This is only to be used by testing code resetShaderCacheForTesting()609 virtual void resetShaderCacheForTesting() const {} 610 611 /** 612 * Inserted as a pair around a block of code to do a GPU frame capture. 613 * Currently only works with the Metal backend. 614 */ testingOnly_startCapture()615 virtual void testingOnly_startCapture() {} testingOnly_endCapture()616 virtual void testingOnly_endCapture() {} 617 #endif 618 619 // width and height may be larger than rt (if underlying API allows it). 620 // Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on 621 // the GrAttachment. 622 virtual sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat, 623 SkISize dimensions, 624 int numStencilSamples) = 0; 625 626 virtual GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) = 0; 627 628 // Creates an MSAA surface to be used as an MSAA attachment on a framebuffer. 629 virtual sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions, 630 const GrBackendFormat& format, 631 int numSamples, 632 GrProtected isProtected, 633 GrMemoryless isMemoryless) = 0; 634 handleDirtyContext()635 void handleDirtyContext() { 636 if (fResetBits) { 637 this->resetContext(); 638 } 639 } 640 storeVkPipelineCacheData()641 virtual void storeVkPipelineCacheData() {} 642 643 // http://skbug.com/9739 insertManualFramebufferBarrier()644 virtual void insertManualFramebufferBarrier() { 645 SkASSERT(!this->caps()->requiresManualFBBarrierAfterTessellatedStencilDraw()); 646 SK_ABORT("Manual framebuffer barrier not supported."); 647 } 648 649 // Called before certain draws in order to guarantee coherent results from dst reads. 650 virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0; 651 652 protected: 653 static bool CompressedDataIsCorrect(SkISize dimensions, 654 SkImage::CompressionType, 655 GrMipmapped, 656 const void* data, 657 size_t length); 658 659 // Handles cases where a surface will be updated without a call to flushRenderTarget. 660 void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds, 661 uint32_t mipLevels = 1) const; 662 setOOMed()663 void setOOMed() { fOOMed = true; } 664 665 Stats fStats; 666 667 // Subclass must call this to initialize caps & compiler in its constructor. 668 void initCapsAndCompiler(sk_sp<const GrCaps> caps); 669 670 private: 671 virtual GrBackendTexture onCreateBackendTexture(SkISize dimensions, 672 const GrBackendFormat&, 673 GrRenderable, 674 GrMipmapped, 675 GrProtected) = 0; 676 677 virtual GrBackendTexture onCreateCompressedBackendTexture( 678 SkISize dimensions, const GrBackendFormat&, GrMipmapped, GrProtected) = 0; 679 680 virtual bool onClearBackendTexture(const GrBackendTexture&, 681 sk_sp<GrRefCntedCallback> finishedCallback, 682 std::array<float, 4> color) = 0; 683 684 virtual bool onUpdateCompressedBackendTexture(const GrBackendTexture&, 685 sk_sp<GrRefCntedCallback> finishedCallback, 686 const void* data, 687 size_t length) = 0; 688 689 // called when the 3D context state is unknown. Subclass should emit any 690 // assumed 3D context state and dirty any state cache. onResetContext(uint32_t resetBits)691 virtual void onResetContext(uint32_t resetBits) {} 692 693 // Implementation of resetTextureBindings. onResetTextureBindings()694 virtual void onResetTextureBindings() {} 695 696 // overridden by backend-specific derived class to create objects. 697 // Texture size, renderablility, format support, sample count will have already been validated 698 // in base class before onCreateTexture is called. 699 // If the ith bit is set in levelClearMask then the ith MIP level should be cleared. 700 virtual sk_sp<GrTexture> onCreateTexture(SkISize dimensions, 701 const GrBackendFormat&, 702 GrRenderable, 703 int renderTargetSampleCnt, 704 SkBudgeted, 705 GrProtected, 706 int mipLevelCoont, 707 uint32_t levelClearMask) = 0; 708 virtual sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, 709 const GrBackendFormat&, 710 SkBudgeted, 711 GrMipmapped, 712 GrProtected, 713 const void* data, size_t dataSize) = 0; 714 virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, 715 GrWrapOwnership, 716 GrWrapCacheable, 717 GrIOType) = 0; 718 719 virtual sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, 720 GrWrapOwnership, 721 GrWrapCacheable) = 0; 722 723 virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 724 int sampleCnt, 725 GrWrapOwnership, 726 GrWrapCacheable) = 0; 727 virtual sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) = 0; 728 virtual sk_sp<GrRenderTarget> onWrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 729 const GrVkDrawableInfo&); 730 731 virtual sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, 732 GrAccessPattern, const void* data) = 0; 733 734 // overridden by backend-specific derived class to perform the surface read 735 virtual bool onReadPixels(GrSurface*, 736 SkIRect, 737 GrColorType surfaceColorType, 738 GrColorType dstColorType, 739 void*, 740 size_t rowBytes) = 0; 741 742 // overridden by backend-specific derived class to perform the surface write 743 virtual bool onWritePixels(GrSurface*, 744 SkIRect, 745 GrColorType surfaceColorType, 746 GrColorType srcColorType, 747 const GrMipLevel[], 748 int mipLevelCount, 749 bool prepForTexSampling) = 0; 750 751 // overridden by backend-specific derived class to perform the texture transfer 752 virtual bool onTransferPixelsTo(GrTexture*, 753 SkIRect, 754 GrColorType textiueColorType, 755 GrColorType bufferColorType, 756 sk_sp<GrGpuBuffer> transferBuffer, 757 size_t offset, 758 size_t rowBytes) = 0; 759 760 // overridden by backend-specific derived class to perform the surface transfer 761 virtual bool onTransferPixelsFrom(GrSurface*, 762 SkIRect, 763 GrColorType surfaceColorType, 764 GrColorType bufferColorType, 765 sk_sp<GrGpuBuffer> transferBuffer, 766 size_t offset) = 0; 767 768 // overridden by backend-specific derived class to perform the resolve 769 virtual void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) = 0; 770 771 // overridden by backend specific derived class to perform mip map level regeneration. 772 virtual bool onRegenerateMipMapLevels(GrTexture*) = 0; 773 774 // overridden by backend specific derived class to perform the copy surface 775 virtual bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 776 const SkIPoint& dstPoint) = 0; 777 778 virtual GrOpsRenderPass* onGetOpsRenderPass( 779 GrRenderTarget* renderTarget, 780 bool useMSAASurface, 781 GrAttachment* stencil, 782 GrSurfaceOrigin, 783 const SkIRect& bounds, 784 const GrOpsRenderPass::LoadAndStoreInfo&, 785 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 786 const SkTArray<GrSurfaceProxy*, true>& sampledProxies, 787 GrXferBarrierFlags renderPassXferBarriers) = 0; 788 prepareSurfacesForBackendAccessAndStateUpdates(SkSpan<GrSurfaceProxy * > proxies,SkSurface::BackendSurfaceAccess access,const GrBackendSurfaceMutableState * newState)789 virtual void prepareSurfacesForBackendAccessAndStateUpdates( 790 SkSpan<GrSurfaceProxy*> proxies, 791 SkSurface::BackendSurfaceAccess access, 792 const GrBackendSurfaceMutableState* newState) {} 793 794 virtual bool onSubmitToGpu(bool syncCpu) = 0; 795 796 void reportSubmitHistograms(); onReportSubmitHistograms()797 virtual void onReportSubmitHistograms() {} 798 799 #ifdef SK_ENABLE_DUMP_GPU onDumpJSON(SkJSONWriter *)800 virtual void onDumpJSON(SkJSONWriter*) const {} 801 #endif 802 803 sk_sp<GrTexture> createTextureCommon(SkISize, 804 const GrBackendFormat&, 805 GrTextureType textureType, 806 GrRenderable, 807 int renderTargetSampleCnt, 808 SkBudgeted, 809 GrProtected, 810 int mipLevelCnt, 811 uint32_t levelClearMask); 812 resetContext()813 void resetContext() { 814 this->onResetContext(fResetBits); 815 fResetBits = 0; 816 } 817 818 void callSubmittedProcs(bool success); 819 820 sk_sp<const GrCaps> fCaps; 821 // Compiler used for compiling SkSL into backend shader code. We only want to create the 822 // compiler once, as there is significant overhead to the first compile. 823 std::unique_ptr<SkSL::Compiler> fCompiler; 824 825 uint32_t fResetBits; 826 // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu. 827 GrDirectContext* fContext; 828 829 struct SubmittedProc { SubmittedProcSubmittedProc830 SubmittedProc(GrGpuSubmittedProc proc, GrGpuSubmittedContext context) 831 : fProc(proc), fContext(context) {} 832 833 GrGpuSubmittedProc fProc; 834 GrGpuSubmittedContext fContext; 835 }; 836 SkSTArray<4, SubmittedProc> fSubmittedProcs; 837 838 bool fOOMed = false; 839 840 #if SK_HISTOGRAMS_ENABLED 841 int fCurrentSubmitRenderPassCount = 0; 842 #endif 843 844 friend class GrPathRendering; 845 using INHERITED = SkRefCnt; 846 }; 847 848 #endif 849