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

Side by Side Diff: gpu/perftests/texture_upload_perftest.cc

Issue 1013463003: Update from https://crrev.com/320931 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 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 | « gpu/perftests/measurements.cc ('k') | mojo/tools/roll/cc_strip_video.patch » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/containers/small_map.h" 8 #include "base/containers/small_map.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
(...skipping 16 matching lines...) Expand all
27 namespace { 27 namespace {
28 28
29 const int kUploadPerfWarmupRuns = 10; 29 const int kUploadPerfWarmupRuns = 10;
30 const int kUploadPerfTestRuns = 100; 30 const int kUploadPerfTestRuns = 100;
31 31
32 #define SHADER(Src) #Src 32 #define SHADER(Src) #Src
33 33
34 // clang-format off 34 // clang-format off
35 const char kVertexShader[] = 35 const char kVertexShader[] =
36 SHADER( 36 SHADER(
37 uniform vec2 translation = vec2(0.0, 0.0); 37 uniform vec2 translation;
38 attribute vec2 a_position; 38 attribute vec2 a_position;
39 attribute vec2 a_texCoord; 39 attribute vec2 a_texCoord;
40 varying vec2 v_texCoord; 40 varying vec2 v_texCoord;
41 void main() { 41 void main() {
42 gl_Position = vec4( 42 gl_Position = vec4(
43 translation.x + a_position.x, translation.y + a_position.y, 0.0, 1.0); 43 translation.x + a_position.x, translation.y + a_position.y, 0.0, 1.0);
44 v_texCoord = a_texCoord; 44 v_texCoord = a_texCoord;
45 } 45 }
46 ); 46 );
47 const char kFragmentShader[] = 47 const char kFragmentShader[] =
48 SHADER( 48 SHADER(
49 precision mediump float;
49 uniform sampler2D a_texture; 50 uniform sampler2D a_texture;
50 varying vec2 v_texCoord; 51 varying vec2 v_texCoord;
51 void main() { 52 void main() {
52 gl_FragColor = texture2D(a_texture, v_texCoord); 53 gl_FragColor = texture2D(a_texture, v_texCoord);
53 } 54 }
54 ); 55 );
55 // clang-format on 56 // clang-format on
56 57
57 void CheckNoGlError() { 58 void CheckNoGlError() {
58 CHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 59 CHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
(...skipping 15 matching lines...) Expand all
74 if (len > 1) { 75 if (len > 1) {
75 scoped_ptr<char> error_log(new char[len]); 76 scoped_ptr<char> error_log(new char[len]);
76 glGetShaderInfoLog(shader, len, NULL, error_log.get()); 77 glGetShaderInfoLog(shader, len, NULL, error_log.get());
77 LOG(ERROR) << "Error compiling shader: " << error_log.get(); 78 LOG(ERROR) << "Error compiling shader: " << error_log.get();
78 } 79 }
79 } 80 }
80 CHECK_NE(0, compiled); 81 CHECK_NE(0, compiled);
81 return shader; 82 return shader;
82 } 83 }
83 84
85 int GLFormatBytePerPixel(GLenum format) {
86 DCHECK(format == GL_RGBA || format == GL_LUMINANCE || format == GL_RED_EXT);
87 return format == GL_RGBA ? 4 : 1;
88 }
89
84 void GenerateTextureData(const gfx::Size& size, 90 void GenerateTextureData(const gfx::Size& size,
85 int bytes_per_pixel, 91 int bytes_per_pixel,
86 const int seed, 92 const int seed,
87 std::vector<uint8>* const pixels) { 93 std::vector<uint8>* const pixels) {
88 int bytes = size.GetArea() * bytes_per_pixel; 94 // Row bytes has to be multiple of 4 (GL_PACK_ALIGNMENT defaults to 4).
89 pixels->resize(bytes); 95 int stride = ((size.width() * bytes_per_pixel) + 3) & ~0x3;
90 for (int i = 0; i < bytes; ++i) { 96 pixels->resize(size.height() * stride);
91 int channel = i % bytes_per_pixel; 97 for (int y = 0; y < size.height(); ++y) {
92 if (channel == 3) { // Alpha channel. 98 for (int x = 0; x < size.width(); ++x) {
93 pixels->at(i) = 255; 99 for (int channel = 0; channel < bytes_per_pixel; ++channel) {
94 } else { 100 int index = y * stride + x * bytes_per_pixel;
95 pixels->at(i) = (i + (seed << 2)) % (32 << channel); 101 pixels->at(index) = (index + (seed << 2)) % (0x20 << channel);
102 }
96 } 103 }
97 } 104 }
98 } 105 }
99 106
100 // Compare a buffer containing pixels in a specified format to GL_RGBA buffer 107 // Compare a buffer containing pixels in a specified format to GL_RGBA buffer
101 // where the former buffer have been uploaded as a texture and drawn on the 108 // where the former buffer have been uploaded as a texture and drawn on the
102 // RGBA buffer. 109 // RGBA buffer.
103 bool CompareBufferToRGBABuffer(GLenum format, 110 bool CompareBufferToRGBABuffer(GLenum format,
111 const gfx::Size& size,
104 const std::vector<uint8>& pixels, 112 const std::vector<uint8>& pixels,
105 const std::vector<uint8>& pixels_rgba) { 113 const std::vector<uint8>& rgba) {
106 for (size_t i = 0; i < pixels.size(); i += 4) { 114 int bytes_per_pixel = GLFormatBytePerPixel(format);
107 switch (format) { 115 int pixels_stride = ((size.width() * bytes_per_pixel) + 3) & ~0x3;
108 case GL_RED_EXT: // (R_t, 0, 0, 1) 116 int rgba_stride = size.width() * GLFormatBytePerPixel(GL_RGBA);
109 if (pixels_rgba[i] != pixels[i / 4] || pixels_rgba[i + 1] != 0 || 117 for (int y = 0; y < size.height(); ++y) {
110 pixels_rgba[i + 2] != 0 || pixels_rgba[i + 3] != 255) { 118 for (int x = 0; x < size.width(); ++x) {
111 return false; 119 int rgba_index = y * rgba_stride + x * GLFormatBytePerPixel(GL_RGBA);
112 } 120 int pixels_index = y * pixels_stride + x * bytes_per_pixel;
113 break; 121 uint8 expected[4] = {0};
114 case GL_LUMINANCE: // (L_t, L_t, L_t, 1) 122 switch (format) {
115 if (pixels_rgba[i] != pixels[i / 4] || 123 case GL_LUMINANCE: // (L_t, L_t, L_t, 1)
116 pixels_rgba[i + 1] != pixels[i / 4] || 124 expected[1] = pixels[pixels_index];
117 pixels_rgba[i + 2] != pixels[i / 4] || pixels_rgba[i + 3] != 255) { 125 expected[2] = pixels[pixels_index];
118 return false; 126 case GL_RED_EXT: // (R_t, 0, 0, 1)n
119 } 127 expected[0] = pixels[pixels_index];
120 break; 128 expected[3] = 255;
121 case GL_RGBA: // (R_t, G_t, B_t, A_t) 129 break;
122 if (pixels_rgba[i] != pixels[i] || 130 case GL_RGBA: // (R_t, G_t, B_t, A_t)
123 pixels_rgba[i + 1] != pixels[i + 1] || 131 memcpy(expected, &pixels[pixels_index], 4);
124 pixels_rgba[i + 2] != pixels[i + 2] || 132 break;
125 pixels_rgba[i + 3] != pixels[i + 3]) { 133 default:
126 return false; 134 NOTREACHED();
127 } 135 }
128 break; 136 if (memcmp(&rgba[rgba_index], expected, 4)) {
129 default: 137 return false;
130 NOTREACHED(); 138 }
131 } 139 }
132 } 140 }
133 return true; 141 return true;
134 } 142 }
135 143
136 // PerfTest to check costs of texture upload at different stages 144 // PerfTest to check costs of texture upload at different stages
137 // on different platforms. 145 // on different platforms.
138 class TextureUploadPerfTest : public testing::Test { 146 class TextureUploadPerfTest : public testing::Test {
139 public: 147 public:
140 TextureUploadPerfTest() : fbo_size_(1024, 1024) {} 148 TextureUploadPerfTest() : fbo_size_(1024, 1024) {}
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 fragment_shader_ = LoadShader(GL_FRAGMENT_SHADER, kFragmentShader); 190 fragment_shader_ = LoadShader(GL_FRAGMENT_SHADER, kFragmentShader);
183 program_object_ = glCreateProgram(); 191 program_object_ = glCreateProgram();
184 CHECK_NE(0u, program_object_); 192 CHECK_NE(0u, program_object_);
185 193
186 glAttachShader(program_object_, vertex_shader_); 194 glAttachShader(program_object_, vertex_shader_);
187 glAttachShader(program_object_, fragment_shader_); 195 glAttachShader(program_object_, fragment_shader_);
188 glBindAttribLocation(program_object_, 0, "a_position"); 196 glBindAttribLocation(program_object_, 0, "a_position");
189 glBindAttribLocation(program_object_, 1, "a_texCoord"); 197 glBindAttribLocation(program_object_, 1, "a_texCoord");
190 glLinkProgram(program_object_); 198 glLinkProgram(program_object_);
191 199
192 translation_location_ =
193 glGetUniformLocation(program_object_, "translation");
194 DCHECK_NE(-1, translation_location_);
195
196 GLint linked = -1; 200 GLint linked = -1;
197 glGetProgramiv(program_object_, GL_LINK_STATUS, &linked); 201 glGetProgramiv(program_object_, GL_LINK_STATUS, &linked);
198 CHECK_NE(0, linked); 202 CHECK_NE(0, linked);
199 glUseProgram(program_object_); 203 glUseProgram(program_object_);
200 glUniform1i(sampler_location_, 0); 204 glUniform1i(sampler_location_, 0);
205 translation_location_ =
206 glGetUniformLocation(program_object_, "translation");
207 DCHECK_NE(-1, translation_location_);
208 glUniform2f(translation_location_, 0.0f, 0.0f);
201 209
202 sampler_location_ = glGetUniformLocation(program_object_, "a_texture"); 210 sampler_location_ = glGetUniformLocation(program_object_, "a_texture");
203 CHECK_NE(-1, sampler_location_); 211 CHECK_NE(-1, sampler_location_);
204 212
205 glGenBuffersARB(1, &vertex_buffer_); 213 glGenBuffersARB(1, &vertex_buffer_);
206 CHECK_NE(0u, vertex_buffer_); 214 CHECK_NE(0u, vertex_buffer_);
207 DCHECK_NE(0u, vertex_buffer_); 215 DCHECK_NE(0u, vertex_buffer_);
208 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); 216 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
209 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0); 217 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
210 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 218 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 glFinish(); 303 glFinish();
296 CheckNoGlError(); 304 CheckNoGlError();
297 finish_timers.Record(); 305 finish_timers.Record();
298 306
299 glDeleteTextures(1, &texture_id); 307 glDeleteTextures(1, &texture_id);
300 308
301 std::vector<uint8> pixels_rendered(size.GetArea() * 4); 309 std::vector<uint8> pixels_rendered(size.GetArea() * 4);
302 glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE, 310 glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE,
303 &pixels_rendered[0]); 311 &pixels_rendered[0]);
304 CheckNoGlError(); 312 CheckNoGlError();
305 EXPECT_TRUE(CompareBufferToRGBABuffer(format, pixels, pixels_rendered)) 313 EXPECT_TRUE(
314 CompareBufferToRGBABuffer(format, size, pixels, pixels_rendered))
306 << "Format is: " << gfx::GLEnums::GetStringEnum(format); 315 << "Format is: " << gfx::GLEnums::GetStringEnum(format);
307 316
308 std::vector<Measurement> measurements; 317 std::vector<Measurement> measurements;
309 bool gpu_timer_errors = 318 bool gpu_timer_errors =
310 gpu_timing_client_->IsAvailable() && 319 gpu_timing_client_->IsAvailable() &&
311 gpu_timing_client_->CheckAndResetTimerErrors(); 320 gpu_timing_client_->CheckAndResetTimerErrors();
312 if (!gpu_timer_errors) { 321 if (!gpu_timer_errors) {
313 measurements.push_back(tex_timers.GetAsMeasurement("teximage2d")); 322 measurements.push_back(tex_timers.GetAsMeasurement("teximage2d"));
314 measurements.push_back(draw_timers.GetAsMeasurement("drawarrays")); 323 measurements.push_back(draw_timers.GetAsMeasurement("drawarrays"));
315 measurements.push_back(finish_timers.GetAsMeasurement("finish")); 324 measurements.push_back(finish_timers.GetAsMeasurement("finish"));
316 } 325 }
317 return measurements; 326 return measurements;
318 } 327 }
319 328
320 void RunUploadAndDrawMultipleTimes(const gfx::Size& size, 329 void RunUploadAndDrawMultipleTimes(const gfx::Size& size,
321 const GLenum format) { 330 const GLenum format) {
322 std::vector<uint8> pixels; 331 std::vector<uint8> pixels;
323 base::SmallMap<std::map<std::string, Measurement>> 332 base::SmallMap<std::map<std::string, Measurement>>
324 aggregates; // indexed by name 333 aggregates; // indexed by name
325 int successful_runs = 0; 334 int successful_runs = 0;
326 ASSERT_THAT(format, testing::AnyOf(GL_RGBA, GL_LUMINANCE, GL_RED_EXT));
327 for (int i = 0; i < kUploadPerfWarmupRuns + kUploadPerfTestRuns; ++i) { 335 for (int i = 0; i < kUploadPerfWarmupRuns + kUploadPerfTestRuns; ++i) {
328 GenerateTextureData(size, format == GL_RGBA ? 4 : 1, i + 1, &pixels); 336 GenerateTextureData(size, GLFormatBytePerPixel(format), i + 1, &pixels);
329 auto run = UploadAndDraw(size, pixels, format); 337 auto run = UploadAndDraw(size, pixels, format);
330 if (i < kUploadPerfWarmupRuns || !run.size()) { 338 if (i < kUploadPerfWarmupRuns || !run.size()) {
331 continue; 339 continue;
332 } 340 }
333 successful_runs++; 341 successful_runs++;
334 for (const Measurement& measurement : run) { 342 for (const Measurement& measurement : run) {
335 auto& aggregate = aggregates[measurement.name]; 343 auto& aggregate = aggregates[measurement.name];
336 aggregate.name = measurement.name; 344 aggregate.name = measurement.name;
337 aggregate.Increment(measurement); 345 aggregate.Increment(measurement);
338 } 346 }
339 } 347 }
340 std::string suffix = base::StringPrintf( 348 std::string graph_name = base::StringPrintf(
341 "_%d_%s", size.width(), gfx::GLEnums::GetStringEnum(format).c_str()); 349 "%d_%s", size.width(), gfx::GLEnums::GetStringEnum(format).c_str());
342 if (successful_runs) { 350 if (successful_runs) {
343 for (const auto& entry : aggregates) { 351 for (const auto& entry : aggregates) {
344 const auto m = entry.second.Divide(successful_runs); 352 const auto m = entry.second.Divide(successful_runs);
345 m.PrintResult(suffix); 353 m.PrintResult(graph_name);
346 } 354 }
347 } 355 }
348 perf_test::PrintResult("sample_runs", suffix, "", 356 perf_test::PrintResult("sample_runs", "", graph_name,
349 static_cast<size_t>(successful_runs), "laps", true); 357 static_cast<size_t>(successful_runs), "laps", true);
350 } 358 }
351 359
352 const gfx::Size fbo_size_; // for the fbo 360 const gfx::Size fbo_size_; // for the fbo
353 scoped_refptr<gfx::GLContext> gl_context_; 361 scoped_refptr<gfx::GLContext> gl_context_;
354 scoped_refptr<gfx::GLSurface> surface_; 362 scoped_refptr<gfx::GLSurface> surface_;
355 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_; 363 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
356 364
357 GLuint color_texture_ = 0; 365 GLuint color_texture_ = 0;
358 GLuint framebuffer_object_ = 0; 366 GLuint framebuffer_object_ = 0;
359 GLuint vertex_shader_ = 0; 367 GLuint vertex_shader_ = 0;
360 GLuint fragment_shader_ = 0; 368 GLuint fragment_shader_ = 0;
361 GLuint program_object_ = 0; 369 GLuint program_object_ = 0;
362 GLint sampler_location_ = -1; 370 GLint sampler_location_ = -1;
363 GLint translation_location_ = -1; 371 GLint translation_location_ = -1;
364 GLuint vertex_buffer_ = 0; 372 GLuint vertex_buffer_ = 0;
365 }; 373 };
366 374
367 // Perf test that generates, uploads and draws a texture on a surface repeatedly 375 // Perf test that generates, uploads and draws a texture on a surface repeatedly
368 // and prints out aggregated measurements for all the runs. 376 // and prints out aggregated measurements for all the runs.
369 TEST_F(TextureUploadPerfTest, glTexImage2d) { 377 TEST_F(TextureUploadPerfTest, glTexImage2d) {
370 int sizes[] = {128, 256, 512, 1024}; 378 int sizes[] = {21, 128, 256, 512, 1024};
371 std::vector<GLenum> formats; 379 std::vector<GLenum> formats;
372 formats.push_back(GL_RGBA); 380 formats.push_back(GL_RGBA);
373 // Used by default for ResourceProvider::yuv_resource_format_. 381 // Used by default for ResourceProvider::yuv_resource_format_.
374 formats.push_back(GL_LUMINANCE); 382 formats.push_back(GL_LUMINANCE);
375 383
376 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get()); 384 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
377 bool has_texture_rg = gl_context_->HasExtension("GL_EXT_texture_rg") || 385 bool has_texture_rg = gl_context_->HasExtension("GL_EXT_texture_rg") ||
378 gl_context_->HasExtension("GL_ARB_texture_rg"); 386 gl_context_->HasExtension("GL_ARB_texture_rg");
379 387
380 if (has_texture_rg) { 388 if (has_texture_rg) {
381 // Used as ResourceProvider::yuv_resource_format_ if 389 // Used as ResourceProvider::yuv_resource_format_ if
382 // {ARB,EXT}_texture_rg is available. 390 // {ARB,EXT}_texture_rg are available.
383 formats.push_back(GL_RED_EXT); 391 formats.push_back(GL_RED_EXT);
384 } 392 }
385 for (int side : sizes) { 393 for (int side : sizes) {
386 ASSERT_GE(fbo_size_.width(), side); 394 ASSERT_GE(fbo_size_.width(), side);
387 ASSERT_GE(fbo_size_.height(), side); 395 ASSERT_GE(fbo_size_.height(), side);
388 gfx::Size size(side, side); 396 gfx::Size size(side, side);
389 GenerateVertexBuffer(size); 397 GenerateVertexBuffer(size);
390 for (GLenum format : formats) { 398 for (GLenum format : formats) {
391 RunUploadAndDrawMultipleTimes(size, format); 399 RunUploadAndDrawMultipleTimes(size, format);
392 } 400 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 texture_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, 456 texture_size.height(), GL_RGBA, GL_UNSIGNED_BYTE,
449 &pixels_rendered[0]); 457 &pixels_rendered[0]);
450 CheckNoGlError(); 458 CheckNoGlError();
451 ASSERT_EQ(pixels[i].size(), pixels_rendered.size()); 459 ASSERT_EQ(pixels[i].size(), pixels_rendered.size());
452 EXPECT_EQ(pixels[i], pixels_rendered); 460 EXPECT_EQ(pixels[i], pixels_rendered);
453 } 461 }
454 462
455 bool gpu_timer_errors = gpu_timing_client_->IsAvailable() && 463 bool gpu_timer_errors = gpu_timing_client_->IsAvailable() &&
456 gpu_timing_client_->CheckAndResetTimerErrors(); 464 gpu_timing_client_->CheckAndResetTimerErrors();
457 if (!gpu_timer_errors) { 465 if (!gpu_timer_errors) {
458 upload_and_draw_timers.GetAsMeasurement("upload_and_draw").PrintResult(""); 466 upload_and_draw_timers.GetAsMeasurement("upload_and_draw")
459 finish_timers.GetAsMeasurement("finish").PrintResult(""); 467 .PrintResult("renaming");
468 finish_timers.GetAsMeasurement("finish").PrintResult("renaming");
460 } 469 }
461 } 470 }
462 471
463 } // namespace 472 } // namespace
464 } // namespace gpu 473 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/perftests/measurements.cc ('k') | mojo/tools/roll/cc_strip_video.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698