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