summaryrefslogtreecommitdiffstats
path: root/content/gpu/gpu_info_collector.cc
blob: 78e7888f1807f761d7691d6109d30d46a312591f (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
// 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.

#include "content/gpu/gpu_info_collector.h"

#include <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_split.h"
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_surface.h"

namespace {

scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
  scoped_refptr<gfx::GLSurface> surface(
      gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1)));
  if (!surface.get()) {
    LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
    return NULL;
  }

  return surface;
}

scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {

  scoped_refptr<gfx::GLContext> context(
      gfx::GLContext::CreateGLContext(NULL,
                                      surface,
                                      gfx::PreferDiscreteGpu));
  if (!context.get()) {
    LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
    return NULL;
  }

  if (!context->MakeCurrent(surface)) {
    LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
    return NULL;
  }

  return context;
}

std::string GetGLString(unsigned int pname) {
  const char* gl_string =
      reinterpret_cast<const char*>(glGetString(pname));
  if (gl_string)
    return std::string(gl_string);
  return "";
}

// Return a version string in the format of "major.minor".
std::string GetVersionFromString(const std::string& version_string) {
  size_t begin = version_string.find_first_of("0123456789");
  if (begin != std::string::npos) {
    size_t end = version_string.find_first_not_of("01234567890.", begin);
    std::string sub_string;
    if (end != std::string::npos)
      sub_string = version_string.substr(begin, end - begin);
    else
      sub_string = version_string.substr(begin);
    std::vector<std::string> pieces;
    base::SplitString(sub_string, '.', &pieces);
    if (pieces.size() >= 2)
      return pieces[0] + "." + pieces[1];
  }
  return "";
}

}  // namespace anonymous

namespace gpu_info_collector {

bool CollectGraphicsInfoGL(content::GPUInfo* gpu_info) {
  if (!gfx::GLSurface::InitializeOneOff()) {
    LOG(ERROR) << "gfx::GLSurface::InitializeOneOff() failed";
    return false;
  }

  scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
  if (!surface.get())
    return false;

  scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
  if (!context.get())
    return false;

  gpu_info->gl_renderer = GetGLString(GL_RENDERER);
  gpu_info->gl_vendor = GetGLString(GL_VENDOR);
  gpu_info->gl_version_string =GetGLString(GL_VERSION);
  gpu_info->gl_extensions =GetGLString(GL_EXTENSIONS);

  bool validGLVersionInfo = CollectGLVersionInfo(gpu_info);
  bool validVideoCardInfo = CollectVideoCardInfo(gpu_info);
  bool validDriverInfo = CollectDriverInfoGL(gpu_info);

  return (validGLVersionInfo && validVideoCardInfo && validDriverInfo);
}

bool CollectGLVersionInfo(content::GPUInfo* gpu_info) {
  std::string gl_version_string = gpu_info->gl_version_string;
  std::string glsl_version_string =
      GetGLString(GL_SHADING_LANGUAGE_VERSION);

  gpu_info->gl_version = GetVersionFromString(gl_version_string);

  std::string glsl_version = GetVersionFromString(glsl_version_string);
  gpu_info->pixel_shader_version = glsl_version;
  gpu_info->vertex_shader_version = glsl_version;

  return true;
}

}  // namespace gpu_info_collector