xref: /aosp_15_r20/external/angle/src/tests/perf_tests/IndexDataManagerTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2015 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 // IndexDataManagerPerfTest:
7 //   Performance test for index buffer management.
8 //
9 
10 #include "ANGLEPerfTest.h"
11 
12 #include <gmock/gmock.h>
13 
14 #include "angle_unittests_utils.h"
15 #include "libANGLE/renderer/d3d/BufferD3D.h"
16 #include "libANGLE/renderer/d3d/IndexBuffer.h"
17 #include "libANGLE/renderer/d3d/IndexDataManager.h"
18 
19 using namespace testing;
20 
21 namespace
22 {
23 constexpr unsigned int kIterationsPerStep = 100;
24 
25 class MockIndexBuffer : public rx::IndexBuffer
26 {
27   public:
MockIndexBuffer(unsigned int bufferSize,gl::DrawElementsType indexType)28     MockIndexBuffer(unsigned int bufferSize, gl::DrawElementsType indexType)
29         : mBufferSize(bufferSize), mIndexType(indexType)
30     {}
31 
32     MOCK_METHOD4(initialize,
33                  angle::Result(const gl::Context *, unsigned int, gl::DrawElementsType, bool));
34     MOCK_METHOD4(mapBuffer,
35                  angle::Result(const gl::Context *, unsigned int, unsigned int, void **));
36     MOCK_METHOD1(unmapBuffer, angle::Result(const gl::Context *));
37     MOCK_METHOD1(discard, angle::Result(const gl::Context *));
38     MOCK_METHOD3(setSize, angle::Result(const gl::Context *, unsigned int, gl::DrawElementsType));
39 
40     // inlined for speed
getIndexType() const41     gl::DrawElementsType getIndexType() const override { return mIndexType; }
getBufferSize() const42     unsigned int getBufferSize() const override { return mBufferSize; }
43 
44   private:
45     unsigned int mBufferSize;
46     gl::DrawElementsType mIndexType;
47 };
48 
49 class MockBufferFactoryD3D : public rx::BufferFactoryD3D
50 {
51   public:
MockBufferFactoryD3D(unsigned int bufferSize,gl::DrawElementsType indexType)52     MockBufferFactoryD3D(unsigned int bufferSize, gl::DrawElementsType indexType)
53         : mBufferSize(bufferSize), mIndexType(indexType)
54     {}
55 
56     MOCK_METHOD0(createVertexBuffer, rx::VertexBuffer *());
57     MOCK_CONST_METHOD1(getVertexConversionType, rx::VertexConversionType(angle::FormatID));
58     MOCK_CONST_METHOD1(getVertexComponentType, GLenum(angle::FormatID));
59     MOCK_CONST_METHOD7(getVertexSpaceRequired,
60                        angle::Result(const gl::Context *,
61                                      const gl::VertexAttribute &,
62                                      const gl::VertexBinding &,
63                                      size_t,
64                                      GLsizei,
65                                      GLuint,
66                                      unsigned int *));
67 
68     // Dependency injection
createIndexBuffer()69     rx::IndexBuffer *createIndexBuffer() override
70     {
71         return new MockIndexBuffer(mBufferSize, mIndexType);
72     }
73 
74   private:
75     unsigned int mBufferSize;
76     gl::DrawElementsType mIndexType;
77 };
78 
79 class MockBufferD3D : public rx::BufferD3D
80 {
81   public:
MockBufferD3D(rx::BufferFactoryD3D * factory)82     MockBufferD3D(rx::BufferFactoryD3D *factory) : BufferD3D(mockState, factory), mData() {}
83 
84     // BufferImpl
setData(const gl::Context * context,gl::BufferBinding target,const void * data,size_t size,gl::BufferUsage)85     angle::Result setData(const gl::Context *context,
86                           gl::BufferBinding target,
87                           const void *data,
88                           size_t size,
89                           gl::BufferUsage) override
90     {
91         mData.resize(size);
92         if (data && size > 0)
93         {
94             memcpy(&mData[0], data, size);
95         }
96         return angle::Result::Continue;
97     }
98 
99     MOCK_METHOD5(
100         setSubData,
101         angle::Result(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t));
102     MOCK_METHOD5(copySubData,
103                  angle::Result(const gl::Context *, BufferImpl *, GLintptr, GLintptr, GLsizeiptr));
104     MOCK_METHOD3(map, angle::Result(const gl::Context *context, GLenum, void **));
105     MOCK_METHOD5(mapRange, angle::Result(const gl::Context *, size_t, size_t, GLbitfield, void **));
106     MOCK_METHOD2(unmap, angle::Result(const gl::Context *context, GLboolean *));
107 
108     // BufferD3D
109     MOCK_METHOD1(markTransformFeedbackUsage, angle::Result(const gl::Context *));
110 
111     // inlined for speed
supportsDirectBinding() const112     bool supportsDirectBinding() const override { return false; }
getSize() const113     size_t getSize() const override { return mData.size(); }
114 
getData(const gl::Context * context,const uint8_t ** outData)115     angle::Result getData(const gl::Context *context, const uint8_t **outData) override
116     {
117         *outData = &mData[0];
118         return angle::Result::Continue;
119     }
120 
121   private:
122     gl::BufferState mockState;
123     std::vector<uint8_t> mData;
124 };
125 
126 class MockGLFactoryD3D : public rx::MockGLFactory
127 {
128   public:
MockGLFactoryD3D(MockBufferFactoryD3D * bufferFactory)129     MockGLFactoryD3D(MockBufferFactoryD3D *bufferFactory) : mBufferFactory(bufferFactory) {}
130 
createBuffer(const gl::BufferState & state)131     rx::BufferImpl *createBuffer(const gl::BufferState &state) override
132     {
133         MockBufferD3D *mockBufferD3D = new MockBufferD3D(mBufferFactory);
134 
135         EXPECT_CALL(*mBufferFactory, createVertexBuffer())
136             .WillOnce(Return(nullptr))
137             .RetiresOnSaturation();
138         mockBufferD3D->initializeStaticData(nullptr);
139 
140         return mockBufferD3D;
141     }
142 
143     MockBufferFactoryD3D *mBufferFactory;
144 };
145 
146 class IndexDataManagerPerfTest : public ANGLEPerfTest
147 {
148   public:
149     IndexDataManagerPerfTest();
150 
151     void step() override;
152 
153     rx::IndexDataManager mIndexDataManager;
154     GLsizei mIndexCount;
155     unsigned int mBufferSize;
156     MockBufferFactoryD3D mMockBufferFactory;
157     MockGLFactoryD3D mMockGLFactory;
158     gl::Buffer mIndexBuffer;
159 };
160 
IndexDataManagerPerfTest()161 IndexDataManagerPerfTest::IndexDataManagerPerfTest()
162     : ANGLEPerfTest("IndexDataManager", "", "_run", kIterationsPerStep),
163       mIndexDataManager(&mMockBufferFactory),
164       mIndexCount(4000),
165       mBufferSize(mIndexCount * sizeof(GLushort)),
166       mMockBufferFactory(mBufferSize, gl::DrawElementsType::UnsignedShort),
167       mMockGLFactory(&mMockBufferFactory),
168       mIndexBuffer(&mMockGLFactory, {1})
169 {
170     std::vector<GLushort> indexData(mIndexCount);
171     for (GLsizei index = 0; index < mIndexCount; ++index)
172     {
173         indexData[index] = static_cast<GLushort>(index);
174     }
175     EXPECT_EQ(
176         angle::Result::Continue,
177         mIndexBuffer.bufferData(nullptr, gl::BufferBinding::Array, &indexData[0],
178                                 indexData.size() * sizeof(GLushort), gl::BufferUsage::StaticDraw));
179 }
180 
step()181 void IndexDataManagerPerfTest::step()
182 {
183     rx::TranslatedIndexData translatedIndexData;
184     gl::IndexRange indexRange;
185     for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration)
186     {
187         (void)mIndexBuffer.getIndexRange(nullptr, gl::DrawElementsType::UnsignedShort, 0,
188                                          mIndexCount, false, &indexRange);
189         (void)mIndexDataManager.prepareIndexData(nullptr, gl::DrawElementsType::UnsignedShort,
190                                                  gl::DrawElementsType::UnsignedShort, mIndexCount,
191                                                  &mIndexBuffer, nullptr, &translatedIndexData);
192     }
193 }
194 
TEST_F(IndexDataManagerPerfTest,Run)195 TEST_F(IndexDataManagerPerfTest, Run)
196 {
197     run();
198 }
199 
200 }  // anonymous namespace
201