hwc_utils.h revision bd51df0d51c9342f705caeea9c245b919dedb120
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
35
36#define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
37#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
38#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
39#define MAX_NUM_APP_LAYERS 32
40#define MIN_DISPLAY_XRES 200
41#define MIN_DISPLAY_YRES 200
42#define HWC_WFDDISPSYNC_LOG 0
43#define STR(f) #f;
44
45//Fwrd decls
46struct hwc_context_t;
47
48namespace ovutils = overlay::utils;
49
50namespace overlay {
51class Overlay;
52class Rotator;
53class RotMgr;
54}
55
56namespace qhwc {
57//fwrd decl
58class QueuedBufferStore;
59class ExternalDisplay;
60class VirtualDisplay;
61class IFBUpdate;
62class IVideoOverlay;
63class MDPComp;
64class CopyBit;
65class HwcDebug;
66class AssertiveDisplay;
67class HWCVirtualBase;
68
69
70struct MDPInfo {
71    int version;
72    char panel;
73    bool hasOverlay;
74};
75
76struct DisplayAttributes {
77    uint32_t vsync_period; //nanos
78    uint32_t xres;
79    uint32_t yres;
80    uint32_t stride;
81    float xdpi;
82    float ydpi;
83    int fd;
84    bool connected; //Applies only to pluggable disp.
85    //Connected does not mean it ready to use.
86    //It should be active also. (UNBLANKED)
87    bool isActive;
88    // In pause state, composition is bypassed
89    // used for WFD displays only
90    bool isPause;
91    // To trigger padding round to clean up mdp
92    // pipes
93    bool isConfiguring;
94    // External Display is in MDP Downscale mode indicator
95    bool mDownScaleMode;
96    // Ext dst Rect
97    hwc_rect_t mDstRect;
98    //Action safe attributes
99    // Flag to indicate the presence of action safe dimensions for external
100    bool mActionSafePresent;
101    int mAsWidthRatio;
102    int mAsHeightRatio;
103
104    //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
105    //following fields are used.
106    bool customFBSize;
107    uint32_t xres_new;
108    uint32_t yres_new;
109
110};
111
112struct ListStats {
113    int numAppLayers; //Total - 1, excluding FB layer.
114    int skipCount;
115    int fbLayerIndex; //Always last for now. = numAppLayers
116    //Video specific
117    int yuvCount;
118    int yuvIndices[MAX_NUM_APP_LAYERS];
119    int extOnlyLayerIndex;
120    bool preMultipliedAlpha;
121    int yuv4k2kIndices[MAX_NUM_APP_LAYERS];
122    int yuv4k2kCount;
123    // Notifies hwcomposer about the start and end of animation
124    // This will be set to true during animation, otherwise false.
125    bool isDisplayAnimating;
126    bool secureUI; // Secure display layer
127    bool isSecurePresent;
128    hwc_rect_t lRoi;  //left ROI
129    hwc_rect_t rRoi;  //right ROI. Unused in single DSI panels.
130    //App Buffer Composition index
131    int  renderBufIndexforABC;
132};
133
134struct LayerProp {
135    uint32_t mFlags; //qcom specific layer flags
136    LayerProp():mFlags(0){};
137};
138
139struct VsyncState {
140    bool enable;
141    bool fakevsync;
142};
143
144struct BwcPM {
145    static void setBwc(const hwc_rect_t& crop,
146            const hwc_rect_t& dst, const int& transform,
147            ovutils::eMdpFlags& mdpFlags);
148};
149
150// LayerProp::flag values
151enum {
152    HWC_MDPCOMP = 0x00000001,
153    HWC_COPYBIT = 0x00000002,
154};
155
156// HAL specific features
157enum {
158    HWC_COLOR_FILL = 0x00000008,
159    HWC_FORMAT_RB_SWAP = 0x00000040,
160};
161
162/* External Display states */
163enum {
164    EXTERNAL_OFFLINE = 0,
165    EXTERNAL_ONLINE,
166    EXTERNAL_PAUSE,
167    EXTERNAL_RESUME,
168    EXTERNAL_MAXSTATES
169};
170
171class LayerRotMap {
172public:
173    LayerRotMap() { reset(); }
174    enum { MAX_SESS = 3 };
175    void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
176    //Resets the mapping of layer to rotator
177    void reset();
178    //Clears mappings and existing rotator fences
179    //Intended to be used during errors
180    void clear();
181    uint32_t getCount() const;
182    hwc_layer_1_t* getLayer(uint32_t index) const;
183    overlay::Rotator* getRot(uint32_t index) const;
184    void setReleaseFd(const int& fence);
185private:
186    hwc_layer_1_t* mLayer[MAX_SESS];
187    overlay::Rotator* mRot[MAX_SESS];
188    uint32_t mCount;
189};
190
191inline uint32_t LayerRotMap::getCount() const {
192    return mCount;
193}
194
195inline hwc_layer_1_t* LayerRotMap::getLayer(uint32_t index) const {
196    if(index >= mCount) return NULL;
197    return mLayer[index];
198}
199
200inline overlay::Rotator* LayerRotMap::getRot(uint32_t index) const {
201    if(index >= mCount) return NULL;
202    return mRot[index];
203}
204
205inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
206    hwc_rect_t cropI = {0,0,0,0};
207    cropI.left = int(ceilf(cropF.left));
208    cropI.top = int(ceilf(cropF.top));
209    cropI.right = int(floorf(cropF.right));
210    cropI.bottom = int(floorf(cropF.bottom));
211    return cropI;
212}
213
214inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
215    if(cropF.left - roundf(cropF.left)     ||
216       cropF.top - roundf(cropF.top)       ||
217       cropF.right - roundf(cropF.right)   ||
218       cropF.bottom - roundf(cropF.bottom))
219        return true;
220    else
221        return false;
222}
223
224// -----------------------------------------------------------------------------
225// Utility functions - implemented in hwc_utils.cpp
226void dumpLayer(hwc_layer_1_t const* l);
227
228// Calculate viewframe for external/primary display from primary resolution and
229// primary device orientation
230hwc_rect_t calculateDisplayViewFrame(hwc_context_t *ctx, int dpy);
231
232void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
233        int dpy);
234void initContext(hwc_context_t *ctx);
235void closeContext(hwc_context_t *ctx);
236//Crops source buffer against destination and FB boundaries
237void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
238                         const hwc_rect_t& scissor, int orient);
239void getNonWormholeRegion(hwc_display_contents_1_t* list,
240                              hwc_rect_t& nwr);
241bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
242bool isSecureModePolicy(int mdpVersion);
243bool isExternalActive(hwc_context_t* ctx);
244bool isAlphaScaled(hwc_layer_1_t const* layer);
245bool needsScaling(hwc_layer_1_t const* layer);
246bool isDownscaleRequired(hwc_layer_1_t const* layer);
247bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
248                           const int& dpy);
249void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
250                        private_handle_t *hnd);
251bool isAlphaPresent(hwc_layer_1_t const* layer);
252int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
253int getBlending(int blending);
254bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
255void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
256bool isAbcInUse(hwc_context_t *ctx);
257
258bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
259                                const hwc_display_contents_1_t *list);
260
261//Helper function to dump logs
262void dumpsys_log(android::String8& buf, const char* fmt, ...);
263
264int getExtOrientation(hwc_context_t* ctx);
265bool isValidRect(const hwc_rect_t& rect);
266hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
267bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2);
268hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off);
269hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
270hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
271void optimizeLayerRects(const hwc_display_contents_1_t *list);
272bool areLayersIntersecting(const hwc_layer_1_t* layer1,
273        const hwc_layer_1_t* layer2);
274bool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs);
275
276// returns true if Action safe dimensions are set and target supports Actionsafe
277bool isActionSafePresent(hwc_context_t *ctx, int dpy);
278
279/* Calculates the destination position based on the action safe rectangle */
280void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
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    // Is WFD enabled through VDS solution ?
558    // This can be set via system property
559    // persist.hwc.enable_vds
560    bool mVDSEnabled;
561    struct gpu_hint_info mGPUHintInfo;
562    //App Buffer Composition
563    bool enableABC;
564};
565
566namespace qhwc {
567static inline bool isSkipPresent (hwc_context_t *ctx, int dpy) {
568    return  ctx->listStats[dpy].skipCount;
569}
570
571static inline bool isYuvPresent (hwc_context_t *ctx, int dpy) {
572    return  ctx->listStats[dpy].yuvCount;
573}
574
575static inline bool has90Transform(hwc_layer_1_t *layer) {
576    return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
577            !(layer->flags & HWC_COLOR_FILL));
578}
579
580inline bool isSecurePresent(hwc_context_t *ctx, int dpy) {
581    return ctx->listStats[dpy].isSecurePresent;
582}
583
584static inline bool isSecondaryConfiguring(hwc_context_t* ctx) {
585    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
586            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring);
587}
588
589static inline bool isSecondaryConnected(hwc_context_t* ctx) {
590    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ||
591            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected);
592}
593
594};
595
596#endif //HWC_UTILS_H
597