1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "host/libs/graphics_detector/graphics_detector.h" 18 19 #include <sstream> 20 #include <vector> 21 22 #include <android-base/logging.h> 23 #include <android-base/strings.h> 24 25 #include "host/libs/graphics_detector/graphics_detector_gl.h" 26 #include "host/libs/graphics_detector/graphics_detector_vk.h" 27 #include "host/libs/graphics_detector/graphics_detector_vk_precision_qualifiers_on_yuv_samplers.h" 28 29 namespace cuttlefish { 30 namespace { 31 ToLower(const std::string & v)32std::string ToLower(const std::string& v) { 33 std::string result = v; 34 std::transform(result.begin(), result.end(), result.begin(), 35 [](unsigned char c) { return std::tolower(c); }); 36 return result; 37 } 38 IsLikelySoftwareRenderer(const std::string & renderer)39bool IsLikelySoftwareRenderer(const std::string& renderer) { 40 const std::string lower_renderer = ToLower(renderer); 41 return lower_renderer.find("llvmpipe") != std::string::npos; 42 } 43 44 } // namespace 45 ShouldEnableAcceleratedRendering(const GraphicsAvailability & availability)46bool ShouldEnableAcceleratedRendering( 47 const GraphicsAvailability& availability) { 48 const bool sufficient_gles2 = 49 availability.can_init_gles2_on_egl_surfaceless && 50 !IsLikelySoftwareRenderer(availability.gles2_renderer); 51 const bool sufficient_gles3 = 52 availability.can_init_gles3_on_egl_surfaceless && 53 !IsLikelySoftwareRenderer(availability.gles3_renderer); 54 return (sufficient_gles2 || sufficient_gles3) && 55 availability.has_discrete_gpu; 56 } 57 58 // Runs various graphics tests inside of subprocesses first to ensure that 59 // this function can complete successfully without crashing the Cuttlefish 60 // launcher. Configurations such as GCE instances without a GPU but with GPU 61 // drivers for example have seen crashes. GetGraphicsAvailabilityWithSubprocessCheck()62GraphicsAvailability GetGraphicsAvailabilityWithSubprocessCheck() { 63 GraphicsAvailability availability; 64 PopulateEglAndGlesAvailability(&availability); 65 PopulateVulkanAvailability(&availability); 66 PopulateVulkanPrecisionQualifiersOnYuvSamplersQuirk(&availability); 67 return availability; 68 } 69 operator <<(std::ostream & stream,const GraphicsAvailability & availability)70std::ostream& operator<<(std::ostream& stream, 71 const GraphicsAvailability& availability) { 72 std::ios_base::fmtflags flags_backup(stream.flags()); 73 stream << std::boolalpha; 74 stream << "Graphics Availability:\n"; 75 76 stream << "\n"; 77 stream << "EGL available: " << availability.has_egl << "\n"; 78 stream << "OpenGL ES 2 available: " << availability.has_gles2 << "\n"; 79 stream << "OpenGL ES 3 available: " << availability.has_gles3 << "\n"; 80 stream << "Vulkan lib available: " << availability.has_vulkan << "\n"; 81 82 stream << "\n"; 83 stream << "EGL client extensions: " << availability.egl_client_extensions 84 << "\n"; 85 86 stream << "\n"; 87 stream << "EGL display vendor: " << availability.egl_vendor << "\n"; 88 stream << "EGL display version: " << availability.egl_version << "\n"; 89 stream << "EGL display extensions: " << availability.egl_extensions << "\n"; 90 91 stream << "GLES2 can init on surfaceless display: " 92 << availability.can_init_gles2_on_egl_surfaceless << "\n"; 93 stream << "GLES2 vendor: " << availability.gles2_vendor << "\n"; 94 stream << "GLES2 version: " << availability.gles2_version << "\n"; 95 stream << "GLES2 renderer: " << availability.gles2_renderer << "\n"; 96 stream << "GLES2 extensions: " << availability.gles2_extensions << "\n"; 97 98 stream << "GLES3 can init on surfaceless display: " 99 << availability.can_init_gles3_on_egl_surfaceless << "\n"; 100 stream << "GLES3 vendor: " << availability.gles3_vendor << "\n"; 101 stream << "GLES3 version: " << availability.gles3_version << "\n"; 102 stream << "GLES3 renderer: " << availability.gles3_renderer << "\n"; 103 stream << "GLES3 extensions: " << availability.gles3_extensions << "\n"; 104 105 stream << "\n"; 106 stream << "Vulkan discrete GPU detected: " << availability.has_discrete_gpu 107 << "\n"; 108 if (availability.has_discrete_gpu) { 109 stream << "Vulkan discrete GPU device name: " 110 << availability.discrete_gpu_device_name << "\n"; 111 stream << "Vulkan discrete GPU device extensions: " 112 << availability.discrete_gpu_device_extensions << "\n"; 113 } 114 115 stream 116 << "Vulkan has quirk with precision qualifiers on YUV samplers: " 117 << availability.vulkan_has_issue_with_precision_qualifiers_on_yuv_samplers 118 << "\n"; 119 120 stream << "\n"; 121 stream << "Accelerated rendering supported: " 122 << ShouldEnableAcceleratedRendering(availability); 123 124 stream.flags(flags_backup); 125 return stream; 126 } 127 128 } // namespace cuttlefish 129