/libgralloc/framebuffer.cpp

http://github.com/CyanogenMod/android_device_zte_blade · C++ · 857 lines · 672 code · 109 blank · 76 comment · 104 complexity · 27393ef6ca051cae7f62889eadbd0268 MD5 · raw file

  1. /*
  2. * Copyright (C) 2008 The Android Open Source Project
  3. * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <sys/mman.h>
  18. #include <dlfcn.h>
  19. #include <cutils/ashmem.h>
  20. #include <cutils/log.h>
  21. #include <cutils/properties.h>
  22. #include <hardware/hardware.h>
  23. #include <hardware/gralloc.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <sys/ioctl.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <pthread.h>
  30. #include <cutils/log.h>
  31. #include <cutils/atomic.h>
  32. #include <linux/fb.h>
  33. #include <linux/msm_mdp.h>
  34. #include <GLES/gl.h>
  35. #include "gralloc_priv.h"
  36. #include "gr.h"
  37. #ifdef NO_SURFACEFLINGER_SWAPINTERVAL
  38. #include <cutils/properties.h>
  39. #endif
  40. #if defined(HDMI_DUAL_DISPLAY)
  41. #define AS_1080_RATIO_H (4.25/100) // Default Action Safe vertical limit for 1080p
  42. #define AS_1080_RATIO_W (4.25/100) // Default Action Safe horizontal limit for 1080p
  43. #define AS_720_RATIO_H (6.0/100) // Default Action Safe vertical limit for 720p
  44. #define AS_720_RATIO_W (4.25/100) // Default Action Safe horizontal limit for 720p
  45. #define AS_480_RATIO_H (8.0/100) // Default Action Safe vertical limit for 480p
  46. #define AS_480_RATIO_W (5.0/100) // Default Action Safe horizontal limit for 480p
  47. #define HEIGHT_1080P 1080
  48. #define HEIGHT_720P 720
  49. #define HEIGHT_480P 480
  50. #define EVEN_OUT(x) if (x & 0x0001) {x--;}
  51. using overlay::Overlay;
  52. /** min of int a, b */
  53. static inline int min(int a, int b) {
  54. return (a<b) ? a : b;
  55. }
  56. /** max of int a, b */
  57. static inline int max(int a, int b) {
  58. return (a>b) ? a : b;
  59. }
  60. /** align */
  61. static inline size_t ALIGN(size_t x, size_t align) {
  62. return (x + align-1) & ~(align-1);
  63. }
  64. #endif
  65. /*****************************************************************************/
  66. enum {
  67. MDDI_PANEL = '1',
  68. EBI2_PANEL = '2',
  69. LCDC_PANEL = '3',
  70. EXT_MDDI_PANEL = '4',
  71. TV_PANEL = '5'
  72. };
  73. enum {
  74. PAGE_FLIP = 0x00000001,
  75. LOCKED = 0x00000002
  76. };
  77. struct fb_context_t {
  78. framebuffer_device_t device;
  79. };
  80. static int neworientation;
  81. /*****************************************************************************/
  82. static void
  83. msm_copy_buffer(buffer_handle_t handle, int fd,
  84. int width, int height, int format,
  85. int x, int y, int w, int h);
  86. static int fb_setSwapInterval(struct framebuffer_device_t* dev,
  87. int interval)
  88. {
  89. fb_context_t* ctx = (fb_context_t*)dev;
  90. private_module_t* m = reinterpret_cast<private_module_t*>(
  91. dev->common.module);
  92. if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
  93. return -EINVAL;
  94. m->swapInterval = interval;
  95. return 0;
  96. }
  97. static int fb_setUpdateRect(struct framebuffer_device_t* dev,
  98. int l, int t, int w, int h)
  99. {
  100. if (((w|h) <= 0) || ((l|t)<0))
  101. return -EINVAL;
  102. fb_context_t* ctx = (fb_context_t*)dev;
  103. private_module_t* m = reinterpret_cast<private_module_t*>(
  104. dev->common.module);
  105. m->info.reserved[0] = 0x54445055; // "UPDT";
  106. m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
  107. m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
  108. return 0;
  109. }
  110. static void *disp_loop(void *ptr)
  111. {
  112. struct qbuf_t nxtBuf;
  113. static int cur_buf=-1;
  114. private_module_t *m = reinterpret_cast<private_module_t*>(ptr);
  115. while (1) {
  116. pthread_mutex_lock(&(m->qlock));
  117. // wait (sleep) while display queue is empty;
  118. if (m->disp.isEmpty()) {
  119. pthread_cond_wait(&(m->qpost),&(m->qlock));
  120. }
  121. // dequeue next buff to display and lock it
  122. nxtBuf = m->disp.getHeadValue();
  123. m->disp.pop();
  124. pthread_mutex_unlock(&(m->qlock));
  125. // post buf out to display synchronously
  126. private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
  127. (nxtBuf.buf);
  128. const size_t offset = hnd->base - m->framebuffer->base;
  129. m->info.activate = FB_ACTIVATE_VBL;
  130. m->info.yoffset = offset / m->finfo.line_length;
  131. #if defined(HDMI_DUAL_DISPLAY)
  132. pthread_mutex_lock(&m->overlayLock);
  133. m->orientation = neworientation;
  134. m->currentOffset = offset;
  135. pthread_cond_signal(&(m->overlayPost));
  136. pthread_mutex_unlock(&m->overlayLock);
  137. #endif
  138. if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
  139. LOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
  140. }
  141. if (cur_buf == -1) {
  142. pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
  143. m->avail[nxtBuf.idx].is_avail = true;
  144. pthread_cond_signal(&(m->avail[nxtBuf.idx].cond));
  145. pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
  146. } else {
  147. pthread_mutex_lock(&(m->avail[cur_buf].lock));
  148. m->avail[cur_buf].is_avail = true;
  149. pthread_cond_signal(&(m->avail[cur_buf].cond));
  150. pthread_mutex_unlock(&(m->avail[cur_buf].lock));
  151. }
  152. cur_buf = nxtBuf.idx;
  153. }
  154. return NULL;
  155. }
  156. #if defined(HDMI_DUAL_DISPLAY)
  157. static void *hdmi_ui_loop(void *ptr)
  158. {
  159. private_module_t* m = reinterpret_cast<private_module_t*>(
  160. ptr);
  161. while (1) {
  162. pthread_mutex_lock(&m->overlayLock);
  163. pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
  164. if (m->exitHDMIUILoop) {
  165. pthread_mutex_unlock(&m->overlayLock);
  166. return NULL;
  167. }
  168. float asWidthRatio = m->actionsafeWidthRatio/100.0f;
  169. float asHeightRatio = m->actionsafeHeightRatio/100.0f;
  170. if (m->pobjOverlay) {
  171. Overlay* pTemp = m->pobjOverlay;
  172. if (!m->enableHDMIOutput)
  173. pTemp->closeChannel();
  174. else if (m->enableHDMIOutput && !m->videoOverlay) {
  175. if (!pTemp->isChannelUP()) {
  176. int alignedW = ALIGN(m->info.xres, 32);
  177. if (pTemp->startChannel(alignedW, m->info.yres,
  178. m->fbFormat, 1, false, true)) {
  179. pTemp->setFd(m->framebuffer->fd);
  180. pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
  181. } else
  182. pTemp->closeChannel();
  183. }
  184. if (pTemp->isChannelUP()) {
  185. int width = pTemp->getFBWidth();
  186. int height = pTemp->getFBHeight();
  187. int aswidth = width, asheight = height;
  188. int asX = 0, asY = 0; // Action safe x, y co-ordinates
  189. int fbwidth = m->info.xres, fbheight = m->info.yres;
  190. float defaultASWidthRatio = 0.0f, defaultASHeightRatio = 0.0f;
  191. if(HEIGHT_1080P == height) {
  192. defaultASHeightRatio = AS_1080_RATIO_H;
  193. defaultASWidthRatio = AS_1080_RATIO_W;
  194. } else if(HEIGHT_720P == height) {
  195. defaultASHeightRatio = AS_720_RATIO_H;
  196. defaultASWidthRatio = AS_720_RATIO_W;
  197. } else if(HEIGHT_480P == height) {
  198. defaultASHeightRatio = AS_480_RATIO_H;
  199. defaultASWidthRatio = AS_480_RATIO_W;
  200. }
  201. if(asWidthRatio <= 0.0f)
  202. asWidthRatio = defaultASWidthRatio;
  203. if(asHeightRatio <= 0.0f)
  204. asHeightRatio = defaultASHeightRatio;
  205. aswidth = (int)((float)width - (float)(width * asWidthRatio));
  206. asheight = (int)((float)height - (float)(height * asHeightRatio));
  207. asX = (width - aswidth) / 2;
  208. asY = (height - asheight) / 2;
  209. int rot = m->orientation;
  210. if (fbwidth < fbheight) {
  211. switch(rot) {
  212. // ROT_0
  213. case 0:
  214. // ROT_180
  215. case HAL_TRANSFORM_ROT_180: {
  216. aswidth = (asheight * fbwidth) / fbheight;
  217. asX = (width - aswidth) / 2;
  218. if(rot == HAL_TRANSFORM_ROT_180)
  219. rot = OVERLAY_TRANSFORM_ROT_180;
  220. else
  221. rot = 0;
  222. }
  223. break;
  224. // ROT_90
  225. case HAL_TRANSFORM_ROT_90:
  226. rot = OVERLAY_TRANSFORM_ROT_270;
  227. break;
  228. // ROT_270
  229. case HAL_TRANSFORM_ROT_270:
  230. rot = OVERLAY_TRANSFORM_ROT_90;
  231. break;
  232. }
  233. }
  234. else if (fbwidth > fbheight) {
  235. switch(rot) {
  236. // ROT_0
  237. case 0:
  238. rot = 0;
  239. break;
  240. // ROT_180
  241. case HAL_TRANSFORM_ROT_180:
  242. rot = OVERLAY_TRANSFORM_ROT_180;
  243. break;
  244. // ROT_90
  245. case HAL_TRANSFORM_ROT_90:
  246. // ROT_270
  247. case HAL_TRANSFORM_ROT_270: {
  248. //Swap width and height
  249. int t = fbwidth;
  250. fbwidth = fbheight;
  251. fbheight = t;
  252. aswidth = (asheight * fbwidth) / fbheight;
  253. asX = (width - aswidth) / 2;
  254. if(rot == HAL_TRANSFORM_ROT_90)
  255. rot = OVERLAY_TRANSFORM_ROT_270;
  256. else
  257. rot = OVERLAY_TRANSFORM_ROT_90;
  258. }
  259. break;
  260. }
  261. }
  262. pTemp->setParameter(OVERLAY_TRANSFORM,
  263. rot);
  264. EVEN_OUT(asX);
  265. EVEN_OUT(asY);
  266. EVEN_OUT(aswidth);
  267. EVEN_OUT(asheight);
  268. pTemp->setPosition(asX, asY, aswidth, asheight);
  269. pTemp->queueBuffer(m->currentOffset);
  270. }
  271. }
  272. else
  273. pTemp->closeChannel();
  274. }
  275. pthread_mutex_unlock(&m->overlayLock);
  276. }
  277. return NULL;
  278. }
  279. static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
  280. {
  281. private_module_t* m = reinterpret_cast<private_module_t*>(
  282. dev->common.module);
  283. pthread_mutex_lock(&m->overlayLock);
  284. Overlay* pTemp = m->pobjOverlay;
  285. if (started && pTemp) {
  286. pTemp->closeChannel();
  287. m->videoOverlay = true;
  288. pthread_cond_signal(&(m->overlayPost));
  289. }
  290. else {
  291. m->videoOverlay = false;
  292. pthread_cond_signal(&(m->overlayPost));
  293. }
  294. pthread_mutex_unlock(&m->overlayLock);
  295. return 0;
  296. }
  297. static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int enable)
  298. {
  299. private_module_t* m = reinterpret_cast<private_module_t*>(
  300. dev->common.module);
  301. pthread_mutex_lock(&m->overlayLock);
  302. Overlay* pTemp = m->pobjOverlay;
  303. if (!enable && pTemp)
  304. pTemp->closeChannel();
  305. m->enableHDMIOutput = enable;
  306. pthread_cond_signal(&(m->overlayPost));
  307. pthread_mutex_unlock(&m->overlayLock);
  308. return 0;
  309. }
  310. static int fb_setActionSafeWidthRatio(struct framebuffer_device_t* dev, float asWidthRatio)
  311. {
  312. private_module_t* m = reinterpret_cast<private_module_t*>(
  313. dev->common.module);
  314. pthread_mutex_lock(&m->overlayLock);
  315. m->actionsafeWidthRatio = asWidthRatio;
  316. pthread_mutex_unlock(&m->overlayLock);
  317. return 0;
  318. }
  319. static int fb_setActionSafeHeightRatio(struct framebuffer_device_t* dev, float asHeightRatio)
  320. {
  321. private_module_t* m = reinterpret_cast<private_module_t*>(
  322. dev->common.module);
  323. pthread_mutex_lock(&m->overlayLock);
  324. m->actionsafeHeightRatio = asHeightRatio;
  325. pthread_mutex_unlock(&m->overlayLock);
  326. return 0;
  327. }
  328. static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
  329. {
  330. private_module_t* m = reinterpret_cast<private_module_t*>(
  331. dev->common.module);
  332. pthread_mutex_lock(&m->overlayLock);
  333. neworientation = orientation;
  334. pthread_mutex_unlock(&m->overlayLock);
  335. return 0;
  336. }
  337. #endif
  338. static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
  339. {
  340. if (private_handle_t::validate(buffer) < 0)
  341. return -EINVAL;
  342. int nxtIdx;
  343. bool reuse;
  344. struct qbuf_t qb;
  345. fb_context_t* ctx = (fb_context_t*)dev;
  346. private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
  347. private_module_t* m = reinterpret_cast<private_module_t*>(
  348. dev->common.module);
  349. if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
  350. reuse = false;
  351. nxtIdx = (m->currentIdx + 1) % NUM_BUFFERS;
  352. if (m->swapInterval == 0) {
  353. // if SwapInterval = 0 and no buffers available then reuse
  354. // current buf for next rendering so don't post new buffer
  355. if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) {
  356. reuse = true;
  357. } else {
  358. if (! m->avail[nxtIdx].is_avail)
  359. reuse = true;
  360. pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
  361. }
  362. }
  363. if(!reuse){
  364. // unlock previous ("current") Buffer and lock the new buffer
  365. m->base.lock(&m->base, buffer,
  366. private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
  367. 0,0, m->info.xres, m->info.yres, NULL);
  368. // post/queue the new buffer
  369. pthread_mutex_lock(&(m->avail[nxtIdx].lock));
  370. m->avail[nxtIdx].is_avail = false;
  371. pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
  372. qb.idx = nxtIdx;
  373. qb.buf = buffer;
  374. pthread_mutex_lock(&(m->qlock));
  375. m->disp.push(qb);
  376. pthread_cond_signal(&(m->qpost));
  377. pthread_mutex_unlock(&(m->qlock));
  378. // LCDC: after new buffer grabbed by MDP can unlock previous
  379. // (current) buffer
  380. if (m->currentBuffer) {
  381. if (m->swapInterval != 0) {
  382. pthread_mutex_lock(&(m->avail[m->currentIdx].lock));
  383. if (! m->avail[m->currentIdx].is_avail) {
  384. pthread_cond_wait(&(m->avail[m->currentIdx].cond),
  385. &(m->avail[m->currentIdx].lock));
  386. m->avail[m->currentIdx].is_avail = true;
  387. }
  388. pthread_mutex_unlock(&(m->avail[m->currentIdx].lock));
  389. }
  390. m->base.unlock(&m->base, m->currentBuffer);
  391. }
  392. m->currentBuffer = buffer;
  393. m->currentIdx = nxtIdx;
  394. } else {
  395. if (m->currentBuffer)
  396. m->base.unlock(&m->base, m->currentBuffer);
  397. m->base.lock(&m->base, buffer,
  398. private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
  399. 0,0, m->info.xres, m->info.yres, NULL);
  400. m->currentBuffer = buffer;
  401. }
  402. } else {
  403. void* fb_vaddr;
  404. void* buffer_vaddr;
  405. m->base.lock(&m->base, m->framebuffer,
  406. GRALLOC_USAGE_SW_WRITE_RARELY,
  407. 0, 0, m->info.xres, m->info.yres,
  408. &fb_vaddr);
  409. m->base.lock(&m->base, buffer,
  410. GRALLOC_USAGE_SW_READ_RARELY,
  411. 0, 0, m->info.xres, m->info.yres,
  412. &buffer_vaddr);
  413. //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
  414. msm_copy_buffer(
  415. m->framebuffer, m->framebuffer->fd,
  416. m->info.xres, m->info.yres, m->fbFormat,
  417. m->info.xoffset, m->info.yoffset,
  418. m->info.width, m->info.height);
  419. m->base.unlock(&m->base, buffer);
  420. m->base.unlock(&m->base, m->framebuffer);
  421. }
  422. return 0;
  423. }
  424. static int fb_compositionComplete(struct framebuffer_device_t* dev)
  425. {
  426. // TODO: Properly implement composition complete callback
  427. glFinish();
  428. return 0;
  429. }
  430. /*****************************************************************************/
  431. int mapFrameBufferLocked(struct private_module_t* module)
  432. {
  433. // already initialized...
  434. if (module->framebuffer) {
  435. return 0;
  436. }
  437. char const * const device_template[] = {
  438. "/dev/graphics/fb%u",
  439. "/dev/fb%u",
  440. 0 };
  441. int fd = -1;
  442. int i=0;
  443. char name[64];
  444. while ((fd==-1) && device_template[i]) {
  445. snprintf(name, 64, device_template[i], 0);
  446. fd = open(name, O_RDWR, 0);
  447. i++;
  448. }
  449. if (fd < 0)
  450. return -errno;
  451. struct fb_fix_screeninfo finfo;
  452. if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
  453. return -errno;
  454. struct fb_var_screeninfo info;
  455. if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
  456. return -errno;
  457. info.reserved[0] = 0;
  458. info.reserved[1] = 0;
  459. info.reserved[2] = 0;
  460. info.xoffset = 0;
  461. info.yoffset = 0;
  462. info.activate = FB_ACTIVATE_NOW;
  463. /* Interpretation of offset for color fields: All offsets are from the right,
  464. * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
  465. * can use the offset as right argument to <<). A pixel afterwards is a bit
  466. * stream and is written to video memory as that unmodified. This implies
  467. * big-endian byte order if bits_per_pixel is greater than 8.
  468. */
  469. if(info.bits_per_pixel == 32) {
  470. /*
  471. * Explicitly request RGBA_8888
  472. */
  473. info.bits_per_pixel = 32;
  474. info.red.offset = 24;
  475. info.red.length = 8;
  476. info.green.offset = 16;
  477. info.green.length = 8;
  478. info.blue.offset = 8;
  479. info.blue.length = 8;
  480. info.transp.offset = 0;
  481. info.transp.length = 8;
  482. /* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
  483. * not use the MDP for composition (i.e. hw composition == 0), ask for
  484. * RGBA instead of RGBX. */
  485. char property[PROPERTY_VALUE_MAX];
  486. if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
  487. module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
  488. else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
  489. module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
  490. else
  491. module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
  492. } else {
  493. /*
  494. * Explicitly request 5/6/5
  495. */
  496. info.bits_per_pixel = 16;
  497. info.red.offset = 11;
  498. info.red.length = 5;
  499. info.green.offset = 5;
  500. info.green.length = 6;
  501. info.blue.offset = 0;
  502. info.blue.length = 5;
  503. info.transp.offset = 0;
  504. info.transp.length = 0;
  505. module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
  506. }
  507. /*
  508. * Request NUM_BUFFERS screens (at lest 2 for page flipping)
  509. */
  510. info.yres_virtual = info.yres * NUM_BUFFERS;
  511. uint32_t flags = PAGE_FLIP;
  512. if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
  513. info.yres_virtual = info.yres;
  514. flags &= ~PAGE_FLIP;
  515. LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
  516. }
  517. if (info.yres_virtual < info.yres * 2) {
  518. // we need at least 2 for page-flipping
  519. info.yres_virtual = info.yres;
  520. flags &= ~PAGE_FLIP;
  521. LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
  522. info.yres_virtual, info.yres*2);
  523. }
  524. if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
  525. return -errno;
  526. int refreshRate = 1000000000000000LLU /
  527. (
  528. uint64_t( info.upper_margin + info.lower_margin + info.yres )
  529. * ( info.left_margin + info.right_margin + info.xres )
  530. * info.pixclock
  531. );
  532. if (refreshRate == 0) {
  533. // bleagh, bad info from the driver
  534. refreshRate = 60*1000; // 60 Hz
  535. }
  536. if (int(info.width) <= 0 || int(info.height) <= 0) {
  537. // the driver doesn't return that information
  538. // default to 160 dpi
  539. info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
  540. info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
  541. }
  542. float xdpi = (info.xres * 25.4f) / info.width;
  543. float ydpi = (info.yres * 25.4f) / info.height;
  544. float fps = refreshRate / 1000.0f;
  545. LOGI( "using (fd=%d)\n"
  546. "id = %s\n"
  547. "xres = %d px\n"
  548. "yres = %d px\n"
  549. "xres_virtual = %d px\n"
  550. "yres_virtual = %d px\n"
  551. "bpp = %d\n"
  552. "r = %2u:%u\n"
  553. "g = %2u:%u\n"
  554. "b = %2u:%u\n",
  555. fd,
  556. finfo.id,
  557. info.xres,
  558. info.yres,
  559. info.xres_virtual,
  560. info.yres_virtual,
  561. info.bits_per_pixel,
  562. info.red.offset, info.red.length,
  563. info.green.offset, info.green.length,
  564. info.blue.offset, info.blue.length
  565. );
  566. LOGI( "width = %d mm (%f dpi)\n"
  567. "height = %d mm (%f dpi)\n"
  568. "refresh rate = %.2f Hz\n",
  569. info.width, xdpi,
  570. info.height, ydpi,
  571. fps
  572. );
  573. if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
  574. return -errno;
  575. if (finfo.smem_len <= 0)
  576. return -errno;
  577. module->flags = flags;
  578. module->info = info;
  579. module->finfo = finfo;
  580. module->xdpi = xdpi;
  581. module->ydpi = ydpi;
  582. module->fps = fps;
  583. #ifdef NO_SURFACEFLINGER_SWAPINTERVAL
  584. char pval[PROPERTY_VALUE_MAX];
  585. property_get("debug.gr.swapinterval", pval, "1");
  586. module->swapInterval = atoi(pval);
  587. if (module->swapInterval < private_module_t::PRIV_MIN_SWAP_INTERVAL ||
  588. module->swapInterval > private_module_t::PRIV_MAX_SWAP_INTERVAL) {
  589. module->swapInterval = 1;
  590. LOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
  591. private_module_t::PRIV_MIN_SWAP_INTERVAL,
  592. private_module_t::PRIV_MAX_SWAP_INTERVAL);
  593. }
  594. #else
  595. /* when surfaceflinger supports swapInterval then can just do this */
  596. module->swapInterval = 1;
  597. #endif
  598. module->currentIdx = -1;
  599. pthread_cond_init(&(module->qpost), NULL);
  600. pthread_mutex_init(&(module->qlock), NULL);
  601. for (i = 0; i < NUM_BUFFERS; i++) {
  602. pthread_mutex_init(&(module->avail[i].lock), NULL);
  603. pthread_cond_init(&(module->avail[i].cond), NULL);
  604. module->avail[i].is_avail = true;
  605. }
  606. /* create display update thread */
  607. pthread_t thread1;
  608. if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
  609. return -errno;
  610. }
  611. /*
  612. * map the framebuffer
  613. */
  614. int err;
  615. size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual);
  616. module->framebuffer = new private_handle_t(dup(fd), fbSize,
  617. private_handle_t::PRIV_FLAGS_USES_PMEM);
  618. module->numBuffers = info.yres_virtual / info.yres;
  619. module->bufferMask = 0;
  620. void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  621. if (vaddr == MAP_FAILED) {
  622. LOGE("Error mapping the framebuffer (%s)", strerror(errno));
  623. return -errno;
  624. }
  625. module->framebuffer->base = intptr_t(vaddr);
  626. memset(vaddr, 0, fbSize);
  627. #if defined(HDMI_DUAL_DISPLAY)
  628. /* Overlay for HDMI*/
  629. pthread_mutex_init(&(module->overlayLock), NULL);
  630. pthread_cond_init(&(module->overlayPost), NULL);
  631. module->pobjOverlay = new Overlay();
  632. module->currentOffset = 0;
  633. module->exitHDMIUILoop = false;
  634. pthread_t hdmiUIThread;
  635. pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
  636. #endif
  637. return 0;
  638. }
  639. static int mapFrameBuffer(struct private_module_t* module)
  640. {
  641. pthread_mutex_lock(&module->lock);
  642. int err = mapFrameBufferLocked(module);
  643. pthread_mutex_unlock(&module->lock);
  644. return err;
  645. }
  646. /*****************************************************************************/
  647. static int fb_close(struct hw_device_t *dev)
  648. {
  649. fb_context_t* ctx = (fb_context_t*)dev;
  650. #if defined(HDMI_DUAL_DISPLAY)
  651. private_module_t* m = reinterpret_cast<private_module_t*>(
  652. ctx->device.common.module);
  653. pthread_mutex_lock(&m->overlayLock);
  654. m->exitHDMIUILoop = true;
  655. pthread_cond_signal(&(m->overlayPost));
  656. pthread_mutex_unlock(&m->overlayLock);
  657. #endif
  658. if (ctx) {
  659. free(ctx);
  660. }
  661. return 0;
  662. }
  663. int fb_device_open(hw_module_t const* module, const char* name,
  664. hw_device_t** device)
  665. {
  666. int status = -EINVAL;
  667. if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
  668. alloc_device_t* gralloc_device;
  669. status = gralloc_open(module, &gralloc_device);
  670. if (status < 0)
  671. return status;
  672. /* initialize our state here */
  673. fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
  674. memset(dev, 0, sizeof(*dev));
  675. /* initialize the procs */
  676. dev->device.common.tag = HARDWARE_DEVICE_TAG;
  677. dev->device.common.version = 0;
  678. dev->device.common.module = const_cast<hw_module_t*>(module);
  679. dev->device.common.close = fb_close;
  680. dev->device.setSwapInterval = fb_setSwapInterval;
  681. dev->device.post = fb_post;
  682. dev->device.setUpdateRect = 0;
  683. dev->device.compositionComplete = fb_compositionComplete;
  684. #if defined(HDMI_DUAL_DISPLAY)
  685. dev->device.orientationChanged = fb_orientationChanged;
  686. dev->device.videoOverlayStarted = fb_videoOverlayStarted;
  687. dev->device.enableHDMIOutput = fb_enableHDMIOutput;
  688. dev->device.setActionSafeWidthRatio = fb_setActionSafeWidthRatio;
  689. dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
  690. #endif
  691. private_module_t* m = (private_module_t*)module;
  692. status = mapFrameBuffer(m);
  693. if (status >= 0) {
  694. int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
  695. const_cast<uint32_t&>(dev->device.flags) = 0;
  696. const_cast<uint32_t&>(dev->device.width) = m->info.xres;
  697. const_cast<uint32_t&>(dev->device.height) = m->info.yres;
  698. const_cast<int&>(dev->device.stride) = stride;
  699. const_cast<int&>(dev->device.format) = m->fbFormat;
  700. const_cast<float&>(dev->device.xdpi) = m->xdpi;
  701. const_cast<float&>(dev->device.ydpi) = m->ydpi;
  702. const_cast<float&>(dev->device.fps) = m->fps;
  703. const_cast<int&>(dev->device.minSwapInterval) = private_module_t::PRIV_MIN_SWAP_INTERVAL;
  704. const_cast<int&>(dev->device.maxSwapInterval) = private_module_t::PRIV_MAX_SWAP_INTERVAL;
  705. if (m->finfo.reserved[0] == 0x5444 &&
  706. m->finfo.reserved[1] == 0x5055) {
  707. dev->device.setUpdateRect = fb_setUpdateRect;
  708. LOGD("UPDATE_ON_DEMAND supported");
  709. }
  710. *device = &dev->device.common;
  711. }
  712. // Close the gralloc module
  713. gralloc_close(gralloc_device);
  714. }
  715. return status;
  716. }
  717. /* Copy a pmem buffer to the framebuffer */
  718. static void
  719. msm_copy_buffer(buffer_handle_t handle, int fd,
  720. int width, int height, int format,
  721. int x, int y, int w, int h)
  722. {
  723. struct {
  724. unsigned int count;
  725. mdp_blit_req req;
  726. } blit;
  727. private_handle_t *priv = (private_handle_t*) handle;
  728. memset(&blit, 0, sizeof(blit));
  729. blit.count = 1;
  730. blit.req.flags = 0;
  731. blit.req.alpha = 0xff;
  732. blit.req.transp_mask = 0xffffffff;
  733. blit.req.src.width = width;
  734. blit.req.src.height = height;
  735. blit.req.src.offset = 0;
  736. blit.req.src.memory_id = priv->fd;
  737. blit.req.dst.width = width;
  738. blit.req.dst.height = height;
  739. blit.req.dst.offset = 0;
  740. blit.req.dst.memory_id = fd;
  741. blit.req.dst.format = format;
  742. blit.req.src_rect.x = blit.req.dst_rect.x = x;
  743. blit.req.src_rect.y = blit.req.dst_rect.y = y;
  744. blit.req.src_rect.w = blit.req.dst_rect.w = w;
  745. blit.req.src_rect.h = blit.req.dst_rect.h = h;
  746. if (ioctl(fd, MSMFB_BLIT, &blit))
  747. LOGE("MSMFB_BLIT failed = %d", -errno);
  748. }