Bug 1828192 [Linux] Remove c style hacks to run glxtest and use FireTestProcess() for it r=emilio

- Migrate glxtest pid and pipe fd variables to static members of GfxInfo on Linux
- Implement GfxInfo::FireGLXTestProcess() to run glxtest process.

Differential Revision: https://phabricator.services.mozilla.com/D175867
This commit is contained in:
stransky 2023-04-20 08:54:17 +00:00
Родитель 2f37fa4403
Коммит 1551b41014
3 изменённых файлов: 43 добавлений и 67 удалений

Просмотреть файл

@ -3664,61 +3664,6 @@ static DWORD WINAPI InitDwriteBG(LPVOID lpdwThreadParam) {
}
#endif
#ifdef USE_GLX_TEST
namespace mozilla::widget {
// the read end of the pipe, which will be used by GfxInfo
extern int glxtest_pipe;
// the PID of the glxtest process, to pass to waitpid()
extern pid_t glxtest_pid;
} // namespace mozilla::widget
void fire_glxtest_process() {
nsCOMPtr<nsIFile> appFile;
nsresult rv = XRE_GetBinaryPath(getter_AddRefs(appFile));
if (NS_FAILED(rv)) {
Output(true, "Couldn't find application file.\n");
return;
}
nsCOMPtr<nsIFile> exePath;
rv = appFile->GetParent(getter_AddRefs(exePath));
if (NS_FAILED(rv)) {
Output(true, "Couldn't get application directory.\n");
return;
}
exePath->Append(FILE_GLX_TEST);
int pfd[2];
if (pipe(pfd) == -1) {
Output(true, "Failed to create pipe\n");
return;
}
mozilla::widget::glxtest_pipe = pfd[0];
char* argv[] = {strdup(exePath->NativePath().get()), strdup("-f"),
strdup(std::to_string(pfd[1]).c_str()),
IsWaylandEnabled() ? strdup("-w") : nullptr, nullptr};
auto cleanup = mozilla::MakeScopeExit([&] {
for (auto& arg : argv) {
free(arg);
}
close(pfd[1]);
});
// Use G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD flags
// to g_spawn_async_with_pipes() run posix_spawn() directly.
GUniquePtr<GError> err;
g_spawn_async_with_pipes(
nullptr, argv, nullptr,
GSpawnFlags(G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD),
nullptr, nullptr, &mozilla::widget::glxtest_pid, nullptr, nullptr,
nullptr, getter_Transfers(err));
if (err) {
Output(true, "Failed to probe graphics hardware! %s\n", err->message);
}
}
#endif
#include "GeckoProfiler.h"
#include "ProfilerControl.h"
@ -5164,7 +5109,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
mozilla::glean_pings::Pageload.Submit("startup"_ns);
#ifdef USE_GLX_TEST
fire_glxtest_process();
GfxInfo::FireGLXTestProcess();
#endif
return 0;

Просмотреть файл

@ -40,21 +40,17 @@
#define GFX_TEST_TIMEOUT 4000
#define VAAPI_TEST_TIMEOUT 2000
#define GLX_PROBE_BINARY u"glxtest"_ns
#define VAAPI_PROBE_BINARY u"vaapitest"_ns
#ifdef DEBUG
bool fire_glxtest_process();
#endif
namespace mozilla::widget {
#ifdef DEBUG
NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
#endif
// these global variables will be set when firing the glxtest process
int glxtest_pipe = -2;
pid_t glxtest_pid = 0;
int GfxInfo::sGLXTestPipe = -1;
pid_t GfxInfo::sGLXTestPID = 0;
// bits to use decoding codec information returned from glxtest
constexpr int CODEC_HW_H264 = 1 << 4;
@ -109,6 +105,11 @@ static bool MakeFdNonBlocking(int fd) {
static bool ManageChildProcess(int* aPID, int* aPipe, int aTimeout,
char** aData) {
// Don't try anything if we failed before
if (*aPID == -1) {
return false;
}
GIOChannel* channel = nullptr;
*aData = nullptr;
@ -188,7 +189,7 @@ void GfxInfo::GetData() {
char* glxData = nullptr;
auto free = mozilla::MakeScopeExit([&] { g_free((void*)glxData); });
bool error = !ManageChildProcess(&glxtest_pid, &glxtest_pipe,
bool error = !ManageChildProcess(&sGLXTestPID, &sGLXTestPipe,
GFX_TEST_TIMEOUT, &glxData);
if (error) {
gfxCriticalNote << "glxtest: ManageChildProcess failed\n";
@ -584,6 +585,33 @@ int GfxInfo::FireTestProcess(const nsAString& aBinaryFile, int* aOutPipe,
return pid;
}
bool GfxInfo::FireGLXTestProcess() {
// If the pid is zero, then we have never run the test process to query for
// driver information. This would normally be run on startup, but we need to
// manually invoke it for XPC shell tests.
if (sGLXTestPID > 0) {
return true;
}
int pfd[2];
if (pipe(pfd) == -1) {
gfxCriticalNote << "FireGLXTestProcess failed to create pipe\n";
return false;
}
sGLXTestPipe = pfd[0];
auto pipeID = std::to_string(pfd[1]);
const char* args[] = {"-f", pipeID.c_str(),
IsWaylandEnabled() ? "-w" : nullptr, nullptr};
sGLXTestPID = FireTestProcess(GLX_PROBE_BINARY, nullptr, args);
// Set pid to -1 to avoid further test launch.
if (!sGLXTestPID) {
sGLXTestPID = -1;
}
close(pfd[1]);
return true;
}
#ifdef MOZ_WAYLAND
void GfxInfo::GetDataVAAPI() {
if (mIsVAAPISupported.isSome()) {
@ -1293,9 +1321,7 @@ NS_IMETHODIMP GfxInfo::FireTestProcess() {
// If the pid is zero, then we have never run the test process to query for
// driver information. This would normally be run on startup, but we need to
// manually invoke it for XPC shell tests.
if (glxtest_pid == 0) {
fire_glxtest_process();
}
FireGLXTestProcess();
return NS_OK;
}

Просмотреть файл

@ -55,6 +55,8 @@ class GfxInfo final : public GfxInfoBase {
NS_IMETHOD_(void) GetData() override;
static bool FireGLXTestProcess();
#ifdef DEBUG
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIGFXINFODEBUG
@ -117,6 +119,9 @@ class GfxInfo final : public GfxInfoBase {
bool mGlxTestError;
mozilla::Maybe<bool> mIsVAAPISupported;
static int sGLXTestPipe;
static pid_t sGLXTestPID;
#ifdef MOZ_WAYLAND
void GetDataVAAPI();
#endif