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/GrAttachment.h"
9
10 #include "include/private/GrResourceKey.h"
11 #include "src/gpu/GrBackendUtils.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/GrDataUtils.h"
14 #include "src/gpu/GrGpu.h"
15
onGpuMemorySize() const16 size_t GrAttachment::onGpuMemorySize() const {
17 // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
18 // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
19 // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
20 // attachment to give its own size since we don't have GrGpuResources owning other
21 // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
22 // the msaa and stencil attachments track their own size because they do get cached separately.
23 // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
24 // the owned attachments will have no size and be uncached.
25 if (!(fSupportedUsages & UsageFlags::kTexture) && fMemoryless == GrMemoryless::kNo) {
26 GrBackendFormat format = this->backendFormat();
27 SkImage::CompressionType compression = GrBackendFormatToCompressionType(format);
28
29 uint64_t size = GrNumBlocks(compression, this->dimensions());
30 size *= GrBackendFormatBytesPerBlock(this->backendFormat());
31 size *= this->numSamples();
32 return size;
33 }
34 return 0;
35 }
36
dumpMemoryStatistics(SkTraceMemoryDump * traceMemoryDump) const37 void GrAttachment::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
38 SkString type;
39 if (fSupportedUsages == UsageFlags::kStencilAttachment) {
40 type = "StencilAttachment";
41 }
42
43 if (fSupportedUsages & UsageFlags::kTexture) {
44 // This return since the memory should all be handled by the textures
45 return;
46 } else if (fSupportedUsages & UsageFlags::kColorAttachment) {
47 type = "ColorAttachment";
48 }
49
50 SkString resourceName = this->getResourceName();
51 resourceName.append("/attachment");
52 this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, type.c_str(), onGpuMemorySize());
53 }
54
build_key(GrResourceKey::Builder * builder,const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,GrAttachment::UsageFlags requiredUsage,int sampleCnt,GrMipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless)55 static void build_key(GrResourceKey::Builder* builder,
56 const GrCaps& caps,
57 const GrBackendFormat& format,
58 SkISize dimensions,
59 GrAttachment::UsageFlags requiredUsage,
60 int sampleCnt,
61 GrMipmapped mipmapped,
62 GrProtected isProtected,
63 GrMemoryless memoryless) {
64 SkASSERT(!dimensions.isEmpty());
65
66 SkASSERT(static_cast<uint32_t>(isProtected) <= 1);
67 SkASSERT(static_cast<uint32_t>(memoryless) <= 1);
68 SkASSERT(static_cast<uint32_t>(requiredUsage) < (1u << 8));
69 SkASSERT(static_cast<uint32_t>(sampleCnt) < (1u << (32 - 10)));
70
71 uint64_t formatKey = caps.computeFormatKey(format);
72 (*builder)[0] = dimensions.width();
73 (*builder)[1] = dimensions.height();
74 (*builder)[2] = formatKey & 0xFFFFFFFF;
75 (*builder)[3] = (formatKey >> 32) & 0xFFFFFFFF;
76 (*builder)[4] = (static_cast<uint32_t>(isProtected) << 0) |
77 (static_cast<uint32_t>(memoryless) << 1) |
78 (static_cast<uint32_t>(requiredUsage) << 2) |
79 (static_cast<uint32_t>(sampleCnt) << 10);
80 }
81
ComputeSharedAttachmentUniqueKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,GrMipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,GrUniqueKey * key)82 void GrAttachment::ComputeSharedAttachmentUniqueKey(const GrCaps& caps,
83 const GrBackendFormat& format,
84 SkISize dimensions,
85 UsageFlags requiredUsage,
86 int sampleCnt,
87 GrMipmapped mipmapped,
88 GrProtected isProtected,
89 GrMemoryless memoryless,
90 GrUniqueKey* key) {
91 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
92
93 GrUniqueKey::Builder builder(key, kDomain, 5);
94 build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
95 memoryless);
96 }
97
ComputeScratchKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,GrMipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,GrScratchKey * key)98 void GrAttachment::ComputeScratchKey(const GrCaps& caps,
99 const GrBackendFormat& format,
100 SkISize dimensions,
101 UsageFlags requiredUsage,
102 int sampleCnt,
103 GrMipmapped mipmapped,
104 GrProtected isProtected,
105 GrMemoryless memoryless,
106 GrScratchKey* key) {
107 static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
108
109 GrScratchKey::Builder builder(key, kType, 5);
110 build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
111 memoryless);
112 }
113
computeScratchKey(GrScratchKey * key) const114 void GrAttachment::computeScratchKey(GrScratchKey* key) const {
115 if (!SkToBool(fSupportedUsages & UsageFlags::kStencilAttachment)) {
116 auto isProtected = this->isProtected() ? GrProtected::kYes : GrProtected::kNo;
117 ComputeScratchKey(*this->getGpu()->caps(),
118 this->backendFormat(),
119 this->dimensions(),
120 fSupportedUsages,
121 this->numSamples(),
122 this->mipmapped(),
123 isProtected,
124 fMemoryless,
125 key);
126 }
127 }
128