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
21#ifndef HWC_UTILS_H
22#define HWC_UTILS_H
23
24#define HWC_REMOVE_DEPRECATED_VERSIONS 1
25#include <fcntl.h>
26#include <math.h>
27#include <hardware/hwcomposer.h>
28#include <gr.h>
29#include <gralloc_priv.h>
30#include <utils/String8.h>
31#include "qdMetaData.h"
32#include <overlayUtils.h>
33#include <EGL/egl.h>
34#include <QService.h>
35
36
37#define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
38#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
39#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
40#define MAX_NUM_APP_LAYERS 32
41#define MIN_DISPLAY_XRES 200
42#define MIN_DISPLAY_YRES 200
43#define HWC_WFDDISPSYNC_LOG 0
44#define STR(f) #f;
45
46//Fwrd decls
47struct hwc_context_t;
48
49namespace ovutils = overlay::utils;
50
51namespace overlay {
52class Overlay;
53class Rotator;
54class RotMgr;
55}
56
57namespace qhwc {
58//fwrd decl
59class QueuedBufferStore;
60class ExternalDisplay;
61class VirtualDisplay;
62class IFBUpdate;
63class IVideoOverlay;
64class MDPComp;
65class CopyBit;
66class HwcDebug;
67class AssertiveDisplay;
68class HWCVirtualBase;
69
70
71struct MDPInfo {
72    int version;
73    char panel;
74    bool hasOverlay;
75};
76
77struct DisplayAttributes {
78    uint32_t vsync_period; //nanos
79    uint32_t xres;
80    uint32_t yres;
81    uint32_t stride;
82    float xdpi;
83    float ydpi;
84    int fd;
85    bool connected; //Applies only to pluggable disp.
86    //Connected does not mean it ready to use.
87    //It should be active also. (UNBLANKED)
88    bool isActive;
89    // In pause state, composition is bypassed
90    // used for WFD displays only
91    bool isPause;
92    // To trigger padding round to clean up mdp
93    // pipes
94    bool isConfiguring;
95    // External Display is in MDP Downscale mode indicator
96    bool mDownScaleMode;
97    // Ext dst Rect
98    hwc_rect_t mDstRect;
99    //Action safe attributes
100    // Flag to indicate the presence of action safe dimensions for external
101    bool mActionSafePresent;
102    int mAsWidthRatio;
103    int mAsHeightRatio;
104
105    //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
106    //following fields are used.
107    bool customFBSize;
108    uint32_t xres_orig;
109    uint32_t yres_orig;
110
111};
112
113struct ListStats {
114    int numAppLayers; //Total - 1, excluding FB layer.
115    int skipCount;
116    int fbLayerIndex; //Always last for now. = numAppLayers
117    //Video specific
118    int yuvCount;
119    int yuvIndices[MAX_NUM_APP_LAYERS];
120    int extOnlyLayerIndex;
121    bool preMultipliedAlpha;
122    int yuv4k2kIndices[MAX_NUM_APP_LAYERS];
123    int yuv4k2kCount;
124    // Notifies hwcomposer about the start and end of animation
125    // This will be set to true during animation, otherwise false.
126    bool isDisplayAnimating;
127    bool secureUI; // Secure display layer
128    bool isSecurePresent;
129    hwc_rect_t lRoi;  //left ROI
130    hwc_rect_t rRoi;  //right ROI. Unused in single DSI panels.
131};
132
133struct LayerProp {
134    uint32_t mFlags; //qcom specific layer flags
135    LayerProp():mFlags(0){};
136};
137
138struct VsyncState {
139    bool enable;
140    bool fakevsync;
141};
142
143struct BwcPM {
144    static void setBwc(const hwc_rect_t& crop,
145            const hwc_rect_t& dst, const int& transform,
146            ovutils::eMdpFlags& mdpFlags);
147};
148
149// LayerProp::flag values
150enum {
151    HWC_MDPCOMP = 0x00000001,
152    HWC_COPYBIT = 0x00000002,
153};
154
155// HAL specific features
156enum {
157    HWC_COLOR_FILL = 0x00000008,
158    HWC_FORMAT_RB_SWAP = 0x00000040,
159};
160
161/* External Display states */
162enum {
163    EXTERNAL_OFFLINE = 0,
164    EXTERNAL_ONLINE,
165    EXTERNAL_PAUSE,
166    EXTERNAL_RESUME,
167    EXTERNAL_MAXSTATES
168};
169
170class LayerRotMap {
171public:
172    LayerRotMap() { reset(); }
173    enum { MAX_SESS = 3 };
174    void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
175    //Resets the mapping of layer to rotator
176    void reset();
177    //Clears mappings and existing rotator fences
178    //Intended to be used during errors
179    void clear();
180    uint32_t getCount() const;
181    hwc_layer_1_t* getLayer(uint32_t index) const;
182    overlay::Rotator* getRot(uint32_t index) const;
183    void setReleaseFd(const int& fence);
184private:
185    hwc_layer_1_t* mLayer[MAX_SESS];
186    overlay::Rotator* mRot[MAX_SESS];
187    uint32_t mCount;
188};
189
190inline uint32_t LayerRotMap::getCount() const {
191    return mCount;
192}
193
194inline hwc_layer_1_t* LayerRotMap::getLayer(uint32_t index) const {
195    if(index >= mCount) return NULL;
196    return mLayer[index];
197}
198
199inline overlay::Rotator* LayerRotMap::getRot(uint32_t index) const {
200    if(index >= mCount) return NULL;
201    return mRot[index];
202}
203
204inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
205    hwc_rect_t cropI = {0,0,0,0};
206    cropI.left = int(ceilf(cropF.left));
207    cropI.top = int(ceilf(cropF.top));
208    cropI.right = int(floorf(cropF.right));
209    cropI.bottom = int(floorf(cropF.bottom));
210    return cropI;
211}
212
213inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
214    if(cropF.left - roundf(cropF.left)     ||
215       cropF.top - roundf(cropF.top)       ||
216       cropF.right - roundf(cropF.right)   ||
217       cropF.bottom - roundf(cropF.bottom))
218        return true;
219    else
220        return false;
221}
222
223// -----------------------------------------------------------------------------
224// Utility functions - implemented in hwc_utils.cpp
225void dumpLayer(hwc_layer_1_t const* l);
226
227// Calculate viewframe for external/primary display from primary resolution and
228// primary device orientation
229hwc_rect_t calculateDisplayViewFrame(hwc_context_t *ctx, int dpy);
230
231void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
232        int dpy);
233void initContext(hwc_context_t *ctx);
234void closeContext(hwc_context_t *ctx);
235//Crops source buffer against destination and FB boundaries
236void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
237                         const hwc_rect_t& scissor, int orient);
238void getNonWormholeRegion(hwc_display_contents_1_t* list,
239                              hwc_rect_t& nwr);
240bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
241bool isSecureModePolicy(int mdpVersion);
242bool isExternalActive(hwc_context_t* ctx);
243bool isAlphaScaled(hwc_layer_1_t const* layer);
244bool needsScaling(hwc_layer_1_t const* layer);
245bool isDownscaleRequired(hwc_layer_1_t const* layer);
246bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
247                           const int& dpy);
248void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
249                        private_handle_t *hnd);
250bool isAlphaPresent(hwc_layer_1_t const* layer);
251int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
252int getBlending(int blending);
253bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
254void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
255
256bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
257                                const hwc_display_contents_1_t *list);
258
259//Helper function to dump logs
260void dumpsys_log(android::String8& buf, const char* fmt, ...);
261
262int getExtOrientation(hwc_context_t* ctx);
263bool isValidRect(const hwc_rect_t& rect);
264hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
265bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2);
266hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off);
267hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
268hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
269void optimizeLayerRects(const hwc_display_contents_1_t *list);
270bool areLayersIntersecting(const hwc_layer_1_t* layer1,
271        const hwc_layer_1_t* layer2);
272
273// returns true if Action safe dimensions are set and target supports Actionsafe
274bool isActionSafePresent(hwc_context_t *ctx, int dpy);
275
276/* Calculates the destination position based on the action safe rectangle */
277void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
278
279void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
280                                int srcHeight, hwc_rect_t& rect);
281
282void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
283                                hwc_rect_t& inRect, hwc_rect_t& outRect);
284
285bool isPrimaryPortrait(hwc_context_t *ctx);
286
287bool isOrientationPortrait(hwc_context_t *ctx);
288
289void calcExtDisplayPosition(hwc_context_t *ctx,
290                               private_handle_t *hnd,
291                               int dpy,
292                               hwc_rect_t& sourceCrop,
293                               hwc_rect_t& displayFrame,
294                               int& transform,
295                               ovutils::eTransform& orient);
296
297// Returns the orientation that needs to be set on external for
298// BufferMirrirMode(Sidesync)
299int getMirrorModeOrientation(hwc_context_t *ctx);
300
301/* Get External State names */
302const char* getExternalDisplayState(uint32_t external_state);
303
304// Resets display ROI to full panel resoluion
305void resetROI(hwc_context_t *ctx, const int dpy);
306
307// Aligns updating ROI to panel restrictions
308hwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary);
309
310// Handles wfd Pause and resume events
311void handle_pause(hwc_context_t *ctx, int dpy);
312void handle_resume(hwc_context_t *ctx, int dpy);
313
314//Close acquireFenceFds of all layers of incoming list
315void closeAcquireFds(hwc_display_contents_1_t* list);
316
317//Sync point impl.
318int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
319        int fd);
320
321//Sets appropriate mdp flags for a layer.
322void setMdpFlags(hwc_layer_1_t *layer,
323        ovutils::eMdpFlags &mdpFlags,
324        int rotDownscale, int transform);
325
326int configRotator(overlay::Rotator *rot, ovutils::Whf& whf,
327        hwc_rect_t& crop, const ovutils::eMdpFlags& mdpFlags,
328        const ovutils::eTransform& orient, const int& downscale);
329
330int configMdp(overlay::Overlay *ov, const ovutils::PipeArgs& parg,
331        const ovutils::eTransform& orient, const hwc_rect_t& crop,
332        const hwc_rect_t& pos, const MetaData_t *metadata,
333        const ovutils::eDest& dest);
334
335int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
336        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
337        ovutils::eIsFg& isFg, const ovutils::eDest& dest);
338
339void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
340        hwc_rect_t& crop);
341
342//Routine to configure low resolution panels (<= 2048 width)
343int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
344        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
345        ovutils::eIsFg& isFg, const ovutils::eDest& dest,
346        overlay::Rotator **rot);
347
348//Routine to configure high resolution panels (> 2048 width)
349int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
350        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
351        ovutils::eIsFg& isFg, const ovutils::eDest& lDest,
352        const ovutils::eDest& rDest, overlay::Rotator **rot);
353
354//Routine to split and configure high resolution YUV layer (> 2048 width)
355int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
356        const int& dpy,
357        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
358        ovutils::eIsFg& isFg, const ovutils::eDest& lDest,
359        const ovutils::eDest& rDest, overlay::Rotator **rot);
360
361//On certain targets DMA pipes are used for rotation and they won't be available
362//for line operations. On a per-target basis we can restrict certain use cases
363//from using rotator, since we know before-hand that such scenarios can lead to
364//extreme unavailability of pipes. This can also be done via hybrid calculations
365//also involving many more variables like number of write-back interfaces etc,
366//but the variety of scenarios is too high to warrant that.
367bool canUseRotator(hwc_context_t *ctx, int dpy);
368
369int getLeftSplit(hwc_context_t *ctx, const int& dpy);
370
371bool isDisplaySplit(hwc_context_t* ctx, int dpy);
372
373// Set the GPU hint flag to high for MIXED/GPU composition only for
374// first frame after MDP to GPU/MIXED mode transition.
375// Set the GPU hint to default if the current composition type is GPU
376// due to idle fallback or MDP composition.
377void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list);
378
379// Inline utility functions
380static inline bool isSkipLayer(const hwc_layer_1_t* l) {
381    return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
382}
383
384// Returns true if the buffer is yuv
385static inline bool isYuvBuffer(const private_handle_t* hnd) {
386    return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
387}
388
389// Returns true if the buffer is yuv
390static inline bool is4kx2kYuvBuffer(const private_handle_t* hnd) {
391    return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
392            (hnd->width > 2048));
393}
394
395// Returns true if the buffer is secure
396static inline bool isSecureBuffer(const private_handle_t* hnd) {
397    return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & hnd->flags));
398}
399
400static inline bool isTileRendered(const private_handle_t* hnd) {
401    return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
402}
403
404//Return true if buffer is marked locked
405static inline bool isBufferLocked(const private_handle_t* hnd) {
406    return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
407}
408
409//Return true if buffer is for external display only
410static inline bool isExtOnly(const private_handle_t* hnd) {
411    return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY));
412}
413
414//Return true if the buffer is intended for Secure Display
415static inline bool isSecureDisplayBuffer(const private_handle_t* hnd) {
416    return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY));
417}
418
419static inline int getWidth(const private_handle_t* hnd) {
420    if(isYuvBuffer(hnd)) {
421        MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
422        if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
423            return metadata->bufferDim.sliceWidth;
424        }
425    }
426    return hnd->width;
427}
428
429static inline int getHeight(const private_handle_t* hnd) {
430    if(isYuvBuffer(hnd)) {
431        MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
432        if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
433            return metadata->bufferDim.sliceHeight;
434        }
435    }
436    return hnd->height;
437}
438
439template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
440template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
441
442// Initialize uevent thread
443void init_uevent_thread(hwc_context_t* ctx);
444// Initialize vsync thread
445void init_vsync_thread(hwc_context_t* ctx);
446
447inline void getLayerResolution(const hwc_layer_1_t* layer,
448                               int& width, int& height) {
449    hwc_rect_t displayFrame  = layer->displayFrame;
450    width = displayFrame.right - displayFrame.left;
451    height = displayFrame.bottom - displayFrame.top;
452}
453
454static inline int openFb(int dpy) {
455    int fd = -1;
456    const char *devtmpl = "/dev/graphics/fb%u";
457    char name[64] = {0};
458    snprintf(name, 64, devtmpl, dpy);
459    fd = open(name, O_RDWR);
460    return fd;
461}
462
463template <class T>
464inline void swap(T& a, T& b) {
465    T tmp = a;
466    a = b;
467    b = tmp;
468}
469
470}; //qhwc namespace
471
472enum eAnimationState{
473    ANIMATION_STOPPED,
474    ANIMATION_STARTED,
475};
476
477// Structure holds the information about the GPU hint.
478struct gpu_hint_info {
479    // system level flag to enable gpu_perf_mode
480    bool mGpuPerfModeEnable;
481    // Stores the current GPU performance mode DEFAULT/HIGH
482    bool mCurrGPUPerfMode;
483    // true if previous composition used GPU
484    bool mPrevCompositionGLES;
485    // Stores the EGLContext of current process
486    EGLContext mEGLContext;
487    // Stores the EGLDisplay of current process
488    EGLDisplay mEGLDisplay;
489};
490
491// -----------------------------------------------------------------------------
492// HWC context
493// This structure contains overall state
494struct hwc_context_t {
495    hwc_composer_device_1_t device;
496    const hwc_procs_t* proc;
497
498    //CopyBit objects
499    qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];
500
501    //Overlay object - NULL for non overlay devices
502    overlay::Overlay *mOverlay;
503    //Holds a few rot objects
504    overlay::RotMgr *mRotMgr;
505
506    //Primary and external FB updater
507    qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
508    // External display related information
509    qhwc::ExternalDisplay *mExtDisplay;
510    qhwc::VirtualDisplay *mVirtualDisplay;
511    qhwc::MDPInfo mMDP;
512    qhwc::VsyncState vstate;
513    qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
514    qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES];
515    qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES];
516    qhwc::MDPComp *mMDPComp[HWC_NUM_DISPLAY_TYPES];
517    qhwc::HwcDebug *mHwcDebug[HWC_NUM_DISPLAY_TYPES];
518    hwc_rect_t mViewFrame[HWC_NUM_DISPLAY_TYPES];
519    qhwc::AssertiveDisplay *mAD;
520    eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
521    qhwc::HWCVirtualBase *mHWCVirtual;
522
523    // stores the #numHwLayers of the previous frame
524    // for each display device
525    int mPrevHwLayerCount[HWC_NUM_DISPLAY_TYPES];
526
527    // stores the primary device orientation
528    int deviceOrientation;
529    //Securing in progress indicator
530    bool mSecuring;
531    //WFD on proprietary stack
532    bool mVirtualonExtActive;
533    //Display in secure mode indicator
534    bool mSecureMode;
535    //Lock to protect drawing data structures
536    mutable Locker mDrawLock;
537    //Drawing round when we use GPU
538    bool isPaddingRound;
539    // External Orientation
540    int mExtOrientation;
541    //Flags the transition of a video session
542    bool mVideoTransFlag;
543    //Used for SideSync feature
544    //which overrides the mExtOrientation
545    bool mBufferMirrorMode;
546    // Used to synchronize between WFD and Display modules
547    mutable Locker mWfdSyncLock;
548
549    qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
550    // Panel reset flag will be set if BTA check fails
551    bool mPanelResetStatus;
552    // number of active Displays
553    int numActiveDisplays;
554    // Downscale feature switch, set via system property
555    // sys.hwc.mdp_downscale_enabled
556    bool mMDPDownscaleEnabled;
557    struct gpu_hint_info mGPUHintInfo;
558    // Display binder service
559    qService::QService* mQService;
560};
561
562namespace qhwc {
563static inline bool isSkipPresent (hwc_context_t *ctx, int dpy) {
564    return  ctx->listStats[dpy].skipCount;
565}
566
567static inline bool isYuvPresent (hwc_context_t *ctx, int dpy) {
568    return  ctx->listStats[dpy].yuvCount;
569}
570
571static inline bool has90Transform(hwc_layer_1_t *layer) {
572    return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
573            !(layer->flags & HWC_COLOR_FILL));
574}
575
576inline bool isSecurePresent(hwc_context_t *ctx, int dpy) {
577    return ctx->listStats[dpy].isSecurePresent;
578}
579
580static inline bool isSecondaryConfiguring(hwc_context_t* ctx) {
581    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
582            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring);
583}
584
585static inline bool isSecondaryConnected(hwc_context_t* ctx) {
586    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ||
587            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected);
588}
589
590};
591
592#endif //HWC_UTILS_H
593