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