• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)32 std::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)39 bool 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)46 bool 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()62 GraphicsAvailability 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)70 std::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