Guest User

AOSP ICS 4.0.4 - /hardware/display/libgralloc/framebuffer.cp

a guest
Nov 27th, 2012
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 34.99 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008 The Android Open Source Project
  3. * Copyright (c) 2010-2012 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.  
  18. #include <sys/mman.h>
  19.  
  20. #include <dlfcn.h>
  21.  
  22. #include <cutils/ashmem.h>
  23. #include <cutils/log.h>
  24. #include <cutils/properties.h>
  25. #include <utils/Timers.h>
  26.  
  27. #include <hardware/hardware.h>
  28. #include <hardware/gralloc.h>
  29.  
  30. #include <fcntl.h>
  31. #include <errno.h>
  32. #include <sys/ioctl.h>
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include <pthread.h>
  36. #include <utils/Timers.h>
  37.  
  38. #include <cutils/log.h>
  39. #include <cutils/atomic.h>
  40.  
  41. #include <linux/fb.h>
  42. #include <linux/msm_mdp.h>
  43.  
  44. #include <GLES/gl.h>
  45.  
  46. #include "gralloc_priv.h"
  47. #include "gr.h"
  48. #ifdef NO_SURFACEFLINGER_SWAPINTERVAL
  49. #include <cutils/properties.h>
  50. #endif
  51.  
  52. #include <utils/profiler.h>
  53. #include <qcom_ui.h>
  54.  
  55. #define FB_DEBUG 0
  56.  
  57. #if defined(HDMI_DUAL_DISPLAY)
  58. #define EVEN_OUT(x) if (x & 0x0001) {x--;}
  59. using overlay::Overlay;
  60. /** min of int a, b */
  61. static inline int min(int a, int b) {
  62.     return (a<b) ? a : b;
  63. }
  64. /** max of int a, b */
  65. static inline int max(int a, int b) {
  66.     return (a>b) ? a : b;
  67. }
  68. #endif
  69.  
  70. char framebufferStateName[] = {'S', 'R', 'A'};
  71.  
  72. /*****************************************************************************/
  73.  
  74. enum {
  75.     MDDI_PANEL = '1',
  76.     EBI2_PANEL = '2',
  77.     LCDC_PANEL = '3',
  78.     EXT_MDDI_PANEL = '4',
  79.     TV_PANEL = '5'
  80. };
  81.  
  82. enum {
  83.     PAGE_FLIP = 0x00000001,
  84.     LOCKED = 0x00000002
  85. };
  86.  
  87. struct fb_context_t {
  88.     framebuffer_device_t  device;
  89. };
  90.  
  91. static int neworientation;
  92.  
  93. /*****************************************************************************/
  94.  
  95. static void
  96. msm_copy_buffer(buffer_handle_t handle, int fd,
  97.                 int width, int height, int format,
  98.                 int x, int y, int w, int h);
  99.  
  100. static int fb_setSwapInterval(struct framebuffer_device_t* dev,
  101.             int interval)
  102. {
  103.     char pval[PROPERTY_VALUE_MAX];
  104.     property_get("debug.egl.swapinterval", pval, "-1");
  105.     int property_interval = atoi(pval);
  106.     if (property_interval >= 0)
  107.         interval = property_interval;
  108.  
  109.     fb_context_t* ctx = (fb_context_t*)dev;
  110.     private_module_t* m = reinterpret_cast<private_module_t*>(
  111.             dev->common.module);
  112.     if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
  113.         return -EINVAL;
  114.  
  115.     m->swapInterval = interval;
  116.     return 0;
  117. }
  118.  
  119. static int fb_setUpdateRect(struct framebuffer_device_t* dev,
  120.         int l, int t, int w, int h)
  121. {
  122.     if (((w|h) <= 0) || ((l|t)<0))
  123.         return -EINVAL;
  124.     fb_context_t* ctx = (fb_context_t*)dev;
  125.     private_module_t* m = reinterpret_cast<private_module_t*>(
  126.             dev->common.module);
  127.     m->info.reserved[0] = 0x54445055; // "UPDT";
  128.     m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
  129.     m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
  130.     return 0;
  131. }
  132.  
  133. static void *disp_loop(void *ptr)
  134. {
  135.     struct qbuf_t nxtBuf;
  136.     static int cur_buf=-1;
  137.     private_module_t *m = reinterpret_cast<private_module_t*>(ptr);
  138.  
  139.     while (1) {
  140.         pthread_mutex_lock(&(m->qlock));
  141.  
  142.         // wait (sleep) while display queue is empty;
  143.         if (m->disp.isEmpty()) {
  144.             pthread_cond_wait(&(m->qpost),&(m->qlock));
  145.         }
  146.  
  147.         // dequeue next buff to display and lock it
  148.         nxtBuf = m->disp.getHeadValue();
  149.         m->disp.pop();
  150.         pthread_mutex_unlock(&(m->qlock));
  151.  
  152.         // post buf out to display synchronously
  153.         private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
  154.                                                 (nxtBuf.buf);
  155.         const size_t offset = hnd->base - m->framebuffer->base;
  156.         m->info.activate = FB_ACTIVATE_VBL;
  157.         m->info.yoffset = offset / m->finfo.line_length;
  158.  
  159. #if defined(HDMI_DUAL_DISPLAY)
  160.         pthread_mutex_lock(&m->overlayLock);
  161.         m->orientation = neworientation;
  162.         m->currentOffset = offset;
  163.         m->hdmiStateChanged = true;
  164.         pthread_cond_signal(&(m->overlayPost));
  165.         pthread_mutex_unlock(&m->overlayLock);
  166. #endif
  167.         if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
  168.             LOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
  169.         }
  170.  
  171.         //Signal so that we can close channels if we need to
  172.         pthread_mutex_lock(&m->bufferPostLock);
  173.         m->bufferPostDone = true;
  174.         pthread_cond_signal(&m->bufferPostCond);
  175.         pthread_mutex_unlock(&m->bufferPostLock);
  176.  
  177.         CALC_FPS();
  178.  
  179.         if (cur_buf == -1) {
  180.             int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers);
  181.             pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
  182.             m->avail[nxtBuf.idx].is_avail = true;
  183.             m->avail[nxtBuf.idx].state = REF;
  184.             pthread_cond_broadcast(&(m->avail[nxtBuf.idx].cond));
  185.             pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
  186.         } else {
  187.             pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
  188.             if (m->avail[nxtBuf.idx].state != SUB) {
  189.                 LOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", nxtBuf.idx,
  190.                     framebufferStateName[m->avail[nxtBuf.idx].state],
  191.                     framebufferStateName[SUB]);
  192.             }
  193.             m->avail[nxtBuf.idx].state = REF;
  194.             pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
  195.  
  196.             pthread_mutex_lock(&(m->avail[cur_buf].lock));
  197.             m->avail[cur_buf].is_avail = true;
  198.             if (m->avail[cur_buf].state != REF) {
  199.                 LOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", cur_buf,
  200.                     framebufferStateName[m->avail[cur_buf].state],
  201.                     framebufferStateName[REF]);
  202.             }
  203.             m->avail[cur_buf].state = AVL;
  204.             pthread_cond_broadcast(&(m->avail[cur_buf].cond));
  205.             pthread_mutex_unlock(&(m->avail[cur_buf].lock));
  206.         }
  207.         cur_buf = nxtBuf.idx;
  208.     }
  209.     return NULL;
  210. }
  211.  
  212. #if defined(HDMI_DUAL_DISPLAY)
  213. static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect&
  214.                                 rect, int& orientation)
  215. {
  216.     Overlay* pTemp = m->pobjOverlay;
  217.     int width = pTemp->getFBWidth();
  218.     int height = pTemp->getFBHeight();
  219.     int fbwidth = m->info.xres, fbheight = m->info.yres;
  220.     rect.x = 0; rect.y = 0;
  221.     rect.w = width; rect.h = height;
  222.     int rot = m->orientation;
  223.     switch(rot) {
  224.         // ROT_0
  225.         case 0:
  226.         // ROT_180
  227.         case HAL_TRANSFORM_ROT_180:
  228.             pTemp->getAspectRatioPosition(fbwidth, fbheight,
  229.                                                    &rect);
  230.             if(rot ==  HAL_TRANSFORM_ROT_180)
  231.                 orientation = HAL_TRANSFORM_ROT_180;
  232.             else
  233.                 orientation  = 0;
  234.             break;
  235.             // ROT_90
  236.         case HAL_TRANSFORM_ROT_90:
  237.             // ROT_270
  238.         case HAL_TRANSFORM_ROT_270:
  239.             //Calculate the Aspectratio for the UI
  240.             //in the landscape mode
  241.             //Width and height will be swapped as there
  242.             //is rotation
  243.             pTemp->getAspectRatioPosition(fbheight, fbwidth,
  244.                     &rect);
  245.  
  246.             if(rot == HAL_TRANSFORM_ROT_90)
  247.                 orientation = HAL_TRANSFORM_ROT_270;
  248.             else if(rot == HAL_TRANSFORM_ROT_270)
  249.                 orientation = HAL_TRANSFORM_ROT_90;
  250.             break;
  251.     }
  252.     return;
  253. }
  254.  
  255. static int closeExternalChannel(private_module_t *m)
  256. {
  257.     Overlay* pTemp = m->pobjOverlay;
  258.     if(pTemp != NULL)
  259.         pTemp->closeChannel();
  260.     return 0;
  261. }
  262.  
  263. static int startExternalChannel(private_module_t *m)
  264. {
  265.     Overlay *pTemp = m->pobjOverlay;
  266.     bool success = true;
  267.     int flags = WAIT_FOR_VSYNC;
  268.     if (!pTemp->isChannelUP()) {
  269.         int alignedW = ALIGN(m->info.xres, 32);
  270.  
  271.         private_handle_t const* hnd =
  272.                 reinterpret_cast<private_handle_t const*>(m->framebuffer);
  273.         overlay_buffer_info info;
  274.         info.width = alignedW;
  275.         info.height = hnd->height;
  276.         info.format = hnd->format;
  277.         info.size = hnd->size / m->numBuffers;
  278.  
  279.         if (m->trueMirrorSupport)
  280.             flags &= ~WAIT_FOR_VSYNC;
  281.         // External display connected during secure video playback
  282.         // Open secure UI session
  283.         // NOTE: when external display is already connected and then secure
  284.         // playback is started, we dont have to do anything
  285.         if(m->secureVideoOverlay)
  286.             flags |= SECURE_OVERLAY_SESSION;
  287.         // start the overlay Channel for mirroring
  288.         // m->enableHDMIOutput corresponds to the fbnum
  289.  
  290.         success = pTemp->startChannel(info, m->enableHDMIOutput,
  291.                         false, true, 0, VG0_PIPE, flags) &&
  292.                   pTemp->setFd(m->framebuffer->fd) &&
  293.                   pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
  294.     }
  295.  
  296.     overlay_rect destRect;
  297.     int rot = 0;
  298.     int currOrientation = 0;
  299.     int currentX = 0, currentY = 0;
  300.     uint32_t currentW = 0, currentH = 0;
  301.  
  302.     getSecondaryDisplayDestinationInfo(m, destRect, rot);
  303.     pTemp->getOrientation(currOrientation);
  304.  
  305.     if(rot != currOrientation) {
  306.         success &= pTemp->setTransform(rot);
  307.     }
  308.  
  309.     pTemp->getPosition(currentX, currentY, currentW, currentH);
  310.  
  311.     if ((currentX != destRect.x) || (currentY != destRect.y) ||
  312.             (currentW != destRect.w) || (currentH != destRect.h)) {
  313.         success &= pTemp->setPosition(destRect.x, destRect.y, destRect.w,
  314.             destRect.h);
  315.     }
  316.  
  317.     if (m->trueMirrorSupport) {
  318.         // if video is started the UI channel should be NO_WAIT.
  319.         flags = !m->videoOverlay ? WAIT_FOR_VSYNC : 0;
  320.         pTemp->updateOverlayFlags(flags);
  321.     }
  322.  
  323.     return success ? 0 : -1;
  324. }
  325.  
  326. static void *hdmi_ui_loop(void *ptr)
  327. {
  328.     private_module_t* m = reinterpret_cast<private_module_t*>(
  329.             ptr);
  330.     while (1) {
  331.         pthread_mutex_lock(&m->overlayLock);
  332.         while(!(m->hdmiStateChanged))
  333.             pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
  334.         m->hdmiStateChanged = false;
  335.         if (m->exitHDMIUILoop) {
  336.             pthread_mutex_unlock(&m->overlayLock);
  337.             return NULL;
  338.         }
  339.         int flags = WAIT_FOR_VSYNC;
  340.         const int NO_ERROR = 0;
  341.         Overlay* pTemp = m->pobjOverlay;
  342.         if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
  343.             if (startExternalChannel(m) == NO_ERROR) {
  344.                 pTemp->queueBuffer(m->currentOffset);
  345.             }
  346.         }
  347.         pthread_mutex_unlock(&m->overlayLock);
  348.     }
  349.     return NULL;
  350. }
  351.  
  352. static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
  353. {
  354.     private_module_t* m = reinterpret_cast<private_module_t*>(
  355.             dev->common.module);
  356.     pthread_mutex_lock(&m->overlayLock);
  357.     Overlay* pTemp = m->pobjOverlay;
  358.     if(started != m->videoOverlay) {
  359.         m->videoOverlay = started;
  360.         if (!m->trueMirrorSupport) {
  361.             m->hdmiStateChanged = true;
  362.             if (started && pTemp) {
  363.                 m->hdmiMirroringState = HDMI_NO_MIRRORING;
  364.                 closeExternalChannel(m);
  365.             } else if (m->enableHDMIOutput)
  366.                 m->hdmiMirroringState = HDMI_UI_MIRRORING;
  367.             pthread_cond_signal(&(m->overlayPost));
  368.         }
  369.     }
  370.     pthread_mutex_unlock(&m->overlayLock);
  371.     return 0;
  372. }
  373.  
  374. static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltype)
  375. {
  376.     private_module_t* m = reinterpret_cast<private_module_t*>(
  377.             dev->common.module);
  378.     pthread_mutex_lock(&m->overlayLock);
  379.     Overlay* pTemp = m->pobjOverlay;
  380.     m->enableHDMIOutput = externaltype;
  381.     LOGE("In fb_enableHDMIOutput: externaltype = %d", m->enableHDMIOutput);
  382.     if(externaltype) {
  383.         if (m->trueMirrorSupport) {
  384.             m->hdmiMirroringState = HDMI_UI_MIRRORING;
  385.         } else {
  386.             if(!m->videoOverlay)
  387.                 m->hdmiMirroringState = HDMI_UI_MIRRORING;
  388.         }
  389.     } else if (!externaltype && pTemp) {
  390.         m->hdmiMirroringState = HDMI_NO_MIRRORING;
  391.         closeExternalChannel(m);
  392.     }
  393.     if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
  394.         startExternalChannel(m);
  395.     }
  396.     pthread_mutex_unlock(&m->overlayLock);
  397.     return 0;
  398. }
  399.  
  400. static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
  401. {
  402.     private_module_t* m = reinterpret_cast<private_module_t*>(
  403.             dev->common.module);
  404.     pthread_mutex_lock(&m->overlayLock);
  405.     neworientation = orientation;
  406.     pthread_mutex_unlock(&m->overlayLock);
  407.     return 0;
  408. }
  409.  
  410. static int handle_open_secure_start(private_module_t* m) {
  411.     pthread_mutex_lock(&m->overlayLock);
  412.     m->hdmiMirroringState = HDMI_NO_MIRRORING;
  413.     m->secureVideoOverlay = true;
  414.     closeExternalChannel(m);
  415.     pthread_mutex_unlock(&m->overlayLock);
  416.     return 0;
  417. }
  418.  
  419. static int handle_open_secure_end(private_module_t* m) {
  420.     pthread_mutex_lock(&m->overlayLock);
  421.     if (m->enableHDMIOutput) {
  422.         if (m->trueMirrorSupport) {
  423.             m->hdmiMirroringState = HDMI_UI_MIRRORING;
  424.         } else if(!m->videoOverlay) {
  425.             m->hdmiMirroringState = HDMI_UI_MIRRORING;
  426.         }
  427.         m->hdmiStateChanged = true;
  428.         pthread_cond_signal(&(m->overlayPost));
  429.     }
  430.     pthread_mutex_unlock(&m->overlayLock);
  431.     return 0;
  432. }
  433.  
  434. static int handle_close_secure_start(private_module_t* m) {
  435.     pthread_mutex_lock(&m->overlayLock);
  436.     m->hdmiMirroringState = HDMI_NO_MIRRORING;
  437.     m->secureVideoOverlay = false;
  438.     closeExternalChannel(m);
  439.     pthread_mutex_unlock(&m->overlayLock);
  440.     return 0;
  441. }
  442.  
  443. static int handle_close_secure_end(private_module_t* m) {
  444.     pthread_mutex_lock(&m->overlayLock);
  445.     if (m->enableHDMIOutput) {
  446.         if (m->trueMirrorSupport) {
  447.             m->hdmiMirroringState = HDMI_UI_MIRRORING;
  448.         } else if(!m->videoOverlay) {
  449.             m->hdmiMirroringState = HDMI_UI_MIRRORING;
  450.         }
  451.         m->hdmiStateChanged = true;
  452.         pthread_cond_signal(&(m->overlayPost));
  453.     }
  454.     pthread_mutex_unlock(&m->overlayLock);
  455.     return 0;
  456. }
  457. #endif
  458.  
  459. //Wait until framebuffer content is displayed.
  460. ////This is called in the context of threadLoop.
  461. ////Display loop wakes this up after display.
  462. static int fb_waitForBufferPost(struct framebuffer_device_t* dev)
  463. {
  464.     private_module_t* m = reinterpret_cast<private_module_t*>(
  465.                             dev->common.module);
  466.     pthread_mutex_lock(&m->bufferPostLock);
  467.     while(m->bufferPostDone == false) {
  468.         pthread_cond_wait(&(m->bufferPostCond), &(m->bufferPostLock));
  469.     }
  470.     pthread_mutex_unlock(&m->bufferPostLock);
  471.     return 0;
  472. }
  473.  
  474. static int fb_resetBufferPostStatus(struct framebuffer_device_t* dev)
  475. {
  476.     private_module_t* m = reinterpret_cast<private_module_t*>(
  477.                             dev->common.module);
  478.     pthread_mutex_lock(&m->bufferPostLock);
  479.     m->bufferPostDone = false;
  480.     pthread_mutex_unlock(&m->bufferPostLock);
  481.     return 0;
  482. }
  483.  
  484. /* fb_perform - used to add custom event and handle them in fb HAL
  485.  * Used for external display related functions as of now
  486. */
  487. static int fb_perform(struct framebuffer_device_t* dev, int event, int value)
  488. {
  489.     private_module_t* m = reinterpret_cast<private_module_t*>(
  490.             dev->common.module);
  491.     switch(event) {
  492. #if defined(HDMI_DUAL_DISPLAY)
  493.         case EVENT_EXTERNAL_DISPLAY:
  494.             fb_enableHDMIOutput(dev, value);
  495.             break;
  496.         case EVENT_VIDEO_OVERLAY:
  497.             fb_videoOverlayStarted(dev, value);
  498.             break;
  499.         case EVENT_ORIENTATION_CHANGE:
  500.             fb_orientationChanged(dev, value);
  501.             break;
  502.         case EVENT_OPEN_SECURE_START:
  503.             handle_open_secure_start(m);
  504.             break;
  505.         case EVENT_OPEN_SECURE_END:
  506.             handle_open_secure_end(m);
  507.             break;
  508.         case EVENT_CLOSE_SECURE_START:
  509.             handle_close_secure_start(m);
  510.             break;
  511.         case EVENT_CLOSE_SECURE_END:
  512.             handle_close_secure_end(m);
  513.             break;
  514. #endif
  515.         case EVENT_RESET_POSTBUFFER:
  516.             fb_resetBufferPostStatus(dev);
  517.             break;
  518.         case EVENT_WAIT_POSTBUFFER:
  519.             fb_waitForBufferPost(dev);
  520.             break;
  521.         default:
  522.             LOGE("In %s: UNKNOWN Event = %d!!!", __FUNCTION__, event);
  523.             break;
  524.     }
  525.     return 0;
  526.  }
  527.  
  528. static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
  529. {
  530.     if (private_handle_t::validate(buffer) < 0)
  531.         return -EINVAL;
  532.  
  533.     int nxtIdx, futureIdx = -1;
  534.     bool reuse;
  535.     struct qbuf_t qb;
  536.     fb_context_t* ctx = (fb_context_t*)dev;
  537.  
  538.     private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
  539.     private_module_t* m = reinterpret_cast<private_module_t*>(
  540.             dev->common.module);
  541.  
  542.     if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
  543.  
  544.         reuse = false;
  545.         nxtIdx = (m->currentIdx + 1) % m->numBuffers;
  546.         futureIdx = (nxtIdx + 1) % m->numBuffers;
  547.  
  548.         if (m->swapInterval == 0) {
  549.             // if SwapInterval = 0 and no buffers available then reuse
  550.             // current buf for next rendering so don't post new buffer
  551.             if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) {
  552.                 reuse = true;
  553.             } else {
  554.                 if (! m->avail[nxtIdx].is_avail)
  555.                     reuse = true;
  556.                 pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
  557.             }
  558.         }
  559.  
  560.         if(!reuse){
  561.             // unlock previous ("current") Buffer and lock the new buffer
  562.             m->base.lock(&m->base, buffer,
  563.                     private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
  564.                     0,0, m->info.xres, m->info.yres, NULL);
  565.  
  566.             // post/queue the new buffer
  567.             pthread_mutex_lock(&(m->avail[nxtIdx].lock));
  568.             if (m->avail[nxtIdx].is_avail != true) {
  569.                 LOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx);
  570.             }
  571.  
  572.             m->avail[nxtIdx].is_avail = false;
  573.  
  574.             if (m->avail[nxtIdx].state != AVL) {
  575.                 LOGD("[%d] state %c, expected %c", nxtIdx,
  576.                     framebufferStateName[m->avail[nxtIdx].state],
  577.                     framebufferStateName[AVL]);
  578.             }
  579.  
  580.             m->avail[nxtIdx].state = SUB;
  581.             pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
  582.  
  583.             qb.idx = nxtIdx;
  584.             qb.buf = buffer;
  585.             pthread_mutex_lock(&(m->qlock));
  586.             m->disp.push(qb);
  587.             pthread_cond_signal(&(m->qpost));
  588.             pthread_mutex_unlock(&(m->qlock));
  589.  
  590.             if (m->currentBuffer)
  591.                 m->base.unlock(&m->base, m->currentBuffer);
  592.  
  593.             m->currentBuffer = buffer;
  594.             m->currentIdx = nxtIdx;
  595.         } else {
  596.             if (m->currentBuffer)
  597.                 m->base.unlock(&m->base, m->currentBuffer);
  598.             m->base.lock(&m->base, buffer,
  599.                          private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
  600.                          0,0, m->info.xres, m->info.yres, NULL);
  601.             m->currentBuffer = buffer;
  602.         }
  603.  
  604.     } else {
  605.         void* fb_vaddr;
  606.         void* buffer_vaddr;
  607.         m->base.lock(&m->base, m->framebuffer,
  608.                 GRALLOC_USAGE_SW_WRITE_RARELY,
  609.                 0, 0, m->info.xres, m->info.yres,
  610.                 &fb_vaddr);
  611.  
  612.         m->base.lock(&m->base, buffer,
  613.                 GRALLOC_USAGE_SW_READ_RARELY,
  614.                 0, 0, m->info.xres, m->info.yres,
  615.                 &buffer_vaddr);
  616.  
  617.         //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
  618.  
  619.         msm_copy_buffer(
  620.                 m->framebuffer, m->framebuffer->fd,
  621.                 m->info.xres, m->info.yres, m->fbFormat,
  622.                 m->info.xoffset, m->info.yoffset,
  623.                 m->info.width, m->info.height);
  624.  
  625.         m->base.unlock(&m->base, buffer);
  626.         m->base.unlock(&m->base, m->framebuffer);
  627.     }
  628.  
  629.     LOGD_IF(FB_DEBUG, "Framebuffer state: [0] = %c [1] = %c [2] = %c",
  630.         framebufferStateName[m->avail[0].state],
  631.         framebufferStateName[m->avail[1].state],
  632.         framebufferStateName[m->avail[2].state]);
  633.     return 0;
  634. }
  635.  
  636. static int fb_compositionComplete(struct framebuffer_device_t* dev)
  637. {
  638.     // TODO: Properly implement composition complete callback
  639.     glFinish();
  640.  
  641.     return 0;
  642. }
  643.  
  644. static int fb_lockBuffer(struct framebuffer_device_t* dev, int index)
  645. {
  646.     private_module_t* m = reinterpret_cast<private_module_t*>(
  647.             dev->common.module);
  648.  
  649.     // Return immediately if the buffer is available
  650.     if ((m->avail[index].state == AVL) || (m->swapInterval == 0))
  651.         return 0;
  652.  
  653.     pthread_mutex_lock(&(m->avail[index].lock));
  654.     while (m->avail[index].state != AVL) {
  655.         pthread_cond_wait(&(m->avail[index].cond),
  656.                          &(m->avail[index].lock));
  657.     }
  658.     pthread_mutex_unlock(&(m->avail[index].lock));
  659.  
  660.     return 0;
  661. }
  662.  
  663. /*****************************************************************************/
  664.  
  665. int mapFrameBufferLocked(struct private_module_t* module)
  666. {
  667.     // already initialized...
  668.     if (module->framebuffer) {
  669.         return 0;
  670.     }
  671.     char const * const device_template[] = {
  672.             "/dev/graphics/fb%u",
  673.             "/dev/fb%u",
  674.             0 };
  675.  
  676.     int fd = -1;
  677.     int i=0;
  678.     char name[64];
  679.     char property[PROPERTY_VALUE_MAX];
  680.  
  681.     while ((fd==-1) && device_template[i]) {
  682.         snprintf(name, 64, device_template[i], 0);
  683.         fd = open(name, O_RDWR, 0);
  684.         i++;
  685.     }
  686.     if (fd < 0) {
  687.         LOGE("%s: %d: unable to open device fb0",__FUNCTION__,__LINE__);
  688.         return -errno;
  689.     }
  690.  
  691.     struct fb_fix_screeninfo finfo;
  692.     if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
  693.         LOGE("%s: %d: fb icotl fail %s",__FUNCTION__,__LINE__,strerror(errno));
  694.         close(fd);
  695.         return -errno;
  696.     }
  697.  
  698.     struct fb_var_screeninfo info;
  699.     if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
  700.         LOGE("%s: %d: fb icotl fail %s",__FUNCTION__,__LINE__,strerror(errno));
  701.         close(fd);
  702.         return -errno;
  703.     }
  704.  
  705.     info.reserved[0] = 0;
  706.     info.reserved[1] = 0;
  707.     info.reserved[2] = 0;
  708.     info.xoffset = 0;
  709.     info.yoffset = 0;
  710.     info.activate = FB_ACTIVATE_NOW;
  711.  
  712.     /* Interpretation of offset for color fields: All offsets are from the right,
  713.     * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
  714.     * can use the offset as right argument to <<). A pixel afterwards is a bit
  715.     * stream and is written to video memory as that unmodified. This implies
  716.     * big-endian byte order if bits_per_pixel is greater than 8.
  717.     */
  718.  
  719.     if(info.bits_per_pixel == 32) {
  720.         /*
  721.          * Explicitly request RGBA_8888
  722.          */
  723. #ifdef SEMC_RGBA_8888_OFFSET
  724.         info.red.offset     = 0;
  725.         info.green.offset   = 8;
  726.         info.blue.offset    = 16;
  727.         info.transp.offset  = 24;
  728. #else
  729.         info.red.offset     = 24;
  730.         info.green.offset   = 16;
  731.         info.blue.offset    = 8;
  732.         info.transp.offset  = 0;
  733. #endif
  734.         info.bits_per_pixel = 32;
  735.         info.red.length     = 8;
  736.         info.green.length   = 8;
  737.         info.blue.length    = 8;
  738.         info.transp.length  = 8;
  739.  
  740.         /* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
  741.          * not use the MDP for composition (i.e. hw composition == 0), ask for
  742.          * RGBA instead of RGBX. */
  743.         if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
  744.             module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
  745.         else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
  746.             module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
  747.         else
  748.             module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
  749.     } else {
  750.         /*
  751.          * Explicitly request 5/6/5
  752.          */
  753.         info.bits_per_pixel = 16;
  754.         info.red.offset     = 11;
  755.         info.red.length     = 5;
  756.         info.green.offset   = 5;
  757.         info.green.length   = 6;
  758.         info.blue.offset    = 0;
  759.         info.blue.length    = 5;
  760.         info.transp.offset  = 0;
  761.         info.transp.length  = 0;
  762.         module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
  763.     }
  764.     /*
  765.      * Request NUM_BUFFERS screens (at lest 2 for page flipping)
  766.      */
  767.     int numberOfBuffers = (int)(finfo.smem_len/(info.yres * info.xres * (info.bits_per_pixel/8)));
  768.     LOGV("num supported framebuffers in kernel = %d", numberOfBuffers);
  769.  
  770.     if (property_get("debug.gr.numframebuffers", property, NULL) > 0) {
  771.         int num = atoi(property);
  772.         if ((num >= NUM_FRAMEBUFFERS_MIN) && (num <= NUM_FRAMEBUFFERS_MAX)) {
  773.             numberOfBuffers = num;
  774.         }
  775.     }
  776.     if (numberOfBuffers > NUM_FRAMEBUFFERS_MAX)
  777.         numberOfBuffers = NUM_FRAMEBUFFERS_MAX;
  778.  
  779.     LOGE("We support %d buffers", numberOfBuffers);
  780.  
  781.     info.yres_virtual = info.yres * numberOfBuffers;
  782.  
  783.     uint32_t flags = PAGE_FLIP;
  784.     if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
  785.         info.yres_virtual = info.yres;
  786.         flags &= ~PAGE_FLIP;
  787.         LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
  788.     }
  789.  
  790.     if (info.yres_virtual < info.yres * 2) {
  791.         // we need at least 2 for page-flipping
  792.         info.yres_virtual = info.yres;
  793.         flags &= ~PAGE_FLIP;
  794.         LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
  795.                 info.yres_virtual, info.yres*2);
  796.     }
  797.  
  798.     if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
  799.         LOGE("%s: %d: fb icotl fail %s",__FUNCTION__,__LINE__,strerror(errno));
  800.         close(fd);
  801.         return -errno;
  802.     }
  803.  
  804.     if (int(info.width) <= 0 || int(info.height) <= 0) {
  805.         // the driver doesn't return that information
  806.         // default to 160 dpi
  807.         info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
  808.         info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
  809.     }
  810.  
  811.     float xdpi = (info.xres * 25.4f) / info.width;
  812.     float ydpi = (info.yres * 25.4f) / info.height;
  813.     //The reserved[4] field is used to store FPS by the driver.
  814.     float fps  = info.reserved[4];
  815.  
  816.     LOGI(   "using (fd=%d)\n"
  817.             "id           = %s\n"
  818.             "xres         = %d px\n"
  819.             "yres         = %d px\n"
  820.             "xres_virtual = %d px\n"
  821.             "yres_virtual = %d px\n"
  822.             "bpp          = %d\n"
  823.             "r            = %2u:%u\n"
  824.             "g            = %2u:%u\n"
  825.             "b            = %2u:%u\n",
  826.             fd,
  827.             finfo.id,
  828.             info.xres,
  829.             info.yres,
  830.             info.xres_virtual,
  831.             info.yres_virtual,
  832.             info.bits_per_pixel,
  833.             info.red.offset, info.red.length,
  834.             info.green.offset, info.green.length,
  835.             info.blue.offset, info.blue.length
  836.     );
  837.  
  838.     LOGI(   "width        = %d mm (%f dpi)\n"
  839.             "height       = %d mm (%f dpi)\n"
  840.             "refresh rate = %.2f Hz\n",
  841.             info.width,  xdpi,
  842.             info.height, ydpi,
  843.             fps
  844.     );
  845.  
  846.  
  847.     if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
  848.         LOGE("%s: %d: fb icotl fail %s",__FUNCTION__,__LINE__,strerror(errno));
  849.         close(fd);
  850.         return -errno;
  851.     }
  852.  
  853.     if (finfo.smem_len <= 0) {
  854.         LOGE("%s: %d: not a valid FB mem size",__FUNCTION__,__LINE__);
  855.         close(fd);
  856.         return -errno;
  857.     }
  858.  
  859.     module->flags = flags;
  860.     module->info = info;
  861.     module->finfo = finfo;
  862.     module->xdpi = xdpi;
  863.     module->ydpi = ydpi;
  864.     module->fps = fps;
  865.  
  866. #ifdef NO_SURFACEFLINGER_SWAPINTERVAL
  867.     char pval[PROPERTY_VALUE_MAX];
  868.     property_get("debug.gr.swapinterval", pval, "1");
  869.     module->swapInterval = atoi(pval);
  870.     if (module->swapInterval < private_module_t::PRIV_MIN_SWAP_INTERVAL ||
  871.         module->swapInterval > private_module_t::PRIV_MAX_SWAP_INTERVAL) {
  872.         module->swapInterval = 1;
  873.         LOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
  874.              private_module_t::PRIV_MIN_SWAP_INTERVAL,
  875.              private_module_t::PRIV_MAX_SWAP_INTERVAL);
  876.     }
  877.  
  878. #else
  879.     /* when surfaceflinger supports swapInterval then can just do this */
  880.     module->swapInterval = 1;
  881. #endif
  882.  
  883.     CALC_INIT();
  884.  
  885.     module->currentIdx = -1;
  886.     pthread_cond_init(&(module->qpost), NULL);
  887.     pthread_mutex_init(&(module->qlock), NULL);
  888.     for (i = 0; i < NUM_FRAMEBUFFERS_MAX; i++) {
  889.         pthread_mutex_init(&(module->avail[i].lock), NULL);
  890.         pthread_cond_init(&(module->avail[i].cond), NULL);
  891.         module->avail[i].is_avail = true;
  892.         module->avail[i].state = AVL;
  893.     }
  894.  
  895.     /* create display update thread */
  896.     pthread_t thread1;
  897.     if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
  898.         LOGE("%s: %d: failed to create display loop thread",__FUNCTION__,__LINE__);
  899.         close(fd);
  900.         return -errno;
  901.     }
  902.  
  903.     /*
  904.      * map the framebuffer
  905.      */
  906.  
  907.     int err;
  908.     size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual);
  909.     module->framebuffer = new private_handle_t(fd, fbSize,
  910.             private_handle_t::PRIV_FLAGS_USES_PMEM, BUFFER_TYPE_UI, module->fbFormat, info.xres, info.yres);
  911.  
  912.     module->numBuffers = info.yres_virtual / info.yres;
  913.     module->bufferMask = 0;
  914.  
  915.     void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  916.     if (vaddr == MAP_FAILED) {
  917.         LOGE("Error mapping the framebuffer (%s)", strerror(errno));
  918.         close(fd);
  919.         return -errno;
  920.     }
  921.     module->framebuffer->base = intptr_t(vaddr);
  922.     memset(vaddr, 0, fbSize);
  923.  
  924. #if defined(HDMI_DUAL_DISPLAY)
  925.     /* Overlay for HDMI*/
  926.     pthread_mutex_init(&(module->overlayLock), NULL);
  927.     pthread_cond_init(&(module->overlayPost), NULL);
  928.     module->pobjOverlay = new Overlay();
  929.     module->currentOffset = 0;
  930.     module->exitHDMIUILoop = false;
  931.     module->hdmiStateChanged = false;
  932.     pthread_t hdmiUIThread;
  933.     pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
  934.     module->hdmiMirroringState = HDMI_NO_MIRRORING;
  935.     module->trueMirrorSupport = FrameBufferInfo::getInstance()->canSupportTrueMirroring();
  936. #endif
  937.     pthread_mutex_init(&(module->bufferPostLock), NULL);
  938.     pthread_cond_init(&(module->bufferPostCond), NULL);
  939.     module->bufferPostDone = false;
  940.  
  941.    return 0;
  942. }
  943.  
  944. static int mapFrameBuffer(struct private_module_t* module)
  945. {
  946.     pthread_mutex_lock(&module->lock);
  947.     int err = mapFrameBufferLocked(module);
  948.     pthread_mutex_unlock(&module->lock);
  949.     return err;
  950. }
  951.  
  952. /*****************************************************************************/
  953.  
  954. static int fb_close(struct hw_device_t *dev)
  955. {
  956.     fb_context_t* ctx = (fb_context_t*)dev;
  957. #if defined(HDMI_DUAL_DISPLAY)
  958.     private_module_t* m = reinterpret_cast<private_module_t*>(
  959.             ctx->device.common.module);
  960.     pthread_mutex_lock(&m->overlayLock);
  961.     m->exitHDMIUILoop = true;
  962.     pthread_cond_signal(&(m->overlayPost));
  963.     pthread_mutex_unlock(&m->overlayLock);
  964. #endif
  965.     if (ctx) {
  966.         free(ctx);
  967.     }
  968.     return 0;
  969. }
  970.  
  971. int fb_device_open(hw_module_t const* module, const char* name,
  972.         hw_device_t** device)
  973. {
  974.     int status = -EINVAL;
  975.     if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
  976.         alloc_device_t* gralloc_device;
  977.         status = gralloc_open(module, &gralloc_device);
  978.         if (status < 0)
  979.             return status;
  980.  
  981.         /* initialize our state here */
  982.         fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
  983.         memset(dev, 0, sizeof(*dev));
  984.  
  985.         /* initialize the procs */
  986.         dev->device.common.tag = HARDWARE_DEVICE_TAG;
  987.         dev->device.common.version = 0;
  988.         dev->device.common.module = const_cast<hw_module_t*>(module);
  989.         dev->device.common.close = fb_close;
  990.         dev->device.setSwapInterval = fb_setSwapInterval;
  991.         dev->device.post            = fb_post;
  992.         dev->device.setUpdateRect = 0;
  993.         dev->device.compositionComplete = fb_compositionComplete;
  994.         dev->device.lockBuffer = fb_lockBuffer;
  995.         dev->device.perform = fb_perform;
  996.  
  997.         private_module_t* m = (private_module_t*)module;
  998.         status = mapFrameBuffer(m);
  999.         if (status >= 0) {
  1000.             int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
  1001.             const_cast<uint32_t&>(dev->device.flags) = 0;
  1002.             const_cast<uint32_t&>(dev->device.width) = m->info.xres;
  1003.             const_cast<uint32_t&>(dev->device.height) = m->info.yres;
  1004.             const_cast<int&>(dev->device.stride) = stride;
  1005.             const_cast<int&>(dev->device.format) = m->fbFormat;
  1006.             const_cast<float&>(dev->device.xdpi) = m->xdpi;
  1007.             const_cast<float&>(dev->device.ydpi) = m->ydpi;
  1008.             const_cast<float&>(dev->device.fps) = m->fps;
  1009.             const_cast<int&>(dev->device.minSwapInterval) = private_module_t::PRIV_MIN_SWAP_INTERVAL;
  1010.             const_cast<int&>(dev->device.maxSwapInterval) = private_module_t::PRIV_MAX_SWAP_INTERVAL;
  1011.             const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
  1012.             if (m->finfo.reserved[0] == 0x5444 &&
  1013.                     m->finfo.reserved[1] == 0x5055) {
  1014.                 dev->device.setUpdateRect = fb_setUpdateRect;
  1015.                 LOGD("UPDATE_ON_DEMAND supported");
  1016.             }
  1017.  
  1018.             *device = &dev->device.common;
  1019.         }
  1020.  
  1021.         // Close the gralloc module
  1022.         gralloc_close(gralloc_device);
  1023.     }
  1024.     return status;
  1025. }
  1026.  
  1027. /* Copy a pmem buffer to the framebuffer */
  1028.  
  1029. static void
  1030. msm_copy_buffer(buffer_handle_t handle, int fd,
  1031.                 int width, int height, int format,
  1032.                 int x, int y, int w, int h)
  1033. {
  1034.     struct {
  1035.         unsigned int count;
  1036.         mdp_blit_req req;
  1037.     } blit;
  1038.     private_handle_t *priv = (private_handle_t*) handle;
  1039.  
  1040.     memset(&blit, 0, sizeof(blit));
  1041.     blit.count = 1;
  1042.  
  1043.     blit.req.flags = 0;
  1044.     blit.req.alpha = 0xff;
  1045.     blit.req.transp_mask = 0xffffffff;
  1046.  
  1047.     blit.req.src.width = width;
  1048.     blit.req.src.height = height;
  1049.     blit.req.src.offset = 0;
  1050.     blit.req.src.memory_id = priv->fd;
  1051.  
  1052.     blit.req.dst.width = width;
  1053.     blit.req.dst.height = height;
  1054.     blit.req.dst.offset = 0;
  1055.     blit.req.dst.memory_id = fd;
  1056.     blit.req.dst.format = format;
  1057.  
  1058.     blit.req.src_rect.x = blit.req.dst_rect.x = x;
  1059.     blit.req.src_rect.y = blit.req.dst_rect.y = y;
  1060.     blit.req.src_rect.w = blit.req.dst_rect.w = w;
  1061.     blit.req.src_rect.h = blit.req.dst_rect.h = h;
  1062.  
  1063.     if (ioctl(fd, MSMFB_BLIT, &blit))
  1064.         LOGE("MSMFB_BLIT failed = %d", -errno);
  1065. }
Advertisement
Add Comment
Please, Sign In to add comment