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 @@
#include <fcntl.h>
#include <poll.h>
#include <iostream>
#include <unistd.h>
#include <sys/time.h>
......@@ -295,7 +294,7 @@ uint32_t DisplayOzone::Buffer::getDRMFB()
uint32_t offsets[4] = {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
{
......@@ -336,8 +335,8 @@ DisplayOzone::DisplayOzone(const egl::DisplayState &state)
mMode(nullptr),
mCRTC(nullptr),
mSetCRTC(true),
mWidth(0),
mHeight(0),
mWidth(1280),
mHeight(1024),
mScanning(nullptr),
mPending(nullptr),
mDrawing(nullptr),
......@@ -358,47 +357,21 @@ DisplayOzone::~DisplayOzone()
{
}
egl::Error DisplayOzone::initialize(egl::Display *display)
bool DisplayOzone::hasUsableScreen(int fd)
{
int 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);
}
}
drmModeResPtr resources = drmModeGetResources(fd);
if (!resources)
{
return egl::Error(EGL_NOT_INITIALIZED, "Could not open drm device.");
return false;
}
mGBM = gbm_create_device(fd);
if (!mGBM)
if (resources->count_connectors < 1)
{
close(fd);
drmModeFreeResources(resources);
return egl::Error(EGL_NOT_INITIALIZED, "Could not create gbm device.");
return false;
}
mConnector = nullptr;
bool monitorConnected = false;
for (int i = 0; !mCRTC && i < resources->count_connectors; ++i)
mConnector = nullptr;
for (int i = 0; i < resources->count_connectors; ++i)
{
drmModeFreeConnector(mConnector);
mConnector = drmModeGetConnector(fd, resources->connectors[i]);
......@@ -406,7 +379,6 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
{
continue;
}
monitorConnected = true;
mMode = ChooseMode(mConnector);
if (!mMode)
{
......@@ -418,25 +390,68 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
continue;
}
mCRTC = drmModeGetCrtc(fd, resources->crtcs[n]);
if (mCRTC)
{
// found a screen
mGBM = gbm_create_device(fd);
if (mGBM)
{
mWidth = mMode->hdisplay;
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];
if (mCRTC)
for (int i = 0; i < 64; ++i)
{
mWidth = mMode->hdisplay;
mHeight = mMode->vdisplay;
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)
{
// Even though there is no monitor to show it, we still do
// everything the same as if there were one, so we need an
// arbitrary size for our buffers.
mWidth = 1280;
mHeight = 1024;
// there's no usable screen so try to proceed without one
for (int i = 128; i < 192; ++i)
{
snprintf(deviceName, sizeof(deviceName), "/dev/dri/renderD%d", i);
fd = open(deviceName, O_RDWR | O_CLOEXEC);
if (fd >= 0)
{
mGBM = gbm_create_device(fd);
if (mGBM)
{
break;
}
close(fd);
}
}
}
else
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.
......@@ -536,7 +551,7 @@ void DisplayOzone::presentScreen()
pfd.events = POLLIN;
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)
{
......@@ -556,14 +571,14 @@ void DisplayOzone::presentScreen()
if (drmModeSetCrtc(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), 0, 0,
&mConnector->connector_id, 1, mMode))
{
std::cerr << "set crtc failed: " << errno << " " << strerror(errno) << std::endl;
WARN() << "set crtc failed: " << errno << " " << strerror(errno);
}
mSetCRTC = false;
}
if (drmModePageFlip(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), DRM_MODE_PAGE_FLIP_EVENT,
this))
{
std::cerr << "page flip failed: " << errno << " " << strerror(errno) << std::endl;
WARN() << "page flip failed: " << errno << " " << strerror(errno);
}
mPending = mDrawing;
mDrawing = nullptr;
......@@ -584,10 +599,7 @@ GLuint DisplayOzone::makeShader(GLuint type, const char *src)
gl->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (compiled != GL_TRUE)
{
// This code is solely for internal debugging of shaders in drawWithTexture(),
// 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;
WARN() << "DisplayOzone shader compilation error: " << buf;
}
return shader;
......@@ -642,7 +654,11 @@ void DisplayOzone::drawWithTexture(Buffer *buffer)
gl->linkProgram(mProgram);
GLint 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");
mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize");
mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize");
......@@ -819,7 +835,11 @@ void DisplayOzone::terminate()
SafeDelete(mEGL);
}
drmModeFreeConnector(mConnector);
mConnector = nullptr;
mMode = nullptr;
drmModeFreeCrtc(mCRTC);
mCRTC = nullptr;
if (mGBM)
{
......
......@@ -152,6 +152,7 @@ class DisplayOzone final : public DisplayEGL
void drawWithBlit(Buffer *buffer);
void drawWithTexture(Buffer *buffer);
void flushGL();
bool hasUsableScreen(int fd);
void presentScreen();
static void pageFlipHandler(int fd,
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