Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Side by Side Diff: content/common/gpu/client/gpu_memory_buffer_impl_perftest.cc

Issue 1220753005: content: perf tests for GpuMemoryBuffers mapping and data coherency Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update to ToT + needed CLs (1128113011, 1134993003, 1208603002 and 1212133006) Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/content_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // The idea is to benchmark how the hardware, on different usages of
6 // GpuMemoryBuffer, performs when a native buffer object is mapped into the
7 // CPU. In particular this test aims to capture the effects of data coherency
8 // and could be extended further to answer the following:
9 //
10 // - measure memory mapping performance of GpuMemoryBuffer using shared memory
11 // (fallback case) and also native implementation.
12 // - what if the Renderer process (client) just writes into the buffer object?
13 // - what's the effect of reading from a write-combining (WC) memory? can we
14 // avoid read backs?
15 // - should it be UC and/or WC mapped, to get a faster access?
16 // - what the effect of clients doing sequential writes or non-sequential? If
17 // the latter, a WC mapping may end up being very slow.
18
19 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
20
21 #include "base/bind.h"
22 #include "content/common/gpu/gpu_memory_buffer_factory.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/perf/perf_test.h"
25
26 namespace content {
27 namespace {
28
29 const int kNumRuns = 1000;
30 const int kClientId = 1;
31
32 // Do we want to move this into a public API?
33 std::string GpuMemoryBufferTypeName(gfx::GpuMemoryBufferType type) {
34 switch (type) {
35 case gfx::SHARED_MEMORY_BUFFER:
36 return "shared_memory";
37 case gfx::IO_SURFACE_BUFFER:
38 return "io_surface";
39 case gfx::SURFACE_TEXTURE_BUFFER:
40 return "surface_texture";
41 case gfx::OZONE_NATIVE_BUFFER:
42 return "ozone_native";
43 default:
44 NOTREACHED();
45 return "";
46 }
47 }
48
49 class GpuMemoryBufferPerfTest
50 : public testing::TestWithParam<gfx::GpuMemoryBufferType> {
51 public:
52 GpuMemoryBufferPerfTest()
53 : buffer_count_(0),
54 buffer_size_(128, 128),
55 buffer_(nullptr),
56 factory_(nullptr) {}
57
58 // Overridden from testing::Test:
59 void SetUp() override {
60 factory_ = GpuMemoryBufferFactory::Create(GetParam());
61 }
62 void TearDown() override { factory_.reset(); }
63
64 gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
65 gfx::GpuMemoryBufferId id,
66 const gfx::Size& size,
67 gfx::GpuMemoryBuffer::Format format,
68 gfx::GpuMemoryBuffer::Usage usage) {
69 ++buffer_count_;
70 return factory_->CreateGpuMemoryBuffer(id, size, format, usage, kClientId,
71 gfx::kNullPluginWindow);
72 }
73
74 void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32 sync_point) {
75 factory_->DestroyGpuMemoryBuffer(id, kClientId);
76 DCHECK_GT(buffer_count_, 0);
77 --buffer_count_;
78 }
79
80 void CreateTestGpuMemoryBuffer(void) {
81 const int kBufferId = 1;
82 const gfx::GpuMemoryBuffer::Format format =
83 gfx::GpuMemoryBuffer::BGRA_8888;
84 const gfx::GpuMemoryBuffer::Usage usage = gfx::GpuMemoryBuffer::MAP;
85 total_time_ = 0;
86
87 handle_ =
88 CreateGpuMemoryBuffer(kBufferId, buffer_size_, format, usage);
89
90 buffer_ =
91 GpuMemoryBufferImpl::CreateFromHandle(
92 handle_,
93 buffer_size_, format, usage,
94 base::Bind(&GpuMemoryBufferPerfTest::DestroyGpuMemoryBuffer,
95 base::Unretained(this), kBufferId));
96 ASSERT_TRUE(buffer_);
97 EXPECT_FALSE(buffer_->IsMapped());
98 }
99
100 void DestroyTestGpuMemoryBuffer(void) {
101 buffer_.reset();
102 }
103
104 void BufferMap(scoped_ptr<void* []> const &buffers) {
105 base::TimeTicks start = base::TimeTicks::Now();
106 bool rv = buffer_->Map(buffers.get());
107 total_time_ +=
108 static_cast<size_t>((base::TimeTicks::Now() - start).InMicroseconds());
109 ASSERT_TRUE(rv);
110 EXPECT_TRUE(buffer_->IsMapped());
111 }
112
113 void BufferUnmap(void) {
114 buffer_->Unmap();
115 EXPECT_FALSE(buffer_->IsMapped());
116 }
117
118 void BufferRead(volatile uint32_t *ptr) {
119 int j;
120 int size = buffer_size_.width() * buffer_size_.height();
121 int x = 0;
122
123 for (j = 0; j < static_cast<int>(size/sizeof(*ptr)); j++)
124 x += ptr[j];
125
126 /* force overtly clever gcc to actually compute x */
127 ptr[0] = x;
128 }
129
130 void BufferWrite(volatile uint32_t *ptr) {
131 int j;
132 int size = buffer_size_.width() * buffer_size_.height();
133
134 for (j = 0; j < static_cast<int>(size/sizeof(*ptr)); j++)
135 ptr[j] = j;
136 }
137
138 void PrintTestGpuMemoryBuffer(std::string name) {
139 // Sometimes the first runs have worse performance so it might be useful to
140 // print out the standard deviation as well to capture this discrepancy.
141 perf_test::PrintResult(
142 "gpu_memory_buffer_time_",
143 GpuMemoryBufferTypeName(handle_.type),
144 name,
145 total_time_ / static_cast<double>(kNumRuns),
146 "us/task",
147 true);
148 }
149 double total_time_;
150
151 private:
152 int buffer_count_;
153 gfx::Size buffer_size_;
154 gfx::GpuMemoryBufferHandle handle_;
155 scoped_ptr<GpuMemoryBufferImpl> buffer_;
156 scoped_ptr<GpuMemoryBufferFactory> factory_;
157 };
158
159 TEST_P(GpuMemoryBufferPerfTest, MapUnmap) {
160 scoped_ptr<void*[]> mapped_buffers(new void*[0]);
161
162 CreateTestGpuMemoryBuffer();
163
164 base::TimeTicks start = base::TimeTicks::Now();
165 for (int i = 0; i < kNumRuns; ++i) {
166 BufferMap(mapped_buffers);
167 BufferUnmap();
168 }
169 total_time_ +=
170 static_cast<size_t>((base::TimeTicks::Now() - start).InMicroseconds());
171
172 DestroyTestGpuMemoryBuffer();
173 PrintTestGpuMemoryBuffer("map & unmap ");
174 }
175
176 TEST_P(GpuMemoryBufferPerfTest, Read) {
177 scoped_ptr<void*[]> mapped_buffers(new void*[0]);
178
179 CreateTestGpuMemoryBuffer();
180
181 base::TimeTicks start = base::TimeTicks::Now();
182 for (int i = 0; i < kNumRuns; ++i) {
183 BufferMap(mapped_buffers);
184 BufferRead(static_cast<uint32_t*>(mapped_buffers[0]));
185 BufferUnmap();
186 }
187 total_time_ +=
188 static_cast<size_t>((base::TimeTicks::Now() - start).InMicroseconds());
189
190 DestroyTestGpuMemoryBuffer();
191 PrintTestGpuMemoryBuffer("read ");
192 }
193
194 TEST_P(GpuMemoryBufferPerfTest, Write) {
195 scoped_ptr<void*[]> mapped_buffers(new void*[0]);
196
197 CreateTestGpuMemoryBuffer();
198
199 base::TimeTicks start = base::TimeTicks::Now();
200 for (int i = 0; i < kNumRuns; ++i) {
201 BufferMap(mapped_buffers);
202 BufferWrite(static_cast<uint32_t*>(mapped_buffers[0]));
203 BufferUnmap();
204 }
205 total_time_ +=
206 static_cast<size_t>((base::TimeTicks::Now() - start).InMicroseconds());
207
208 DestroyTestGpuMemoryBuffer();
209 PrintTestGpuMemoryBuffer("write ");
210 }
211
212 // TODO: description
213 TEST_P(GpuMemoryBufferPerfTest, ReadWrite) {
214 scoped_ptr<void*[]> mapped_buffers(new void*[0]);
215
216 CreateTestGpuMemoryBuffer();
217
218 base::TimeTicks start = base::TimeTicks::Now();
219 for (int i = 0; i < kNumRuns; ++i) {
220 BufferMap(mapped_buffers);
221 BufferRead(static_cast<uint32_t*>(mapped_buffers[0]));
222 BufferWrite(static_cast<uint32_t*>(mapped_buffers[0]));
223 BufferUnmap();
224 }
225 total_time_ +=
226 static_cast<size_t>((base::TimeTicks::Now() - start).InMicroseconds());
227
228 DestroyTestGpuMemoryBuffer();
229 PrintTestGpuMemoryBuffer("read & write ");
230 }
231
232 std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() {
233 std::vector<gfx::GpuMemoryBufferType> supported_types;
234 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
235 return supported_types;
236 }
237
238 INSTANTIATE_TEST_CASE_P(
239 GpuMemoryBufferPerfTests,
240 GpuMemoryBufferPerfTest,
241 ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes()));
242 } // namespace
243 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698