• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/gpu/ganesh/GrAttachment.h"
9 
10 #include "include/core/SkTextureCompressionType.h"
11 #include "src/gpu/DataUtils.h"
12 #include "src/gpu/ganesh/GrBackendUtils.h"
13 #include "src/gpu/ganesh/GrCaps.h"
14 #include "src/gpu/ganesh/GrDataUtils.h"
15 #include "src/gpu/ganesh/GrGpu.h"
16 
onGpuMemorySize() const17 size_t GrAttachment::onGpuMemorySize() const {
18     // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
19     // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
20     // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
21     // attachment to give its own size since we don't have GrGpuResources owning other
22     // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
23     // the msaa and stencil attachments track their own size because they do get cached separately.
24     // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
25     // the owned attachments will have no size and be uncached.
26     if (!(fSupportedUsages & UsageFlags::kTexture) && fMemoryless == GrMemoryless::kNo) {
27         GrBackendFormat format = this->backendFormat();
28         SkTextureCompressionType compression = GrBackendFormatToCompressionType(format);
29 
30         uint64_t size = skgpu::NumCompressedBlocks(compression, this->dimensions());
31         size *= GrBackendFormatBytesPerBlock(this->backendFormat());
32         size *= this->numSamples();
33         return size;
34     }
35     return 0;
36 }
37 
build_key(skgpu::ResourceKey::Builder * builder,const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,GrAttachment::UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless)38 static void build_key(skgpu::ResourceKey::Builder* builder,
39                       const GrCaps& caps,
40                       const GrBackendFormat& format,
41                       SkISize dimensions,
42                       GrAttachment::UsageFlags requiredUsage,
43                       int sampleCnt,
44                       skgpu::Mipmapped mipmapped,
45                       GrProtected isProtected,
46                       GrMemoryless memoryless) {
47     SkASSERT(!dimensions.isEmpty());
48 
49     SkASSERT(static_cast<uint32_t>(isProtected) <= 1);
50     SkASSERT(static_cast<uint32_t>(memoryless) <= 1);
51     SkASSERT(static_cast<uint32_t>(requiredUsage) < (1u << 8));
52     SkASSERT(static_cast<uint32_t>(sampleCnt) < (1u << (32 - 10)));
53 
54     uint64_t formatKey = caps.computeFormatKey(format);
55     (*builder)[0] = dimensions.width();
56     (*builder)[1] = dimensions.height();
57     (*builder)[2] = formatKey & 0xFFFFFFFF;
58     (*builder)[3] = (formatKey >> 32) & 0xFFFFFFFF;
59     (*builder)[4] = (static_cast<uint32_t>(isProtected) << 0) |
60                     (static_cast<uint32_t>(memoryless) << 1) |
61                     (static_cast<uint32_t>(requiredUsage) << 2) |
62                     (static_cast<uint32_t>(sampleCnt) << 10);
63 }
64 
ComputeSharedAttachmentUniqueKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,skgpu::UniqueKey * key)65 void GrAttachment::ComputeSharedAttachmentUniqueKey(const GrCaps& caps,
66                                                     const GrBackendFormat& format,
67                                                     SkISize dimensions,
68                                                     UsageFlags requiredUsage,
69                                                     int sampleCnt,
70                                                     skgpu::Mipmapped mipmapped,
71                                                     GrProtected isProtected,
72                                                     GrMemoryless memoryless,
73                                                     skgpu::UniqueKey* key) {
74     static const skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
75 
76     skgpu::UniqueKey::Builder builder(key, kDomain, 5);
77     build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
78               memoryless);
79 }
80 
ComputeScratchKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,skgpu::ScratchKey * key)81 void GrAttachment::ComputeScratchKey(const GrCaps& caps,
82                                      const GrBackendFormat& format,
83                                      SkISize dimensions,
84                                      UsageFlags requiredUsage,
85                                      int sampleCnt,
86                                      skgpu::Mipmapped mipmapped,
87                                      GrProtected isProtected,
88                                      GrMemoryless memoryless,
89                                      skgpu::ScratchKey* key) {
90     static const skgpu::ScratchKey::ResourceType kType = skgpu::ScratchKey::GenerateResourceType();
91 
92     skgpu::ScratchKey::Builder builder(key, kType, 5);
93     build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
94               memoryless);
95 }
96 
computeScratchKey(skgpu::ScratchKey * key) const97 void GrAttachment::computeScratchKey(skgpu::ScratchKey* key) const {
98     // We do don't cache GrAttachments as scratch resources when used for stencils or textures. For
99     // stencils we share/cache them with unique keys so that they can be shared. Textures are in a
100     // weird place on the Vulkan backend. Currently, GrVkTexture contains a GrAttachment (GrVkImage)
101     // that actually holds the VkImage. The GrVkTexture is cached as a scratch resource and is
102     // responsible for tracking the gpuMemorySize. Thus we set the size of the texture GrVkImage,
103     // above in onGpuMemorySize, to be zero. Therefore, we can't have the GrVkImage getting cached
104     // separately on its own in the GrResourceCache or we may grow forever adding them thinking they
105     // contatin a memory that's size 0 and never freeing the actual VkImages.
106     if (!SkToBool(fSupportedUsages & UsageFlags::kStencilAttachment) &&
107         !SkToBool(fSupportedUsages & UsageFlags::kTexture)) {
108         auto isProtected = this->isProtected() ? GrProtected::kYes : GrProtected::kNo;
109         ComputeScratchKey(*this->getGpu()->caps(),
110                           this->backendFormat(),
111                           this->dimensions(),
112                           fSupportedUsages,
113                           this->numSamples(),
114                           this->mipmapped(),
115                           isProtected,
116                           fMemoryless,
117                           key);
118     }
119 }
120