Blender V4.5
wm_platform_support.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <cstring>
12
13#include "BLI_dynstr.h"
14#include "BLI_fileops.h"
15#include "BLI_linklist.h"
16#include "BLI_path_utils.hh"
17#include "BLI_string.h"
18
19#include "BLT_translation.hh"
20
21#include "BKE_appdir.hh"
22#include "BKE_global.hh"
23
24#include "GPU_context.hh"
25#include "GPU_platform.hh"
26
27#define WM_PLATFORM_SUPPORT_TEXT_SIZE 1024
28
32static bool wm_platform_support_check_approval(const char *platform_support_key, bool update)
33{
34 if (G.factory_startup) {
35 return false;
36 }
37 const std::optional<std::string> cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr);
38 if (!cfgdir.has_value()) {
39 return false;
40 }
41
42 bool result = false;
43 char filepath[FILE_MAX];
44 BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_PLATFORM_SUPPORT_FILE);
45 LinkNode *lines = BLI_file_read_as_lines(filepath);
46 for (LinkNode *line_node = lines; line_node; line_node = line_node->next) {
47 const char *line = static_cast<char *>(line_node->link);
48 if (STREQ(line, platform_support_key)) {
49 result = true;
50 break;
51 }
52 }
53
54 if (!result && update) {
55 FILE *fp = BLI_fopen(filepath, "a");
56 if (fp) {
57 fprintf(fp, "%s\n", platform_support_key);
58 fclose(fp);
59 }
60 }
61
63 return result;
64}
65
66static void wm_platform_support_create_link(char *link)
67{
68 DynStr *ds = BLI_dynstr_new();
69
70 BLI_dynstr_append(ds, "https://docs.blender.org/manual/en/dev/troubleshooting/gpu/");
71#if defined(_WIN32)
72 BLI_dynstr_append(ds, "windows/");
73#elif defined(__APPLE__)
74 BLI_dynstr_append(ds, "apple/");
75#else /* UNIX. */
76 BLI_dynstr_append(ds, "linux/");
77#endif
78
80 BLI_dynstr_append(ds, "intel.html");
81 }
83 BLI_dynstr_append(ds, "nvidia.html");
84 }
86 BLI_dynstr_append(ds, "amd.html");
87 }
88 else {
89 BLI_dynstr_append(ds, "unknown.html");
90 }
91
95}
96
98{
100 char message[WM_PLATFORM_SUPPORT_TEXT_SIZE];
102
103 bool result = true;
104
106 const char *platform_key = GPU_platform_support_level_key();
107
108 /* Check if previous check matches the current check. Don't update the approval when running in
109 * `background`. this could have been triggered by installing add-ons via installers. */
110 if (support_level != GPU_SUPPORT_LEVEL_UNSUPPORTED && !G.factory_startup &&
111 wm_platform_support_check_approval(platform_key, !G.background))
112 {
113 /* If it matches the user has confirmed and wishes to use it. */
114 return result;
115 }
116
117 /* Update the message and link based on the found support level. */
118 GHOST_DialogOptions dialog_options = GHOST_DialogOptions(0);
119
120 switch (support_level) {
121 default:
123 break;
124
126 size_t slen = 0;
127 STR_CONCAT(title, slen, "Blender - ");
129 title, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Limited Platform Support"));
130 slen = 0;
132 message,
133 slen,
135 "Your graphics card or driver has limited support. It may work, but with "
136 "issues."));
137
138 /* TODO: Extra space is needed for the split function in GHOST_SystemX11. We should change
139 * the behavior in GHOST_SystemX11. */
140 STR_CONCAT(message, slen, "\n \n");
142 message,
143 slen,
145 "Newer graphics drivers may be available to improve Blender support."));
146 STR_CONCAT(message, slen, "\n \n");
147 STR_CONCAT(message, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Graphics card:\n"));
148 STR_CONCAT(message, slen, GPU_platform_gpu_name());
149
150 dialog_options = GHOST_DialogWarning;
151 break;
152 }
153
155 size_t slen = 0;
156 STR_CONCAT(title, slen, "Blender - ");
158 title, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Platform Unsupported"));
159 slen = 0;
160
161#ifdef __APPLE__
164 message,
165 slen,
166 CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Your graphics card is not supported"));
167 }
168 else {
169 STR_CONCAT(message,
170 slen,
172 "Your graphics card or macOS version is not supported"));
173 STR_CONCAT(message, slen, "\n \n");
174
176 message,
177 slen,
179 "Upgrading to the latest macOS version may improve Blender support"));
180 }
181#else
182 STR_CONCAT(message,
183 slen,
185 "Your graphics card or driver is not supported."));
186 STR_CONCAT(message, slen, "\n \n");
188 message,
189 slen,
191 "Newer graphics drivers may be available to improve Blender support."));
192
193 STR_CONCAT(message, slen, "\n \n");
194 STR_CONCAT(message, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Graphics card:\n"));
195 STR_CONCAT(message, slen, GPU_platform_gpu_name());
196#endif
197 STR_CONCAT(message, slen, "\n \n");
198
199 STR_CONCAT(message,
200 slen,
201 CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "The program will now close."));
202 dialog_options = GHOST_DialogError;
203 result = false;
204 break;
205 }
206 }
207
208 bool backend_detected = GPU_backend_get_type() != GPU_BACKEND_NONE;
209 bool show_message = ELEM(
211 bool show_continue = backend_detected;
212 bool show_link = backend_detected;
213 link[0] = '\0';
214 if (show_link) {
216 }
217
218 /* We are running in the background print the message in the console. */
219 if ((G.background || G.debug & G_DEBUG) && show_message) {
220 printf("%s\n\n%s\n%s\n", title, message, link);
221 }
222 if (G.background) {
223 /* Don't show the message-box when running in background mode.
224 * Printing to console is enough. */
225 result = true;
226 }
227 else if (show_message) {
229 message,
230 "Find Latest Drivers",
231 show_continue ? "Continue Anyway" : "Exit",
232 link,
233 dialog_options);
234 }
235
236 return result;
237}
@ BLENDER_USER_CONFIG
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
Definition appdir.cc:717
#define BLENDER_PLATFORM_SUPPORT_FILE
@ G_DEBUG
#define BLI_assert(a)
Definition BLI_assert.h:46
A dynamically sized string ADT.
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:36
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.cc:55
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct LinkNode * BLI_file_read_as_lines(const char *filepath) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:576
void BLI_file_free_lines(struct LinkNode *lines)
Definition storage.cc:622
#define FILE_MAX
#define BLI_path_join(...)
#define STR_CONCAT(dst, len, suffix)
Definition BLI_string.h:604
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER
#define CTX_IFACE_(context, msgid)
GHOST_DialogOptions
Definition GHOST_Types.h:73
@ GHOST_DialogError
Definition GHOST_Types.h:75
@ GHOST_DialogWarning
Definition GHOST_Types.h:74
eGPUBackendType GPU_backend_get_type()
@ GPU_DRIVER_ANY
const char * GPU_platform_gpu_name()
const char * GPU_platform_support_level_key()
eGPUSupportLevel
@ GPU_SUPPORT_LEVEL_LIMITED
@ GPU_SUPPORT_LEVEL_SUPPORTED
@ GPU_SUPPORT_LEVEL_UNSUPPORTED
@ GPU_OS_ANY
@ GPU_DEVICE_ATI
@ GPU_DEVICE_NVIDIA
@ GPU_DEVICE_INTEL
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
eGPUSupportLevel GPU_platform_support_level()
#define printf(...)
#define G(x, y, z)
static void update(bNodeTree *ntree)
struct LinkNode * next
static bool wm_platform_support_check_approval(const char *platform_support_key, bool update)
#define WM_PLATFORM_SUPPORT_TEXT_SIZE
bool WM_platform_support_perform_checks()
static void wm_platform_support_create_link(char *link)
void WM_ghost_show_message_box(const char *title, const char *message, const char *help_label, const char *continue_label, const char *link, GHOST_DialogOptions dialog_options)