1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  * Copyright (C) 2012-2014, 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 <overlayWriteback.h>
32 #include <mdp_version.h>
33 #include "hwc_utils.h"
34 #include "hwc_fbupdate.h"
35 #include "hwc_mdpcomp.h"
36 #include "hwc_dump_layers.h"
37 #include "external.h"
38 #include "hwc_copybit.h"
39 #include "hwc_ad.h"
40 #include "profiler.h"
41 #include "hwc_virtual.h"
42 
43 using namespace qhwc;
44 using namespace overlay;
45 
46 #define VSYNC_DEBUG 0
47 #define POWER_MODE_DEBUG 1
48 
49 static int hwc_device_open(const struct hw_module_t* module,
50                            const char* name,
51                            struct hw_device_t** device);
52 
53 static struct hw_module_methods_t hwc_module_methods = {
54     open: hwc_device_open
55 };
56 
57 static void reset_panel(struct hwc_composer_device_1* dev);
58 
59 hwc_module_t HAL_MODULE_INFO_SYM = {
60     common: {
61         tag: HARDWARE_MODULE_TAG,
62         version_major: 2,
63         version_minor: 0,
64         id: HWC_HARDWARE_MODULE_ID,
65         name: "Qualcomm Hardware Composer Module",
66         author: "CodeAurora Forum",
67         methods: &hwc_module_methods,
68         dso: 0,
69         reserved: {0},
70     }
71 };
72 
73 /* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
74  * HDMI display ID for virtual. This helper is needed to differentiate their
75  * paths in HAL.
76  * TODO: Not needed once we have WFD client working on top of Google API's */
77 
getDpyforExternalDisplay(hwc_context_t * ctx,int dpy)78 static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
79     if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
80         return HWC_DISPLAY_VIRTUAL;
81     return dpy;
82 }
83 
84 /*
85  * Save callback functions registered to HWC
86  */
hwc_registerProcs(struct hwc_composer_device_1 * dev,hwc_procs_t const * procs)87 static void hwc_registerProcs(struct hwc_composer_device_1* dev,
88                               hwc_procs_t const* procs)
89 {
90     ALOGI("%s", __FUNCTION__);
91     hwc_context_t* ctx = (hwc_context_t*)(dev);
92     if(!ctx) {
93         ALOGE("%s: Invalid context", __FUNCTION__);
94         return;
95     }
96     ctx->proc = procs;
97 
98     // Now that we have the functions needed, kick off
99     // the uevent & vsync threads
100     init_uevent_thread(ctx);
101     init_vsync_thread(ctx);
102 }
103 
setPaddingRound(hwc_context_t * ctx,int numDisplays,hwc_display_contents_1_t ** displays)104 static void setPaddingRound(hwc_context_t *ctx, int numDisplays,
105                             hwc_display_contents_1_t** displays) {
106     ctx->isPaddingRound = false;
107     for(int i = 0; i < numDisplays; i++) {
108         hwc_display_contents_1_t *list = displays[i];
109         if (LIKELY(list && list->numHwLayers > 0)) {
110             if((ctx->mPrevHwLayerCount[i] == 1 or
111                 ctx->mPrevHwLayerCount[i] == 0) and
112                (list->numHwLayers > 1)) {
113                 /* If the previous cycle for dpy 'i' has 0 AppLayers and the
114                  * current cycle has atleast 1 AppLayer, padding round needs
115                  * to be invoked in current cycle on all the active displays
116                  * to free up the resources.
117                  */
118                 ctx->isPaddingRound = true;
119             }
120             ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers;
121         } else {
122             ctx->mPrevHwLayerCount[i] = 0;
123         }
124     }
125 }
126 
127 /* Based on certain conditions, isPaddingRound will be set
128  * to make this function self-contained */
setDMAState(hwc_context_t * ctx,int numDisplays,hwc_display_contents_1_t ** displays)129 static void setDMAState(hwc_context_t *ctx, int numDisplays,
130                         hwc_display_contents_1_t** displays) {
131 
132     if(ctx->mRotMgr->getNumActiveSessions() == 0)
133         Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
134 
135     for(int dpy = 0; dpy < numDisplays; dpy++) {
136         hwc_display_contents_1_t *list = displays[dpy];
137         if (LIKELY(list && list->numHwLayers > 0)) {
138             for(size_t layerIndex = 0; layerIndex < list->numHwLayers;
139                                                   layerIndex++) {
140                 if(list->hwLayers[layerIndex].compositionType !=
141                                             HWC_FRAMEBUFFER_TARGET)
142                 {
143                     hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
144                     private_handle_t *hnd = (private_handle_t *)layer->handle;
145 
146                     /* If a layer requires rotation, set the DMA state
147                      * to BLOCK_MODE */
148 
149                     if (canUseRotator(ctx, dpy) &&
150                         has90Transform(layer) && isRotationDoable(ctx, hnd)) {
151                         if(not ctx->mOverlay->isDMAMultiplexingSupported()) {
152                             if(ctx->mOverlay->isPipeTypeAttached(
153                                              overlay::utils::OV_MDP_PIPE_DMA))
154                                 ctx->isPaddingRound = true;
155                         }
156                         Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
157                     }
158                 }
159             }
160             if(dpy) {
161                 /* Uncomment the below code for testing purpose.
162                    Assuming the orientation value is in terms of HAL_TRANSFORM,
163                    this needs mapping to HAL, if its in different convention */
164 
165                 /* char value[PROPERTY_VALUE_MAX];
166                    property_get("sys.ext_orientation", value, "0");
167                    ctx->mExtOrientation = atoi(value);*/
168 
169                 if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
170                     if(ctx->mOverlay->isPipeTypeAttached(
171                                          overlay::utils::OV_MDP_PIPE_DMA)) {
172                         ctx->isPaddingRound = true;
173                     }
174                     Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
175                 }
176             }
177         }
178     }
179 }
180 
setNumActiveDisplays(hwc_context_t * ctx,int numDisplays,hwc_display_contents_1_t ** displays)181 static void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays,
182                             hwc_display_contents_1_t** displays) {
183 
184     ctx->numActiveDisplays = 0;
185     for(int i = 0; i < numDisplays; i++) {
186         hwc_display_contents_1_t *list = displays[i];
187         if (LIKELY(list && list->numHwLayers > 0)) {
188             /* For display devices like SSD and screenrecord, we cannot
189              * rely on isActive and connected attributes of dpyAttr to
190              * determine if the displaydevice is active. Hence in case if
191              * the layer-list is non-null and numHwLayers > 0, we assume
192              * the display device to be active.
193              */
194             ctx->numActiveDisplays += 1;
195         }
196     }
197 }
198 
reset(hwc_context_t * ctx,int numDisplays,hwc_display_contents_1_t ** displays)199 static void reset(hwc_context_t *ctx, int numDisplays,
200                   hwc_display_contents_1_t** displays) {
201 
202 
203     for(int i = 0; i < numDisplays; i++) {
204         hwc_display_contents_1_t *list = displays[i];
205         // XXX:SurfaceFlinger no longer guarantees that this
206         // value is reset on every prepare. However, for the layer
207         // cache we need to reset it.
208         // We can probably rethink that later on
209         if (LIKELY(list && list->numHwLayers > 0)) {
210             for(size_t j = 0; j < list->numHwLayers; j++) {
211                 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
212                     list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
213             }
214 
215         }
216 
217         if(ctx->mMDPComp[i])
218             ctx->mMDPComp[i]->reset();
219         if(ctx->mFBUpdate[i])
220             ctx->mFBUpdate[i]->reset();
221         if(ctx->mCopyBit[i])
222             ctx->mCopyBit[i]->reset();
223         if(ctx->mLayerRotMap[i])
224             ctx->mLayerRotMap[i]->reset();
225     }
226 
227     ctx->mAD->reset();
228     if(ctx->mHWCVirtual)
229         ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
230 }
231 
scaleDisplayFrame(hwc_context_t * ctx,int dpy,hwc_display_contents_1_t * list)232 static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
233                             hwc_display_contents_1_t *list) {
234     uint32_t origXres = ctx->dpyAttr[dpy].xres;
235     uint32_t origYres = ctx->dpyAttr[dpy].yres;
236     uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
237     uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
238     float xresRatio = (float)origXres / (float)newXres;
239     float yresRatio = (float)origYres / (float)newYres;
240     for (size_t i = 0; i < list->numHwLayers; i++) {
241         hwc_layer_1_t *layer = &list->hwLayers[i];
242         hwc_rect_t& displayFrame = layer->displayFrame;
243         hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
244         uint32_t layerWidth = displayFrame.right - displayFrame.left;
245         uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
246         displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
247         displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
248         displayFrame.right = (int)((float)displayFrame.left +
249                                    (float)layerWidth * xresRatio);
250         displayFrame.bottom = (int)((float)displayFrame.top +
251                                     (float)layerHeight * yresRatio);
252     }
253 }
254 
hwc_prepare_primary(hwc_composer_device_1 * dev,hwc_display_contents_1_t * list)255 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
256         hwc_display_contents_1_t *list) {
257     ATRACE_CALL();
258     hwc_context_t* ctx = (hwc_context_t*)(dev);
259     const int dpy = HWC_DISPLAY_PRIMARY;
260     bool fbComp = false;
261     if (LIKELY(list && list->numHwLayers > 1) &&
262             ctx->dpyAttr[dpy].isActive) {
263 
264         if (ctx->dpyAttr[dpy].customFBSize &&
265                 list->flags & HWC_GEOMETRY_CHANGED)
266             scaleDisplayFrame(ctx, dpy, list);
267 
268         reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
269         setListStats(ctx, list, dpy);
270 
271         fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
272 
273         if (fbComp) {
274             const int fbZ = 0;
275             if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) {
276                 ctx->mOverlay->clear(dpy);
277                 ctx->mLayerRotMap[dpy]->clear();
278             }
279         }
280 
281         if (ctx->mMDP.version < qdutils::MDP_V4_0) {
282             if(ctx->mCopyBit[dpy])
283                 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
284         }
285         setGPUHint(ctx, list);
286     }
287     return 0;
288 }
289 
hwc_prepare_external(hwc_composer_device_1 * dev,hwc_display_contents_1_t * list)290 static int hwc_prepare_external(hwc_composer_device_1 *dev,
291         hwc_display_contents_1_t *list) {
292     ATRACE_CALL();
293     hwc_context_t* ctx = (hwc_context_t*)(dev);
294     const int dpy = HWC_DISPLAY_EXTERNAL;
295 
296     if (LIKELY(list && list->numHwLayers > 1) &&
297             ctx->dpyAttr[dpy].isActive &&
298             ctx->dpyAttr[dpy].connected) {
299         reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
300         if(!ctx->dpyAttr[dpy].isPause) {
301             ctx->dpyAttr[dpy].isConfiguring = false;
302             setListStats(ctx, list, dpy);
303             if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
304                 const int fbZ = 0;
305                 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
306                 {
307                     ctx->mOverlay->clear(dpy);
308                     ctx->mLayerRotMap[dpy]->clear();
309                 }
310             }
311         } else {
312             /* External Display is in Pause state.
313              * Mark all application layers as OVERLAY so that
314              * GPU will not compose.
315              */
316             for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
317                 hwc_layer_1_t *layer = &list->hwLayers[i];
318                 layer->compositionType = HWC_OVERLAY;
319             }
320         }
321     }
322     return 0;
323 }
324 
hwc_prepare(hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)325 static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
326                        hwc_display_contents_1_t** displays)
327 {
328     int ret = 0;
329     hwc_context_t* ctx = (hwc_context_t*)(dev);
330 
331     if (ctx->mPanelResetStatus) {
332         ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
333         reset_panel(dev);
334     }
335 
336     //Will be unlocked at the end of set
337     ctx->mDrawLock.lock();
338     setPaddingRound(ctx, (int)numDisplays, displays);
339     setDMAState(ctx, (int)numDisplays, displays);
340     setNumActiveDisplays(ctx, (int)numDisplays, displays);
341     reset(ctx, (int)numDisplays, displays);
342 
343     ctx->mOverlay->configBegin();
344     ctx->mRotMgr->configBegin();
345     overlay::Writeback::configBegin();
346 
347     for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) {
348         hwc_display_contents_1_t *list = displays[i];
349         int dpy = getDpyforExternalDisplay(ctx, i);
350         switch(dpy) {
351             case HWC_DISPLAY_PRIMARY:
352                 ret = hwc_prepare_primary(dev, list);
353                 break;
354             case HWC_DISPLAY_EXTERNAL:
355                 ret = hwc_prepare_external(dev, list);
356                 break;
357             case HWC_DISPLAY_VIRTUAL:
358                 if(ctx->mHWCVirtual)
359                     ret = ctx->mHWCVirtual->prepare(dev, list);
360                 break;
361             default:
362                 ret = -EINVAL;
363         }
364     }
365 
366     ctx->mOverlay->configDone();
367     ctx->mRotMgr->configDone();
368     overlay::Writeback::configDone();
369 
370     return ret;
371 }
372 
hwc_eventControl(struct hwc_composer_device_1 * dev,int dpy,int event,int enable)373 static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
374                              int event, int enable)
375 {
376     ATRACE_CALL();
377     int ret = 0;
378     hwc_context_t* ctx = (hwc_context_t*)(dev);
379     switch(event) {
380         case HWC_EVENT_VSYNC:
381             if (ctx->vstate.enable == enable)
382                 break;
383             ret = hwc_vsync_control(ctx, dpy, enable);
384             if(ret == 0)
385                 ctx->vstate.enable = !!enable;
386             ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
387                       (enable)?"ENABLED":"DISABLED");
388             break;
389 #ifdef QCOM_BSP
390         case  HWC_EVENT_ORIENTATION:
391             if(dpy == HWC_DISPLAY_PRIMARY) {
392                 Locker::Autolock _l(ctx->mDrawLock);
393                 // store the primary display orientation
394                 ctx->deviceOrientation = enable;
395             }
396             break;
397 #endif
398         default:
399             ret = -EINVAL;
400     }
401     return ret;
402 }
403 
hwc_setPowerMode(struct hwc_composer_device_1 * dev,int dpy,int mode)404 static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
405         int mode)
406 {
407     ATRACE_CALL();
408     hwc_context_t* ctx = (hwc_context_t*)(dev);
409     int ret = 0, value = 0;
410 
411     Locker::Autolock _l(ctx->mDrawLock);
412     ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
413             __FUNCTION__, mode, dpy);
414 
415     switch(mode) {
416         case HWC_POWER_MODE_OFF:
417             // free up all the overlay pipes in use
418             // when we get a blank for either display
419             // makes sure that all pipes are freed
420             ctx->mOverlay->configBegin();
421             ctx->mOverlay->configDone();
422             ctx->mRotMgr->clear();
423             // If VDS is connected, do not clear WB object as it
424             // will end up detaching IOMMU. This is required
425             // to send black frame to WFD sink on power suspend.
426             // Note: With this change, we keep the WriteBack object
427             // alive on power suspend for AD use case.
428             value = FB_BLANK_POWERDOWN;
429             break;
430         case HWC_POWER_MODE_DOZE:
431         case HWC_POWER_MODE_DOZE_SUSPEND:
432             value = FB_BLANK_VSYNC_SUSPEND;
433             break;
434         case HWC_POWER_MODE_NORMAL:
435             value = FB_BLANK_UNBLANK;
436             break;
437     }
438 
439     switch(dpy) {
440     case HWC_DISPLAY_PRIMARY:
441         if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
442             ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
443                     " value %d", __FUNCTION__, strerror(errno), value);
444             return -errno;
445         }
446 
447         if(mode == HWC_POWER_MODE_NORMAL) {
448             // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
449             // when SF is completely initialized
450             ctx->mExtDisplay->setHPD(1);
451         }
452 
453         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
454         //Deliberate fall through since there is no explicit power mode for
455         //virtual displays.
456     case HWC_DISPLAY_VIRTUAL:
457         if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
458             const int dpy = HWC_DISPLAY_VIRTUAL;
459             if(mode == HWC_POWER_MODE_OFF and
460                     (not ctx->dpyAttr[dpy].isPause)) {
461                 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
462                     ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
463                     ret = -1;
464                 }
465             }
466             ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
467         }
468         break;
469     case HWC_DISPLAY_EXTERNAL:
470         if(mode == HWC_POWER_MODE_OFF) {
471             if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
472                 ALOGE("%s: displayCommit failed for external", __FUNCTION__);
473                 ret = -1;
474             }
475         }
476         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
477         break;
478     default:
479         return -EINVAL;
480     }
481 
482     ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
483             __FUNCTION__, mode, dpy);
484     return ret;
485 }
486 
reset_panel(struct hwc_composer_device_1 * dev)487 static void reset_panel(struct hwc_composer_device_1* dev)
488 {
489     int ret = 0;
490     hwc_context_t* ctx = (hwc_context_t*)(dev);
491 
492     if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
493         ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
494         ctx->mPanelResetStatus = false;
495         return;
496     }
497 
498     ALOGD("%s: setting power mode off", __FUNCTION__);
499     ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF);
500     if (ret < 0) {
501         ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
502                 strerror(errno));
503     }
504 
505     ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__);
506     ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL);
507     if (ret < 0) {
508         ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
509                 strerror(errno));
510     }
511     hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
512 
513     ctx->mPanelResetStatus = false;
514 }
515 
516 
hwc_query(struct hwc_composer_device_1 * dev,int param,int * value)517 static int hwc_query(struct hwc_composer_device_1* dev,
518                      int param, int* value)
519 {
520     hwc_context_t* ctx = (hwc_context_t*)(dev);
521     int supported = HWC_DISPLAY_PRIMARY_BIT;
522 
523     switch (param) {
524     case HWC_BACKGROUND_LAYER_SUPPORTED:
525         // Not supported for now
526         value[0] = 0;
527         break;
528     case HWC_DISPLAY_TYPES_SUPPORTED:
529         if(ctx->mMDP.hasOverlay) {
530             supported |= HWC_DISPLAY_VIRTUAL_BIT;
531             if(!(qdutils::MDPVersion::getInstance().is8x26() ||
532                         qdutils::MDPVersion::getInstance().is8x16() ||
533                         qdutils::MDPVersion::getInstance().is8x39()))
534                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
535         }
536         value[0] = supported;
537         break;
538     case HWC_FORMAT_RB_SWAP:
539         value[0] = 1;
540         break;
541     case HWC_COLOR_FILL:
542         value[0] = 1;
543         break;
544     default:
545         return -EINVAL;
546     }
547     return 0;
548 
549 }
550 
551 
hwc_set_primary(hwc_context_t * ctx,hwc_display_contents_1_t * list)552 static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
553     ATRACE_CALL();
554     int ret = 0;
555     const int dpy = HWC_DISPLAY_PRIMARY;
556     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
557         size_t last = list->numHwLayers - 1;
558         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
559         int fd = -1; //FenceFD from the Copybit(valid in async mode)
560         bool copybitDone = false;
561 
562         if (ctx->mCopyBit[dpy]) {
563             if (ctx->mMDP.version < qdutils::MDP_V4_0)
564                 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
565             else
566                 fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
567         }
568 
569         if(list->numHwLayers > 1)
570             hwc_sync(ctx, list, dpy, fd);
571 
572         // Dump the layers for primary
573         if(ctx->mHwcDebug[dpy])
574             ctx->mHwcDebug[dpy]->dumpLayers(list);
575 
576         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
577             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
578             ret = -1;
579         }
580 
581         //TODO We dont check for SKIP flag on this layer because we need PAN
582         //always. Last layer is always FB
583         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
584         if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
585             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
586         }
587 
588         if(isAbcInUse(ctx) == true) {
589             int index = ctx->listStats[dpy].renderBufIndexforABC;
590             hwc_layer_1_t *tempLayer = &list->hwLayers[index];
591             hnd = (private_handle_t *)tempLayer->handle;
592         }
593 
594         if(hnd) {
595             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
596                 ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
597                 ret = -1;
598             }
599         }
600 
601         int lSplit = getLeftSplit(ctx, dpy);
602         qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim(
603             ctx->listStats[dpy].lRoi.left,
604             ctx->listStats[dpy].lRoi.top,
605             ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left,
606             ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top);
607 
608         qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim(
609             ctx->listStats[dpy].rRoi.left - lSplit,
610             ctx->listStats[dpy].rRoi.top,
611             ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left,
612             ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top);
613 
614         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
615             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
616             ret = -1;
617         }
618 
619     }
620 
621     closeAcquireFds(list);
622     return ret;
623 }
624 
hwc_set_external(hwc_context_t * ctx,hwc_display_contents_1_t * list)625 static int hwc_set_external(hwc_context_t *ctx,
626                             hwc_display_contents_1_t* list)
627 {
628     ATRACE_CALL();
629     int ret = 0;
630 
631     const int dpy = HWC_DISPLAY_EXTERNAL;
632 
633 
634     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
635         ctx->dpyAttr[dpy].connected &&
636         !ctx->dpyAttr[dpy].isPause) {
637         size_t last = list->numHwLayers - 1;
638         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
639         int fd = -1; //FenceFD from the Copybit(valid in async mode)
640         bool copybitDone = false;
641         if(ctx->mCopyBit[dpy])
642             copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
643 
644         if(list->numHwLayers > 1)
645             hwc_sync(ctx, list, dpy, fd);
646 
647         // Dump the layers for external
648         if(ctx->mHwcDebug[dpy])
649             ctx->mHwcDebug[dpy]->dumpLayers(list);
650 
651         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
652             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
653             ret = -1;
654         }
655 
656         int extOnlyLayerIndex =
657                 ctx->listStats[dpy].extOnlyLayerIndex;
658 
659         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
660         if(extOnlyLayerIndex!= -1) {
661             hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
662             hnd = (private_handle_t *)extLayer->handle;
663         } else if(copybitDone) {
664             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
665         }
666 
667         if(hnd && !isYuvBuffer(hnd)) {
668             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
669                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
670                 ret = -1;
671             }
672         }
673 
674         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
675             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
676             ret = -1;
677         }
678     }
679 
680     closeAcquireFds(list);
681     return ret;
682 }
683 
hwc_set(hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)684 static int hwc_set(hwc_composer_device_1 *dev,
685                    size_t numDisplays,
686                    hwc_display_contents_1_t** displays)
687 {
688     int ret = 0;
689     hwc_context_t* ctx = (hwc_context_t*)(dev);
690     for (int i = 0; i < (int)numDisplays; i++) {
691         hwc_display_contents_1_t* list = displays[i];
692         int dpy = getDpyforExternalDisplay(ctx, i);
693         switch(dpy) {
694             case HWC_DISPLAY_PRIMARY:
695                 ret = hwc_set_primary(ctx, list);
696                 break;
697             case HWC_DISPLAY_EXTERNAL:
698                 ret = hwc_set_external(ctx, list);
699                 break;
700             case HWC_DISPLAY_VIRTUAL:
701                 if(ctx->mHWCVirtual)
702                     ret = ctx->mHWCVirtual->set(ctx, list);
703                 break;
704             default:
705                 ret = -EINVAL;
706         }
707     }
708     // This is only indicative of how many times SurfaceFlinger posts
709     // frames to the display.
710     CALC_FPS();
711     MDPComp::resetIdleFallBack();
712     ctx->mVideoTransFlag = false;
713     //Was locked at the beginning of prepare
714     ctx->mDrawLock.unlock();
715     return ret;
716 }
717 
hwc_getDisplayConfigs(struct hwc_composer_device_1 * dev,int disp,uint32_t * configs,size_t * numConfigs)718 int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
719         uint32_t* configs, size_t* numConfigs) {
720     int ret = 0;
721     hwc_context_t* ctx = (hwc_context_t*)(dev);
722     disp = getDpyforExternalDisplay(ctx, disp);
723     //Currently we allow only 1 config, reported as config id # 0
724     //This config is passed in to getDisplayAttributes. Ignored for now.
725     switch(disp) {
726         case HWC_DISPLAY_PRIMARY:
727             if(*numConfigs > 0) {
728                 configs[0] = 0;
729                 *numConfigs = 1;
730             }
731             ret = 0; //NO_ERROR
732             break;
733         case HWC_DISPLAY_EXTERNAL:
734         case HWC_DISPLAY_VIRTUAL:
735             ret = -1; //Not connected
736             if(ctx->dpyAttr[disp].connected) {
737                 ret = 0; //NO_ERROR
738                 if(*numConfigs > 0) {
739                     configs[0] = 0;
740                     *numConfigs = 1;
741                 }
742             }
743             break;
744     }
745     return ret;
746 }
747 
hwc_getDisplayAttributes(struct hwc_composer_device_1 * dev,int disp,uint32_t,const uint32_t * attributes,int32_t * values)748 int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
749         uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
750 
751     hwc_context_t* ctx = (hwc_context_t*)(dev);
752     disp = getDpyforExternalDisplay(ctx, disp);
753     //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
754     if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
755         return -1;
756     }
757 
758     //From HWComposer
759     static const uint32_t DISPLAY_ATTRIBUTES[] = {
760         HWC_DISPLAY_VSYNC_PERIOD,
761         HWC_DISPLAY_WIDTH,
762         HWC_DISPLAY_HEIGHT,
763         HWC_DISPLAY_DPI_X,
764         HWC_DISPLAY_DPI_Y,
765         HWC_DISPLAY_NO_ATTRIBUTE,
766     };
767 
768     const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
769             sizeof(DISPLAY_ATTRIBUTES)[0]);
770 
771     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
772         switch (attributes[i]) {
773         case HWC_DISPLAY_VSYNC_PERIOD:
774             values[i] = ctx->dpyAttr[disp].vsync_period;
775             break;
776         case HWC_DISPLAY_WIDTH:
777             if (ctx->dpyAttr[disp].customFBSize)
778                 values[i] = ctx->dpyAttr[disp].xres_new;
779             else
780                 values[i] = ctx->dpyAttr[disp].xres;
781 
782             ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
783                     values[i]);
784             break;
785         case HWC_DISPLAY_HEIGHT:
786             if (ctx->dpyAttr[disp].customFBSize)
787                 values[i] = ctx->dpyAttr[disp].yres_new;
788             else
789                 values[i] = ctx->dpyAttr[disp].yres;
790             ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
791                     values[i]);
792             break;
793         case HWC_DISPLAY_DPI_X:
794             values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
795             break;
796         case HWC_DISPLAY_DPI_Y:
797             values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
798             break;
799         default:
800             ALOGE("Unknown display attribute %d",
801                     attributes[i]);
802             return -EINVAL;
803         }
804     }
805     return 0;
806 }
807 
hwc_dump(struct hwc_composer_device_1 * dev,char * buff,int buff_len)808 void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
809 {
810     hwc_context_t* ctx = (hwc_context_t*)(dev);
811     Locker::Autolock _l(ctx->mDrawLock);
812     android::String8 aBuf("");
813     dumpsys_log(aBuf, "Qualcomm HWC state:\n");
814     dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
815     dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
816     if(ctx->vstate.fakevsync)
817         dumpsys_log(aBuf, "  Vsync is being faked!!\n");
818     for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
819         if(ctx->mMDPComp[dpy])
820             ctx->mMDPComp[dpy]->dump(aBuf, ctx);
821     }
822     char ovDump[2048] = {'\0'};
823     ctx->mOverlay->getDump(ovDump, 2048);
824     dumpsys_log(aBuf, ovDump);
825     ovDump[0] = '\0';
826     ctx->mRotMgr->getDump(ovDump, 1024);
827     dumpsys_log(aBuf, ovDump);
828     ovDump[0] = '\0';
829     if(Writeback::getDump(ovDump, 1024)) {
830         dumpsys_log(aBuf, ovDump);
831         ovDump[0] = '\0';
832     }
833     strlcpy(buff, aBuf.string(), buff_len);
834 }
835 
hwc_getActiveConfig(struct hwc_composer_device_1 *,int)836 int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) {
837     //Supports only the default config (0th index) for now
838     return 0;
839 }
840 
hwc_setActiveConfig(struct hwc_composer_device_1 *,int,int index)841 int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/,
842         int index) {
843     //Supports only the default config (0th index) for now
844     return (index == 0) ? index : -EINVAL;
845 }
846 
hwc_device_close(struct hw_device_t * dev)847 static int hwc_device_close(struct hw_device_t *dev)
848 {
849     if(!dev) {
850         ALOGE("%s: NULL device pointer", __FUNCTION__);
851         return -1;
852     }
853     closeContext((hwc_context_t*)dev);
854     free(dev);
855 
856     return 0;
857 }
858 
hwc_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)859 static int hwc_device_open(const struct hw_module_t* module, const char* name,
860                            struct hw_device_t** device)
861 {
862     int status = -EINVAL;
863 
864     if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
865         struct hwc_context_t *dev;
866         dev = (hwc_context_t*)malloc(sizeof(*dev));
867         if(dev == NULL)
868             return status;
869         memset(dev, 0, sizeof(*dev));
870 
871         //Initialize hwc context
872         initContext(dev);
873 
874         //Setup HWC methods
875         dev->device.common.tag          = HARDWARE_DEVICE_TAG;
876         dev->device.common.version      = HWC_DEVICE_API_VERSION_1_4;
877         dev->device.common.module       = const_cast<hw_module_t*>(module);
878         dev->device.common.close        = hwc_device_close;
879         dev->device.prepare             = hwc_prepare;
880         dev->device.set                 = hwc_set;
881         dev->device.eventControl        = hwc_eventControl;
882         dev->device.setPowerMode        = hwc_setPowerMode;
883         dev->device.query               = hwc_query;
884         dev->device.registerProcs       = hwc_registerProcs;
885         dev->device.dump                = hwc_dump;
886         dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
887         dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
888         dev->device.getActiveConfig     = hwc_getActiveConfig;
889         dev->device.setActiveConfig     = hwc_setActiveConfig;
890         *device = &dev->device.common;
891         status = 0;
892     }
893     return status;
894 }
895