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