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
10 #include "tests/Test.h"
11
12 #include "include/gpu/GrTexture.h"
13 #include "src/gpu/GrContextPriv.h"
14 #include "src/gpu/GrRenderTarget.h"
15 #include "src/gpu/gl/GrGLBuffer.h"
16 #include "src/gpu/gl/GrGLDefines.h"
17 #include "src/gpu/gl/GrGLGpu.h"
18
19 /*
20 * Build test for SkTraceMemoryDump.
21 */
22 class TestSkTraceMemoryDump : public SkTraceMemoryDump {
23 public:
TestSkTraceMemoryDump(bool shouldDumpWrappedObjects)24 TestSkTraceMemoryDump(bool shouldDumpWrappedObjects)
25 : fShouldDumpWrappedObjects(shouldDumpWrappedObjects) {}
~TestSkTraceMemoryDump()26 ~TestSkTraceMemoryDump() override { }
27
dumpNumericValue(const char * dumpName,const char * valueName,const char * units,uint64_t value)28 void dumpNumericValue(const char* dumpName, const char* valueName, const char* units,
29 uint64_t value) override {
30 // Only count "size" dumps, others are just providing metadata.
31 if (SkString("size") == SkString(valueName)) {
32 ++fNumDumpedObjects;
33 fDumpedObjectsSize += value;
34 }
35 }
setMemoryBacking(const char * dumpName,const char * backingType,const char * backingObjectId)36 void setMemoryBacking(const char* dumpName, const char* backingType,
37 const char* backingObjectId) override { }
setDiscardableMemoryBacking(const char * dumpName,const SkDiscardableMemory & discardableMemoryObject)38 void setDiscardableMemoryBacking(
39 const char* dumpName,
40 const SkDiscardableMemory& discardableMemoryObject) override { }
getRequestedDetails() const41 LevelOfDetail getRequestedDetails() const override {
42 return SkTraceMemoryDump::kObjectsBreakdowns_LevelOfDetail;
43 }
shouldDumpWrappedObjects() const44 bool shouldDumpWrappedObjects() const override { return fShouldDumpWrappedObjects; }
45
numDumpedObjects() const46 size_t numDumpedObjects() const { return fNumDumpedObjects; }
dumpedObjectsSize() const47 size_t dumpedObjectsSize() const { return fDumpedObjectsSize; }
48
49 private:
50 bool fShouldDumpWrappedObjects;
51 size_t fNumDumpedObjects = 0;
52 size_t fDumpedObjectsSize = 0;
53 };
54
ValidateMemoryDumps(skiatest::Reporter * reporter,GrContext * context,size_t size,bool isOwned)55 void ValidateMemoryDumps(skiatest::Reporter* reporter, GrContext* context, size_t size,
56 bool isOwned) {
57 // Note than one entry in the dumped objects is expected for the text blob cache.
58 TestSkTraceMemoryDump dump_with_wrapped(true /* shouldDumpWrappedObjects */);
59 context->dumpMemoryStatistics(&dump_with_wrapped);
60 REPORTER_ASSERT(reporter, 2 == dump_with_wrapped.numDumpedObjects());
61 REPORTER_ASSERT(reporter, size == dump_with_wrapped.dumpedObjectsSize());
62
63 TestSkTraceMemoryDump dump_no_wrapped(false /* shouldDumpWrappedObjects */);
64 context->dumpMemoryStatistics(&dump_no_wrapped);
65 if (isOwned) {
66 REPORTER_ASSERT(reporter, 2 == dump_no_wrapped.numDumpedObjects());
67 REPORTER_ASSERT(reporter, size == dump_no_wrapped.dumpedObjectsSize());
68 } else {
69 REPORTER_ASSERT(reporter, 1 == dump_no_wrapped.numDumpedObjects());
70 REPORTER_ASSERT(reporter, 0 == dump_no_wrapped.dumpedObjectsSize());
71 }
72 }
73
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLBuffer,reporter,ctxInfo)74 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLBuffer, reporter, ctxInfo) {
75 GrContext* context = ctxInfo.grContext();
76 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
77 const size_t kMemorySize = 1024;
78 sk_sp<GrGLBuffer> buffer =
79 GrGLBuffer::Make(gpu, kMemorySize, GrGpuBufferType::kVertex, kDynamic_GrAccessPattern);
80
81 ValidateMemoryDumps(reporter, context, kMemorySize, true /* isOwned */);
82 }
83
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTexture,reporter,ctxInfo)84 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLTexture, reporter, ctxInfo) {
85 GrContext* context = ctxInfo.grContext();
86 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
87
88 GrGLTexture::Desc desc;
89 desc.fTarget = GR_GL_TEXTURE_2D;
90 desc.fID = 7; // Arbitrary, we don't actually use the texture.
91 desc.fFormat = GrGLFormat::kRGBA8;
92 desc.fOwnership = GrBackendObjectOwnership::kOwned;
93 desc.fConfig = kRGBA_8888_GrPixelConfig;
94 desc.fSize = SkISize::Make(64, 64);
95
96 auto texture =
97 sk_make_sp<GrGLTexture>(gpu, SkBudgeted::kNo, desc, GrMipMapsStatus::kNotAllocated);
98
99 ValidateMemoryDumps(reporter, context, texture->gpuMemorySize(), true /* isOwned */);
100 }
101
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture,reporter,ctxInfo)102 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture, reporter, ctxInfo) {
103 GrContext* context = ctxInfo.grContext();
104 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
105
106 GrGLTexture::Desc desc;
107 desc.fTarget = GR_GL_TEXTURE_2D;
108 desc.fID = 7; // Arbitrary, we don't actually use the texture.
109 desc.fFormat = GrGLFormat::kRGBA8;
110 desc.fOwnership = GrBackendObjectOwnership::kBorrowed;
111 desc.fConfig = kRGBA_8888_GrPixelConfig;
112 desc.fSize = SkISize::Make(64, 64);
113
114 auto params = sk_make_sp<GrGLTextureParameters>();
115
116 auto texture =
117 GrGLTexture::MakeWrapped(gpu, GrMipMapsStatus::kNotAllocated, desc, std::move(params),
118 GrWrapCacheable::kNo, kRead_GrIOType);
119
120 ValidateMemoryDumps(reporter, context, texture->gpuMemorySize(), false /* isOwned */);
121 }
122
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLRenderTarget,reporter,ctxInfo)123 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_ownedGLRenderTarget, reporter, ctxInfo) {
124 GrContext* context = ctxInfo.grContext();
125 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
126
127 static constexpr auto kSize = SkISize::Make(64, 64);
128 static constexpr auto kConfig = kRGBA_8888_GrPixelConfig;
129
130 GrGLRenderTarget::IDs rtIDs;
131 rtIDs.fRTFBOID = 20;
132 rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
133 rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
134 rtIDs.fMSColorRenderbufferID = 22;
135
136 sk_sp<GrGLRenderTarget> rt =
137 GrGLRenderTarget::MakeWrapped(gpu, kSize, GrGLFormat::kRGBA8, kConfig, 1, rtIDs, 0);
138
139 ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), true /* isOwned */);
140 }
141
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLRenderTarget,reporter,ctxInfo)142 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLRenderTarget, reporter, ctxInfo) {
143 GrContext* context = ctxInfo.grContext();
144 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
145
146 static constexpr auto kSize = SkISize::Make(64, 64);
147 static constexpr auto kConfig = kRGBA_8888_GrPixelConfig;
148
149 GrGLRenderTarget::IDs rtIDs;
150 rtIDs.fRTFBOID = 20;
151 rtIDs.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
152 rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
153 rtIDs.fMSColorRenderbufferID = 22;
154
155 sk_sp<GrGLRenderTarget> rt =
156 GrGLRenderTarget::MakeWrapped(gpu, kSize, GrGLFormat::kRGBA8, kConfig, 1, rtIDs, 0);
157
158 ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), false /* isOwned */);
159 }
160