• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     //Will be unlocked at the end of set
332     ctx->mDrawLock.lock();
333 
334     if (ctx->mPanelResetStatus) {
335         ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
336         reset_panel(dev);
337     }
338 
339     setPaddingRound(ctx, (int)numDisplays, displays);
340     setDMAState(ctx, (int)numDisplays, displays);
341     setNumActiveDisplays(ctx, (int)numDisplays, displays);
342     reset(ctx, (int)numDisplays, displays);
343 
344     ctx->mOverlay->configBegin();
345     ctx->mRotMgr->configBegin();
346     overlay::Writeback::configBegin();
347 
348     for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) {
349         hwc_display_contents_1_t *list = displays[i];
350         int dpy = getDpyforExternalDisplay(ctx, i);
351         switch(dpy) {
352             case HWC_DISPLAY_PRIMARY:
353                 ret = hwc_prepare_primary(dev, list);
354                 break;
355             case HWC_DISPLAY_EXTERNAL:
356                 ret = hwc_prepare_external(dev, list);
357                 break;
358             case HWC_DISPLAY_VIRTUAL:
359                 if(ctx->mHWCVirtual)
360                     ret = ctx->mHWCVirtual->prepare(dev, list);
361                 break;
362             default:
363                 ret = -EINVAL;
364         }
365     }
366 
367     ctx->mOverlay->configDone();
368     ctx->mRotMgr->configDone();
369     overlay::Writeback::configDone();
370 
371     return ret;
372 }
373 
hwc_eventControl(struct hwc_composer_device_1 * dev,int dpy,int event,int enable)374 static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
375                              int event, int enable)
376 {
377     ATRACE_CALL();
378     int ret = 0;
379     hwc_context_t* ctx = (hwc_context_t*)(dev);
380     switch(event) {
381         case HWC_EVENT_VSYNC:
382             if (ctx->vstate.enable == enable)
383                 break;
384             ret = hwc_vsync_control(ctx, dpy, enable);
385             if(ret == 0)
386                 ctx->vstate.enable = !!enable;
387             ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
388                       (enable)?"ENABLED":"DISABLED");
389             break;
390 #ifdef QCOM_BSP
391         case  HWC_EVENT_ORIENTATION:
392             if(dpy == HWC_DISPLAY_PRIMARY) {
393                 Locker::Autolock _l(ctx->mDrawLock);
394                 // store the primary display orientation
395                 ctx->deviceOrientation = enable;
396             }
397             break;
398 #endif
399         default:
400             ret = -EINVAL;
401     }
402     return ret;
403 }
404 
hwc_setPowerMode(struct hwc_composer_device_1 * dev,int dpy,int mode)405 static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
406         int mode)
407 {
408     ATRACE_CALL();
409     hwc_context_t* ctx = (hwc_context_t*)(dev);
410     int ret = 0, value = 0;
411 
412     Locker::Autolock _l(ctx->mDrawLock);
413     ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
414             __FUNCTION__, mode, dpy);
415 
416     switch(mode) {
417         case HWC_POWER_MODE_OFF:
418             // free up all the overlay pipes in use
419             // when we get a blank for either display
420             // makes sure that all pipes are freed
421             ctx->mOverlay->configBegin();
422             ctx->mOverlay->configDone();
423             ctx->mRotMgr->clear();
424             // If VDS is connected, do not clear WB object as it
425             // will end up detaching IOMMU. This is required
426             // to send black frame to WFD sink on power suspend.
427             // Note: With this change, we keep the WriteBack object
428             // alive on power suspend for AD use case.
429             value = FB_BLANK_POWERDOWN;
430             break;
431         case HWC_POWER_MODE_DOZE:
432         case HWC_POWER_MODE_DOZE_SUSPEND:
433             value = FB_BLANK_VSYNC_SUSPEND;
434             break;
435         case HWC_POWER_MODE_NORMAL:
436             value = FB_BLANK_UNBLANK;
437             break;
438     }
439 
440     ctx->dpyAttr[dpy].lastPowerMode = value;
441     switch(dpy) {
442     case HWC_DISPLAY_PRIMARY:
443         if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
444             ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
445                     " value %d", __FUNCTION__, strerror(errno), value);
446             return -errno;
447         }
448 
449         if(mode == HWC_POWER_MODE_NORMAL) {
450             // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
451             // when SF is completely initialized
452             ctx->mExtDisplay->setHPD(1);
453         }
454 
455         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
456         //Deliberate fall through since there is no explicit power mode for
457         //virtual displays.
458     case HWC_DISPLAY_VIRTUAL:
459         if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
460             const int dpy = HWC_DISPLAY_VIRTUAL;
461             if(mode == HWC_POWER_MODE_OFF and
462                     (not ctx->dpyAttr[dpy].isPause)) {
463                 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
464                     ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
465                     ret = -1;
466                 }
467             }
468             ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
469         }
470         break;
471     case HWC_DISPLAY_EXTERNAL:
472         if(mode == HWC_POWER_MODE_OFF) {
473             if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
474                 ALOGE("%s: displayCommit failed for external", __FUNCTION__);
475                 ret = -1;
476             }
477         }
478         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
479         break;
480     default:
481         return -EINVAL;
482     }
483 
484     ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
485             __FUNCTION__, mode, dpy);
486     return ret;
487 }
488 
reset_panel(struct hwc_composer_device_1 * dev)489 static void reset_panel(struct hwc_composer_device_1* dev)
490 {
491     int ret = 0;
492     hwc_context_t* ctx = (hwc_context_t*)(dev);
493 
494     if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
495         ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
496         ctx->mPanelResetStatus = false;
497         return;
498     }
499 
500     ALOGD("%s: Blanking display", __FUNCTION__);
501     ret = ioctl(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, FBIOBLANK,
502             FB_BLANK_POWERDOWN);
503     if (ret < 0) {
504         ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
505                 strerror(errno));
506     }
507 
508     ALOGD("%s: setting power mode to previous active mode and enabling vsync",
509             __FUNCTION__);
510     ret = ioctl(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, FBIOBLANK,
511             ctx->dpyAttr[HWC_DISPLAY_PRIMARY].lastPowerMode);
512     if (ret < 0) {
513         ALOGE("%s: FBIOBLANK failed to restore mode %d : %s", __FUNCTION__,
514                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].lastPowerMode,
515                 strerror(errno));
516     }
517     hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
518 
519     ctx->mPanelResetStatus = false;
520 }
521 
522 
hwc_query(struct hwc_composer_device_1 * dev,int param,int * value)523 static int hwc_query(struct hwc_composer_device_1* dev,
524                      int param, int* value)
525 {
526     hwc_context_t* ctx = (hwc_context_t*)(dev);
527     int supported = HWC_DISPLAY_PRIMARY_BIT;
528 
529     switch (param) {
530     case HWC_BACKGROUND_LAYER_SUPPORTED:
531         // Not supported for now
532         value[0] = 0;
533         break;
534     case HWC_DISPLAY_TYPES_SUPPORTED:
535         if(ctx->mMDP.hasOverlay) {
536             supported |= HWC_DISPLAY_VIRTUAL_BIT;
537             if(!(qdutils::MDPVersion::getInstance().is8x26() ||
538                         qdutils::MDPVersion::getInstance().is8x16() ||
539                         qdutils::MDPVersion::getInstance().is8x39()))
540                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
541         }
542         value[0] = supported;
543         break;
544     case HWC_FORMAT_RB_SWAP:
545         value[0] = 1;
546         break;
547     case HWC_COLOR_FILL:
548         value[0] = 1;
549         break;
550     default:
551         return -EINVAL;
552     }
553     return 0;
554 
555 }
556 
557 
hwc_set_primary(hwc_context_t * ctx,hwc_display_contents_1_t * list)558 static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
559     ATRACE_CALL();
560     int ret = 0;
561     const int dpy = HWC_DISPLAY_PRIMARY;
562     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
563         size_t last = list->numHwLayers - 1;
564         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
565         int fd = -1; //FenceFD from the Copybit(valid in async mode)
566         bool copybitDone = false;
567 
568         if (ctx->mCopyBit[dpy]) {
569             if (ctx->mMDP.version < qdutils::MDP_V4_0)
570                 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
571             else
572                 fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
573         }
574 
575         if(list->numHwLayers > 1)
576             hwc_sync(ctx, list, dpy, fd);
577 
578         // Dump the layers for primary
579         if(ctx->mHwcDebug[dpy])
580             ctx->mHwcDebug[dpy]->dumpLayers(list);
581 
582         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
583             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
584             ret = -1;
585         }
586 
587         //TODO We dont check for SKIP flag on this layer because we need PAN
588         //always. Last layer is always FB
589         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
590         if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
591             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
592         }
593 
594         if(isAbcInUse(ctx) == true) {
595             int index = ctx->listStats[dpy].renderBufIndexforABC;
596             hwc_layer_1_t *tempLayer = &list->hwLayers[index];
597             hnd = (private_handle_t *)tempLayer->handle;
598         }
599 
600         if(hnd) {
601             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
602                 ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
603                 ret = -1;
604             }
605         }
606 
607         int lSplit = getLeftSplit(ctx, dpy);
608         qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim(
609             ctx->listStats[dpy].lRoi.left,
610             ctx->listStats[dpy].lRoi.top,
611             ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left,
612             ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top);
613 
614         qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim(
615             ctx->listStats[dpy].rRoi.left - lSplit,
616             ctx->listStats[dpy].rRoi.top,
617             ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left,
618             ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top);
619 
620         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
621             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
622             ret = -1;
623         }
624 
625     }
626 
627     closeAcquireFds(list);
628     return ret;
629 }
630 
hwc_set_external(hwc_context_t * ctx,hwc_display_contents_1_t * list)631 static int hwc_set_external(hwc_context_t *ctx,
632                             hwc_display_contents_1_t* list)
633 {
634     ATRACE_CALL();
635     int ret = 0;
636 
637     const int dpy = HWC_DISPLAY_EXTERNAL;
638 
639 
640     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
641         ctx->dpyAttr[dpy].connected &&
642         !ctx->dpyAttr[dpy].isPause) {
643         size_t last = list->numHwLayers - 1;
644         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
645         int fd = -1; //FenceFD from the Copybit(valid in async mode)
646         bool copybitDone = false;
647         if(ctx->mCopyBit[dpy])
648             copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
649 
650         if(list->numHwLayers > 1)
651             hwc_sync(ctx, list, dpy, fd);
652 
653         // Dump the layers for external
654         if(ctx->mHwcDebug[dpy])
655             ctx->mHwcDebug[dpy]->dumpLayers(list);
656 
657         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
658             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
659             ret = -1;
660         }
661 
662         int extOnlyLayerIndex =
663                 ctx->listStats[dpy].extOnlyLayerIndex;
664 
665         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
666         if(extOnlyLayerIndex!= -1) {
667             hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
668             hnd = (private_handle_t *)extLayer->handle;
669         } else if(copybitDone) {
670             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
671         }
672 
673         if(hnd && !isYuvBuffer(hnd)) {
674             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
675                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
676                 ret = -1;
677             }
678         }
679 
680         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
681             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
682             ret = -1;
683         }
684     }
685 
686     closeAcquireFds(list);
687     return ret;
688 }
689 
hwc_set(hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)690 static int hwc_set(hwc_composer_device_1 *dev,
691                    size_t numDisplays,
692                    hwc_display_contents_1_t** displays)
693 {
694     int ret = 0;
695     hwc_context_t* ctx = (hwc_context_t*)(dev);
696     for (int i = 0; i < (int)numDisplays; i++) {
697         hwc_display_contents_1_t* list = displays[i];
698         int dpy = getDpyforExternalDisplay(ctx, i);
699         switch(dpy) {
700             case HWC_DISPLAY_PRIMARY:
701                 ret = hwc_set_primary(ctx, list);
702                 break;
703             case HWC_DISPLAY_EXTERNAL:
704                 ret = hwc_set_external(ctx, list);
705                 break;
706             case HWC_DISPLAY_VIRTUAL:
707                 if(ctx->mHWCVirtual)
708                     ret = ctx->mHWCVirtual->set(ctx, list);
709                 break;
710             default:
711                 ret = -EINVAL;
712         }
713     }
714     // This is only indicative of how many times SurfaceFlinger posts
715     // frames to the display.
716     CALC_FPS();
717     MDPComp::resetIdleFallBack();
718     ctx->mVideoTransFlag = false;
719     //Was locked at the beginning of prepare
720     ctx->mDrawLock.unlock();
721     return ret;
722 }
723 
hwc_getDisplayConfigs(struct hwc_composer_device_1 * dev,int disp,uint32_t * configs,size_t * numConfigs)724 int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
725         uint32_t* configs, size_t* numConfigs) {
726     int ret = 0;
727     hwc_context_t* ctx = (hwc_context_t*)(dev);
728     disp = getDpyforExternalDisplay(ctx, disp);
729     //Currently we allow only 1 config, reported as config id # 0
730     //This config is passed in to getDisplayAttributes. Ignored for now.
731     switch(disp) {
732         case HWC_DISPLAY_PRIMARY:
733             if(*numConfigs > 0) {
734                 configs[0] = 0;
735                 *numConfigs = 1;
736             }
737             ret = 0; //NO_ERROR
738             break;
739         case HWC_DISPLAY_EXTERNAL:
740         case HWC_DISPLAY_VIRTUAL:
741             ret = -1; //Not connected
742             if(ctx->dpyAttr[disp].connected) {
743                 ret = 0; //NO_ERROR
744                 if(*numConfigs > 0) {
745                     configs[0] = 0;
746                     *numConfigs = 1;
747                 }
748             }
749             break;
750     }
751     return ret;
752 }
753 
hwc_getDisplayAttributes(struct hwc_composer_device_1 * dev,int disp,uint32_t,const uint32_t * attributes,int32_t * values)754 int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
755         uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
756 
757     hwc_context_t* ctx = (hwc_context_t*)(dev);
758     disp = getDpyforExternalDisplay(ctx, disp);
759     //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
760     if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
761         return -1;
762     }
763 
764     //From HWComposer
765     static const uint32_t DISPLAY_ATTRIBUTES[] = {
766         HWC_DISPLAY_VSYNC_PERIOD,
767         HWC_DISPLAY_WIDTH,
768         HWC_DISPLAY_HEIGHT,
769         HWC_DISPLAY_DPI_X,
770         HWC_DISPLAY_DPI_Y,
771         HWC_DISPLAY_NO_ATTRIBUTE,
772     };
773 
774     const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
775             sizeof(DISPLAY_ATTRIBUTES)[0]);
776 
777     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
778         switch (attributes[i]) {
779         case HWC_DISPLAY_VSYNC_PERIOD:
780             values[i] = ctx->dpyAttr[disp].vsync_period;
781             break;
782         case HWC_DISPLAY_WIDTH:
783             if (ctx->dpyAttr[disp].customFBSize)
784                 values[i] = ctx->dpyAttr[disp].xres_new;
785             else
786                 values[i] = ctx->dpyAttr[disp].xres;
787 
788             ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
789                     values[i]);
790             break;
791         case HWC_DISPLAY_HEIGHT:
792             if (ctx->dpyAttr[disp].customFBSize)
793                 values[i] = ctx->dpyAttr[disp].yres_new;
794             else
795                 values[i] = ctx->dpyAttr[disp].yres;
796             ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
797                     values[i]);
798             break;
799         case HWC_DISPLAY_DPI_X:
800             values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
801             break;
802         case HWC_DISPLAY_DPI_Y:
803             values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
804             break;
805         default:
806             ALOGE("Unknown display attribute %d",
807                     attributes[i]);
808             return -EINVAL;
809         }
810     }
811     return 0;
812 }
813 
hwc_dump(struct hwc_composer_device_1 * dev,char * buff,int buff_len)814 void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
815 {
816     hwc_context_t* ctx = (hwc_context_t*)(dev);
817     Locker::Autolock _l(ctx->mDrawLock);
818     android::String8 aBuf("");
819     dumpsys_log(aBuf, "Qualcomm HWC state:\n");
820     dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
821     dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
822     if(ctx->vstate.fakevsync)
823         dumpsys_log(aBuf, "  Vsync is being faked!!\n");
824     for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
825         if(ctx->mMDPComp[dpy])
826             ctx->mMDPComp[dpy]->dump(aBuf, ctx);
827     }
828     char ovDump[2048] = {'\0'};
829     ctx->mOverlay->getDump(ovDump, 2048);
830     dumpsys_log(aBuf, ovDump);
831     ovDump[0] = '\0';
832     ctx->mRotMgr->getDump(ovDump, 1024);
833     dumpsys_log(aBuf, ovDump);
834     ovDump[0] = '\0';
835     if(Writeback::getDump(ovDump, 1024)) {
836         dumpsys_log(aBuf, ovDump);
837         ovDump[0] = '\0';
838     }
839     strlcpy(buff, aBuf.string(), buff_len);
840 }
841 
hwc_getActiveConfig(struct hwc_composer_device_1 *,int)842 int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) {
843     //Supports only the default config (0th index) for now
844     return 0;
845 }
846 
hwc_setActiveConfig(struct hwc_composer_device_1 *,int,int index)847 int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/,
848         int index) {
849     //Supports only the default config (0th index) for now
850     return (index == 0) ? index : -EINVAL;
851 }
852 
hwc_device_close(struct hw_device_t * dev)853 static int hwc_device_close(struct hw_device_t *dev)
854 {
855     if(!dev) {
856         ALOGE("%s: NULL device pointer", __FUNCTION__);
857         return -1;
858     }
859     closeContext((hwc_context_t*)dev);
860     free(dev);
861 
862     return 0;
863 }
864 
hwc_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)865 static int hwc_device_open(const struct hw_module_t* module, const char* name,
866                            struct hw_device_t** device)
867 {
868     int status = -EINVAL;
869 
870     if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
871         struct hwc_context_t *dev;
872         dev = (hwc_context_t*)malloc(sizeof(*dev));
873         if(dev == NULL)
874             return status;
875         memset(dev, 0, sizeof(*dev));
876 
877         //Initialize hwc context
878         initContext(dev);
879 
880         //Setup HWC methods
881         dev->device.common.tag          = HARDWARE_DEVICE_TAG;
882         dev->device.common.version      = HWC_DEVICE_API_VERSION_1_4;
883         dev->device.common.module       = const_cast<hw_module_t*>(module);
884         dev->device.common.close        = hwc_device_close;
885         dev->device.prepare             = hwc_prepare;
886         dev->device.set                 = hwc_set;
887         dev->device.eventControl        = hwc_eventControl;
888         dev->device.setPowerMode        = hwc_setPowerMode;
889         dev->device.query               = hwc_query;
890         dev->device.registerProcs       = hwc_registerProcs;
891         dev->device.dump                = hwc_dump;
892         dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
893         dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
894         dev->device.getActiveConfig     = hwc_getActiveConfig;
895         dev->device.setActiveConfig     = hwc_setActiveConfig;
896         *device = &dev->device.common;
897         status = 0;
898     }
899     return status;
900 }
901