Home | History | Annotate | Download | only in config
      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 "gpu/config/gpu_info_collector.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/debug/trace_event.h"
     11 #include "base/logging.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/string_piece.h"
     15 #include "base/strings/string_split.h"
     16 #include "ui/gl/gl_bindings.h"
     17 #include "ui/gl/gl_context.h"
     18 #include "ui/gl/gl_implementation.h"
     19 #include "ui/gl/gl_surface.h"
     20 
     21 namespace {
     22 
     23 scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
     24   scoped_refptr<gfx::GLSurface> surface(
     25       gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size()));
     26   if (!surface.get()) {
     27     LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
     28     return NULL;
     29   }
     30 
     31   return surface;
     32 }
     33 
     34 scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
     35 
     36   scoped_refptr<gfx::GLContext> context(
     37       gfx::GLContext::CreateGLContext(NULL,
     38                                       surface,
     39                                       gfx::PreferIntegratedGpu));
     40   if (!context.get()) {
     41     LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
     42     return NULL;
     43   }
     44 
     45   if (!context->MakeCurrent(surface)) {
     46     LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
     47     return NULL;
     48   }
     49 
     50   return context;
     51 }
     52 
     53 std::string GetGLString(unsigned int pname) {
     54   const char* gl_string =
     55       reinterpret_cast<const char*>(glGetString(pname));
     56   if (gl_string)
     57     return std::string(gl_string);
     58   return std::string();
     59 }
     60 
     61 // Return a version string in the format of "major.minor".
     62 std::string GetVersionFromString(const std::string& version_string) {
     63   size_t begin = version_string.find_first_of("0123456789");
     64   if (begin != std::string::npos) {
     65     size_t end = version_string.find_first_not_of("01234567890.", begin);
     66     std::string sub_string;
     67     if (end != std::string::npos)
     68       sub_string = version_string.substr(begin, end - begin);
     69     else
     70       sub_string = version_string.substr(begin);
     71     std::vector<std::string> pieces;
     72     base::SplitString(sub_string, '.', &pieces);
     73     if (pieces.size() >= 2)
     74       return pieces[0] + "." + pieces[1];
     75   }
     76   return std::string();
     77 }
     78 
     79 }  // namespace anonymous
     80 
     81 namespace gpu {
     82 
     83 CollectInfoResult CollectGraphicsInfoGL(GPUInfo* gpu_info) {
     84   TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
     85   DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone);
     86 
     87   scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
     88   if (!surface.get()) {
     89     LOG(ERROR) << "Could not create surface for info collection.";
     90     return kCollectInfoFatalFailure;
     91   }
     92 
     93   scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
     94   if (!context.get()) {
     95     LOG(ERROR) << "Could not create context for info collection.";
     96     return kCollectInfoFatalFailure;
     97   }
     98 
     99   gpu_info->gl_renderer = GetGLString(GL_RENDERER);
    100   gpu_info->gl_vendor = GetGLString(GL_VENDOR);
    101   gpu_info->gl_extensions = GetGLString(GL_EXTENSIONS);
    102   gpu_info->gl_version = GetGLString(GL_VERSION);
    103   std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION);
    104 
    105   gfx::GLWindowSystemBindingInfo window_system_binding_info;
    106   if (GetGLWindowSystemBindingInfo(&window_system_binding_info)) {
    107     gpu_info->gl_ws_vendor = window_system_binding_info.vendor;
    108     gpu_info->gl_ws_version = window_system_binding_info.version;
    109     gpu_info->gl_ws_extensions = window_system_binding_info.extensions;
    110     gpu_info->direct_rendering = window_system_binding_info.direct_rendering;
    111   }
    112 
    113   bool supports_robustness =
    114       gpu_info->gl_extensions.find("GL_EXT_robustness") != std::string::npos ||
    115       gpu_info->gl_extensions.find("GL_ARB_robustness") != std::string::npos;
    116   if (supports_robustness) {
    117     glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
    118         reinterpret_cast<GLint*>(&gpu_info->gl_reset_notification_strategy));
    119   }
    120 
    121   // TODO(kbr): remove once the destruction of a current context automatically
    122   // clears the current context.
    123   context->ReleaseCurrent(surface.get());
    124 
    125   std::string glsl_version = GetVersionFromString(glsl_version_string);
    126   gpu_info->pixel_shader_version = glsl_version;
    127   gpu_info->vertex_shader_version = glsl_version;
    128 
    129   return CollectDriverInfoGL(gpu_info);
    130 }
    131 
    132 void MergeGPUInfoGL(GPUInfo* basic_gpu_info,
    133                     const GPUInfo& context_gpu_info) {
    134   DCHECK(basic_gpu_info);
    135   basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer;
    136   basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor;
    137   basic_gpu_info->gl_version = context_gpu_info.gl_version;
    138   basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
    139   basic_gpu_info->pixel_shader_version =
    140       context_gpu_info.pixel_shader_version;
    141   basic_gpu_info->vertex_shader_version =
    142       context_gpu_info.vertex_shader_version;
    143   basic_gpu_info->gl_ws_vendor = context_gpu_info.gl_ws_vendor;
    144   basic_gpu_info->gl_ws_version = context_gpu_info.gl_ws_version;
    145   basic_gpu_info->gl_ws_extensions = context_gpu_info.gl_ws_extensions;
    146   basic_gpu_info->gl_reset_notification_strategy =
    147       context_gpu_info.gl_reset_notification_strategy;
    148 
    149   if (!context_gpu_info.driver_vendor.empty())
    150     basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor;
    151   if (!context_gpu_info.driver_version.empty())
    152     basic_gpu_info->driver_version = context_gpu_info.driver_version;
    153 
    154   basic_gpu_info->can_lose_context = context_gpu_info.can_lose_context;
    155   basic_gpu_info->sandboxed = context_gpu_info.sandboxed;
    156   basic_gpu_info->direct_rendering = context_gpu_info.direct_rendering;
    157   basic_gpu_info->context_info_state = context_gpu_info.context_info_state;
    158   basic_gpu_info->initialization_time = context_gpu_info.initialization_time;
    159   basic_gpu_info->video_encode_accelerator_supported_profiles =
    160       context_gpu_info.video_encode_accelerator_supported_profiles;
    161 }
    162 
    163 }  // namespace gpu
    164 
    165