1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLMemoryUsageReportTest:
7 // Tests pertaining to EGL_ANGLE_memory_usage_report extension.
8 //
9
10 #include <gtest/gtest.h>
11
12 #include "test_utils/ANGLETest.h"
13 #include "test_utils/gl_raii.h"
14 #include "util/EGLWindow.h"
15
16 using namespace angle;
17
18 class EGLMemoryUsageReportTest : public ANGLETest<>
19 {
20 protected:
hasEGLDisplayExtension(const char * extname) const21 bool hasEGLDisplayExtension(const char *extname) const
22 {
23 return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), extname);
24 }
25
hasMemoryUsageReportExtension() const26 bool hasMemoryUsageReportExtension() const
27 {
28 return hasEGLDisplayExtension("EGL_ANGLE_memory_usage_report");
29 }
30
getMemoryUsage(EGLDisplay display,EGLContext context)31 uint64_t getMemoryUsage(EGLDisplay display, EGLContext context)
32 {
33 GLint parts[2];
34 EXPECT_EGL_TRUE(eglQueryContext(display, context, EGL_CONTEXT_MEMORY_USAGE_ANGLE, parts));
35
36 return (static_cast<uint64_t>(parts[0]) & 0xffffffff) |
37 ((static_cast<uint64_t>(parts[1]) & 0xffffffff) << 32);
38 }
39 };
40
41 // Basic memory usage queries
TEST_P(EGLMemoryUsageReportTest,BasicQuery)42 TEST_P(EGLMemoryUsageReportTest, BasicQuery)
43 {
44 ANGLE_SKIP_TEST_IF(!hasMemoryUsageReportExtension());
45
46 constexpr GLint kTextureDim = 1024;
47 constexpr GLuint kTextureSize = kTextureDim * kTextureDim * 4;
48 constexpr GLuint kBufferSize = 4096;
49 constexpr GLint kRenderbufferDim = 512;
50 constexpr GLuint kRenderbufferSize = kRenderbufferDim * kRenderbufferDim * 4;
51 constexpr GLuint kTotalObjectsMemorySize = kBufferSize + kRenderbufferSize + kTextureSize;
52
53 EGLDisplay display = getEGLWindow()->getDisplay();
54 EGLContext context = getEGLWindow()->getContext();
55
56 uint64_t memorySize1 = getMemoryUsage(display, context);
57 uint64_t memorySize2;
58
59 {
60 GLBuffer buffer;
61 glBindBuffer(GL_ARRAY_BUFFER, buffer);
62 glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
63
64 GLTexture texture;
65 glBindTexture(GL_TEXTURE_2D, texture);
66 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureDim, kTextureDim);
67
68 GLRenderbuffer rbo;
69 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
70 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kRenderbufferDim, kRenderbufferDim);
71
72 memorySize2 = getMemoryUsage(display, context);
73
74 EXPECT_EQ(memorySize2 - memorySize1, kTotalObjectsMemorySize);
75 }
76
77 uint64_t memorySize3 = getMemoryUsage(display, context);
78 EXPECT_EQ(memorySize2 - memorySize3, kTotalObjectsMemorySize);
79 }
80
81 // Test that querying memory usage of a context that is not current works.
TEST_P(EGLMemoryUsageReportTest,QueryNonCurrentContext)82 TEST_P(EGLMemoryUsageReportTest, QueryNonCurrentContext)
83 {
84 ANGLE_SKIP_TEST_IF(!hasMemoryUsageReportExtension());
85
86 constexpr GLint kTextureDim = 1024;
87 constexpr GLuint kTextureSize = kTextureDim * kTextureDim * 4;
88
89 EGLWindow *window = getEGLWindow();
90 EGLDisplay display = window->getDisplay();
91
92 // Create a 2nd context.
93 EGLContext context2 = window->createContext(EGL_NO_CONTEXT, nullptr);
94
95 uint64_t context2MemorySize1 = getMemoryUsage(display, context2);
96
97 {
98 EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context2));
99 GLTexture texture;
100 glBindTexture(GL_TEXTURE_2D, texture);
101 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureDim, kTextureDim);
102
103 // Make default context current.
104 EXPECT_TRUE(window->makeCurrent());
105 EXPECT_NE(eglGetCurrentContext(), context2);
106
107 // Query 2nd context's memory size
108 uint64_t context2MemorySize2 = getMemoryUsage(display, context2);
109
110 EXPECT_EQ(context2MemorySize2 - context2MemorySize1, kTextureSize);
111 }
112
113 EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
114 }
115
116 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLMemoryUsageReportTest);
117 ANGLE_INSTANTIATE_TEST_ES3(EGLMemoryUsageReportTest);
118