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

Side by Side Diff: content/child/child_thread_impl_perftest.cc

Issue 1187793006: content: perf tests for GpuMemoryBuffers mapping and data coherency (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add description, move from DRAFT to a real CL 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 the native buffer object (bo) is mapped into
7 // the CPU. In particular this test aims to capture the effects of data
8 // coherency and answer the following:
9 //
10 // - measure memory mapping performance of GpuMemoryBuffer using shared memory
11 // (fallback case) and also native implementation of it.
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 "base/bind.h"
20 #include "base/command_line.h"
21 #include "base/memory/scoped_vector.h"
22 #include "base/time/time.h"
23 #include "content/child/child_gpu_memory_buffer_manager.h"
24 #include "content/child/child_thread_impl.h"
25 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
26 #include "content/public/common/content_switches.h"
27 #include "content/public/test/content_browser_test.h"
28 #include "content/public/test/content_browser_test_utils.h"
29 #include "content/shell/browser/shell.h"
30 #include "testing/perf/perf_test.h"
31 #include "url/gurl.h"
32
33 namespace content {
34 namespace {
35
36 ChildGpuMemoryBufferManager* child_gpu_memory_buffer_manager_ = NULL;
dshwang 2015/06/25 10:52:11 nullptr. why don't BufferPerfTest have this as mem
37
38 static const int kNumRuns = 30;
dshwang 2015/06/25 10:52:11 'static' is not needed because of anonymous namesp
39
40 enum NativeBufferFlag { kDisableNativeBuffers, kEnableNativeBuffers };
41
42 std::string NativeBufferFlagName(NativeBufferFlag flag) {
43 switch (flag) {
44 case kDisableNativeBuffers:
45 return "";
46 case kEnableNativeBuffers:
47 return "_native";
48 }
49
50 NOTREACHED();
51 return "";
52 }
53
54 static NativeBufferFlag native_buffer_flag_;
dshwang 2015/06/25 10:52:11 why don't ChildThreadImplGpuMemoryBufferPerfTest h
55
56 enum MemoryOperation { kMemoryOperationWrite, kMemoryOperationNoop };
dshwang 2015/06/25 10:52:11 unused
57
58 class BufferPerfTest {
59 public:
60 BufferPerfTest ()
61 : gpu_memory_buffer_(nullptr),
62 num_planes_(0),
63 format_(gfx::GpuMemoryBuffer::BGRA_8888),
64 buffer_size_(4, 4) {}
65
66 void Allocate(void) {
67 gpu_memory_buffer_ =
68 child_gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
69 buffer_size_, format_, gfx::GpuMemoryBuffer::MAP);
70 ASSERT_TRUE(gpu_memory_buffer_);
71
72 EXPECT_EQ(format_, gpu_memory_buffer_->GetFormat());
73
74 num_planes_ =
75 GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(format_);
76 }
77
78 void Map(scoped_ptr<void* []> const &planes, std::string operation_name) {
79 std::string flag_name = NativeBufferFlagName(native_buffer_flag_);
80
81 base::TimeTicks start = base::TimeTicks::Now();
82 bool rv = gpu_memory_buffer_->Map(planes.get());
83 base::TimeTicks end = base::TimeTicks::Now();
84 ASSERT_TRUE(rv);
85 EXPECT_TRUE(gpu_memory_buffer_->IsMapped());
86
87 // TODO(vignatti): get the mean time and print to stdout only once. At the
88 // moment it's being useful to check individual runs though cause for
89 // example VGEM has way worse performance on its first runs (got check why).
90 perf_test::PrintResult(
dshwang 2015/06/25 10:52:11 This test measures only Map time even in "time_to_
91 "time_to_execute_map",
92 flag_name,
93 operation_name,
94 static_cast<size_t>((end - start).InMicroseconds()),
95 "us", true);
96 }
97
98 void Unmap(void) {
99 gpu_memory_buffer_->Unmap();
100 EXPECT_FALSE(gpu_memory_buffer_->IsMapped());
101 }
102
103 void Write(scoped_ptr<void* []> const &planes) {
104 // Get stride.
105 scoped_ptr<int[]> strides(new int[num_planes_]);
106 gpu_memory_buffer_->GetStride(strides.get());
107
108 for (size_t plane = 0; plane < num_planes_; ++plane) {
109 size_t row_size_in_bytes = 0;
110 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(buffer_size_.width(),
111 format_, plane, &row_size_in_bytes));
112
113 scoped_ptr<char[]> data(new char[row_size_in_bytes]);
114 memset(data.get(), 0x2a + plane, row_size_in_bytes);
115
116 size_t height = buffer_size_.height() /
117 GpuMemoryBufferImpl::SubsamplingFactor(format_, plane);
118 for (size_t y = 0; y < height; ++y) {
119 // Copy |data| to row |y| of |plane| and verify result.
120 memcpy(static_cast<char*>(planes[plane]) + y * strides[plane],
121 data.get(),
122 row_size_in_bytes);
123 #if defined(NDEBUG)
124 EXPECT_EQ(memcmp(static_cast<char*>(planes[plane]) + y * strides[plane],
125 data.get(), row_size_in_bytes),
126 0);
127 #endif
128 }
129 }
130 }
131
132 size_t GetNumPlanes() { return num_planes_; }
133
134 private:
135 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
136 size_t num_planes_;
137 gfx::GpuMemoryBuffer::Format format_;
138 gfx::Size buffer_size_;
139 };
140
141 class ChildThreadImplBrowserTest : public ContentBrowserTest {
142 public:
143 ChildThreadImplBrowserTest() {}
144
145 // Overridden from BrowserTestBase:
146 void SetUpCommandLine(base::CommandLine* command_line) override {
147 command_line->AppendSwitch(switches::kSingleProcess);
148 }
149 void SetUpOnMainThread() override {
150 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
151 PostTaskToInProcessRendererAndWait(
152 base::Bind(&ChildThreadImplBrowserTest::SetUpOnChildThread, this));
153 }
154
155 private:
156 void SetUpOnChildThread() {
157 child_gpu_memory_buffer_manager_ =
158 ChildThreadImpl::current()->gpu_memory_buffer_manager();
159 }
160
161 };
162
163 class ChildThreadImplGpuMemoryBufferPerfTest
164 : public ChildThreadImplBrowserTest,
165 public testing::WithParamInterface<
166 ::testing::tuple<NativeBufferFlag>> {
167 public:
168 ChildThreadImplGpuMemoryBufferPerfTest() {}
169
170 // Overridden from BrowserTestBase:
171 void SetUpCommandLine(base::CommandLine* command_line) override {
172 ChildThreadImplBrowserTest::SetUpCommandLine(command_line);
173 native_buffer_flag_ = ::testing::get<0>(GetParam());
174 switch (native_buffer_flag_) {
175 case kEnableNativeBuffers:
176 command_line->AppendSwitch(switches::kEnableNativeGpuMemoryBuffers);
177 break;
178 case kDisableNativeBuffers:
179 break;
180 }
181 }
182
183 protected:
184 scoped_ptr<BufferPerfTest> buffer_;
185
186 private:
187 DISALLOW_COPY_AND_ASSIGN(ChildThreadImplGpuMemoryBufferPerfTest);
188 };
189
190 IN_PROC_BROWSER_TEST_P(ChildThreadImplGpuMemoryBufferPerfTest,
191 Write) {
192 buffer_.reset(new BufferPerfTest());
193 buffer_->Allocate();
194
195 scoped_ptr<void* []> planes(new void* [buffer_->GetNumPlanes()]);
196
197 for (int i = 0; i < kNumRuns; ++i) {
198 buffer_->Map(planes, "Write");
199 buffer_->Write(planes);
dshwang 2015/06/25 10:52:11 I think Map and Unmap should be out of 'for block'
200 buffer_->Unmap();
201 }
202 }
203
204 IN_PROC_BROWSER_TEST_P(ChildThreadImplGpuMemoryBufferPerfTest,
205 Map) {
206 buffer_.reset(new BufferPerfTest());
207 buffer_->Allocate();
208
209 scoped_ptr<void* []> planes(new void* [buffer_->GetNumPlanes()]);
210
211 for (int i = 0; i < kNumRuns; ++i) {
212 buffer_->Map(planes, "Map");
213 buffer_->Unmap();
214 }
215 }
216
217 INSTANTIATE_TEST_CASE_P(
218 ChildThreadImplGpuMemoryBufferPerfTests,
219 ChildThreadImplGpuMemoryBufferPerfTest,
220 ::testing::Values(kDisableNativeBuffers, kEnableNativeBuffers));
221 } // namespace
222 } // 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