Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EGLUtils: rework the way we choose the egl config #14514

Merged
merged 2 commits into from Oct 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 46 additions & 22 deletions xbmc/utils/EGLUtils.cpp
Expand Up @@ -93,7 +93,7 @@ bool CEGLContextUtils::CreateDisplay(EGLNativeDisplayType nativeDisplay, EGLint
return InitializeDisplay(renderableType, renderingApi);
}

bool CEGLContextUtils::CreatePlatformDisplay(void* nativeDisplay, EGLNativeDisplayType nativeDisplayLegacy, EGLint renderableType, EGLint renderingApi)
bool CEGLContextUtils::CreatePlatformDisplay(void* nativeDisplay, EGLNativeDisplayType nativeDisplayLegacy, EGLint renderableType, EGLint renderingApi, EGLint visualId)
{
if (m_eglDisplay != EGL_NO_DISPLAY)
{
Expand Down Expand Up @@ -123,10 +123,11 @@ bool CEGLContextUtils::CreatePlatformDisplay(void* nativeDisplay, EGLNativeDispl
{
return CreateDisplay(nativeDisplayLegacy, renderableType, renderingApi);
}
return InitializeDisplay(renderableType, renderingApi);

return InitializeDisplay(renderableType, renderingApi, visualId);
}

bool CEGLContextUtils::InitializeDisplay(EGLint renderableType, EGLint renderingApi)
bool CEGLContextUtils::InitializeDisplay(EGLint renderableType, EGLint renderingApi, EGLint visualId)
{
int major, minor;
if (!eglInitialize(m_eglDisplay, &major, &minor))
Expand All @@ -144,42 +145,65 @@ bool CEGLContextUtils::InitializeDisplay(EGLint renderableType, EGLint rendering
return false;
}

if (!ChooseConfig(renderableType, visualId))
return false;

return true;
}

bool CEGLContextUtils::ChooseConfig(EGLint renderableType, EGLint visualId)
{
EGLint numMatched{0};

EGLint surfaceType = EGL_WINDOW_BIT;
// for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates
if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION ||
g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION)
surfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;

EGLint attribs[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, 0,
EGL_SURFACE_TYPE, surfaceType,
EGL_RENDERABLE_TYPE, renderableType,
EGL_NONE
};

EGLint neglconfigs = 0;
if (eglChooseConfig(m_eglDisplay, attribs, &m_eglConfig, 1, &neglconfigs) != EGL_TRUE)
CEGLAttributes<10> attribs;
attribs.Add({{EGL_RED_SIZE, 8},
{EGL_GREEN_SIZE, 8},
{EGL_BLUE_SIZE, 8},
{EGL_ALPHA_SIZE, 2},
{EGL_DEPTH_SIZE, 16},

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

{EGL_STENCIL_SIZE, 0},
{EGL_SAMPLE_BUFFERS, 0},
{EGL_SAMPLES, 0},
{EGL_SURFACE_TYPE, surfaceType},
{EGL_RENDERABLE_TYPE, renderableType}});

if (eglChooseConfig(m_eglDisplay, attribs.Get(), nullptr, 0, &numMatched) != EGL_TRUE)
{
CEGLUtils::LogError("failed to query number of EGL configs");
Destroy();
return false;
}

if (neglconfigs <= 0)
std::vector<EGLConfig> eglConfigs(numMatched);

if (eglChooseConfig(m_eglDisplay, attribs.Get(), eglConfigs.data(), numMatched, &numMatched) != EGL_TRUE)
{
CLog::Log(LOGERROR, "No suitable EGL configs found");
CEGLUtils::LogError("failed to find EGL configs with appropriate attributes");
Destroy();
return false;
}

for (const auto &eglConfig: eglConfigs)
{
m_eglConfig = eglConfig;

if (visualId == 0)
break;

EGLint id{0};
if (eglGetConfigAttrib(m_eglDisplay, m_eglConfig, EGL_NATIVE_VISUAL_ID, &id) != EGL_TRUE)
CEGLUtils::LogError("failed to query EGL attibute EGL_NATIVE_VISUAL_ID");

if (visualId == id)
break;
}

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

return true;
}

Expand Down
5 changes: 3 additions & 2 deletions xbmc/utils/EGLUtils.h
Expand Up @@ -131,7 +131,7 @@ class CEGLContextUtils final
* \param nativeDisplay native display to use with eglGetPlatformDisplayEXT
* \param nativeDisplayLegacy native display to use with eglGetDisplay
*/
bool CreatePlatformDisplay(void* nativeDisplay, EGLNativeDisplayType nativeDisplayLegacy, EGLint renderableType, EGLint renderingApi);
bool CreatePlatformDisplay(void* nativeDisplay, EGLNativeDisplayType nativeDisplayLegacy, EGLint renderableType, EGLint renderingApi, EGLint visualId = 0);

bool CreateSurface(EGLNativeWindowType nativeWindow);
bool CreatePlatformSurface(void* nativeWindow, EGLNativeWindowType nativeWindowLegacy);
Expand Down Expand Up @@ -162,7 +162,8 @@ class CEGLContextUtils final
}

private:
bool InitializeDisplay(EGLint renderableType, EGLint renderingApi);
bool InitializeDisplay(EGLint renderableType, EGLint renderingApi, EGLint visualId = 0);
bool ChooseConfig(EGLint renderableType, EGLint visualId);
void SurfaceAttrib();

EGLenum m_platform{EGL_NONE};
Expand Down
4 changes: 2 additions & 2 deletions xbmc/windowing/gbm/DRMAtomic.cpp
Expand Up @@ -99,9 +99,9 @@ void CDRMAtomic::FlipPage(struct gbm_bo *bo, bool rendered, bool videoLayer)
if (rendered)
{
if (videoLayer)
m_overlay_plane->format = DRM_FORMAT_ARGB8888;
m_overlay_plane->format = CDRMUtils::FourCCWithAlpha(m_overlay_plane->format);
else
m_overlay_plane->format = DRM_FORMAT_XRGB8888;
m_overlay_plane->format = CDRMUtils::FourCCWithoutAlpha(m_overlay_plane->format);

drm_fb = CDRMUtils::DrmFbGetFromBo(bo);
if (!drm_fb)
Expand Down
10 changes: 10 additions & 0 deletions xbmc/windowing/gbm/DRMUtils.cpp
Expand Up @@ -727,3 +727,13 @@ std::vector<RESOLUTION_INFO> CDRMUtils::GetModes()

return resolutions;
}

uint32_t CDRMUtils::FourCCWithAlpha(uint32_t fourcc)
{
return (fourcc & 0xFFFFFF00) | static_cast<uint32_t>('A');
}

uint32_t CDRMUtils::FourCCWithoutAlpha(uint32_t fourcc)
{
return (fourcc & 0xFFFFFF00) | static_cast<uint32_t>('X');
}
3 changes: 3 additions & 0 deletions xbmc/windowing/gbm/DRMUtils.h
Expand Up @@ -89,6 +89,9 @@ class CDRMUtils
virtual bool AddProperty(struct drm_object *object, const char *name, uint64_t value) { return false; }
virtual bool SetProperty(struct drm_object *object, const char *name, uint64_t value) { return false; }

static uint32_t FourCCWithAlpha(uint32_t fourcc);
static uint32_t FourCCWithoutAlpha(uint32_t fourcc);

protected:
bool OpenDrm(bool needConnector);
uint32_t GetPropertyId(struct drm_object *object, const char *name);
Expand Down
5 changes: 4 additions & 1 deletion xbmc/windowing/gbm/WinSystemGbmEGLContext.cpp
Expand Up @@ -22,7 +22,10 @@ bool CWinSystemGbmEGLContext::InitWindowSystemEGL(EGLint renderableType, EGLint
return false;
}

if (!m_eglContext.CreatePlatformDisplay(m_GBM->GetDevice(), m_GBM->GetDevice(), renderableType, apiType))
// we need to provide an alpha format to egl to workaround a mesa bug
int visualId = CDRMUtils::FourCCWithAlpha(CWinSystemGbm::GetDrm()->GetOverlayPlane()->format);

if (!m_eglContext.CreatePlatformDisplay(m_GBM->GetDevice(), m_GBM->GetDevice(), renderableType, apiType, visualId))
{
return false;
}
Expand Down