summaryrefslogtreecommitdiff
path: root/chromium/media/tools/shader_bench/shader_bench.cc
blob: b26733ce03263282f7c53966bc009d8d4825fea9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright (c) 2012 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.

#include <stdio.h>
#include <stdlib.h>
#include <deque>
#include <ostream>

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "media/base/video_frame.h"
#include "media/tools/shader_bench/cpu_color_painter.h"
#include "media/tools/shader_bench/gpu_color_painter.h"
#include "media/tools/shader_bench/painter.h"
#include "media/tools/shader_bench/window.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface.h"

#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#endif

static const int kNumFramesToPaint = 500;
static base::TimeTicks g_start_;
static base::TimeTicks g_end_;

long CalculateYUVFrameSize(FILE* file_handle, int num_frames) {
  fseek(file_handle, 0, SEEK_END);
  long file_size = (long) ftell(file_handle);
  rewind(file_handle);
  return file_size / num_frames;
}

void GetFrames(std::string file_name,
               int width, int height, int num_frames,
               std::deque<scoped_refptr<media::VideoFrame> >& out_frames) {
  FILE* file_handle = fopen(file_name.c_str(), "rb");
  if (!file_handle) {
    printf("Could not open %s\n", file_name.c_str());
    exit(1);
  }

  long frame_size = CalculateYUVFrameSize(file_handle, num_frames);

  gfx::Size size(width, height);
  for (int i = 0; i < num_frames; i++) {
    scoped_refptr<media::VideoFrame> video_frame =
        media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size,
                                       gfx::Rect(size), size,
                                       base::TimeDelta());
    long bytes_read =
        fread(video_frame->data(0), 1, frame_size, file_handle);

    if (bytes_read != frame_size) {
      printf("Could not read %s\n", file_name.c_str());
      fclose(file_handle);
      exit(1);
    }
    out_frames.push_back(video_frame);
  }

  fclose(file_handle);
}

void TestFinished() {
  g_end_ = base::TimeTicks::HighResNow();
  double time_in_seconds =
      static_cast<double>((g_end_ - g_start_).InMilliseconds()) / 1000;
  double fps = kNumFramesToPaint / time_in_seconds;
  printf("Printed %f frames per second.\n", fps);
}

void RunTest(media::Window* window, Painter* painter) {
  g_start_ = base::TimeTicks::HighResNow();
  window->Start(kNumFramesToPaint, base::Bind(&TestFinished), painter);
}

int main(int argc, char** argv) {
  // Read arguments.
  if (argc == 1) {
    printf("Usage: %s --file=FILE --wxh=DIMENSIONS --frames=NUM_FRAMES\n"
           "FILE is a raw .yuv file with 1+ frames in it\n"
           "DIMENSIONS is the width and height of the frame in pixels\n"
           "NUM_FRAMES is the number of frames in FILE\n", argv[0]);
    return 1;
  }

  // Read command line.
#if defined(TOOLKIT_GTK)
  gtk_init(&argc, &argv);
#endif
  CommandLine::Init(argc, argv);

  // Determine file name.
  std::string file_name =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII("file");

  // Determine number of frames.
  int num_frames = 0;
  std::string str_num_frames =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII("frames");
  base::StringToInt(str_num_frames, &num_frames);

  // Determine video dimensions.
  int width = 0;
  int height = 0;
  std::string dimensions =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII("wxh");
  int x_index = dimensions.find('x');
  std::string str_width = dimensions.substr(0, x_index);
  std::string str_height =
      dimensions.substr(x_index + 1, dimensions.length() - x_index - 1);
  base::StringToInt(str_width, &width);
  base::StringToInt(str_height, &height);

  // Process files.
  std::deque<scoped_refptr<media::VideoFrame> > frames;
  GetFrames(file_name, width, height, num_frames, frames);

  // Initialize window and graphics context.
  base::AtExitManager at_exit_manager;
  gfx::GLSurface::InitializeOneOff();
  scoped_ptr<media::Window> window(new media::Window(width, height));
  gfx::GLSurface* surface =
      gfx::GLSurface::CreateViewGLSurface(window->PluginWindow()).get();
  gfx::GLContext* context = gfx::GLContext::CreateGLContext(
      NULL, surface, gfx::PreferDiscreteGpu).get();
  context->MakeCurrent(surface);
  // This sets D3DPRESENT_INTERVAL_IMMEDIATE on Windows.
  context->SetSwapInterval(0);

  // Initialize and name GPU painters.
  static const struct {
    const char* name;
    GPUPainter* painter;
  } painters[] = {
    { "CPU CSC + GPU Render", new CPUColorPainter() },
    { "GPU CSC/Render", new GPUColorWithLuminancePainter() },
  };

  // Run GPU painter tests.
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(painters); i++) {
    scoped_ptr<GPUPainter> painter(painters[i].painter);
    painter->LoadFrames(&frames);
    painter->SetGLContext(surface, context);
    painter->Initialize(width, height);
    printf("Running %s tests...", painters[i].name);
    RunTest(window.get(), painter.get());
  }

  return 0;
}