John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 1 | /* |
| 2 | * drm_display.cpp - drm display |
| 3 | * |
| 4 | * Copyright (c) 2015 Intel Corporation |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | * you may not use this file except in compliance with the License. |
| 8 | * You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, software |
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | * See the License for the specific language governing permissions and |
| 16 | * limitations under the License. |
| 17 | * |
| 18 | * Author: John Ye <john.ye@intel.com> |
| 19 | */ |
| 20 | |
| 21 | |
| 22 | #include "drm_display.h" |
| 23 | #include "drm_v4l2_buffer.h" |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 24 | #include "drm_bo_buffer.h" |
Wind Yuan | 95e5b36 | 2015-03-27 15:17:50 +0800 | [diff] [blame] | 25 | #include <drm_fourcc.h> |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 26 | |
| 27 | #define DEFAULT_DRM_DEVICE "i915" |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 28 | #define DEFAULT_DRM_BATCH_SIZE 0x80000 |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 29 | |
| 30 | namespace XCam { |
| 31 | |
| 32 | SmartPtr<DrmDisplay> DrmDisplay::_instance(NULL); |
| 33 | Mutex DrmDisplay::_mutex; |
| 34 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 35 | static std::atomic<uint32_t> global_signal_index(0); |
| 36 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 37 | SmartPtr<DrmDisplay> |
| 38 | DrmDisplay::instance() |
| 39 | { |
| 40 | SmartLock lock(_mutex); |
| 41 | if (_instance.ptr()) |
| 42 | return _instance; |
| 43 | _instance = new DrmDisplay; |
| 44 | return _instance; |
| 45 | } |
| 46 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 47 | DrmDisplay::DrmDisplay(const char* module) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 48 | : _module(NULL) |
| 49 | , _fd (-1) |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 50 | , _buf_manager (NULL) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 51 | , _crtc_index (-1) |
| 52 | , _crtc_id (0) |
| 53 | , _con_id (0) |
| 54 | , _plane_id (0) |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 55 | , _connector (NULL) |
| 56 | , _is_render_inited (false) |
John Ye | cef3680 | 2015-01-26 16:00:16 +0800 | [diff] [blame] | 57 | , _format (0) |
| 58 | , _width (0) |
| 59 | , _height (0) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 60 | { |
John Ye | cef3680 | 2015-01-26 16:00:16 +0800 | [diff] [blame] | 61 | xcam_mem_clear(&_compose); |
| 62 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 63 | if (module) |
| 64 | _module = strdup (module); |
| 65 | else |
| 66 | _module = strdup (DEFAULT_DRM_DEVICE); |
| 67 | |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 68 | //_fd = drmOpenRender (128); |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 69 | _fd = drmOpen (_module, NULL); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 70 | if (_fd < 0) |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 71 | XCAM_LOG_ERROR("failed to open drm device %s", _module); |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 72 | |
| 73 | _buf_manager = drm_intel_bufmgr_gem_init (_fd, DEFAULT_DRM_BATCH_SIZE); |
| 74 | drm_intel_bufmgr_gem_enable_reuse (_buf_manager); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 75 | } |
| 76 | |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 77 | DrmDisplay::~DrmDisplay() |
| 78 | { |
| 79 | if (_buf_manager) |
| 80 | drm_intel_bufmgr_destroy (_buf_manager); |
| 81 | if (_fd > 0) |
| 82 | drmClose(_fd); |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 83 | if (_module) |
| 84 | xcam_free (_module); |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 85 | }; |
| 86 | |
Wind Yuan | 95e5b36 | 2015-03-27 15:17:50 +0800 | [diff] [blame] | 87 | uint32_t |
| 88 | DrmDisplay::to_drm_fourcc (uint32_t fourcc_of_v4l2) |
| 89 | { |
| 90 | switch (fourcc_of_v4l2) { |
| 91 | case V4L2_PIX_FMT_RGB565: |
| 92 | return DRM_FORMAT_RGB565; |
| 93 | default: |
| 94 | break; |
| 95 | } |
| 96 | return fourcc_of_v4l2; |
| 97 | } |
| 98 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 99 | XCamReturn |
| 100 | DrmDisplay::get_crtc(drmModeRes *res) |
| 101 | { |
| 102 | _crtc_index = -1; |
| 103 | |
| 104 | for (int i = 0; i < res->count_crtcs; i++) { |
| 105 | if (_crtc_id == res->crtcs[i]) { |
| 106 | _crtc_index = i; |
| 107 | break; |
| 108 | } |
| 109 | } |
| 110 | XCAM_FAIL_RETURN(ERROR, _crtc_index != -1, XCAM_RETURN_ERROR_PARAM, |
| 111 | "CRTC %d not found", _crtc_id); |
| 112 | |
| 113 | return XCAM_RETURN_NO_ERROR; |
| 114 | } |
| 115 | |
| 116 | XCamReturn |
| 117 | DrmDisplay::get_connector(drmModeRes *res) |
| 118 | { |
| 119 | XCAM_FAIL_RETURN(ERROR, res->count_connectors > 0, XCAM_RETURN_ERROR_PARAM, |
| 120 | "No connector found"); |
| 121 | _connector = drmModeGetConnector(_fd, _con_id); |
| 122 | XCAM_FAIL_RETURN(ERROR, _connector, XCAM_RETURN_ERROR_PARAM, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 123 | "drmModeGetConnector failed: %s", strerror(errno)); |
Wind Yuan | 024e1f3 | 2015-03-30 16:27:41 +0800 | [diff] [blame] | 124 | XCAM_FAIL_RETURN(ERROR, _connector->connection == DRM_MODE_CONNECTED, |
| 125 | XCAM_RETURN_ERROR_PARAM, "get_connector failed since it is not connected"); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 126 | |
| 127 | return XCAM_RETURN_NO_ERROR; |
| 128 | } |
| 129 | |
| 130 | |
| 131 | XCamReturn |
| 132 | DrmDisplay::get_plane() |
| 133 | { |
| 134 | drmModePlaneResPtr planes = drmModeGetPlaneResources(_fd); |
| 135 | XCAM_FAIL_RETURN(ERROR, planes, XCAM_RETURN_ERROR_PARAM, |
| 136 | "failed to query planes: %s", strerror(errno)); |
| 137 | |
| 138 | drmModePlanePtr plane = NULL; |
| 139 | for (uint32_t i = 0; i < planes->count_planes; i++) { |
| 140 | if (plane) { |
| 141 | drmModeFreePlane(plane); |
| 142 | plane = NULL; |
| 143 | } |
| 144 | plane = drmModeGetPlane(_fd, planes->planes[i]); |
| 145 | XCAM_FAIL_RETURN(ERROR, plane, XCAM_RETURN_ERROR_PARAM, |
| 146 | "failed to query plane %d: %s", i, strerror(errno)); |
| 147 | |
| 148 | if (plane->crtc_id || !(plane->possible_crtcs & (1 << _crtc_index))) { |
| 149 | continue; |
| 150 | } |
| 151 | |
| 152 | for (uint32_t j = 0; j < plane->count_formats; j++) { |
| 153 | // found a plane matching the requested format |
| 154 | if (plane->formats[j] == _format) { |
| 155 | _plane_id = plane->plane_id; |
| 156 | drmModeFreePlane(plane); |
| 157 | drmModeFreePlaneResources(planes); |
| 158 | return XCAM_RETURN_NO_ERROR; |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | if (plane) |
| 164 | drmModeFreePlane(plane); |
| 165 | |
| 166 | drmModeFreePlaneResources(planes); |
| 167 | |
| 168 | return XCAM_RETURN_ERROR_PARAM; |
| 169 | } |
| 170 | |
| 171 | XCamReturn |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 172 | DrmDisplay::render_init ( |
| 173 | uint32_t con_id, |
| 174 | uint32_t crtc_id, |
| 175 | uint32_t width, |
| 176 | uint32_t height, |
| 177 | uint32_t format, |
| 178 | const struct v4l2_rect* compose) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 179 | { |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 180 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 181 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 182 | if (is_render_inited ()) |
| 183 | return ret; |
| 184 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 185 | _con_id = con_id; |
| 186 | _crtc_id = crtc_id; |
| 187 | _width = width; |
| 188 | _height = height; |
Wind Yuan | 95e5b36 | 2015-03-27 15:17:50 +0800 | [diff] [blame] | 189 | _format = to_drm_fourcc (format); |
John Ye | cef3680 | 2015-01-26 16:00:16 +0800 | [diff] [blame] | 190 | _compose = *compose; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 191 | _crtc_index = -1; |
| 192 | _plane_id = 0; |
| 193 | _connector = NULL; |
| 194 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 195 | drmModeRes *resource = drmModeGetResources(_fd); |
| 196 | XCAM_FAIL_RETURN(ERROR, resource, XCAM_RETURN_ERROR_PARAM, |
| 197 | "failed to query Drm Mode resources: %s", strerror(errno)); |
| 198 | |
| 199 | ret = get_crtc(resource); |
| 200 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, |
| 201 | XCAM_RETURN_ERROR_PARAM, |
| 202 | "failed to get CRTC %s", strerror(errno)); |
| 203 | |
| 204 | ret = get_connector(resource); |
| 205 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, |
| 206 | XCAM_RETURN_ERROR_PARAM, |
| 207 | "failed to get connector %s", strerror(errno)); |
| 208 | |
| 209 | ret = get_plane(); |
| 210 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, |
| 211 | XCAM_RETURN_ERROR_PARAM, |
| 212 | "failed to get plane with required format %s", strerror(errno)); |
| 213 | |
| 214 | drmModeFreeResources(resource); |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 215 | |
| 216 | _is_render_inited = true; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 217 | return XCAM_RETURN_NO_ERROR; |
| 218 | } |
| 219 | |
| 220 | |
| 221 | SmartPtr<V4l2Buffer> |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 222 | DrmDisplay::create_drm_buf ( |
| 223 | const struct v4l2_format &format, |
| 224 | const uint32_t index, |
| 225 | const enum v4l2_buf_type buf_type) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 226 | { |
| 227 | struct drm_mode_create_dumb gem; |
| 228 | struct drm_prime_handle prime; |
| 229 | struct v4l2_buffer v4l2_buf; |
| 230 | int ret = 0; |
| 231 | |
| 232 | xcam_mem_clear (&gem); |
| 233 | xcam_mem_clear (&prime); |
| 234 | xcam_mem_clear (&v4l2_buf); |
| 235 | |
| 236 | gem.width = format.fmt.pix.bytesperline; |
| 237 | gem.height = format.fmt.pix.height; |
| 238 | gem.bpp = 8; |
| 239 | ret = xcam_device_ioctl (_fd, DRM_IOCTL_MODE_CREATE_DUMB, &gem); |
| 240 | XCAM_ASSERT (ret >= 0); |
| 241 | |
| 242 | prime.handle = gem.handle; |
| 243 | ret = xcam_device_ioctl (_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime); |
| 244 | if (ret < 0) { |
| 245 | XCAM_LOG_WARNING ("create drm failed on DRM_IOCTL_PRIME_HANDLE_TO_FD"); |
| 246 | return NULL; |
| 247 | } |
| 248 | |
| 249 | v4l2_buf.index = index; |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 250 | v4l2_buf.type = buf_type; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 251 | v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| 252 | v4l2_buf.m.fd = prime.fd; |
| 253 | v4l2_buf.length = XCAM_MAX (format.fmt.pix.sizeimage, gem.size); // todo check gem.size and format.fmt.pix.length |
| 254 | XCAM_LOG_DEBUG ("create drm buffer size:%lld", gem.size); |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 255 | return new DrmV4l2Buffer (gem.handle, v4l2_buf, format, _instance); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 256 | } |
| 257 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 258 | XCamReturn |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 259 | DrmDisplay::render_setup_frame_buffer (SmartPtr<VideoBuffer> &buf) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 260 | { |
| 261 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 262 | VideoBufferInfo video_info = buf->get_video_info (); |
| 263 | uint32_t fourcc = video_info.format; |
| 264 | uint32_t fb_handle = 0; |
| 265 | uint32_t bo_handle = 0; |
| 266 | uint32_t bo_handles[4] = { 0 }; |
| 267 | FB fb; |
| 268 | SmartPtr<V4l2BufferProxy> v4l2_proxy; |
| 269 | SmartPtr<DrmBoBuffer> bo_buf; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 270 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 271 | if (has_frame_buffer (buf)) |
| 272 | return XCAM_RETURN_NO_ERROR; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 273 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 274 | v4l2_proxy = buf.dynamic_cast_ptr<V4l2BufferProxy> (); |
| 275 | bo_buf = buf.dynamic_cast_ptr<DrmBoBuffer> (); |
| 276 | if (v4l2_proxy.ptr ()) { |
| 277 | struct drm_prime_handle prime; |
| 278 | memset(&prime, 0, sizeof (prime)); |
| 279 | prime.fd = v4l2_proxy->get_v4l2_dma_fd(); |
| 280 | |
| 281 | ret = (XCamReturn) xcam_device_ioctl(_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime); |
| 282 | if (ret) { |
| 283 | XCAM_LOG_WARNING("FD_TO_PRIME_HANDLE failed: %s", strerror(errno)); |
| 284 | return XCAM_RETURN_ERROR_IOCTL; |
| 285 | } |
| 286 | bo_handle = prime.handle; |
| 287 | } else if (bo_buf.ptr ()) { |
| 288 | const drm_intel_bo* bo = bo_buf->get_bo (); |
| 289 | bo_handle = bo->handle; |
| 290 | } else { |
| 291 | XCAM_ASSERT (false); |
| 292 | XCAM_LOG_WARNING("drm setup framebuffer doesn't support this buffer"); |
| 293 | return XCAM_RETURN_ERROR_PARAM; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 294 | } |
| 295 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 296 | for (uint32_t i = 0; i < 4; ++i) { |
| 297 | bo_handles [i] = bo_handle; |
| 298 | } |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 299 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 300 | ret = (XCamReturn) drmModeAddFB2(_fd, video_info.width, video_info.height, fourcc, bo_handles, |
| 301 | video_info.strides, video_info.offsets, &fb_handle, 0); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 302 | |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 303 | fb.fb_handle = fb_handle; |
| 304 | fb.index = global_signal_index++; |
| 305 | _buf_fb_handles[buf.ptr ()] = fb; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 306 | |
| 307 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_PARAM, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 308 | "drmModeAddFB2 failed: %s", strerror(errno)); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 309 | |
| 310 | return ret; |
| 311 | } |
| 312 | |
| 313 | XCamReturn |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 314 | DrmDisplay::set_plane (const FB &fb) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 315 | { |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 316 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
| 317 | uint32_t fb_handle = fb.fb_handle; |
| 318 | uint32_t index = fb.index; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 319 | |
| 320 | ret = (XCamReturn) drmModeSetPlane(_fd, _plane_id, _crtc_id, |
| 321 | fb_handle, 0, |
| 322 | _compose.left, _compose.top, |
| 323 | _compose.width, _compose.height, |
| 324 | 0, 0, _width << 16, _height << 16); |
| 325 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_IOCTL, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 326 | "failed to set plane via drm: %s", strerror(errno)); |
Wind Yuan | 024e1f3 | 2015-03-30 16:27:41 +0800 | [diff] [blame] | 327 | #if 0 |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 328 | drmVBlank vblank; |
| 329 | vblank.request.type = (drmVBlankSeqType) (DRM_VBLANK_EVENT | DRM_VBLANK_RELATIVE); |
| 330 | vblank.request.sequence = 1; |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 331 | vblank.request.signal = (unsigned long) index; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 332 | ret = (XCamReturn) drmWaitVBlank(_fd, &vblank); |
| 333 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_IOCTL, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 334 | "failed to wait vblank: %s", strerror(errno)); |
Wind Yuan | 024e1f3 | 2015-03-30 16:27:41 +0800 | [diff] [blame] | 335 | #endif |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 336 | return XCAM_RETURN_NO_ERROR; |
| 337 | } |
| 338 | |
| 339 | XCamReturn |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 340 | DrmDisplay::page_flip (const FB &fb) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 341 | { |
| 342 | XCamReturn ret; |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 343 | uint32_t fb_handle = fb.fb_handle; |
| 344 | uint32_t index = fb.index; |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 345 | |
| 346 | ret = (XCamReturn) drmModePageFlip(_fd, _crtc_id, fb_handle, |
| 347 | DRM_MODE_PAGE_FLIP_EVENT, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 348 | (void*)(unsigned long) index); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 349 | XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_IOCTL, |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 350 | "failed on page flip: %s", strerror(errno)); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 351 | |
| 352 | return XCAM_RETURN_NO_ERROR; |
| 353 | } |
| 354 | |
| 355 | XCamReturn |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 356 | DrmDisplay::render_buffer(SmartPtr<VideoBuffer> &buf) |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 357 | { |
Wind Yuan | 50f5e9e | 2015-03-26 16:57:13 +0800 | [diff] [blame] | 358 | FBMap::iterator iter = _buf_fb_handles.find (buf.ptr ()); |
| 359 | XCAM_FAIL_RETURN( |
| 360 | ERROR, |
| 361 | iter != _buf_fb_handles.end (), |
| 362 | XCAM_RETURN_ERROR_PARAM, |
| 363 | "buffer not register on framebuf"); |
| 364 | |
| 365 | return _plane_id ? set_plane(iter->second) : page_flip(iter->second); |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 366 | } |
| 367 | |
Wind Yuan | 25aed2b | 2015-02-10 17:46:23 +0800 | [diff] [blame] | 368 | |
| 369 | SmartPtr<DrmBoBuffer> |
| 370 | DrmDisplay::convert_to_drm_bo_buf (SmartPtr<DrmDisplay> &self, SmartPtr<VideoBuffer> &buf_in) |
| 371 | { |
| 372 | drm_intel_bo *bo = NULL; |
| 373 | int dma_fd = 0; |
| 374 | SmartPtr<V4l2BufferProxy> v4l2_proxy; |
| 375 | SmartPtr<DrmBoBuffer> new_bo_buf; |
| 376 | SmartPtr<DrmBoWrapper> bo_wrapper; |
| 377 | |
| 378 | XCAM_ASSERT (self.ptr () == this); |
| 379 | |
| 380 | new_bo_buf = buf_in.dynamic_cast_ptr<DrmBoBuffer> (); |
| 381 | if (new_bo_buf.ptr ()) |
| 382 | return new_bo_buf; |
| 383 | |
| 384 | v4l2_proxy = buf_in.dynamic_cast_ptr<V4l2BufferProxy> (); |
| 385 | if (!v4l2_proxy.ptr () || v4l2_proxy->get_v4l2_mem_type () != V4L2_MEMORY_DMABUF) { |
| 386 | XCAM_LOG_DEBUG ("DrmDisplay only support dma buffer conversion to drm bo by now"); |
| 387 | return NULL; |
| 388 | } |
| 389 | |
| 390 | dma_fd = v4l2_proxy->get_v4l2_dma_fd (); |
| 391 | XCAM_ASSERT (dma_fd > 0); |
| 392 | bo = drm_intel_bo_gem_create_from_prime (_buf_manager, dma_fd, v4l2_proxy->get_v4l2_buf_length ()); |
| 393 | if (bo == NULL) { |
| 394 | XCAM_LOG_WARNING ("convert dma fd to drm bo failed"); |
| 395 | return NULL; |
| 396 | } |
| 397 | bo_wrapper = new DrmBoWrapper (self, bo); |
| 398 | new_bo_buf = new DrmBoBuffer (self, buf_in->get_video_info (), bo_wrapper); |
| 399 | new_bo_buf->set_parent (buf_in); |
| 400 | return new_bo_buf; |
| 401 | } |
| 402 | |
| 403 | SmartPtr<DrmBoWrapper> |
| 404 | DrmDisplay::create_drm_bo (SmartPtr<DrmDisplay> &self, const VideoBufferInfo &info) |
| 405 | { |
| 406 | SmartPtr<DrmBoWrapper> new_bo; |
| 407 | |
| 408 | XCAM_ASSERT (_buf_manager); |
| 409 | XCAM_ASSERT (self.ptr() == this); |
| 410 | drm_intel_bo *bo = drm_intel_bo_alloc ( |
| 411 | _buf_manager, "xcam drm bo buf", info.size, 0x1000); |
| 412 | |
| 413 | new_bo = new DrmBoWrapper (self, bo); |
| 414 | return new_bo; |
| 415 | } |
| 416 | |
John Ye | 1503c6b | 2015-01-22 13:26:33 +0800 | [diff] [blame] | 417 | }; |