Skip to content

Commit

Permalink
windowing/gbm: add drm modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
lrusak committed Jul 27, 2018
1 parent a9daa0f commit 21de917
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 12 deletions.
11 changes: 11 additions & 0 deletions cmake/modules/FindGBM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,24 @@ check_c_source_compiles("#include <gbm.h>
}
" GBM_HAS_BO_MAP)

check_c_source_compiles("#include <gbm.h>
int main()
{
gbm_surface_create_with_modifiers(NULL, 0, 0, 0, NULL, 0);
}
" GBM_HAS_MODIFIERS)

if(GBM_FOUND)
set(GBM_LIBRARIES ${GBM_LIBRARY})
set(GBM_INCLUDE_DIRS ${GBM_INCLUDE_DIR})
set(GBM_DEFINITIONS -DHAVE_GBM=1)
if(GBM_HAS_BO_MAP)
list(APPEND GBM_DEFINITIONS -DHAS_GBM_BO_MAP=1)
endif()
if(GBM_HAS_MODIFIERS)
list(APPEND GBM_DEFINITIONS -DHAS_GBM_MODIFIERS=1)
endif()
if(NOT TARGET GBM::GBM)
add_library(GBM::GBM UNKNOWN IMPORTED)
set_target_properties(GBM::GBM PROPERTIES
Expand Down
85 changes: 76 additions & 9 deletions xbmc/windowing/gbm/DRMUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,40 @@ drm_fb * CDRMUtils::DrmFbGetFromBo(struct gbm_bo *bo)
strides[4] = {0},
offsets[4] = {0};

uint64_t modifiers[4] = {0};

width = gbm_bo_get_width(bo);
height = gbm_bo_get_height(bo);

#if defined(HAS_GBM_MODIFIERS)
for (int i = 0; i < gbm_bo_get_plane_count(bo); i++)
{
handles[i] = gbm_bo_get_handle_for_plane(bo, i).u32;
strides[i] = gbm_bo_get_stride_for_plane(bo, i);
offsets[i] = gbm_bo_get_offset(bo, i);
modifiers[i] = gbm_bo_get_modifier(bo);
}
#else
handles[0] = gbm_bo_get_handle(bo).u32;
strides[0] = gbm_bo_get_stride(bo);
memset(offsets, 0, 16);
#endif

if (modifiers[0] == DRM_FORMAT_MOD_INVALID)
modifiers[0] = DRM_FORMAT_MOD_LINEAR;

auto ret = drmModeAddFB2(m_fd,
width,
height,
fb->format,
handles,
strides,
offsets,
&fb->fb_id,
0);
CLog::Log(LOGDEBUG, "CDRMUtils::%s - using modifier: %lli", __FUNCTION__, modifiers[0]);

auto ret = drmModeAddFB2WithModifiers(m_fd,
width,
height,
fb->format,
handles,
strides,
offsets,
modifiers,
&fb->fb_id,
(modifiers[0] > 0) ? DRM_MODE_FB_MODIFIERS : 0);

if(ret)
{
Expand Down Expand Up @@ -414,6 +432,11 @@ bool CDRMUtils::FindPlanes()
CLog::Log(LOGERROR, "CDRMUtils::%s - could not get primary plane %u properties: %s", __FUNCTION__, m_primary_plane->plane->plane_id, strerror(errno));
return false;
}

if (!FindModifiersForPlane(m_primary_plane))
{
CLog::Log(LOGDEBUG, "CDRMUtils::%s - no drm modifiers present for the primary plane", __FUNCTION__);
}
}

// overlay plane should always be available
Expand All @@ -423,6 +446,50 @@ bool CDRMUtils::FindPlanes()
return false;
}

if (!FindModifiersForPlane(m_overlay_plane))
{
CLog::Log(LOGDEBUG, "CDRMUtils::%s - no drm modifiers present for the overlay plane", __FUNCTION__);
}

return true;
}

bool CDRMUtils::FindModifiersForPlane(struct plane *object)
{
uint64_t blob_id = 0;

for (uint32_t i = 0; i < object->props->count_props; i++)
{
if (strcmp(object->props_info[i]->name, "IN_FORMATS") == 0)
blob_id = object->props->prop_values[i];
}

if (blob_id == 0)
return false;

drmModePropertyBlobPtr blob = drmModeGetPropertyBlob(m_fd, blob_id);
if (!blob)
return false;

drm_format_modifier_blob *header = static_cast<drm_format_modifier_blob*>(blob->data);
uint32_t *formats = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(header) + header->formats_offset);
drm_format_modifier *mod = reinterpret_cast<drm_format_modifier*>(reinterpret_cast<char*>(header) + header->modifiers_offset);

for (uint32_t i = 0; i < header->count_formats; i++)
{
std::vector<uint64_t> modifiers;
for (uint32_t j = 0; j < header->count_modifiers; j++)
{
if (mod[j].formats & 1ULL << i)
modifiers.emplace_back(mod[j].modifier);
}

object->modifiers_map.emplace(formats[i], modifiers);
}

if (blob)
drmModeFreePropertyBlob(blob);

return true;
}

Expand Down
5 changes: 5 additions & 0 deletions xbmc/windowing/gbm/DRMUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#include <map>
#include <vector>

#include "windowing/Resolution.h"
Expand All @@ -47,6 +48,7 @@ struct plane : drm_object
{
drmModePlanePtr plane = nullptr;
uint32_t format = DRM_FORMAT_XRGB8888;
std::map<uint32_t, std::vector<uint64_t>> modifiers_map;
};

struct connector : drm_object
Expand Down Expand Up @@ -87,6 +89,8 @@ class CDRMUtils
int GetFileDescriptor() const { return m_fd; }
struct plane* GetPrimaryPlane() const { return m_primary_plane; }
struct plane* GetOverlayPlane() const { return m_overlay_plane; }
std::vector<uint64_t> *GetPrimaryPlaneModifiersForFormat(uint32_t format) { return &m_primary_plane->modifiers_map[format]; }
std::vector<uint64_t> *GetOverlayPlaneModifiersForFormat(uint32_t format) { return &m_overlay_plane->modifiers_map[format]; }
struct crtc* GetCrtc() const { return m_crtc; }

virtual RESOLUTION_INFO GetCurrentMode();
Expand Down Expand Up @@ -124,6 +128,7 @@ class CDRMUtils
bool FindEncoder();
bool FindCrtc();
bool FindPlanes();
bool FindModifiersForPlane(struct plane *object);
bool FindPreferredMode();
bool RestoreOriginalMode();
static void DrmFbDestroyCallback(struct gbm_bo *bo, void *data);
Expand Down
11 changes: 10 additions & 1 deletion xbmc/windowing/gbm/GBMUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,25 @@ void CGBMUtils::DestroyDevice()
}
}

bool CGBMUtils::CreateSurface(int width, int height)
bool CGBMUtils::CreateSurface(int width, int height, const uint64_t *modifiers, const int modifiers_count)
{
if (m_surface)
CLog::Log(LOGWARNING, "CGBMUtils::%s - surface already created", __FUNCTION__);

#if defined(HAS_GBM_MODIFIERS)
m_surface = gbm_surface_create_with_modifiers(m_device,
width,
height,
GBM_FORMAT_ARGB8888,
modifiers,
modifiers_count);
#else
m_surface = gbm_surface_create(m_device,
width,
height,
GBM_FORMAT_ARGB8888,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
#endif

if (!m_surface)
{
Expand Down
2 changes: 1 addition & 1 deletion xbmc/windowing/gbm/GBMUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CGBMUtils
~CGBMUtils() = default;
bool CreateDevice(int fd);
void DestroyDevice();
bool CreateSurface(int width, int height);
bool CreateSurface(int width, int height, const uint64_t *modifiers, const int modifiers_count);
void DestroySurface();
struct gbm_bo *LockFrontBuffer();
void ReleaseBuffer();
Expand Down
4 changes: 3 additions & 1 deletion xbmc/windowing/gbm/WinSystemGbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ bool CWinSystemGbm::CreateNewWindow(const std::string& name,
return false;
}

if(!m_GBM->CreateSurface(res.iWidth, res.iHeight))
std::vector<uint64_t> *modifiers = m_DRM->GetOverlayPlaneModifiersForFormat(m_DRM->GetOverlayPlane()->format);

if (!m_GBM->CreateSurface(res.iWidth, res.iHeight, modifiers->data(), modifiers->size()))
{
CLog::Log(LOGERROR, "CWinSystemGbm::%s - failed to initialize GBM", __FUNCTION__);
return false;
Expand Down

0 comments on commit 21de917

Please sign in to comment.