• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 "include/core/SkTraceMemoryDump.h"
9 #include "include/gpu/GrDirectContext.h"
10 
11 #include "tests/Test.h"
12 
13 #include "src/gpu/GrDirectContextPriv.h"
14 #include "src/gpu/GrRenderTarget.h"
15 #include "src/gpu/GrTexture.h"
16 #ifdef SK_GL
17 #include "src/gpu/gl/GrGLBuffer.h"
18 #include "src/gpu/gl/GrGLDefines.h"
19 #include "src/gpu/gl/GrGLGpu.h"
20 #include "src/gpu/gl/GrGLTextureRenderTarget.h"
21 #endif
22 
23 /*
24  * Build test for SkTraceMemoryDump.
25  */
26 class TestSkTraceMemoryDump : public SkTraceMemoryDump {
27 public:
TestSkTraceMemoryDump(bool shouldDumpWrappedObjects)28     TestSkTraceMemoryDump(bool shouldDumpWrappedObjects)
29             : fShouldDumpWrappedObjects(shouldDumpWrappedObjects) {}
~TestSkTraceMemoryDump()30     ~TestSkTraceMemoryDump() override { }
31 
dumpNumericValue(const char * dumpName,const char * valueName,const char * units,uint64_t value)32     void dumpNumericValue(const char* dumpName, const char* valueName, const char* units,
33                           uint64_t value) override {
34         // Only count "size" dumps, others are just providing metadata.
35         if (SkString("size") == SkString(valueName)) {
36             ++fNumDumpedObjects;
37             fDumpedObjectsSize += value;
38         }
39     }
setMemoryBacking(const char * dumpName,const char * backingType,const char * backingObjectId)40     void setMemoryBacking(const char* dumpName, const char* backingType,
41                           const char* backingObjectId) override { }
setDiscardableMemoryBacking(const char * dumpName,const SkDiscardableMemory & discardableMemoryObject)42     void setDiscardableMemoryBacking(
43         const char* dumpName,
44         const SkDiscardableMemory& discardableMemoryObject) override { }
getRequestedDetails() const45     LevelOfDetail getRequestedDetails() const override {
46         return SkTraceMemoryDump::kObjectsBreakdowns_LevelOfDetail;
47     }
shouldDumpWrappedObjects() const48     bool shouldDumpWrappedObjects() const override { return fShouldDumpWrappedObjects; }
49 
numDumpedObjects() const50     size_t numDumpedObjects() const { return fNumDumpedObjects; }
dumpedObjectsSize() const51     size_t dumpedObjectsSize() const { return fDumpedObjectsSize; }
52 
53 private:
54     bool fShouldDumpWrappedObjects;
55     size_t fNumDumpedObjects = 0;
56     size_t fDumpedObjectsSize = 0;
57 };
58 
ValidateMemoryDumps(skiatest::Reporter * reporter,GrDirectContext * dContext,size_t numDumpedObjects,size_t size,bool isOwned)59 void ValidateMemoryDumps(skiatest::Reporter* reporter, GrDirectContext* dContext,
60                          size_t numDumpedObjects, size_t size, bool isOwned) {
61     // Note than one entry in the dumped objects is expected for the text blob cache.
62     TestSkTraceMemoryDump dump_with_wrapped(true /* shouldDumpWrappedObjects */);
63     dContext->dumpMemoryStatistics(&dump_with_wrapped);
64     REPORTER_ASSERT(reporter, numDumpedObjects == dump_with_wrapped.numDumpedObjects());
65     REPORTER_ASSERT(reporter, size == dump_with_wrapped.dumpedObjectsSize());
66 
67     TestSkTraceMemoryDump dump_no_wrapped(false /* shouldDumpWrappedObjects */);
68     dContext->dumpMemoryStatistics(&dump_no_wrapped);
69     if (isOwned) {
70         REPORTER_ASSERT(reporter, numDumpedObjects == dump_no_wrapped.numDumpedObjects());
71         REPORTER_ASSERT(reporter, size == dump_no_wrapped.dumpedObjectsSize());
72     } else {
73         REPORTER_ASSERT(reporter, 1 == dump_no_wrapped.numDumpedObjects());
74         REPORTER_ASSERT(reporter, 0 == dump_no_wrapped.dumpedObjectsSize());
75     }
76 }
77 
78 #ifdef SK_GL
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLBuffer,reporter,ctxInfo)79 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLBuffer, reporter, ctxInfo) {
80     auto dContext = ctxInfo.directContext();
81     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
82     const size_t kMemorySize = 1024;
83     sk_sp<GrGLBuffer> buffer =
84             GrGLBuffer::Make(gpu, kMemorySize, GrGpuBufferType::kVertex, kDynamic_GrAccessPattern);
85 
86     ValidateMemoryDumps(reporter, dContext, 2, kMemorySize, true /* isOwned */);
87 }
88 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTexture,reporter,ctxInfo)89 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTexture, reporter, ctxInfo) {
90     auto dContext = ctxInfo.directContext();
91     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
92 
93     GrGLTexture::Desc desc;
94     desc.fTarget = GR_GL_TEXTURE_2D;
95     desc.fID = 7;  // Arbitrary, we don't actually use the texture.
96     desc.fFormat = GrGLFormat::kRGBA8;
97     desc.fOwnership = GrBackendObjectOwnership::kOwned;
98     desc.fSize = SkISize::Make(64, 64);
99 
100     auto texture =
101             sk_make_sp<GrGLTexture>(gpu, SkBudgeted::kNo, desc, GrMipmapStatus::kNotAllocated);
102 
103     ValidateMemoryDumps(reporter, dContext, 2, texture->gpuMemorySize(), true /* isOwned */);
104 }
105 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture,reporter,ctxInfo)106 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture, reporter, ctxInfo) {
107     auto dContext = ctxInfo.directContext();
108     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
109 
110     GrGLTexture::Desc desc;
111     desc.fTarget = GR_GL_TEXTURE_2D;
112     desc.fID = 7;  // Arbitrary, we don't actually use the texture.
113     desc.fFormat = GrGLFormat::kRGBA8;
114     desc.fOwnership = GrBackendObjectOwnership::kBorrowed;
115     desc.fSize = SkISize::Make(64, 64);
116 
117     auto params = sk_make_sp<GrGLTextureParameters>();
118 
119     auto texture =
120             GrGLTexture::MakeWrapped(gpu, GrMipmapStatus::kNotAllocated, desc, std::move(params),
121                                      GrWrapCacheable::kNo, kRead_GrIOType);
122 
123     ValidateMemoryDumps(reporter, dContext, 2, texture->gpuMemorySize(), false /* isOwned */);
124 }
125 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLRenderTarget,reporter,ctxInfo)126 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLRenderTarget, reporter, ctxInfo) {
127     auto dContext = ctxInfo.directContext();
128     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
129 
130     static constexpr auto kSize = SkISize::Make(64, 64);
131 
132     GrGLRenderTarget::IDs rtIDs;
133     rtIDs.fMultisampleFBOID = 0;
134     rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
135     rtIDs.fSingleSampleFBOID = 20;
136     rtIDs.fMSColorRenderbufferID = 0;
137     rtIDs.fTotalMemorySamplesPerPixel = 1;
138 
139     sk_sp<GrGLRenderTarget> rt =
140             GrGLRenderTarget::MakeWrapped(gpu, kSize, GrGLFormat::kRGBA8, 1, rtIDs, 0);
141 
142     ValidateMemoryDumps(reporter, dContext, 2, rt->gpuMemorySize(), true /* isOwned */);
143 }
144 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLRenderTarget,reporter,ctxInfo)145 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLRenderTarget, reporter, ctxInfo) {
146     auto dContext = ctxInfo.directContext();
147     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
148 
149     static constexpr auto kSize = SkISize::Make(64, 64);
150 
151     GrGLRenderTarget::IDs rtIDs;
152     rtIDs.fMultisampleFBOID = 12;
153     rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
154     rtIDs.fSingleSampleFBOID = 0;
155     rtIDs.fMSColorRenderbufferID = 0;
156     rtIDs.fTotalMemorySamplesPerPixel = 4;
157 
158     sk_sp<GrGLRenderTarget> rt =
159             GrGLRenderTarget::MakeWrapped(gpu, kSize, GrGLFormat::kRGBA8, 4, rtIDs, 0);
160 
161     ValidateMemoryDumps(reporter, dContext, 2, rt->gpuMemorySize(), false /* isOwned */);
162 }
163 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTextureRenderTarget,reporter,ctxInfo)164 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTextureRenderTarget, reporter,
165                                       ctxInfo) {
166     auto dContext = ctxInfo.directContext();
167     GrGLGpu* gpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
168 
169     static constexpr auto kSize = SkISize::Make(64, 64);
170 
171     GrGLTexture::Desc texDesc;
172     texDesc.fSize = kSize;
173     texDesc.fTarget = GR_GL_TEXTURE_2D;
174     texDesc.fID = 17;
175     texDesc.fFormat = GrGLFormat::kRGBA8;
176     texDesc.fOwnership = GrBackendObjectOwnership::kOwned;
177 
178     GrGLRenderTarget::IDs rtIDs;
179     rtIDs.fMultisampleFBOID = 12;
180     rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
181     rtIDs.fSingleSampleFBOID = 20;
182     rtIDs.fMSColorRenderbufferID = 22;
183     rtIDs.fTotalMemorySamplesPerPixel = 9;
184 
185     auto texRT = sk_make_sp<GrGLTextureRenderTarget>(gpu, SkBudgeted::kYes, 8, texDesc, rtIDs,
186                                                      GrMipmapStatus::kNotAllocated);
187 
188     ValidateMemoryDumps(reporter, dContext, 3, texRT->gpuMemorySize(), true /* isOwned */);
189 }
190 
191 #endif  // SK_GL
192