Commit 7d670a33 by chrome-bot Committed by Commit Bot

Make ozone backend work if it can't display.

The ozone backend will no longer fail if it is unable to display on screen for any reason. It no longer assumes it can control the first screen it finds. BUG=angleproject:1423 Change-Id: I5d5274c54b1bc6de50e704903391bf6161efa487 Reviewed-on: https://chromium-review.googlesource.com/445805 Commit-Queue: Frank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 61f0db8e
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <iostream>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
...@@ -295,7 +294,7 @@ uint32_t DisplayOzone::Buffer::getDRMFB() ...@@ -295,7 +294,7 @@ uint32_t DisplayOzone::Buffer::getDRMFB()
uint32_t offsets[4] = {0}; uint32_t offsets[4] = {0};
if (drmModeAddFB2(fd, mWidth, mHeight, mDRMFormatFB, handles, pitches, offsets, &mDRMFB, 0)) if (drmModeAddFB2(fd, mWidth, mHeight, mDRMFormatFB, handles, pitches, offsets, &mDRMFB, 0))
{ {
std::cerr << "drmModeAddFB2 failed" << std::endl; WARN() << "drmModeAddFB2 failed: " << errno << " " << strerror(errno);
} }
else else
{ {
...@@ -336,8 +335,8 @@ DisplayOzone::DisplayOzone(const egl::DisplayState &state) ...@@ -336,8 +335,8 @@ DisplayOzone::DisplayOzone(const egl::DisplayState &state)
mMode(nullptr), mMode(nullptr),
mCRTC(nullptr), mCRTC(nullptr),
mSetCRTC(true), mSetCRTC(true),
mWidth(0), mWidth(1280),
mHeight(0), mHeight(1024),
mScanning(nullptr), mScanning(nullptr),
mPending(nullptr), mPending(nullptr),
mDrawing(nullptr), mDrawing(nullptr),
...@@ -358,47 +357,21 @@ DisplayOzone::~DisplayOzone() ...@@ -358,47 +357,21 @@ DisplayOzone::~DisplayOzone()
{ {
} }
egl::Error DisplayOzone::initialize(egl::Display *display) bool DisplayOzone::hasUsableScreen(int fd)
{ {
int fd; drmModeResPtr resources = drmModeGetResources(fd);
char deviceName[30];
drmModeResPtr resources = nullptr;
for (int i = 0; i < 9; ++i)
{
snprintf(deviceName, sizeof(deviceName), "/dev/dri/card%d", i);
fd = open(deviceName, O_RDWR | O_CLOEXEC);
if (fd >= 0)
{
resources = drmModeGetResources(fd);
if (resources)
{
if (resources->count_connectors > 0)
{
break;
}
drmModeFreeResources(resources);
resources = nullptr;
}
close(fd);
}
}
if (!resources) if (!resources)
{ {
return egl::Error(EGL_NOT_INITIALIZED, "Could not open drm device."); return false;
} }
if (resources->count_connectors < 1)
mGBM = gbm_create_device(fd);
if (!mGBM)
{ {
close(fd);
drmModeFreeResources(resources); drmModeFreeResources(resources);
return egl::Error(EGL_NOT_INITIALIZED, "Could not create gbm device."); return false;
} }
mConnector = nullptr; mConnector = nullptr;
bool monitorConnected = false; for (int i = 0; i < resources->count_connectors; ++i)
for (int i = 0; !mCRTC && i < resources->count_connectors; ++i)
{ {
drmModeFreeConnector(mConnector); drmModeFreeConnector(mConnector);
mConnector = drmModeGetConnector(fd, resources->connectors[i]); mConnector = drmModeGetConnector(fd, resources->connectors[i]);
...@@ -406,7 +379,6 @@ egl::Error DisplayOzone::initialize(egl::Display *display) ...@@ -406,7 +379,6 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
{ {
continue; continue;
} }
monitorConnected = true;
mMode = ChooseMode(mConnector); mMode = ChooseMode(mConnector);
if (!mMode) if (!mMode)
{ {
...@@ -418,25 +390,68 @@ egl::Error DisplayOzone::initialize(egl::Display *display) ...@@ -418,25 +390,68 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
continue; continue;
} }
mCRTC = drmModeGetCrtc(fd, resources->crtcs[n]); mCRTC = drmModeGetCrtc(fd, resources->crtcs[n]);
}
drmModeFreeResources(resources);
if (mCRTC) if (mCRTC)
{ {
// found a screen
mGBM = gbm_create_device(fd);
if (mGBM)
{
mWidth = mMode->hdisplay; mWidth = mMode->hdisplay;
mHeight = mMode->vdisplay; mHeight = mMode->vdisplay;
drmModeFreeResources(resources);
return true;
}
// can't use this screen
drmModeFreeCrtc(mCRTC);
mCRTC = nullptr;
}
}
drmModeFreeResources(resources);
return false;
}
egl::Error DisplayOzone::initialize(egl::Display *display)
{
int fd;
char deviceName[30];
for (int i = 0; i < 64; ++i)
{
snprintf(deviceName, sizeof(deviceName), "/dev/dri/card%d", i);
fd = open(deviceName, O_RDWR | O_CLOEXEC);
if (fd >= 0)
{
if (hasUsableScreen(fd))
{
break;
}
close(fd);
}
} }
else if (!monitorConnected)
if (!mGBM)
{
// there's no usable screen so try to proceed without one
for (int i = 128; i < 192; ++i)
{ {
// Even though there is no monitor to show it, we still do snprintf(deviceName, sizeof(deviceName), "/dev/dri/renderD%d", i);
// everything the same as if there were one, so we need an fd = open(deviceName, O_RDWR | O_CLOEXEC);
// arbitrary size for our buffers. if (fd >= 0)
mWidth = 1280; {
mHeight = 1024; mGBM = gbm_create_device(fd);
if (mGBM)
{
break;
} }
else close(fd);
}
}
}
if (!mGBM)
{ {
return egl::Error(EGL_NOT_INITIALIZED, "Failed to choose mode/crtc."); return egl::Error(EGL_NOT_INITIALIZED, "Could not open drm device.");
} }
// ANGLE builds its executables with an RPATH so they pull in ANGLE's libGL and libEGL. // ANGLE builds its executables with an RPATH so they pull in ANGLE's libGL and libEGL.
...@@ -536,7 +551,7 @@ void DisplayOzone::presentScreen() ...@@ -536,7 +551,7 @@ void DisplayOzone::presentScreen()
pfd.events = POLLIN; pfd.events = POLLIN;
if (poll(&pfd, 1, 0) < 0) if (poll(&pfd, 1, 0) < 0)
{ {
std::cerr << "poll failed: " << errno << " " << strerror(errno) << std::endl; WARN() << "poll failed: " << errno << " " << strerror(errno);
} }
if (pfd.revents & POLLIN) if (pfd.revents & POLLIN)
{ {
...@@ -556,14 +571,14 @@ void DisplayOzone::presentScreen() ...@@ -556,14 +571,14 @@ void DisplayOzone::presentScreen()
if (drmModeSetCrtc(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), 0, 0, if (drmModeSetCrtc(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), 0, 0,
&mConnector->connector_id, 1, mMode)) &mConnector->connector_id, 1, mMode))
{ {
std::cerr << "set crtc failed: " << errno << " " << strerror(errno) << std::endl; WARN() << "set crtc failed: " << errno << " " << strerror(errno);
} }
mSetCRTC = false; mSetCRTC = false;
} }
if (drmModePageFlip(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), DRM_MODE_PAGE_FLIP_EVENT, if (drmModePageFlip(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), DRM_MODE_PAGE_FLIP_EVENT,
this)) this))
{ {
std::cerr << "page flip failed: " << errno << " " << strerror(errno) << std::endl; WARN() << "page flip failed: " << errno << " " << strerror(errno);
} }
mPending = mDrawing; mPending = mDrawing;
mDrawing = nullptr; mDrawing = nullptr;
...@@ -584,10 +599,7 @@ GLuint DisplayOzone::makeShader(GLuint type, const char *src) ...@@ -584,10 +599,7 @@ GLuint DisplayOzone::makeShader(GLuint type, const char *src)
gl->getShaderiv(shader, GL_COMPILE_STATUS, &compiled); gl->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (compiled != GL_TRUE) if (compiled != GL_TRUE)
{ {
// This code is solely for internal debugging of shaders in drawWithTexture(), WARN() << "DisplayOzone shader compilation error: " << buf;
// used when putting pixels on screen when running tests on ChromeOS device.
// Error will not propagate beyond ASSERT(linked) there.
ERR() << "DisplayOzone shader compilation error: " << buf;
} }
return shader; return shader;
...@@ -642,7 +654,11 @@ void DisplayOzone::drawWithTexture(Buffer *buffer) ...@@ -642,7 +654,11 @@ void DisplayOzone::drawWithTexture(Buffer *buffer)
gl->linkProgram(mProgram); gl->linkProgram(mProgram);
GLint linked; GLint linked;
gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked); gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT(linked); if (!linked)
{
WARN() << "shader link failed: cannot display buffer";
return;
}
mCenterUniform = gl->getUniformLocation(mProgram, "center"); mCenterUniform = gl->getUniformLocation(mProgram, "center");
mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize"); mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize");
mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize"); mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize");
...@@ -819,7 +835,11 @@ void DisplayOzone::terminate() ...@@ -819,7 +835,11 @@ void DisplayOzone::terminate()
SafeDelete(mEGL); SafeDelete(mEGL);
} }
drmModeFreeConnector(mConnector);
mConnector = nullptr;
mMode = nullptr;
drmModeFreeCrtc(mCRTC); drmModeFreeCrtc(mCRTC);
mCRTC = nullptr;
if (mGBM) if (mGBM)
{ {
......
...@@ -152,6 +152,7 @@ class DisplayOzone final : public DisplayEGL ...@@ -152,6 +152,7 @@ class DisplayOzone final : public DisplayEGL
void drawWithBlit(Buffer *buffer); void drawWithBlit(Buffer *buffer);
void drawWithTexture(Buffer *buffer); void drawWithTexture(Buffer *buffer);
void flushGL(); void flushGL();
bool hasUsableScreen(int fd);
void presentScreen(); void presentScreen();
static void pageFlipHandler(int fd, static void pageFlipHandler(int fd,
unsigned int sequence, unsigned int sequence,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment