Advertisement
Guest User

Untitled

a guest
Apr 9th, 2015
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.81 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  4. *
  5. * Not a Contribution, Apache license notifications and license are retained
  6. * for attribution purposes only.
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
  21. #include <fcntl.h>
  22. #include <errno.h>
  23.  
  24. #include <cutils/log.h>
  25. #include <cutils/atomic.h>
  26. #include <EGL/egl.h>
  27. #include <utils/Trace.h>
  28. #include <sys/ioctl.h>
  29. #include <overlay.h>
  30. #include <overlayRotator.h>
  31. #include <mdp_version.h>
  32. #include "hwc_utils.h"
  33. #include "hwc_fbupdate.h"
  34. #include "hwc_mdpcomp.h"
  35. #include "hwc_dump_layers.h"
  36. #include "external.h"
  37. #include "hwc_copybit.h"
  38. #include "profiler.h"
  39.  
  40. using namespace qhwc;
  41. using namespace overlay;
  42.  
  43. #define VSYNC_DEBUG 0
  44. #define BLANK_DEBUG 1
  45.  
  46. static int hwc_device_open(const struct hw_module_t* module,
  47. const char* name,
  48. struct hw_device_t** device);
  49.  
  50. static struct hw_module_methods_t hwc_module_methods = {
  51. open: hwc_device_open
  52. };
  53.  
  54. static void reset_panel(struct hwc_composer_device_1* dev);
  55.  
  56. hwc_module_t HAL_MODULE_INFO_SYM = {
  57. common: {
  58. tag: HARDWARE_MODULE_TAG,
  59. version_major: 2,
  60. version_minor: 0,
  61. id: HWC_HARDWARE_MODULE_ID,
  62. name: "Qualcomm Hardware Composer Module",
  63. author: "CodeAurora Forum",
  64. methods: &hwc_module_methods,
  65. dso: 0,
  66. reserved: {0},
  67. }
  68. };
  69.  
  70. /* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
  71. * HDMI display ID for virtual. This helper is needed to differentiate their
  72. * paths in HAL.
  73. * TODO: Not needed once we have WFD client working on top of Google API's */
  74.  
  75. static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
  76. if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
  77. return HWC_DISPLAY_VIRTUAL;
  78. return dpy;
  79. }
  80.  
  81. /*
  82. * Save callback functions registered to HWC
  83. */
  84. static void hwc_registerProcs(struct hwc_composer_device_1* dev,
  85. hwc_procs_t const* procs)
  86. {
  87. ALOGI("%s", __FUNCTION__);
  88. hwc_context_t* ctx = (hwc_context_t*)(dev);
  89. if(!ctx) {
  90. ALOGE("%s: Invalid context", __FUNCTION__);
  91. return;
  92. }
  93. ctx->proc = procs;
  94.  
  95. // Now that we have the functions needed, kick off
  96. // the uevent & vsync threads
  97. init_uevent_thread(ctx);
  98. init_vsync_thread(ctx);
  99. }
  100.  
  101. //Helper
  102. static void reset(hwc_context_t *ctx, int numDisplays,
  103. hwc_display_contents_1_t** displays) {
  104. ctx->isPaddingRound = false;
  105. memset(ctx->listStats, 0, sizeof(ctx->listStats));
  106. for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
  107. hwc_display_contents_1_t *list = displays[i];
  108. // XXX:SurfaceFlinger no longer guarantees that this
  109. // value is reset on every prepare. However, for the layer
  110. // cache we need to reset it.
  111. // We can probably rethink that later on
  112. if (LIKELY(list && list->numHwLayers > 0)) {
  113. for(uint32_t j = 0; j < list->numHwLayers; j++) {
  114. if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
  115. list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
  116. }
  117.  
  118. if((ctx->mPrevHwLayerCount[i] == 1) and (list->numHwLayers > 1)) {
  119. /* If the previous cycle for dpy 'i' has 0 AppLayers and the
  120. * current cycle has atleast 1 AppLayer, padding round needs
  121. * to be invoked on current cycle to free up the resources.
  122. */
  123. ctx->isPaddingRound = true;
  124. }
  125. ctx->mPrevHwLayerCount[i] = list->numHwLayers;
  126. } else {
  127. ctx->mPrevHwLayerCount[i] = 0;
  128. }
  129.  
  130. if(ctx->mFBUpdate[i])
  131. ctx->mFBUpdate[i]->reset();
  132. if(ctx->mCopyBit[i])
  133. ctx->mCopyBit[i]->reset();
  134. if(ctx->mLayerRotMap[i])
  135. ctx->mLayerRotMap[i]->reset();
  136. }
  137.  
  138. }
  139.  
  140. //clear prev layer prop flags and realloc for current frame
  141. static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
  142. if(ctx->layerProp[dpy]) {
  143. delete[] ctx->layerProp[dpy];
  144. ctx->layerProp[dpy] = NULL;
  145. }
  146. ctx->layerProp[dpy] = new LayerProp[numAppLayers];
  147. }
  148.  
  149.  
  150. static int hwc_prepare_primary(hwc_composer_device_1 *dev,
  151. hwc_display_contents_1_t *list) {
  152. hwc_context_t* ctx = (hwc_context_t*)(dev);
  153. const int dpy = HWC_DISPLAY_PRIMARY;
  154. int ret = -1;
  155. if(UNLIKELY(!ctx->mBasePipeSetup) &&
  156. qdutils::MDPVersion::getInstance().getMDPVersion() >= qdutils::MDP_V4_2)
  157. setupBasePipe(ctx);
  158. if (LIKELY(list && list->numHwLayers > 1) &&
  159. ctx->dpyAttr[dpy].isActive) {
  160. reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
  161. setListStats(ctx, list, dpy);
  162. if((ret = ctx->mMDPComp[dpy]->prepare(ctx, list)) < 0) {
  163. const int fbZ = 0;
  164. ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
  165. }
  166. #ifdef USE_COPYBIT_COMPOSITION_FALLBACK
  167. // Use Copybit, when MDP comp fails
  168. // (only for 8960 which has dedicated 2D core)
  169. if((ret < 1) && ctx->mCopyBit[dpy])
  170. ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
  171. #endif
  172. }
  173. return 0;
  174. }
  175.  
  176. static int hwc_prepare_external(hwc_composer_device_1 *dev,
  177. hwc_display_contents_1_t *list) {
  178. hwc_context_t* ctx = (hwc_context_t*)(dev);
  179. const int dpy = HWC_DISPLAY_EXTERNAL;
  180. int ret = -1;
  181.  
  182. if (LIKELY(list && list->numHwLayers > 1) &&
  183. ctx->dpyAttr[dpy].isActive &&
  184. ctx->dpyAttr[dpy].connected) {
  185. reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
  186. if(!ctx->dpyAttr[dpy].isPause) {
  187. ctx->dpyAttr[dpy].isConfiguring = false;
  188. setListStats(ctx, list, dpy);
  189. if((ret = ctx->mMDPComp[dpy]->prepare(ctx, list)) < 0) {
  190. const int fbZ = 0;
  191. ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
  192. }
  193. #ifdef USE_COPYBIT_COMPOSITION_FALLBACK
  194. // Use Copybit, when MDP comp fails
  195. // (only for 8960 which has dedicated 2D core)
  196. if((ret < 1) && ctx->mCopyBit[dpy] &&
  197. !ctx->listStats[dpy].isDisplayAnimating)
  198. ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
  199. #endif
  200. if(ctx->listStats[dpy].isDisplayAnimating) {
  201. // Mark all app layers as HWC_OVERLAY for external during
  202. // animation, so that SF doesnt draw it on FB
  203. for(int i = 0 ;i < ctx->listStats[dpy].numAppLayers; i++) {
  204. hwc_layer_1_t *layer = &list->hwLayers[i];
  205. layer->compositionType = HWC_OVERLAY;
  206. }
  207. }
  208. } else {
  209. /* External Display is in Pause state.
  210. * Mark all application layers as OVERLAY so that
  211. * GPU will not compose.
  212. */
  213. for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
  214. hwc_layer_1_t *layer = &list->hwLayers[i];
  215. layer->compositionType = HWC_OVERLAY;
  216. }
  217. }
  218. }
  219. return 0;
  220. }
  221.  
  222. static int hwc_prepare_virtual(hwc_composer_device_1 *dev,
  223. hwc_display_contents_1_t *list) {
  224.  
  225. hwc_context_t* ctx = (hwc_context_t*)(dev);
  226. const int dpy = HWC_DISPLAY_VIRTUAL;
  227.  
  228. if (LIKELY(list && list->numHwLayers > 1) &&
  229. ctx->dpyAttr[dpy].isActive &&
  230. ctx->dpyAttr[dpy].connected) {
  231. reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
  232. if(!ctx->dpyAttr[dpy].isPause) {
  233. ctx->dpyAttr[dpy].isConfiguring = false;
  234. setListStats(ctx, list, dpy);
  235. if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
  236. const int fbZ = 0;
  237. ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
  238. }
  239.  
  240. if(ctx->listStats[dpy].isDisplayAnimating) {
  241. // Mark all app layers as HWC_OVERLAY for virtual during
  242. // animation, so that SF doesnt draw it on FB
  243. for(int i = 0 ;i < ctx->listStats[dpy].numAppLayers; i++) {
  244. hwc_layer_1_t *layer = &list->hwLayers[i];
  245. layer->compositionType = HWC_OVERLAY;
  246. }
  247. }
  248. } else {
  249. /* Virtual Display is in Pause state.
  250. * Mark all application layers as OVERLAY so that
  251. * GPU will not compose.
  252. */
  253. for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
  254. hwc_layer_1_t *layer = &list->hwLayers[i];
  255. layer->compositionType = HWC_OVERLAY;
  256. }
  257. }
  258. }
  259. return 0;
  260. }
  261.  
  262.  
  263. static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
  264. hwc_display_contents_1_t** displays)
  265. {
  266. int ret = 0;
  267. hwc_context_t* ctx = (hwc_context_t*)(dev);
  268.  
  269. if (ctx->mPanelResetStatus) {
  270. ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
  271. reset_panel(dev);
  272. }
  273.  
  274. //Will be unlocked at the end of set
  275. ctx->mDrawLock.lock();
  276. reset(ctx, numDisplays, displays);
  277.  
  278. ctx->mOverlay->configBegin();
  279. ctx->mRotMgr->configBegin();
  280. ctx->mNeedsRotator = false;
  281.  
  282. for (int32_t i = numDisplays; i >= 0; i--) {
  283. hwc_display_contents_1_t *list = displays[i];
  284. int dpy = getDpyforExternalDisplay(ctx, i);
  285. switch(dpy) {
  286. case HWC_DISPLAY_PRIMARY:
  287. ret = hwc_prepare_primary(dev, list);
  288. break;
  289. case HWC_DISPLAY_EXTERNAL:
  290. ret = hwc_prepare_external(dev, list);
  291. break;
  292. case HWC_DISPLAY_VIRTUAL:
  293. ret = hwc_prepare_virtual(dev, list);
  294. break;
  295. default:
  296. ret = -EINVAL;
  297. }
  298. }
  299.  
  300. ctx->mOverlay->configDone();
  301. ctx->mRotMgr->configDone();
  302.  
  303. return ret;
  304. }
  305.  
  306. static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
  307. int event, int enable)
  308. {
  309. int ret = 0;
  310. hwc_context_t* ctx = (hwc_context_t*)(dev);
  311.  
  312. if(!ctx->dpyAttr[dpy].isActive) {
  313. ALOGE("Display is blanked - Cannot %s vsync",
  314. enable ? "enable" : "disable");
  315. return -EINVAL;
  316. }
  317.  
  318. switch(event) {
  319. case HWC_EVENT_VSYNC:
  320. if (ctx->vstate.enable == enable)
  321. break;
  322. ret = hwc_vsync_control(ctx, dpy, enable);
  323. if(ret == 0)
  324. ctx->vstate.enable = !!enable;
  325. ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
  326. (enable)?"ENABLED":"DISABLED");
  327. break;
  328. #ifdef QCOM_BSP
  329. case HWC_EVENT_ORIENTATION:
  330. if(dpy == HWC_DISPLAY_PRIMARY) {
  331. Locker::Autolock _l(ctx->mDrawLock);
  332. // store the primary display orientation
  333. // will be used in hwc_video::configure to disable
  334. // rotation animation on external display
  335. ctx->deviceOrientation = enable;
  336. }
  337. break;
  338. #endif
  339. default:
  340. ret = -EINVAL;
  341. }
  342. return ret;
  343. }
  344.  
  345. static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
  346. {
  347. ATRACE_CALL();
  348. hwc_context_t* ctx = (hwc_context_t*)(dev);
  349.  
  350. Locker::Autolock _l(ctx->mDrawLock);
  351. int ret = 0, value = 0;
  352.  
  353. /* In case of non-hybrid WFD session, we are fooling SF by
  354. * piggybacking on HDMI display ID for virtual.
  355. * TODO: Not needed once we have WFD client working on top
  356. * of Google API's.
  357. */
  358. dpy = getDpyforExternalDisplay(ctx,dpy);
  359.  
  360. ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
  361. blank==1 ? "Blanking":"Unblanking", dpy);
  362. if(blank) {
  363. // free up all the overlay pipes in use
  364. // when we get a blank for either display
  365. // makes sure that all pipes are freed
  366. ctx->mOverlay->configBegin();
  367. ctx->mOverlay->configDone();
  368. ctx->mRotMgr->clear();
  369. }
  370. switch(dpy) {
  371. case HWC_DISPLAY_PRIMARY:
  372. if(blank) {
  373. int dpy = HWC_DISPLAY_PRIMARY;
  374. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)){
  375. ALOGE("%s: display commit fail for primary!", __FUNCTION__);
  376. ret = -1;
  377. }
  378. }
  379. value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
  380. if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
  381. ALOGE("%s: Failed to handle blank event(%d) for Primary!!",
  382. __FUNCTION__, blank );
  383. return -1;
  384. }
  385.  
  386. if(!blank) {
  387. // Enable HPD here, as during bootup unblank is called
  388. // when SF is completely initialized
  389. ctx->mExtDisplay->setHPD(1);
  390. }
  391.  
  392. ctx->dpyAttr[dpy].isActive = !blank;
  393.  
  394. if(ctx->mVirtualonExtActive) {
  395. /* if mVirtualonExtActive is true, display hal will
  396. * receive unblank calls for non-hybrid WFD solution
  397. * since we piggyback on HDMI.
  398. * TODO: Not needed once we have WFD client working on top
  399. of Google API's */
  400. break;
  401. }
  402. case HWC_DISPLAY_VIRTUAL:
  403. /* There are two ways to reach this block of code.
  404.  
  405. * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL
  406. and ctx->mVirtualonExtActive is true. In this case, non-hybrid
  407. WFD is active. If so, getDpyforExternalDisplay will return dpy
  408. as HWC_DISPLAY_VIRTUAL.
  409.  
  410. * Display hal has received unblank call on HWC_DISPLAY_PRIMARY
  411. and since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
  412. it wont send blank / unblank events for it. We piggyback on
  413. PRIMARY DISPLAY events to release mdp pipes and
  414. activate/deactivate VIRTUAL DISPLAY.
  415.  
  416. * TODO: This separate case statement is not needed once we have
  417. WFD client working on top of Google API's.
  418.  
  419. */
  420.  
  421. if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
  422. if(blank) {
  423. int dpy = HWC_DISPLAY_VIRTUAL;
  424. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd,1)) {
  425. ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
  426. ret = -1;
  427. }
  428. }
  429. ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
  430. }
  431. break;
  432. case HWC_DISPLAY_EXTERNAL:
  433. if(blank) {
  434. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd,1)) {
  435. ALOGE("%s: display commit fail for external!", __FUNCTION__);
  436. ret = -1;
  437. }
  438. }
  439. ctx->dpyAttr[dpy].isActive = !blank;
  440. break;
  441. default:
  442. return -EINVAL;
  443. }
  444.  
  445. ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
  446. blank ? "blanking":"unblanking", dpy);
  447. return ret;
  448. }
  449.  
  450. static void reset_panel(struct hwc_composer_device_1* dev)
  451. {
  452. int ret = 0;
  453. hwc_context_t* ctx = (hwc_context_t*)(dev);
  454.  
  455. if (!ctx->mPanelResetStatus)
  456. return;
  457.  
  458. ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__);
  459. ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1);
  460. if (ret < 0) {
  461. ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__,
  462. strerror(errno));
  463. }
  464.  
  465. ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__);
  466. ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0);
  467. if (ret < 0) {
  468. ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
  469. strerror(errno));
  470. }
  471. hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
  472.  
  473. ctx->mPanelResetStatus = false;
  474. }
  475.  
  476.  
  477. static int hwc_query(struct hwc_composer_device_1* dev,
  478. int param, int* value)
  479. {
  480. hwc_context_t* ctx = (hwc_context_t*)(dev);
  481. int supported = HWC_DISPLAY_PRIMARY_BIT;
  482.  
  483. switch (param) {
  484. case HWC_BACKGROUND_LAYER_SUPPORTED:
  485. // Not supported for now
  486. value[0] = 0;
  487. break;
  488. case HWC_DISPLAY_TYPES_SUPPORTED:
  489. if(ctx->mMDP.hasOverlay)
  490. supported |= HWC_DISPLAY_EXTERNAL_BIT;
  491. value[0] = supported;
  492. break;
  493. default:
  494. return -EINVAL;
  495. }
  496. return 0;
  497.  
  498. }
  499.  
  500.  
  501. static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
  502. ATRACE_CALL();
  503. int ret = 0;
  504. const int dpy = HWC_DISPLAY_PRIMARY;
  505. if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
  506. uint32_t last = list->numHwLayers - 1;
  507. hwc_layer_1_t *fbLayer = &list->hwLayers[last];
  508. int fd = -1; //FenceFD from the Copybit(valid in async mode)
  509. bool copybitDone = false;
  510. if(ctx->mCopyBit[dpy])
  511. copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
  512. if(list->numHwLayers > 1)
  513. hwc_sync(ctx, list, dpy, fd);
  514.  
  515. // Dump the layers for primary
  516. if(ctx->mHwcDebug[dpy])
  517. ctx->mHwcDebug[dpy]->dumpLayers(list);
  518.  
  519. if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
  520. ALOGE("%s: MDPComp draw failed", __FUNCTION__);
  521. ret = -1;
  522. }
  523.  
  524. //TODO We dont check for SKIP flag on this layer because we need PAN
  525. //always. Last layer is always FB
  526. private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
  527. if(copybitDone && ctx->mMDP.version > qdutils::MDP_V4_3) {
  528. hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
  529. }
  530.  
  531. if(hnd) {
  532. if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
  533. ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
  534. ret = -1;
  535. }
  536. }
  537.  
  538. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
  539. ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
  540. ret = -1;
  541. }
  542. }
  543.  
  544. closeAcquireFds(list);
  545. return ret;
  546. }
  547.  
  548. static int hwc_set_external(hwc_context_t *ctx,
  549. hwc_display_contents_1_t* list)
  550. {
  551. ATRACE_CALL();
  552. int ret = 0;
  553.  
  554. const int dpy = HWC_DISPLAY_EXTERNAL;
  555.  
  556.  
  557. if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
  558. ctx->dpyAttr[dpy].connected &&
  559. !ctx->dpyAttr[dpy].isPause) {
  560. uint32_t last = list->numHwLayers - 1;
  561. hwc_layer_1_t *fbLayer = &list->hwLayers[last];
  562. int fd = -1; //FenceFD from the Copybit(valid in async mode)
  563. bool copybitDone = false;
  564. if(ctx->mCopyBit[dpy])
  565. copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
  566.  
  567. if(list->numHwLayers > 1)
  568. hwc_sync(ctx, list, dpy, fd);
  569.  
  570. // Dump the layers for external
  571. if(ctx->mHwcDebug[dpy])
  572. ctx->mHwcDebug[dpy]->dumpLayers(list);
  573.  
  574. if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
  575. ALOGE("%s: MDPComp draw failed", __FUNCTION__);
  576. ret = -1;
  577. }
  578.  
  579. int extOnlyLayerIndex =
  580. ctx->listStats[dpy].extOnlyLayerIndex;
  581.  
  582. private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
  583. if(extOnlyLayerIndex!= -1) {
  584. hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
  585. hnd = (private_handle_t *)extLayer->handle;
  586. } else if(copybitDone && ctx->mMDP.version > qdutils::MDP_V4_3) {
  587. hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
  588. }
  589.  
  590. if(hnd && !isYuvBuffer(hnd)) {
  591. if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
  592. ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
  593. ret = -1;
  594. }
  595. }
  596.  
  597. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
  598. ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
  599. ret = -1;
  600. }
  601. }
  602.  
  603. closeAcquireFds(list);
  604. return ret;
  605. }
  606.  
  607. static int hwc_set_virtual(hwc_context_t *ctx,
  608. hwc_display_contents_1_t* list)
  609. {
  610. ATRACE_CALL();
  611. int ret = 0;
  612.  
  613. const int dpy = HWC_DISPLAY_VIRTUAL;
  614.  
  615.  
  616. if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
  617. ctx->dpyAttr[dpy].connected &&
  618. !ctx->dpyAttr[dpy].isPause) {
  619. uint32_t last = list->numHwLayers - 1;
  620. hwc_layer_1_t *fbLayer = &list->hwLayers[last];
  621. int fd = -1; //FenceFD from the Copybit(valid in async mode)
  622. bool copybitDone = false;
  623. if(ctx->mCopyBit[dpy])
  624. copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
  625.  
  626. if(list->numHwLayers > 1)
  627. hwc_sync(ctx, list, dpy, fd);
  628.  
  629.  
  630. if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
  631. ALOGE("%s: MDPComp draw failed", __FUNCTION__);
  632. ret = -1;
  633. }
  634.  
  635. int extOnlyLayerIndex =
  636. ctx->listStats[dpy].extOnlyLayerIndex;
  637.  
  638. private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
  639. if(extOnlyLayerIndex!= -1) {
  640. hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
  641. hnd = (private_handle_t *)extLayer->handle;
  642. } else if(copybitDone) {
  643. hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
  644. }
  645.  
  646. if(hnd && !isYuvBuffer(hnd)) {
  647. if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
  648. ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
  649. ret = -1;
  650. }
  651. }
  652.  
  653. if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
  654. ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
  655. ret = -1;
  656. }
  657. }
  658.  
  659. closeAcquireFds(list);
  660.  
  661. if (list && !ctx->mVirtualonExtActive && (list->retireFenceFd < 0) ) {
  662. // SF assumes HWC waits for the acquire fence and returns a new fence
  663. // that signals when we're done. Since we don't wait, and also don't
  664. // touch the buffer, we can just handle the acquire fence back to SF
  665. // as the retire fence.
  666. list->retireFenceFd = list->outbufAcquireFenceFd;
  667. }
  668.  
  669. return ret;
  670. }
  671.  
  672.  
  673. static int hwc_set(hwc_composer_device_1 *dev,
  674. size_t numDisplays,
  675. hwc_display_contents_1_t** displays)
  676. {
  677. int ret = 0;
  678. hwc_context_t* ctx = (hwc_context_t*)(dev);
  679. for (uint32_t i = 0; i <= numDisplays; i++) {
  680. hwc_display_contents_1_t* list = displays[i];
  681. int dpy = getDpyforExternalDisplay(ctx, i);
  682. switch(dpy) {
  683. case HWC_DISPLAY_PRIMARY:
  684. ret = hwc_set_primary(ctx, list);
  685. break;
  686. case HWC_DISPLAY_EXTERNAL:
  687. ret = hwc_set_external(ctx, list);
  688. break;
  689. case HWC_DISPLAY_VIRTUAL:
  690. ret = hwc_set_virtual(ctx, list);
  691. break;
  692. default:
  693. ret = -EINVAL;
  694. }
  695. }
  696. // This is only indicative of how many times SurfaceFlinger posts
  697. // frames to the display.
  698. CALC_FPS();
  699. MDPComp::resetIdleFallBack();
  700. //Was locked at the beginning of prepare
  701. //Composition cycle is complete signal all waiting threads
  702. ctx->mDrawLock.signal();
  703. ctx->mDrawLock.unlock();
  704. return ret;
  705. }
  706.  
  707. int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
  708. uint32_t* configs, size_t* numConfigs) {
  709. int ret = 0;
  710. hwc_context_t* ctx = (hwc_context_t*)(dev);
  711. disp = getDpyforExternalDisplay(ctx, disp);
  712. //in 1.1 there is no way to choose a config, report as config id # 0
  713. //This config is passed to getDisplayAttributes. Ignore for now.
  714. switch(disp) {
  715. case HWC_DISPLAY_PRIMARY:
  716. if(*numConfigs > 0) {
  717. configs[0] = 0;
  718. *numConfigs = 1;
  719. }
  720. ret = 0; //NO_ERROR
  721. break;
  722. case HWC_DISPLAY_EXTERNAL:
  723. case HWC_DISPLAY_VIRTUAL:
  724. ret = -1; //Not connected
  725. if(ctx->dpyAttr[disp].connected) {
  726. ret = 0; //NO_ERROR
  727. if(*numConfigs > 0) {
  728. configs[0] = 0;
  729. *numConfigs = 1;
  730. }
  731. }
  732. break;
  733. }
  734. return ret;
  735. }
  736.  
  737. int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
  738. uint32_t config, const uint32_t* attributes, int32_t* values) {
  739.  
  740. hwc_context_t* ctx = (hwc_context_t*)(dev);
  741. disp = getDpyforExternalDisplay(ctx, disp);
  742. //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
  743. if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
  744. return -1;
  745. }
  746.  
  747. //From HWComposer
  748. static const uint32_t DISPLAY_ATTRIBUTES[] = {
  749. HWC_DISPLAY_VSYNC_PERIOD,
  750. HWC_DISPLAY_WIDTH,
  751. HWC_DISPLAY_HEIGHT,
  752. HWC_DISPLAY_DPI_X,
  753. HWC_DISPLAY_DPI_Y,
  754. HWC_DISPLAY_NO_ATTRIBUTE,
  755. };
  756.  
  757. const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
  758. sizeof(DISPLAY_ATTRIBUTES)[0]);
  759.  
  760. for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
  761. switch (attributes[i]) {
  762. case HWC_DISPLAY_VSYNC_PERIOD:
  763. values[i] = ctx->dpyAttr[disp].vsync_period;
  764. break;
  765. case HWC_DISPLAY_WIDTH:
  766. values[i] = ctx->dpyAttr[disp].xres;
  767. ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
  768. ctx->dpyAttr[disp].xres);
  769. break;
  770. case HWC_DISPLAY_HEIGHT:
  771. values[i] = ctx->dpyAttr[disp].yres;
  772. ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
  773. ctx->dpyAttr[disp].yres);
  774. break;
  775. case HWC_DISPLAY_DPI_X:
  776. values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
  777. break;
  778. case HWC_DISPLAY_DPI_Y:
  779. values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
  780. break;
  781. default:
  782. ALOGE("Unknown display attribute %d",
  783. attributes[i]);
  784. return -EINVAL;
  785. }
  786. }
  787. return 0;
  788. }
  789.  
  790. void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
  791. {
  792. hwc_context_t* ctx = (hwc_context_t*)(dev);
  793. Locker::Autolock _l(ctx->mDrawLock);
  794. android::String8 aBuf("");
  795. dumpsys_log(aBuf, "Qualcomm HWC state:\n");
  796. dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version);
  797. dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel);
  798. for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
  799. if(ctx->mMDPComp[dpy])
  800. ctx->mMDPComp[dpy]->dump(aBuf);
  801. }
  802. char ovDump[2048] = {'\0'};
  803. ctx->mOverlay->getDump(ovDump, 2048);
  804. dumpsys_log(aBuf, ovDump);
  805. ovDump[0] = '\0';
  806. ctx->mRotMgr->getDump(ovDump, 2048);
  807. dumpsys_log(aBuf, ovDump);
  808. strlcpy(buff, aBuf.string(), buff_len);
  809. }
  810.  
  811. static int hwc_device_close(struct hw_device_t *dev)
  812. {
  813. if(!dev) {
  814. ALOGE("%s: NULL device pointer", __FUNCTION__);
  815. return -1;
  816. }
  817. closeContext((hwc_context_t*)dev);
  818. free(dev);
  819.  
  820. return 0;
  821. }
  822.  
  823. static int hwc_device_open(const struct hw_module_t* module, const char* name,
  824. struct hw_device_t** device)
  825. {
  826. int status = -EINVAL;
  827.  
  828. if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
  829. struct hwc_context_t *dev;
  830. dev = (hwc_context_t*)malloc(sizeof(*dev));
  831. memset(dev, 0, sizeof(*dev));
  832.  
  833. //Initialize hwc context
  834. initContext(dev);
  835.  
  836. //Setup HWC methods
  837. dev->device.common.tag = HARDWARE_DEVICE_TAG;
  838. dev->device.common.version = HWC_DEVICE_API_VERSION_1_3;
  839. dev->device.common.module = const_cast<hw_module_t*>(module);
  840. dev->device.common.close = hwc_device_close;
  841. dev->device.prepare = hwc_prepare;
  842. dev->device.set = hwc_set;
  843. dev->device.eventControl = hwc_eventControl;
  844. dev->device.blank = hwc_blank;
  845. dev->device.query = hwc_query;
  846. dev->device.registerProcs = hwc_registerProcs;
  847. dev->device.dump = hwc_dump;
  848. dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
  849. dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
  850. *device = &dev->device.common;
  851. status = 0;
  852. }
  853. return status;
  854. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement