190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_info_collector.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/android/build_info.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_piece.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_split.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gl/gl_bindings.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gl/gl_context.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gl/gl_surface.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string GetDriverVersionFromString(const std::string& version_string) { 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Extract driver version from the second number in a string like: 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "OpenGL ES 2.0 V@6.0 AU@ (CL@2946718)" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Exclude first "2.0". 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t begin = version_string.find_first_of("0123456789"); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (begin == std::string::npos) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "0"; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t end = version_string.find_first_not_of("01234567890.", begin); 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Extract number of the form "%d.%d" 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) begin = version_string.find_first_of("0123456789", end); 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (begin == std::string::npos) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "0"; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) end = version_string.find_first_not_of("01234567890.", begin); 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string sub_string; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (end != std::string::npos) 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sub_string = version_string.substr(begin, end - begin); 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sub_string = version_string.substr(begin); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::string> pieces; 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::SplitString(sub_string, '.', &pieces); 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pieces.size() < 2) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "0"; 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return pieces[0] + "." + pieces[1]; 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ScopedRestoreNonOwnedEGLContext { 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedRestoreNonOwnedEGLContext(); 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ~ScopedRestoreNonOwnedEGLContext(); 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EGLContext context_; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EGLDisplay display_; 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EGLSurface draw_surface_; 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EGLSurface read_surface_; 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ScopedRestoreNonOwnedEGLContext::ScopedRestoreNonOwnedEGLContext() 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : context_(EGL_NO_CONTEXT), 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) display_(EGL_NO_DISPLAY), 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) draw_surface_(EGL_NO_SURFACE), 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_surface_(EGL_NO_SURFACE) { 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This should only used to restore a context that is not created or owned by 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Chromium native code, but created by Android system itself. 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!gfx::GLContext::GetCurrent()); 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context_ = eglGetCurrentContext(); 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_ = eglGetCurrentDisplay(); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) draw_surface_ = eglGetCurrentSurface(EGL_DRAW); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read_surface_ = eglGetCurrentSurface(EGL_READ); 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ScopedRestoreNonOwnedEGLContext::~ScopedRestoreNonOwnedEGLContext() { 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (context_ == EGL_NO_CONTEXT || display_ == EGL_NO_DISPLAY || 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) draw_surface_ == EGL_NO_SURFACE || read_surface_ == EGL_NO_SURFACE) 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!eglMakeCurrent(display_, draw_surface_, read_surface_, context_)) 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Failed to restore EGL context"; 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace gpu { 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 87effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochCollectInfoResult CollectContextGraphicsInfo(GPUInfo* gpu_info) { 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return CollectBasicGraphicsInfo(gpu_info); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCollectInfoResult CollectGpuID(uint32* vendor_id, uint32* device_id) { 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(vendor_id && device_id); 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *vendor_id = 0; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *device_id = 0; 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return kCollectInfoNonFatalFailure; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 98effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochCollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) { 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gpu_info->can_lose_context = false; 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch gpu_info->machine_model_name = 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::android::BuildInfo::GetInstance()->model(); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create a short-lived context on the UI thread to collect the GL strings. 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make sure we restore the existing context if there is one. 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedRestoreNonOwnedEGLContext restore_context; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CollectInfoResult result = CollectGraphicsInfoGL(gpu_info); 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gpu_info->basic_info_state = result; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gpu_info->context_info_state = result; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 113effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochCollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gpu_info->driver_version = GetDriverVersionFromString( 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gpu_info->gl_version); 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gpu_info->gpu.vendor_string = gpu_info->gl_vendor; 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gpu_info->gpu.device_string = gpu_info->gl_renderer; 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return kCollectInfoSuccess; 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MergeGPUInfo(GPUInfo* basic_gpu_info, 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GPUInfo& context_gpu_info) { 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MergeGPUInfoGL(basic_gpu_info, context_gpu_info); 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace gpu 127