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