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

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

Issue 1011343005: Revert of gpu: Measure texture uploads with glTexSubImage2D and glTexImage2D. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.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 | « no previous file | no next file » | 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"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "gpu/perftests/measurements.h" 13 #include "gpu/perftests/measurements.h"
14 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/perf/perf_test.h" 16 #include "testing/perf/perf_test.h"
17 #include "ui/gfx/geometry/size.h" 17 #include "ui/gfx/geometry/size.h"
18 #include "ui/gfx/geometry/vector2d_f.h" 18 #include "ui/gfx/geometry/vector2d_f.h"
19 #include "ui/gl/gl_bindings.h" 19 #include "ui/gl/gl_bindings.h"
20 #include "ui/gl/gl_context.h" 20 #include "ui/gl/gl_context.h"
21 #include "ui/gl/gl_enums.h" 21 #include "ui/gl/gl_enums.h"
22 #include "ui/gl/gl_surface.h" 22 #include "ui/gl/gl_surface.h"
23 #include "ui/gl/gl_version_info.h"
24 #include "ui/gl/gpu_timing.h" 23 #include "ui/gl/gpu_timing.h"
25 #include "ui/gl/scoped_make_current.h" 24 #include "ui/gl/scoped_make_current.h"
26 25
27 namespace gpu { 26 namespace gpu {
28 namespace { 27 namespace {
29 28
30 const int kUploadPerfWarmupRuns = 5; 29 const int kUploadPerfWarmupRuns = 10;
31 const int kUploadPerfTestRuns = 30; 30 const int kUploadPerfTestRuns = 100;
32 31
33 #define SHADER(Src) #Src 32 #define SHADER(Src) #Src
34 33
35 // clang-format off 34 // clang-format off
36 const char kVertexShader[] = 35 const char kVertexShader[] =
37 SHADER( 36 SHADER(
38 uniform vec2 translation; 37 uniform vec2 translation;
39 attribute vec2 a_position; 38 attribute vec2 a_position;
40 attribute vec2 a_texCoord; 39 attribute vec2 a_texCoord;
41 varying vec2 v_texCoord; 40 varying vec2 v_texCoord;
(...skipping 10 matching lines...) Expand all
52 const char kFragmentShader[] = 51 const char kFragmentShader[] =
53 SHADER( 52 SHADER(
54 uniform sampler2D a_texture; 53 uniform sampler2D a_texture;
55 varying vec2 v_texCoord; 54 varying vec2 v_texCoord;
56 void main() { 55 void main() {
57 gl_FragColor = texture2D(a_texture, v_texCoord); 56 gl_FragColor = texture2D(a_texture, v_texCoord);
58 } 57 }
59 ); 58 );
60 // clang-format on 59 // clang-format on
61 60
62 void CheckNoGlError(const std::string& msg) { 61 void CheckNoGlError() {
63 CHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()) << " " << msg; 62 CHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
64 } 63 }
65 64
66 // Utility function to compile a shader from a string. 65 // Utility function to compile a shader from a string.
67 GLuint LoadShader(const GLenum type, const char* const src) { 66 GLuint LoadShader(const GLenum type, const char* const src) {
68 GLuint shader = 0; 67 GLuint shader = 0;
69 shader = glCreateShader(type); 68 shader = glCreateShader(type);
70 CHECK_NE(0u, shader); 69 CHECK_NE(0u, shader);
71 glShaderSource(shader, 1, &src, NULL); 70 glShaderSource(shader, 1, &src, NULL);
72 glCompileShader(shader); 71 glCompileShader(shader);
73 72
(...skipping 10 matching lines...) Expand all
84 } 83 }
85 CHECK_NE(0, compiled); 84 CHECK_NE(0, compiled);
86 return shader; 85 return shader;
87 } 86 }
88 87
89 int GLFormatBytePerPixel(GLenum format) { 88 int GLFormatBytePerPixel(GLenum format) {
90 DCHECK(format == GL_RGBA || format == GL_LUMINANCE || format == GL_RED_EXT); 89 DCHECK(format == GL_RGBA || format == GL_LUMINANCE || format == GL_RED_EXT);
91 return format == GL_RGBA ? 4 : 1; 90 return format == GL_RGBA ? 4 : 1;
92 } 91 }
93 92
94 GLenum GLFormatToStorageFormat(GLenum format) {
95 switch (format) {
96 case GL_RGBA:
97 return GL_RGBA8;
98 case GL_LUMINANCE:
99 return GL_LUMINANCE8;
100 case GL_RED_EXT:
101 return GL_R8;
102 default:
103 NOTREACHED();
104 }
105 return 0;
106 }
107
108 void GenerateTextureData(const gfx::Size& size, 93 void GenerateTextureData(const gfx::Size& size,
109 int bytes_per_pixel, 94 int bytes_per_pixel,
110 const int seed, 95 const int seed,
111 std::vector<uint8>* const pixels) { 96 std::vector<uint8>* const pixels) {
112 // Row bytes has to be multiple of 4 (GL_PACK_ALIGNMENT defaults to 4). 97 // Row bytes has to be multiple of 4 (GL_PACK_ALIGNMENT defaults to 4).
113 int stride = ((size.width() * bytes_per_pixel) + 3) & ~0x3; 98 int stride = ((size.width() * bytes_per_pixel) + 3) & ~0x3;
114 pixels->resize(size.height() * stride); 99 pixels->resize(size.height() * stride);
115 for (int y = 0; y < size.height(); ++y) { 100 for (int y = 0; y < size.height(); ++y) {
116 for (int x = 0; x < size.width(); ++x) { 101 for (int x = 0; x < size.width(); ++x) {
117 for (int channel = 0; channel < bytes_per_pixel; ++channel) { 102 for (int channel = 0; channel < bytes_per_pixel; ++channel) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 220
236 glGenBuffersARB(1, &vertex_buffer_); 221 glGenBuffersARB(1, &vertex_buffer_);
237 CHECK_NE(0u, vertex_buffer_); 222 CHECK_NE(0u, vertex_buffer_);
238 DCHECK_NE(0u, vertex_buffer_); 223 DCHECK_NE(0u, vertex_buffer_);
239 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); 224 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
240 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0); 225 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
241 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 226 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4,
242 reinterpret_cast<void*>(sizeof(GLfloat) * 2)); 227 reinterpret_cast<void*>(sizeof(GLfloat) * 2));
243 glEnableVertexAttribArray(0); 228 glEnableVertexAttribArray(0);
244 glEnableVertexAttribArray(1); 229 glEnableVertexAttribArray(1);
245 CheckNoGlError("glEnableVertexAttribArray"); 230 CheckNoGlError();
246
247 has_texture_storage_ =
248 gl_context_->GetVersionInfo()->is_es3 ||
249 gl_context_->HasExtension("GL_EXT_texture_storage") ||
250 gl_context_->HasExtension("GL_ARB_texture_storage");
251 } 231 }
252 232
253 void GenerateVertexBuffer(const gfx::Size& size) { 233 void GenerateVertexBuffer(const gfx::Size& size) {
254 DCHECK_NE(0u, vertex_buffer_); 234 DCHECK_NE(0u, vertex_buffer_);
255 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); 235 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
256 // right and top are in clipspace 236 // right and top are in clipspace
257 float right = -1.f + 2.f * size.width() / fbo_size_.width(); 237 float right = -1.f + 2.f * size.width() / fbo_size_.width();
258 float top = -1.f + 2.f * size.height() / fbo_size_.height(); 238 float top = -1.f + 2.f * size.height() / fbo_size_.height();
259 // Four vertexes, one per line. Each vertex has two components per 239 // Four vertexes, one per line. Each vertex has two components per
260 // position and two per texcoord. 240 // position and two per texcoord.
261 // It represents a quad formed by two triangles if interpreted 241 // It represents a quad formed by two triangles if interpreted
262 // as a tristrip. 242 // as a tristrip.
263 243
264 // clang-format off 244 // clang-format off
265 GLfloat data[16] = { 245 GLfloat data[16] = {
266 -1.f, -1.f, 0.f, 0.f, 246 -1.f, -1.f, 0.f, 0.f,
267 right, -1.f, 1.f, 0.f, 247 right, -1.f, 1.f, 0.f,
268 -1.f, top, 0.f, 1.f, 248 -1.f, top, 0.f, 1.f,
269 right, top, 1.f, 1.f}; 249 right, top, 1.f, 1.f};
270 // clang-format on 250 // clang-format on
271 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 251 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
272 CheckNoGlError("glBufferData"); 252 CheckNoGlError();
273 } 253 }
274 254
275 void TearDown() override { 255 void TearDown() override {
276 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get()); 256 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
277 glDeleteProgram(program_object_); 257 glDeleteProgram(program_object_);
278 glDeleteShader(vertex_shader_); 258 glDeleteShader(vertex_shader_);
279 glDeleteShader(fragment_shader_); 259 glDeleteShader(fragment_shader_);
280 glDeleteBuffersARB(1, &vertex_buffer_); 260 glDeleteBuffersARB(1, &vertex_buffer_);
281 261
282 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 262 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
283 glDeleteFramebuffersEXT(1, &framebuffer_object_); 263 glDeleteFramebuffersEXT(1, &framebuffer_object_);
284 glDeleteTextures(1, &color_texture_); 264 glDeleteTextures(1, &color_texture_);
285 CheckNoGlError("glDeleteTextures"); 265 CheckNoGlError();
286 266
287 gpu_timing_client_ = nullptr; 267 gpu_timing_client_ = nullptr;
288 gl_context_ = nullptr; 268 gl_context_ = nullptr;
289 surface_ = nullptr; 269 surface_ = nullptr;
290 } 270 }
291 271
292 protected: 272 protected:
293 GLuint CreateGLTexture(const GLenum format, 273 GLuint CreateGLTexture() {
294 const gfx::Size& size,
295 const bool specify_storage) {
296 GLuint texture_id = 0; 274 GLuint texture_id = 0;
297 glActiveTexture(GL_TEXTURE0); 275 glActiveTexture(GL_TEXTURE0);
298 glGenTextures(1, &texture_id); 276 glGenTextures(1, &texture_id);
299 glBindTexture(GL_TEXTURE_2D, texture_id); 277 glBindTexture(GL_TEXTURE_2D, texture_id);
300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
304 if (specify_storage) {
305 if (has_texture_storage_) {
306 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GLFormatToStorageFormat(format),
307 size.width(), size.height());
308 CheckNoGlError("glTexStorage2DEXT");
309 } else {
310 glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0,
311 format, GL_UNSIGNED_BYTE, nullptr);
312 CheckNoGlError("glTexImage2D");
313 }
314 }
315 return texture_id; 278 return texture_id;
316 } 279 }
317 280
318 void UploadTexture(GLuint texture_id, 281 void UploadTexture(GLuint texture_id,
319 const gfx::Size& size, 282 const gfx::Size& size,
320 const std::vector<uint8>& pixels, 283 const std::vector<uint8>& pixels,
321 GLenum format, 284 GLenum format) {
322 const bool subimage) { 285 glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0,
323 if (subimage) { 286 format, GL_UNSIGNED_BYTE, &pixels[0]);
324 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.width(), size.height(), 287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
325 format, GL_UNSIGNED_BYTE, &pixels[0]); 288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
326 CheckNoGlError("glTexSubImage2D"); 289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
327 } else { 290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
328 glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, 291 CheckNoGlError();
329 format, GL_UNSIGNED_BYTE, &pixels[0]);
330 CheckNoGlError("glTexImage2D");
331 }
332 } 292 }
333 293
334 // Upload and draw on the offscren surface. 294 // Upload and draw on the offscren surface.
335 // Return a list of pair. Each pair describe a gl operation and the wall 295 // Return a list of pair. Each pair describe a gl operation and the wall
336 // time elapsed in milliseconds. 296 // time elapsed in milliseconds.
337 std::vector<Measurement> UploadAndDraw(GLuint texture_id, 297 std::vector<Measurement> UploadAndDraw(const gfx::Size& size,
338 const gfx::Size& size,
339 const std::vector<uint8>& pixels, 298 const std::vector<uint8>& pixels,
340 const GLenum format, 299 const GLenum format) {
341 const bool subimage) { 300 GLuint texture_id = CreateGLTexture();
342 MeasurementTimers tex_timers(gpu_timing_client_.get()); 301 MeasurementTimers tex_timers(gpu_timing_client_.get());
343 UploadTexture(texture_id, size, pixels, format, subimage); 302 UploadTexture(texture_id, size, pixels, format);
344 tex_timers.Record(); 303 tex_timers.Record();
345 304
346 MeasurementTimers draw_timers(gpu_timing_client_.get()); 305 MeasurementTimers draw_timers(gpu_timing_client_.get());
347 306
348 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 307 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
349 draw_timers.Record(); 308 draw_timers.Record();
350 309
351 MeasurementTimers finish_timers(gpu_timing_client_.get()); 310 MeasurementTimers finish_timers(gpu_timing_client_.get());
352 glFinish(); 311 glFinish();
353 CheckNoGlError("glFinish"); 312 CheckNoGlError();
354 finish_timers.Record(); 313 finish_timers.Record();
355 314
315 glDeleteTextures(1, &texture_id);
316
356 std::vector<uint8> pixels_rendered(size.GetArea() * 4); 317 std::vector<uint8> pixels_rendered(size.GetArea() * 4);
357 glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE, 318 glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE,
358 &pixels_rendered[0]); 319 &pixels_rendered[0]);
359 CheckNoGlError("glReadPixels"); 320 CheckNoGlError();
360 EXPECT_TRUE( 321 EXPECT_TRUE(
361 CompareBufferToRGBABuffer(format, size, pixels, pixels_rendered)) 322 CompareBufferToRGBABuffer(format, size, pixels, pixels_rendered))
362 << "Format is: " << gfx::GLEnums::GetStringEnum(format); 323 << "Format is: " << gfx::GLEnums::GetStringEnum(format);
363 324
364 std::vector<Measurement> measurements; 325 std::vector<Measurement> measurements;
365 bool gpu_timer_errors = 326 bool gpu_timer_errors =
366 gpu_timing_client_->IsAvailable() && 327 gpu_timing_client_->IsAvailable() &&
367 gpu_timing_client_->CheckAndResetTimerErrors(); 328 gpu_timing_client_->CheckAndResetTimerErrors();
368 if (!gpu_timer_errors) { 329 if (!gpu_timer_errors) {
369 measurements.push_back(tex_timers.GetAsMeasurement( 330 measurements.push_back(tex_timers.GetAsMeasurement("teximage2d"));
370 subimage ? "texsubimage2d" : "teximage2d"));
371 measurements.push_back(draw_timers.GetAsMeasurement("drawarrays")); 331 measurements.push_back(draw_timers.GetAsMeasurement("drawarrays"));
372 measurements.push_back(finish_timers.GetAsMeasurement("finish")); 332 measurements.push_back(finish_timers.GetAsMeasurement("finish"));
373 } 333 }
374 return measurements; 334 return measurements;
375 } 335 }
376 336
377 void RunUploadAndDrawMultipleTimes(const gfx::Size& size, 337 void RunUploadAndDrawMultipleTimes(const gfx::Size& size,
378 const GLenum format, 338 const GLenum format) {
379 const bool subimage) {
380 std::vector<uint8> pixels; 339 std::vector<uint8> pixels;
381 base::SmallMap<std::map<std::string, Measurement>> 340 base::SmallMap<std::map<std::string, Measurement>>
382 aggregates; // indexed by name 341 aggregates; // indexed by name
383 int successful_runs = 0; 342 int successful_runs = 0;
384 GLuint texture_id = CreateGLTexture(format, size, subimage);
385 for (int i = 0; i < kUploadPerfWarmupRuns + kUploadPerfTestRuns; ++i) { 343 for (int i = 0; i < kUploadPerfWarmupRuns + kUploadPerfTestRuns; ++i) {
386 GenerateTextureData(size, GLFormatBytePerPixel(format), i + 1, &pixels); 344 GenerateTextureData(size, GLFormatBytePerPixel(format), i + 1, &pixels);
387 auto run = UploadAndDraw(texture_id, size, pixels, format, subimage); 345 auto run = UploadAndDraw(size, pixels, format);
388 if (i < kUploadPerfWarmupRuns || !run.size()) { 346 if (i < kUploadPerfWarmupRuns || !run.size()) {
389 continue; 347 continue;
390 } 348 }
391 successful_runs++; 349 successful_runs++;
392 for (const Measurement& measurement : run) { 350 for (const Measurement& measurement : run) {
393 auto& aggregate = aggregates[measurement.name]; 351 auto& aggregate = aggregates[measurement.name];
394 aggregate.name = measurement.name; 352 aggregate.name = measurement.name;
395 aggregate.Increment(measurement); 353 aggregate.Increment(measurement);
396 } 354 }
397 } 355 }
398 glDeleteTextures(1, &texture_id);
399
400 std::string graph_name = base::StringPrintf( 356 std::string graph_name = base::StringPrintf(
401 "%d_%s", size.width(), gfx::GLEnums::GetStringEnum(format).c_str()); 357 "%d_%s", size.width(), gfx::GLEnums::GetStringEnum(format).c_str());
402 if (subimage) {
403 graph_name += "_sub";
404 }
405
406 if (successful_runs) { 358 if (successful_runs) {
407 for (const auto& entry : aggregates) { 359 for (const auto& entry : aggregates) {
408 const auto m = entry.second.Divide(successful_runs); 360 const auto m = entry.second.Divide(successful_runs);
409 m.PrintResult(graph_name); 361 m.PrintResult(graph_name);
410 } 362 }
411 } 363 }
412 perf_test::PrintResult("sample_runs", "", graph_name, 364 perf_test::PrintResult("sample_runs", "", graph_name,
413 static_cast<size_t>(successful_runs), "laps", true); 365 static_cast<size_t>(successful_runs), "laps", true);
414 } 366 }
415 367
416 const gfx::Size fbo_size_; // for the fbo 368 const gfx::Size fbo_size_; // for the fbo
417 scoped_refptr<gfx::GLContext> gl_context_; 369 scoped_refptr<gfx::GLContext> gl_context_;
418 scoped_refptr<gfx::GLSurface> surface_; 370 scoped_refptr<gfx::GLSurface> surface_;
419 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_; 371 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
420 372
421 GLuint color_texture_ = 0; 373 GLuint color_texture_ = 0;
422 GLuint framebuffer_object_ = 0; 374 GLuint framebuffer_object_ = 0;
423 GLuint vertex_shader_ = 0; 375 GLuint vertex_shader_ = 0;
424 GLuint fragment_shader_ = 0; 376 GLuint fragment_shader_ = 0;
425 GLuint program_object_ = 0; 377 GLuint program_object_ = 0;
426 GLint sampler_location_ = -1; 378 GLint sampler_location_ = -1;
427 GLint translation_location_ = -1; 379 GLint translation_location_ = -1;
428 GLuint vertex_buffer_ = 0; 380 GLuint vertex_buffer_ = 0;
429
430 bool has_texture_storage_ = false;
431 }; 381 };
432 382
433 // Perf test that generates, uploads and draws a texture on a surface repeatedly 383 // Perf test that generates, uploads and draws a texture on a surface repeatedly
434 // and prints out aggregated measurements for all the runs. 384 // and prints out aggregated measurements for all the runs.
435 TEST_F(TextureUploadPerfTest, upload) { 385 TEST_F(TextureUploadPerfTest, glTexImage2d) {
436 int sizes[] = {21, 128, 256, 512, 1024}; 386 int sizes[] = {21, 128, 256, 512, 1024};
437 std::vector<GLenum> formats; 387 std::vector<GLenum> formats;
438 formats.push_back(GL_RGBA); 388 formats.push_back(GL_RGBA);
439 // Used by default for ResourceProvider::yuv_resource_format_. 389 // Used by default for ResourceProvider::yuv_resource_format_.
440 formats.push_back(GL_LUMINANCE); 390 formats.push_back(GL_LUMINANCE);
441 391
442 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get()); 392 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
443 const bool has_texture_rg = gl_context_->HasExtension("GL_EXT_texture_rg") || 393 bool has_texture_rg = gl_context_->HasExtension("GL_EXT_texture_rg") ||
444 gl_context_->HasExtension("GL_ARB_texture_rg"); 394 gl_context_->HasExtension("GL_ARB_texture_rg");
445 395
446 if (has_texture_rg) { 396 if (has_texture_rg) {
447 // Used as ResourceProvider::yuv_resource_format_ if 397 // Used as ResourceProvider::yuv_resource_format_ if
448 // {ARB,EXT}_texture_rg are available. 398 // {ARB,EXT}_texture_rg are available.
449 formats.push_back(GL_RED_EXT); 399 formats.push_back(GL_RED_EXT);
450 } 400 }
451
452 for (int side : sizes) { 401 for (int side : sizes) {
453 ASSERT_GE(fbo_size_.width(), side); 402 ASSERT_GE(fbo_size_.width(), side);
454 ASSERT_GE(fbo_size_.height(), side); 403 ASSERT_GE(fbo_size_.height(), side);
455 gfx::Size size(side, side); 404 gfx::Size size(side, side);
456 GenerateVertexBuffer(size); 405 GenerateVertexBuffer(size);
457 for (GLenum format : formats) { 406 for (GLenum format : formats) {
458 RunUploadAndDrawMultipleTimes(size, format, true); // use glTexSubImage2D 407 RunUploadAndDrawMultipleTimes(size, format);
459 RunUploadAndDrawMultipleTimes(size, format, false); // use glTexImage2D
460 } 408 }
461 } 409 }
462 } 410 }
463 411
464 // Perf test to check if the driver is doing texture renaming. 412 // Perf test to check if the driver is doing texture renaming.
465 // This test creates one GL texture_id and four different images. For 413 // This test creates one GL texture_id and four different images. For
466 // every image it uploads it using texture_id and it draws multiple 414 // every image it uploads it using texture_id and it draws multiple
467 // times. The cpu/wall time and the gpu time for all the uploads and 415 // times. The cpu/wall time and the gpu time for all the uploads and
468 // draws, but before glFinish, is computed and is printed out at the end as 416 // draws, but before glFinish, is computed and is printed out at the end as
469 // "upload_and_draw". If the gpu time is >> than the cpu/wall time we expect the 417 // "upload_and_draw". If the gpu time is >> than the cpu/wall time we expect the
470 // driver to do texture renaming: this means that while the gpu is drawing using 418 // driver to do texture renaming: this means that while the gpu is drawing using
471 // texture_id it didn't block cpu side the texture upload using the same 419 // texture_id it didn't block cpu side the texture upload using the same
472 // texture_id. 420 // texture_id.
473 TEST_F(TextureUploadPerfTest, renaming) { 421 TEST_F(TextureUploadPerfTest, renaming) {
474 gfx::Size texture_size(fbo_size_.width() / 2, fbo_size_.height() / 2); 422 gfx::Size texture_size(fbo_size_.width() / 2, fbo_size_.height() / 2);
475 423
476 std::vector<uint8> pixels[4]; 424 std::vector<uint8> pixels[4];
477 for (int i = 0; i < 4; ++i) { 425 for (int i = 0; i < 4; ++i) {
478 GenerateTextureData(texture_size, 4, i + 1, &pixels[i]); 426 GenerateTextureData(texture_size, 4, i + 1, &pixels[i]);
479 } 427 }
480 428
481 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get()); 429 ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
482 GenerateVertexBuffer(texture_size); 430 GenerateVertexBuffer(texture_size);
483 431
484 gfx::Vector2dF positions[] = {gfx::Vector2dF(0.f, 0.f), 432 gfx::Vector2dF positions[] = {gfx::Vector2dF(0.f, 0.f),
485 gfx::Vector2dF(1.f, 0.f), 433 gfx::Vector2dF(1.f, 0.f),
486 gfx::Vector2dF(0.f, 1.f), 434 gfx::Vector2dF(0.f, 1.f),
487 gfx::Vector2dF(1.f, 1.f)}; 435 gfx::Vector2dF(1.f, 1.f)};
488 GLuint texture_id = CreateGLTexture(GL_RGBA, texture_size, true); 436 GLuint texture_id = CreateGLTexture();
489 437
490 MeasurementTimers upload_and_draw_timers(gpu_timing_client_.get()); 438 MeasurementTimers upload_and_draw_timers(gpu_timing_client_.get());
491 439
492 for (int i = 0; i < 4; ++i) { 440 for (int i = 0; i < 4; ++i) {
493 UploadTexture(texture_id, texture_size, pixels[i % 4], GL_RGBA, true); 441 UploadTexture(texture_id, texture_size, pixels[i % 4], GL_RGBA);
494 DCHECK_NE(-1, translation_location_); 442 DCHECK_NE(-1, translation_location_);
495 glUniform2f(translation_location_, positions[i % 4].x(), 443 glUniform2f(translation_location_, positions[i % 4].x(),
496 positions[i % 4].y()); 444 positions[i % 4].y());
497 // Draw the same quad multiple times to make sure that the time spent on the 445 // Draw the same quad multiple times to make sure that the time spent on the
498 // gpu is more than the cpu time. 446 // gpu is more than the cpu time.
499 for (int draw = 0; draw < 128; ++draw) { 447 for (int draw = 0; draw < 128; ++draw) {
500 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 448 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
501 } 449 }
502 } 450 }
503 451
504 upload_and_draw_timers.Record(); 452 upload_and_draw_timers.Record();
505 MeasurementTimers finish_timers(gpu_timing_client_.get()); 453 MeasurementTimers finish_timers(gpu_timing_client_.get());
506 glFinish(); 454 glFinish();
507 CheckNoGlError("glFinish"); 455 CheckNoGlError();
508 finish_timers.Record(); 456 finish_timers.Record();
509 457
510 glDeleteTextures(1, &texture_id); 458 glDeleteTextures(1, &texture_id);
511 459
512 for (int i = 0; i < 4; ++i) { 460 for (int i = 0; i < 4; ++i) {
513 std::vector<uint8> pixels_rendered(texture_size.GetArea() * 4); 461 std::vector<uint8> pixels_rendered(texture_size.GetArea() * 4);
514 glReadPixels(texture_size.width() * positions[i].x(), 462 glReadPixels(texture_size.width() * positions[i].x(),
515 texture_size.height() * positions[i].y(), texture_size.width(), 463 texture_size.height() * positions[i].y(), texture_size.width(),
516 texture_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, 464 texture_size.height(), GL_RGBA, GL_UNSIGNED_BYTE,
517 &pixels_rendered[0]); 465 &pixels_rendered[0]);
518 CheckNoGlError("glReadPixels"); 466 CheckNoGlError();
519 ASSERT_EQ(pixels[i].size(), pixels_rendered.size()); 467 ASSERT_EQ(pixels[i].size(), pixels_rendered.size());
520 EXPECT_EQ(pixels[i], pixels_rendered); 468 EXPECT_EQ(pixels[i], pixels_rendered);
521 } 469 }
522 470
523 bool gpu_timer_errors = gpu_timing_client_->IsAvailable() && 471 bool gpu_timer_errors = gpu_timing_client_->IsAvailable() &&
524 gpu_timing_client_->CheckAndResetTimerErrors(); 472 gpu_timing_client_->CheckAndResetTimerErrors();
525 if (!gpu_timer_errors) { 473 if (!gpu_timer_errors) {
526 upload_and_draw_timers.GetAsMeasurement("upload_and_draw") 474 upload_and_draw_timers.GetAsMeasurement("upload_and_draw")
527 .PrintResult("renaming"); 475 .PrintResult("renaming");
528 finish_timers.GetAsMeasurement("finish").PrintResult("renaming"); 476 finish_timers.GetAsMeasurement("finish").PrintResult("renaming");
529 } 477 }
530 } 478 }
531 479
532 } // namespace 480 } // namespace
533 } // namespace gpu 481 } // namespace gpu
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698