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