diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-22 18:15:49 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-22 18:15:49 +0000 |
commit | cb2b3f98951576dc6923416bab580bc437263da7 (patch) | |
tree | 54b465487ad152721e375c9060e0e86ea62270c9 /media | |
parent | 21f9ea345cbf2b4d4c1d574bca1ee37aed801e34 (diff) | |
download | chromium_src-cb2b3f98951576dc6923416bab580bc437263da7.zip chromium_src-cb2b3f98951576dc6923416bab580bc437263da7.tar.gz chromium_src-cb2b3f98951576dc6923416bab580bc437263da7.tar.bz2 |
Benchmark tool for tile rendering
A tool for using tiles to render an image.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/6542045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75607 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/media.gyp | 19 | ||||
-rw-r--r-- | media/tools/tile_render_bench/tile_render_bench.cc | 246 |
2 files changed, 265 insertions, 0 deletions
diff --git a/media/media.gyp b/media/media.gyp index 2e6e613..70a45a8 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -602,6 +602,25 @@ }, ], }], + ['OS == "linux" and target_arch != "arm"', { + 'targets': [ + { + 'target_name': 'tile_render_bench', + 'type': 'executable', + 'dependencies': [ + '../app/app.gyp:app_base', + '../base/base.gyp:base', + ], + 'libraries': [ + '-lGL', + '-ldl', + ], + 'sources': [ + 'tools/tile_render_bench/tile_render_bench.cc', + ], + }, + ], + }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { 'targets': [ { diff --git a/media/tools/tile_render_bench/tile_render_bench.cc b/media/tools/tile_render_bench/tile_render_bench.cc new file mode 100644 index 0000000..707e112 --- /dev/null +++ b/media/tools/tile_render_bench/tile_render_bench.cc @@ -0,0 +1,246 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This tool is used to benchmark the technique of using tiles to render a +// large tecture. This tool runs with different tile sizes so that developer +// can determine the right dimensions for the tiles. + +#include <iostream> + +#include <X11/keysym.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include "app/gfx/gl/gl_bindings.h" +#include "app/gfx/gl/gl_implementation.h" +#include "base/at_exit.h" +#include "base/basictypes.h" +#include "base/message_loop.h" +#include "base/scoped_ptr.h" +#include "base/task.h" + +// Initial size of the window and the texture. +static const int kStartSize = 1024; + +// The smallest texture size we're trying. +static const int kEndSize = 16; + +// Factor for dividing the size from one step to another. +static const int kSizeFactor = 2; + +// Number of renders before we output. +static const int kRenderCount = 1000; +static const int kMaxTextures = kStartSize * kStartSize / kEndSize / kEndSize; + +Display* g_display = NULL; +Window g_window = 0; +bool g_running = false; +GLXContext g_gl_context = NULL; +GLuint g_textures[kMaxTextures]; +scoped_array<uint8> g_image; + +// Initialize X11. Returns true if successful. This method creates the X11 +// window. Further initialization is done in X11VideoRenderer. +bool InitX11() { + g_display = XOpenDisplay(NULL); + if (!g_display) { + std::cout << "Error - cannot open display" << std::endl; + return false; + } + + // Get properties of the screen. + int screen = DefaultScreen(g_display); + int root_window = RootWindow(g_display, screen); + + // Creates the window. + g_window = XCreateSimpleWindow(g_display, root_window, 1, 1, 100, 50, 0, + BlackPixel(g_display, screen), + BlackPixel(g_display, screen)); + XStoreName(g_display, g_window, "Tile Render Bench"); + + XSelectInput(g_display, g_window, + ExposureMask | ButtonPressMask | KeyPressMask); + XMapWindow(g_display, g_window); + + XResizeWindow(g_display, g_window, kStartSize, kStartSize); + + return true; +} + +// Initialize the OpenGL context. +void InitGLContext() { + if (!InitializeGLBindings(gfx::kGLImplementationDesktopGL)) { + LOG(ERROR) << "InitializeGLBindings failed"; + return; + } + + XWindowAttributes attributes; + XGetWindowAttributes(g_display, g_window, &attributes); + XVisualInfo visual_info_template; + visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); + int visual_info_count = 0; + XVisualInfo* visual_info_list = XGetVisualInfo(g_display, VisualIDMask, + &visual_info_template, + &visual_info_count); + + for (int i = 0; i < visual_info_count && !g_gl_context; ++i) { + g_gl_context = glXCreateContext(g_display, visual_info_list + i, 0, + True /* Direct rendering */); + } + + XFree(visual_info_list); + if (!g_gl_context) { + return; + } + + if (!glXMakeCurrent(g_display, g_window, g_gl_context)) { + glXDestroyContext(g_display, g_gl_context); + g_gl_context = NULL; + return; + } +} + +void InitTest() { + g_image.reset(new uint8[kStartSize * kStartSize]); + for (int i = 0; i < kStartSize; ++i) { + for (int j = 0; j < kStartSize; ++j) { + bool white = (i / 16) % 2 == (j / 16) % 2; + g_image.get()[i * kStartSize + j] = white ? 255 : 0; + } + } + + glGenTextures(kMaxTextures, g_textures); + for (int i = 0; i < kMaxTextures; ++i) { + glBindTexture(GL_TEXTURE_2D, g_textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glEnable(GL_TEXTURE_2D); +} + +void UpdateTextures(int tile_size) { + int k = 0; + uint8* image = g_image.get(); + for (int y = 0; y < kStartSize; y += tile_size) { + for (int x = 0; x < kStartSize; x += tile_size) { + glBindTexture(GL_TEXTURE_2D, g_textures[k]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, kStartSize); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tile_size, tile_size, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, image); + ++k; + image += tile_size; + } + image += tile_size * kStartSize - kStartSize; + } +} + +void Render(int tile_size) { + float points[] ={ + 0, 0, 0, + 1, 0, 0, + 1, 1, 0, + 0, 1, 0 + }; + GLfloat tex_coords[] = {0, 0, 1, 0, 1, 1, 0, 1}; + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, points); + glTexCoordPointer(2, GL_FLOAT, 0, tex_coords); + + // This will tile them from bottom-up. I'm too lazy to think about top-down. + int k = 0; + int scale_factor = kStartSize / tile_size; + double step = 1 / scale_factor; + for (int y = 0; y < kStartSize; y += tile_size) { + for (int x = 0; x < kStartSize; x += tile_size) { + glBindTexture(GL_TEXTURE_2D, g_textures[k++]); + glPushMatrix(); + glTranslated(-1, -1, 0); + glScaled(2.0 / scale_factor, 2.0 / scale_factor, 0); + glTranslated(x / tile_size * step, y / tile_size * step, 0); + glDrawArrays(GL_QUADS, 0, 4); + glPopMatrix(); + } + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glXSwapBuffers(g_display, g_window); +} + +void RunTest() { + static int tile_size = kStartSize; + static int count = kRenderCount; + static int64 start_time = 0; + + // If this is 0 that means this is the first time we render for this size. + if (!start_time) { + start_time = base::Time::Now().ToInternalValue(); + } + + UpdateTextures(tile_size); + Render(tile_size); + + // We have finished rendering for this size, output the numbers. + if (--count == 0) { + base::TimeDelta delta = base::Time::Now() - + base::Time::FromInternalValue(start_time); + std::cout << "size = " << tile_size + << " speed = " << delta.InMilliseconds() + << std::endl; + std::cout.flush(); + tile_size /= kSizeFactor; + count = kRenderCount; + start_time = 0; + } + + if (tile_size <= kEndSize) { + MessageLoop::current()->Quit(); + return; + } + + XExposeEvent ev = { Expose, 0, 1, g_display, g_window, + 0, 0, kStartSize, kStartSize, 0 }; + XSendEvent(g_display, g_window, False, ExposureMask, (XEvent*)&ev); + + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(&RunTest)); +} + +void ProcessEvents() { + // Consume all the X events + while (XPending(g_display)) { + XEvent e; + XNextEvent(g_display, &e); + switch (e.type) { + case Expose: + RunTest(); + default: + break; + } + } +} + +int main() { + base::AtExitManager at_exit; + MessageLoop loop; + InitX11(); + InitGLContext(); + InitTest(); + + loop.PostTask(FROM_HERE, NewRunnableFunction(&ProcessEvents)); + loop.Run(); + + // Cleanup GL. + glXMakeCurrent(g_display, 0, NULL); + glXDestroyContext(g_display, g_gl_context); + + // Destroy window and display. + XDestroyWindow(g_display, g_window); + XCloseDisplay(g_display); + return 0; +} |