OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS 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 <fcntl.h> | 5 #include <fcntl.h> |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <sys/mman.h> | 9 #include <sys/mman.h> |
10 | 10 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 } else { | 63 } else { |
64 printf("# %s is too slow, returning zero.\n", name); | 64 printf("# %s is too slow, returning zero.\n", name); |
65 printf("%s: 0\n", name); | 65 printf("%s: 0\n", name); |
66 } | 66 } |
67 } | 67 } |
68 } | 68 } |
69 | 69 |
70 static int arg1 = 0; | 70 static int arg1 = 0; |
71 static void *arg2 = NULL; | 71 static void *arg2 = NULL; |
72 | 72 |
73 | |
74 void SwapTestFunc(int iter) { | 73 void SwapTestFunc(int iter) { |
75 for (int i = 0 ; i < iter; ++i) { | 74 for (int i = 0 ; i < iter; ++i) { |
76 SwapBuffers(); | 75 SwapBuffers(); |
77 } | 76 } |
78 } | 77 } |
79 | 78 |
80 void SwapTest() { | 79 void SwapTest() { |
81 RunTest(SwapTestFunc, "us_swap_swap", 1.f, false); | 80 RunTest(SwapTestFunc, "us_swap_swap", 1.f, false); |
82 } | 81 } |
83 | 82 |
84 | |
85 void ClearTestFunc(int iter) { | 83 void ClearTestFunc(int iter) { |
86 GLbitfield mask = arg1; | 84 GLbitfield mask = arg1; |
87 glClear(mask); | 85 glClear(mask); |
88 glFlush(); // Kick GPU as soon as possible | 86 glFlush(); // Kick GPU as soon as possible |
89 for (int i = 0 ; i < iter-1; ++i) { | 87 for (int i = 0 ; i < iter-1; ++i) { |
90 glClear(mask); | 88 glClear(mask); |
91 } | 89 } |
92 } | 90 } |
93 | 91 |
94 | 92 |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 } | 568 } |
571 | 569 |
572 void YuvToRgbShaderTest1() { | 570 void YuvToRgbShaderTest1() { |
573 YuvToRgbShaderTestHelper(1, "yuv_shader_1"); | 571 YuvToRgbShaderTestHelper(1, "yuv_shader_1"); |
574 } | 572 } |
575 | 573 |
576 void YuvToRgbShaderTest2() { | 574 void YuvToRgbShaderTest2() { |
577 YuvToRgbShaderTestHelper(2, "yuv_shader_2"); | 575 YuvToRgbShaderTestHelper(2, "yuv_shader_2"); |
578 } | 576 } |
579 | 577 |
| 578 static GLuint compositing_textures[5]; |
| 579 static uint32_t texture_base[WINDOW_HEIGHT*WINDOW_WIDTH]; |
| 580 static uint32_t texture_update[WINDOW_HEIGHT*WINDOW_WIDTH]; |
| 581 static ShaderProgram compositing_background_program = 0; |
| 582 static ShaderProgram compositing_foreground_program = 0; |
| 583 |
| 584 void InitBaseTexture() { |
| 585 for (int y = 0; y < WINDOW_HEIGHT; y++) { |
| 586 for (int x = 0; x < WINDOW_WIDTH; x++) { |
| 587 // This color is gray, half alpha. |
| 588 texture_base[y*WINDOW_WIDTH+x] = 0x80808080; |
| 589 } |
| 590 } |
| 591 } |
| 592 |
| 593 // UpdateTexture simulates Chrome updating tab contents. |
| 594 // We cause a bunch of read and write cpu memory bandwidth. |
| 595 // It's a very rough approximation. |
| 596 void UpdateTexture() { |
| 597 memcpy(texture_update, texture_base, sizeof(texture_base)); |
| 598 } |
| 599 |
| 600 void LoadTexture() { |
| 601 // Use GL_RGBA for compatibility with GLES2.0. |
| 602 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
| 603 WINDOW_WIDTH, WINDOW_HEIGHT, 0, |
| 604 GL_RGBA, GL_UNSIGNED_BYTE, texture_update); |
| 605 } |
| 606 |
| 607 // Test how fast we can do full-screen compositing of images |
| 608 // continuously updated from the CPU. |
| 609 // This tests both GPU compositing performance and also |
| 610 // CPU -> GPU data transfer speed. |
| 611 // It is a basic perf test to make sure we have enough performance |
| 612 // to run a compositing window manager. |
| 613 void CompositingTestFunc(int iter) { |
| 614 for (int i = 0 ; i < iter; ++i) { |
| 615 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| 616 |
| 617 // Draw the background |
| 618 glDisable(GL_BLEND); |
| 619 glDisable(GL_DEPTH_TEST); |
| 620 // We have to blend three textures, but we use multi-texture for this |
| 621 // blending, not fb blend, to avoid the external memory traffic |
| 622 glActiveTexture(GL_TEXTURE0); |
| 623 glBindTexture(GL_TEXTURE_2D, compositing_textures[0]); |
| 624 glActiveTexture(GL_TEXTURE1); |
| 625 glBindTexture(GL_TEXTURE_2D, compositing_textures[1]); |
| 626 glActiveTexture(GL_TEXTURE2); |
| 627 glBindTexture(GL_TEXTURE_2D, compositing_textures[2]); |
| 628 // Set up the texture coordinate arrays |
| 629 glClientActiveTexture(GL_TEXTURE0); |
| 630 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| 631 glClientActiveTexture(GL_TEXTURE1); |
| 632 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| 633 glClientActiveTexture(GL_TEXTURE2); |
| 634 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| 635 // Use the right shader |
| 636 glUseProgram(compositing_background_program); |
| 637 // Draw the quad |
| 638 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 639 |
| 640 // Set up one texture coordinate array |
| 641 glClientActiveTexture(GL_TEXTURE0); |
| 642 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| 643 glClientActiveTexture(GL_TEXTURE1); |
| 644 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
| 645 glClientActiveTexture(GL_TEXTURE2); |
| 646 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
| 647 // Use the right shader |
| 648 glUseProgram(compositing_foreground_program); |
| 649 |
| 650 // Compositing is blending, so we shall blend. |
| 651 glEnable(GL_BLEND); |
| 652 // Depth test is on for window occlusion |
| 653 glEnable(GL_DEPTH_TEST); |
| 654 |
| 655 // Draw window number one |
| 656 // This update acts like a chrome webkit sw rendering update. |
| 657 glActiveTexture(GL_TEXTURE0); |
| 658 glBindTexture(GL_TEXTURE_2D, compositing_textures[3]); |
| 659 UpdateTexture(); |
| 660 // TODO(papakipos): this LoadTexture is likely doing more CPU memory copies |
| 661 // than we would like. |
| 662 LoadTexture(); |
| 663 // TODO(papakipos): add color interpolation here, and modulate |
| 664 // texture against it. |
| 665 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 666 |
| 667 // Draw window number two |
| 668 // This is a static window, so we don't update it. |
| 669 glActiveTexture(GL_TEXTURE0); |
| 670 glBindTexture(GL_TEXTURE_2D, compositing_textures[4]); |
| 671 // TODO(papakipos): add color interpolation here, and modulate |
| 672 // texture against it. |
| 673 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 674 } |
| 675 } |
| 676 |
| 677 void InitializeCompositing() { |
| 678 InitBaseTexture(); |
| 679 |
| 680 glClearColor(0.f, 0.f, 0.f, 0.f); |
| 681 glDisable(GL_DEPTH_TEST); |
| 682 glDisable(GL_BLEND); |
| 683 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| 684 glDepthFunc(GL_LEQUAL); |
| 685 |
| 686 glGenTextures(5, compositing_textures); |
| 687 glActiveTexture(GL_TEXTURE0); |
| 688 for (int i = 0; i < 5; i++) { |
| 689 glBindTexture(GL_TEXTURE_2D, compositing_textures[i]); |
| 690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
| 691 GL_LINEAR); |
| 692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
| 693 GL_LINEAR); |
| 694 } |
| 695 |
| 696 glColor4f(1.f, 1.f, 1.f, 1.f); |
| 697 |
| 698 // Set up the vertex arrays for drawing textured quads later on. |
| 699 glEnableClientState(GL_VERTEX_ARRAY); |
| 700 GLfloat buffer_vertex[8] = { |
| 701 -1.f, -1.f, |
| 702 1.f, -1.f, |
| 703 -1.f, 1.f, |
| 704 1.f, 1.f, |
| 705 }; |
| 706 GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER, |
| 707 sizeof(buffer_vertex), buffer_vertex); |
| 708 if (!vbo_vertex) |
| 709 printf("# Not Using VBO!\n"); |
| 710 glVertexPointer(2, GL_FLOAT, 0, vbo_vertex ? 0 : buffer_vertex); |
| 711 |
| 712 GLfloat buffer_texture[8] = { |
| 713 0.f, 0.f, |
| 714 1.f, 0.f, |
| 715 0.f, 1.f, |
| 716 1.f, 1.f, |
| 717 }; |
| 718 GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER, |
| 719 sizeof(buffer_texture), buffer_texture); |
| 720 for (int i = 0; i < 3; i++) { |
| 721 glClientActiveTexture(GL_TEXTURE0 + i); |
| 722 glTexCoordPointer(2, GL_FLOAT, 0, vbo_texture ? 0 : buffer_texture); |
| 723 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| 724 } |
| 725 |
| 726 // Set up the static background textures. |
| 727 UpdateTexture(); |
| 728 UpdateTexture(); |
| 729 UpdateTexture(); |
| 730 // Load these textures into bound texture ids and keep using them |
| 731 // from there to avoid having to reload this texture every frame |
| 732 glActiveTexture(GL_TEXTURE0); |
| 733 glBindTexture(GL_TEXTURE_2D, compositing_textures[0]); |
| 734 LoadTexture(); |
| 735 glActiveTexture(GL_TEXTURE1); |
| 736 glBindTexture(GL_TEXTURE_2D, compositing_textures[1]); |
| 737 LoadTexture(); |
| 738 glActiveTexture(GL_TEXTURE2); |
| 739 glBindTexture(GL_TEXTURE_2D, compositing_textures[2]); |
| 740 LoadTexture(); |
| 741 |
| 742 glActiveTexture(GL_TEXTURE0); |
| 743 glBindTexture(GL_TEXTURE_2D, compositing_textures[3]); |
| 744 UpdateTexture(); |
| 745 LoadTexture(); |
| 746 |
| 747 glActiveTexture(GL_TEXTURE0); |
| 748 glBindTexture(GL_TEXTURE_2D, compositing_textures[4]); |
| 749 UpdateTexture(); |
| 750 LoadTexture(); |
| 751 |
| 752 // Set up vertex & fragment shaders. |
| 753 compositing_background_program = |
| 754 TripleTextureBlendShaderProgram(vbo_vertex, |
| 755 vbo_texture, vbo_texture, vbo_texture); |
| 756 compositing_foreground_program = |
| 757 BasicTextureShaderProgram(vbo_vertex, vbo_texture); |
| 758 if ((!compositing_background_program) || |
| 759 (!compositing_foreground_program)) { |
| 760 printf("# Could not set up compositing shader.\n"); |
| 761 } |
| 762 |
| 763 if (!vbo_vertex) |
| 764 printf("# Not Using VBO!\n"); |
| 765 glVertexPointer(2, GL_FLOAT, 0, vbo_vertex ? 0 : buffer_vertex); |
| 766 } |
| 767 |
| 768 void TeardownCompositing() { |
| 769 glDeleteProgram(compositing_background_program); |
| 770 glDeleteProgram(compositing_foreground_program); |
| 771 } |
| 772 |
| 773 // Notes on the window manager compositing test: |
| 774 // Depth |
| 775 // Depth complexity = 3: background, active window, static window |
| 776 // Background: may be a tex-blend of three images (2.5d effect) |
| 777 // The windows -- at most two, fullscreen |
| 778 // Depth test is on, passing most of the time. |
| 779 // A lot of texture min-filtering -- not modelled |
| 780 // One of the two windows is getting live browser frame updates -- not mod |
| 781 // The live window runs at x/2 and y/2 size -- not modelled |
| 782 // The two windows are modulated by color interpolation to get gradient |
| 783 static float screen_scale_factor = (1e6f* |
| 784 (WINDOW_WIDTH*WINDOW_HEIGHT)/ |
| 785 (1280.f*768)); |
| 786 |
| 787 void WindowManagerCompositingTest() { |
| 788 InitializeCompositing(); |
| 789 RunTest(CompositingTestFunc, "1280x768_fps_compositing", |
| 790 screen_scale_factor, true); |
| 791 TeardownCompositing(); |
| 792 } |
| 793 |
| 794 void NoFillWindowManagerCompositingTest() { |
| 795 glScissor(0, 0, 1, 1); |
| 796 glEnable(GL_SCISSOR_TEST); |
| 797 InitializeCompositing(); |
| 798 RunTest(CompositingTestFunc, "1280x768_fps_no_fill_compositing", |
| 799 screen_scale_factor, true); |
| 800 TeardownCompositing(); |
| 801 } |
580 | 802 |
581 // TODO: get resources file from a command line option or something. | 803 // TODO: get resources file from a command line option or something. |
582 // TODO: use proper command line parsing library. | 804 // TODO: use proper command line parsing library. |
583 static void ParseArgs(int argc, char *argv[]) { | 805 static void ParseArgs(int argc, char *argv[]) { |
584 const char **enabled_tests_ptr = enabled_tests; | 806 const char **enabled_tests_ptr = enabled_tests; |
585 bool test_name_arg = false; | 807 bool test_name_arg = false; |
586 bool duration_arg = false; | 808 bool duration_arg = false; |
587 for (int i = 0; i < argc; i++) { | 809 for (int i = 0; i < argc; i++) { |
588 if (test_name_arg) { | 810 if (test_name_arg) { |
589 test_name_arg = false; | 811 test_name_arg = false; |
(...skipping 23 matching lines...) Expand all Loading... |
613 | 835 |
614 void (*test[])() = { | 836 void (*test[])() = { |
615 SwapTest, | 837 SwapTest, |
616 ClearTest, | 838 ClearTest, |
617 FillRateTest, | 839 FillRateTest, |
618 TriangleSetupTest, | 840 TriangleSetupTest, |
619 AttributeFetchShaderTest, | 841 AttributeFetchShaderTest, |
620 VaryingsAndDdxyShaderTest, | 842 VaryingsAndDdxyShaderTest, |
621 YuvToRgbShaderTest1, | 843 YuvToRgbShaderTest1, |
622 YuvToRgbShaderTest2, | 844 YuvToRgbShaderTest2, |
| 845 NoFillWindowManagerCompositingTest, |
| 846 WindowManagerCompositingTest, |
623 }; | 847 }; |
624 | 848 |
625 uint64_t done = GetUTime() + 1000000ULL * seconds_to_run; | 849 uint64_t done = GetUTime() + 1000000ULL * seconds_to_run; |
626 do { | 850 do { |
627 for (unsigned int i = 0; i < sizeof(test) / sizeof(*test); i++) { | 851 for (unsigned int i = 0; i < sizeof(test) / sizeof(*test); i++) { |
628 InitContext(); | 852 InitContext(); |
629 test[i](); | 853 test[i](); |
630 GLenum err = glGetError(); | 854 GLenum err = glGetError(); |
631 if (err != 0) | 855 if (err != 0) |
632 printf("# glGetError returned non-zero: 0x%x\n", err); | 856 printf("# glGetError returned non-zero: 0x%x\n", err); |
633 DestroyContext(); | 857 DestroyContext(); |
634 } | 858 } |
635 } while (GetUTime() < done); | 859 } while (GetUTime() < done); |
636 | 860 |
637 return 0; | 861 return 0; |
638 } | 862 } |
OLD | NEW |