| 148 | } |
| 149 | |
| 150 | DrmFb* drmFbGetFromBo(gbm_bo& bo) |
| 151 | { |
| 152 | const int drmFd = gbm_device_get_fd(gbm_bo_get_device(&bo)); |
| 153 | auto* fb = static_cast<DrmFb*>(gbm_bo_get_user_data(&bo)); |
| 154 | if (fb) |
| 155 | return fb; |
| 156 | |
| 157 | fb = new DrmFb(); |
| 158 | fb->bo = &bo; |
| 159 | |
| 160 | const std::uint32_t width = gbm_bo_get_width(&bo); |
| 161 | const std::uint32_t height = gbm_bo_get_height(&bo); |
| 162 | const std::uint32_t format = gbm_bo_get_format(&bo); |
| 163 | |
| 164 | std::array<std::uint32_t, 4> strides{}; |
| 165 | std::array<std::uint32_t, 4> handles{}; |
| 166 | std::array<std::uint32_t, 4> offsets{}; |
| 167 | std::array<std::uint64_t, 4> modifiers{}; |
| 168 | modifiers[0] = gbm_bo_get_modifier(&bo); |
| 169 | const int numPlanes = gbm_bo_get_plane_count(&bo); |
| 170 | for (int i = 0; i < numPlanes; ++i) |
| 171 | { |
| 172 | strides[static_cast<std::size_t>(i)] = gbm_bo_get_stride_for_plane(&bo, i); |
| 173 | handles[static_cast<std::size_t>(i)] = gbm_bo_get_handle(&bo).u32; |
| 174 | offsets[static_cast<std::size_t>(i)] = gbm_bo_get_offset(&bo, i); |
| 175 | modifiers[static_cast<std::size_t>(i)] = modifiers[0]; |
| 176 | } |
| 177 | |
| 178 | const std::uint32_t flags = modifiers[0] ? DRM_MODE_FB_MODIFIERS : 0; |
| 179 | int result = drmModeAddFB2WithModifiers(drmFd, |
| 180 | width, |
| 181 | height, |
| 182 | format, |
| 183 | handles.data(), |
| 184 | strides.data(), |
| 185 | offsets.data(), |
| 186 | modifiers.data(), |
| 187 | &fb->fbId, |
| 188 | flags); |
| 189 | |
| 190 | if (result) |
| 191 | { |
| 192 | handles.fill(0); |
| 193 | handles[0] = gbm_bo_get_handle(&bo).u32; |
| 194 | strides.fill(0); |
| 195 | strides[0] = gbm_bo_get_stride(&bo); |
| 196 | offsets.fill(0); |
| 197 | result = drmModeAddFB2(drmFd, width, height, format, handles.data(), strides.data(), offsets.data(), &fb->fbId, 0); |
| 198 | } |
| 199 | |
| 200 | if (result) |
| 201 | { |
| 202 | sf::err() << "Failed to create fb: " << std::strerror(errno) << std::endl; |
| 203 | delete fb; |
| 204 | return nullptr; |
| 205 | } |
| 206 | |
| 207 | gbm_bo_set_user_data(&bo, fb, drmFbDestroyCallback); |