Home | History | Annotate | Download | only in shader_bench
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <deque>
      8 #include <ostream>
      9 
     10 #include "base/at_exit.h"
     11 #include "base/bind.h"
     12 #include "base/command_line.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/strings/string_number_conversions.h"
     15 #include "base/time/time.h"
     16 #include "media/base/video_frame.h"
     17 #include "media/tools/shader_bench/cpu_color_painter.h"
     18 #include "media/tools/shader_bench/gpu_color_painter.h"
     19 #include "media/tools/shader_bench/painter.h"
     20 #include "media/tools/shader_bench/window.h"
     21 #include "ui/gfx/native_widget_types.h"
     22 #include "ui/gl/gl_bindings.h"
     23 #include "ui/gl/gl_context.h"
     24 #include "ui/gl/gl_implementation.h"
     25 #include "ui/gl/gl_surface.h"
     26 
     27 #if defined(TOOLKIT_GTK)
     28 #include <gtk/gtk.h>
     29 #endif
     30 
     31 static const int kNumFramesToPaint = 500;
     32 static base::TimeTicks g_start_;
     33 static base::TimeTicks g_end_;
     34 
     35 long CalculateYUVFrameSize(FILE* file_handle, int num_frames) {
     36   fseek(file_handle, 0, SEEK_END);
     37   long file_size = (long) ftell(file_handle);
     38   rewind(file_handle);
     39   return file_size / num_frames;
     40 }
     41 
     42 void GetFrames(std::string file_name,
     43                int width, int height, int num_frames,
     44                std::deque<scoped_refptr<media::VideoFrame> >& out_frames) {
     45   FILE* file_handle = fopen(file_name.c_str(), "rb");
     46   if (!file_handle) {
     47     printf("Could not open %s\n", file_name.c_str());
     48     exit(1);
     49   }
     50 
     51   long frame_size = CalculateYUVFrameSize(file_handle, num_frames);
     52 
     53   gfx::Size size(width, height);
     54   for (int i = 0; i < num_frames; i++) {
     55     scoped_refptr<media::VideoFrame> video_frame =
     56         media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size,
     57                                        gfx::Rect(size), size,
     58                                        base::TimeDelta());
     59     long bytes_read =
     60         fread(video_frame->data(0), 1, frame_size, file_handle);
     61 
     62     if (bytes_read != frame_size) {
     63       printf("Could not read %s\n", file_name.c_str());
     64       fclose(file_handle);
     65       exit(1);
     66     }
     67     out_frames.push_back(video_frame);
     68   }
     69 
     70   fclose(file_handle);
     71 }
     72 
     73 void TestFinished() {
     74   g_end_ = base::TimeTicks::HighResNow();
     75   double time_in_seconds =
     76       static_cast<double>((g_end_ - g_start_).InMilliseconds()) / 1000;
     77   double fps = kNumFramesToPaint / time_in_seconds;
     78   printf("Printed %f frames per second.\n", fps);
     79 }
     80 
     81 void RunTest(media::Window* window, Painter* painter) {
     82   g_start_ = base::TimeTicks::HighResNow();
     83   window->Start(kNumFramesToPaint, base::Bind(&TestFinished), painter);
     84 }
     85 
     86 int main(int argc, char** argv) {
     87   // Read arguments.
     88   if (argc == 1) {
     89     printf("Usage: %s --file=FILE --wxh=DIMENSIONS --frames=NUM_FRAMES\n"
     90            "FILE is a raw .yuv file with 1+ frames in it\n"
     91            "DIMENSIONS is the width and height of the frame in pixels\n"
     92            "NUM_FRAMES is the number of frames in FILE\n", argv[0]);
     93     return 1;
     94   }
     95 
     96   // Read command line.
     97 #if defined(TOOLKIT_GTK)
     98   gtk_init(&argc, &argv);
     99 #endif
    100   CommandLine::Init(argc, argv);
    101 
    102   // Determine file name.
    103   std::string file_name =
    104       CommandLine::ForCurrentProcess()->GetSwitchValueASCII("file");
    105 
    106   // Determine number of frames.
    107   int num_frames = 0;
    108   std::string str_num_frames =
    109       CommandLine::ForCurrentProcess()->GetSwitchValueASCII("frames");
    110   base::StringToInt(str_num_frames, &num_frames);
    111 
    112   // Determine video dimensions.
    113   int width = 0;
    114   int height = 0;
    115   std::string dimensions =
    116       CommandLine::ForCurrentProcess()->GetSwitchValueASCII("wxh");
    117   int x_index = dimensions.find('x');
    118   std::string str_width = dimensions.substr(0, x_index);
    119   std::string str_height =
    120       dimensions.substr(x_index + 1, dimensions.length() - x_index - 1);
    121   base::StringToInt(str_width, &width);
    122   base::StringToInt(str_height, &height);
    123 
    124   // Process files.
    125   std::deque<scoped_refptr<media::VideoFrame> > frames;
    126   GetFrames(file_name, width, height, num_frames, frames);
    127 
    128   // Initialize window and graphics context.
    129   base::AtExitManager at_exit_manager;
    130   gfx::GLSurface::InitializeOneOff();
    131   scoped_ptr<media::Window> window(new media::Window(width, height));
    132   gfx::GLSurface* surface =
    133       gfx::GLSurface::CreateViewGLSurface(window->PluginWindow()).get();
    134   gfx::GLContext* context = gfx::GLContext::CreateGLContext(
    135       NULL, surface, gfx::PreferDiscreteGpu).get();
    136   context->MakeCurrent(surface);
    137   // This sets D3DPRESENT_INTERVAL_IMMEDIATE on Windows.
    138   context->SetSwapInterval(0);
    139 
    140   // Initialize and name GPU painters.
    141   static const struct {
    142     const char* name;
    143     GPUPainter* painter;
    144   } painters[] = {
    145     { "CPU CSC + GPU Render", new CPUColorPainter() },
    146     { "GPU CSC/Render", new GPUColorWithLuminancePainter() },
    147   };
    148 
    149   // Run GPU painter tests.
    150   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(painters); i++) {
    151     scoped_ptr<GPUPainter> painter(painters[i].painter);
    152     painter->LoadFrames(&frames);
    153     painter->SetGLContext(surface, context);
    154     painter->Initialize(width, height);
    155     printf("Running %s tests...", painters[i].name);
    156     RunTest(window.get(), painter.get());
    157   }
    158 
    159   return 0;
    160 }
    161