summaryrefslogtreecommitdiff
path: root/libhwc2.1/libresource/ExynosMPP.h
blob: 7ea3fbe466ff1acef402b4227a35eb313ea795c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Project HWC 2.0 Design
 */

#ifndef _EXYNOSMPP_H
#define _EXYNOSMPP_H

#include <utils/Thread.h>
#include <utils/Mutex.h>
#include <utils/Condition.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <utils/List.h>
#include <utils/Vector.h>
#include <map>
#include <hardware/exynos/acryl.h>
#include <map>
#include "ExynosHWCModule.h"
#include "ExynosHWCHelper.h"
#include "ExynosMPPType.h"

class ExynosDisplay;
class ExynosMPP;
class ExynosResourceManager;

#ifndef NUM_MPP_DST_BUFS
#define NUM_MPP_DST_BUFS_DEFAULT 3
/*
 * Buffer number can be different according to type
 * #define NUM_MPP_DST_BUFS(type) ((type == MPP_LOGICAL_G2D_RGB) ? 3:2)
 */
#define NUM_MPP_DST_BUFS(type) (3)
#endif

#ifndef G2D_MAX_SRC_NUM
#define G2D_MAX_SRC_NUM 15
#endif

#define G2D_JUSTIFIED_DST_ALIGN     16

#define NUM_MPP_SRC_BUFS G2D_MAX_SRC_NUM

#ifndef G2D_RESTRICTIVE_SRC_NUM
#define G2D_RESTRICTIVE_SRC_NUM   5
#endif

#ifndef G2D_BASE_PPC
#define G2D_BASE_PPC 2.8
#endif
#ifndef G2D_DST_BASE_PPC
#define G2D_DST_BASE_PPC 3.5
#endif
#ifndef G2D_DST_BASE_PPC_YUV420
#define G2D_DST_BASE_PPC_YUV420 2.8
#endif
#ifndef G2D_DST_BASE_PPC_ROT
#define G2D_DST_BASE_PPC_ROT  2.4
#endif
#ifndef G2D_BASE_PPC_COLORFILL
#define G2D_BASE_PPC_COLORFILL  3.8
#endif

#ifndef G2D_CLOCK
#define G2D_CLOCK   711000
#endif

#ifndef MSC_CLOCK
#define MSC_CLOCK   534000
#endif

#ifndef VPP_CLOCK
#define VPP_CLOCK 664000
#endif
#ifndef VPP_MIC_FACTOR
#define VPP_MIC_FACTOR  2
#endif

#ifndef VPP_TE_PERIOD
#define VPP_TE_PERIOD 63
#endif
#ifndef VPP_MARGIN
#define VPP_MARGIN 1.1
#endif
#ifndef VPP_BUBBLE
#define VPP_BUBBLE 0.06
#endif

#define VPP_RESOL_CLOCK_FACTOR (VPP_TE_PERIOD * VPP_MARGIN)
#define VPP_RESOL_MARGIN (VPP_MARGIN + VPP_BUBBLE)
#ifndef VPP_DISP_FACTOR
#define VPP_DISP_FACTOR 1.0
#endif
#ifndef VPP_PIXEL_PER_CLOCK
#define VPP_PIXEL_PER_CLOCK 2
#endif

#ifndef MPP_G2D_CAPACITY
#define MPP_G2D_CAPACITY    8
#endif
// G2D or MSC additional margin capacity when HDR layer is passed.
#ifndef MPP_HDR_MARGIN
#define MPP_HDR_MARGIN 1.2
#endif

#ifndef MPP_MSC_CAPACITY
#define MPP_MSC_CAPACITY    8
#endif

/* Currently allowed capacity percentage is over 10% */
#define MPP_CAPA_OVER_THRESHOLD 1.1

#ifndef MPP_G2D_SRC_SCALED_WEIGHT
#define MPP_G2D_SRC_SCALED_WEIGHT   1.125
#endif

#ifndef MPP_G2D_DST_ROT_WEIGHT
#define MPP_G2D_DST_ROT_WEIGHT  2.0
#endif

#define MPP_DUMP_PATH  "/data/vendor/log/hwc/output.dat"

using namespace android;

enum {
    eMPPSaveCapability            =     1ULL << 0,
    eMPPStrideCrop                =     1ULL << 1,
    eMPPUnsupportedRotation       =     1ULL << 2,
    eMPPHWBusy                    =     1ULL << 3,
    eMPPExeedSrcCropMax           =     1ULL << 4,
    eMPPUnsupportedColorTransform =     1ULL << 5,
    eMPPUnsupportedBlending       =     1ULL << 6,
    eMPPUnsupportedFormat         =     1ULL << 7,
    eMPPNotAlignedDstSize         =     1ULL << 8,
    eMPPNotAlignedSrcCropPosition =     1ULL << 9,
    eMPPNotAlignedHStride         =     1ULL << 10,
    eMPPNotAlignedVStride         =     1ULL << 11,
    eMPPExceedHStrideMaximum      =     1ULL << 12,
    eMPPExceedVStrideMaximum      =     1ULL << 13,
    eMPPExeedMaxDownScale         =     1ULL << 14,
    eMPPExeedMaxDstWidth          =     1ULL << 15,
    eMPPExeedMaxDstHeight         =     1ULL << 16,
    eMPPExeedMinSrcWidth          =     1ULL << 17,
    eMPPExeedMinSrcHeight         =     1ULL << 18,
    eMPPExeedMaxUpScale           =     1ULL << 19,
    eMPPExeedSrcWCropMax          =     1ULL << 20,
    eMPPExeedSrcHCropMax          =     1ULL << 21,
    eMPPExeedSrcWCropMin          =     1ULL << 22,
    eMPPExeedSrcHCropMin          =     1ULL << 23,
    eMPPNotAlignedCrop            =     1ULL << 24,
    eMPPNotAlignedOffset          =     1ULL << 25,
    eMPPExeedMinDstWidth          =     1ULL << 26,
    eMPPExeedMinDstHeight         =     1ULL << 27,
    eMPPUnsupportedCompression    =     1ULL << 28,
    eMPPUnsupportedCSC            =     1ULL << 29,
    eMPPUnsupportedDIMLayer       =     1ULL << 30,
    eMPPUnsupportedDRM            =     1ULL << 31,
    eMPPUnsupportedDynamicMeta    =     1ULL << 32,
    eMPPSatisfiedRestriction      =     1ULL << 33,
    eMPPExeedHWResource           =     1ULL << 34,
};

enum {
    MPP_TYPE_NONE,
    MPP_TYPE_OTF,
    MPP_TYPE_M2M
};

enum {
    MPP_ASSIGN_STATE_FREE       =     0x00000000,
    MPP_ASSIGN_STATE_RESERVED   =     0x00000001,
    MPP_ASSIGN_STATE_ASSIGNED   =     0x00000002,
};

enum {
    MPP_HW_STATE_IDLE,
    MPP_HW_STATE_RUNNING
};

enum {
    MPP_BUFFER_NORMAL = 0,
    MPP_BUFFER_NORMAL_DRM,
    MPP_BUFFER_SECURE_DRM,
    MPP_BUFFER_DUMP,
};

enum {
    MPP_MEM_MMAP = 1,
    MPP_MEM_USERPTR,
    MPP_MEM_OVERLAY,
    MPP_MEM_DMABUF,
};

enum {
    MPP_SOURCE_COMPOSITION_TARGET,
    MPP_SOURCE_LAYER,
    MPP_SOURCE_MAX
};

/* Based on multi-resolution feature */
typedef enum {
    DST_SIZE_HD = 0,
    DST_SIZE_HD_PLUS,
    DST_SIZE_FHD,
    DST_SIZE_FHD_PLUS,
    DST_SIZE_WQHD,
    DST_SIZE_WQHD_PLUS,
    DST_SIZE_UNKNOWN,
} dst_alloc_buf_size_t;

#ifndef DEFAULT_MPP_DST_FORMAT
#define DEFAULT_MPP_DST_FORMAT HAL_PIXEL_FORMAT_RGBA_8888
#endif

/* TODO: Switch back to single-fd format, tracked in b/261356480 */
#ifndef DEFAULT_MPP_DST_YUV_FORMAT
#define DEFAULT_MPP_DST_YUV_FORMAT HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M
#endif
#ifndef DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT
#define DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M
#endif

typedef struct exynos_mpp_img_info {
    buffer_handle_t bufferHandle;
    uint32_t bufferType;
    uint32_t format;
    android_dataspace_t dataspace;
    AcrylicLayer *mppLayer;
    int acrylicAcquireFenceFd;
    int acrylicReleaseFenceFd;
} exynos_mpp_img_info_t;

typedef enum {
    PPC_SCALE_NO = 0,   /* no scale */
    PPC_SCALE_DOWN_1_4, /* x1/1.xx ~ x1/4 */
    PPC_SCALE_DOWN_4_9, /* x1/4 ~ x1/9 */
    PPC_SCALE_DOWN_9_16, /* x1/9 ~ x1/16 */
    PPC_SCALE_DOWN_16_,  /* x1/16 ~ */
    PPC_SCALE_UP_1_4,   /* x1.xx ~ x4 */
    PPC_SCALE_UP_4_,    /* x4 ~ */
    PPC_SCALE_MAX
} scaling_index_t;

typedef enum {
    PPC_FORMAT_YUV420   =   0,
    PPC_FORMAT_YUV422,
    PPC_FORMAT_RGB32,
    PPC_FORMAT_SBWC,
    PPC_FORMAT_P010,
    PPC_FORMAT_AFBC_RGB,
    PPC_FORMAT_AFBC_YUV,
    PPC_FORMAT_FORMAT_MAX
} format_index_t;

typedef enum {
    PPC_ROT_NO   =   0,
    PPC_ROT,
    PPC_ROT_MAX
} rot_index_t;

typedef struct ppc_list_for_scaling {
    float ppcList[PPC_SCALE_MAX];
} ppc_list_for_scaling_t;

typedef std::map<uint32_t, ppc_list_for_scaling> ppc_table;

typedef struct dstMetaInfo {
    uint16_t minLuminance = 0;
    uint16_t maxLuminance = 0;
} dstMetaInfo_t;

enum
{
    NODE_NONE,
    NODE_SRC,
    NODE_DST
}; /* nodeType */

enum
{
    HAL_TRANSFORM_NONE = 0
};

enum
{
    HAL_PIXEL_FORMAT_NONE = 0
};

#define YUV_CHROMA_H_SUBSAMPLE  static_cast<uint32_t>(2) // Horizontal
#define YUV_CHROMA_V_SUBSAMPLE  static_cast<uint32_t>(2) // Vertical
#define RESTRICTION_CNT_MAX 1024

typedef enum restriction_classification {
    RESTRICTION_RGB =   0,
    RESTRICTION_YUV,
    RESTRICTION_MAX
} restriction_classification_t;

typedef struct restriction_key
{
    mpp_phycal_type_t hwType; /* MPP_DPP_VG, MPP_DPP_VGFS, ... */
    uint32_t nodeType; /* src or dst */
    uint32_t format; /* HAL format */
    uint32_t reserved;
} restriction_key_t;

typedef struct restriction_size
{
    static constexpr size_t kNumofRestriction = 16;
    union {
        std::array<uint32_t, kNumofRestriction> mData;
        struct {
            uint32_t maxDownScale;
            uint32_t maxUpScale;
            uint32_t maxFullWidth;
            uint32_t maxFullHeight;
            uint32_t minFullWidth;
            uint32_t minFullHeight;
            uint32_t fullWidthAlign;
            uint32_t fullHeightAlign;
            uint32_t maxCropWidth;
            uint32_t maxCropHeight;
            uint32_t minCropWidth;
            uint32_t minCropHeight;
            uint32_t cropXAlign;
            uint32_t cropYAlign;
            uint32_t cropWidthAlign;
            uint32_t cropHeightAlign;
        };
    };

    restriction_size() = default;
    restriction_size(std::array<uint32_t, kNumofRestriction> &&rdata) : mData(rdata){};

    bool operator==(const restriction_size &rhs) const { return rhs.mData == mData; }
} restriction_size_t;

typedef struct restriction_size_element
{
    restriction_key_t key;
    restriction_size_t sizeRestriction;
} restriction_size_element_t;

typedef struct restriction_table_element
{
    uint32_t classfication_type;
    const restriction_size_element *table;
    uint32_t table_element_size;
} restriction_table_element_t;
/* */

#define FORMAT_SHIFT   10
#define ROT_SHIFT   20
#define PPC_IDX(x,y,z) (x|(y<<FORMAT_SHIFT)|(z<<ROT_SHIFT))

const std::map<uint32_t, int32_t> dataspace_standard_map =
{
    {HAL_DATASPACE_STANDARD_UNSPECIFIED,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT709,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT601_625,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT601_525,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT2020,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_BT470M,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_FILM,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_DCI_P3,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_STANDARD_ADOBE_RGB,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS}
};

const std::map<uint32_t, int32_t> dataspace_transfer_map =
{
    {HAL_DATASPACE_TRANSFER_UNSPECIFIED,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_LINEAR,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_SRGB,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_SMPTE_170M,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_GAMMA2_2,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_GAMMA2_6,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_GAMMA2_8,
        MPP_ATTR_WCG | MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_ST2084,
        MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS},

    {HAL_DATASPACE_TRANSFER_HLG,
        MPP_ATTR_HDR10 | MPP_ATTR_HDR10PLUS}
};

void dumpExynosMPPImgInfo(uint32_t type, exynos_mpp_img_info &imgInfo);

struct ExynosMPPFrameInfo
{
    uint32_t srcNum;
    exynos_image srcInfo[NUM_MPP_SRC_BUFS];
    exynos_image dstInfo[NUM_MPP_SRC_BUFS];
};

class ExynosMPPSource {
    public:
        ExynosMPPSource();
        ExynosMPPSource(uint32_t sourceType, void *source);
        ~ExynosMPPSource(){};
        void setExynosImage(const exynos_image& src_img, const exynos_image& dst_img);
        void setExynosMidImage(const exynos_image& mid_img);

        uint32_t mSourceType;
        void *mSource;
        exynos_image mSrcImg;
        exynos_image mDstImg;
        exynos_image mMidImg;

        ExynosMPP *mOtfMPP;
        ExynosMPP *mM2mMPP;

        /**
         * SRAM/HW resource info
         */
        std::unordered_map<tdm_attr_t, int32_t> mHWResourceAmount;
        uint32_t getHWResourceAmount(tdm_attr_t attr) { return mHWResourceAmount[attr]; }

        uint32_t setHWResourceAmount(tdm_attr_t attr, uint32_t amount) {
            mHWResourceAmount[attr] = amount;
            return 0;
        }

        bool mNeedPreblending = false;
};

bool exynosMPPSourceComp(const ExynosMPPSource* l, const ExynosMPPSource* r);
void dump(const restriction_size_t &restrictionSize, String8 &result);

class ExynosMPP {
private:
    class ResourceManageThread: public Thread {
        private:
            ExynosMPP *mExynosMPP;
            Condition mCondition;
            List<exynos_mpp_img_info > mFreedBuffers;
            List<int> mStateFences;

            void freeBuffers();
            bool checkStateFences();
        public:
            bool mRunning;
            Mutex mMutex;
            ResourceManageThread(ExynosMPP *exynosMPP);
            ~ResourceManageThread();
            virtual bool threadLoop();
            void addFreedBuffer(exynos_mpp_img_info freedBuffer);
            void addStateFence(int fence);
    };

public:
    ExynosResourceManager *mResourceManager;
    /**
     * Resource type
     * Ex: MPP_DPP_VGFS, MPP_DPP_VG, MPP_MSC, MPP_G2D
     */
    uint32_t mMPPType;
    uint32_t  mPhysicalType;
    uint32_t  mLogicalType;
    String8 mName;
    uint32_t mPhysicalIndex;
    uint32_t mLogicalIndex;
    uint32_t mPreAssignDisplayInfo;
    uint32_t mPreAssignDisplayList[DISPLAY_MODE_NUM];
    static int mainDisplayWidth;
    static int mainDisplayHeight;

    uint32_t mHWState;
    int mLastStateFenceFd;
    uint32_t mAssignedState;
    bool    mEnable;

    ExynosDisplay *mAssignedDisplay;

    /* Some resource can support blending feature
     * then source can be multiple layers */
    Vector <ExynosMPPSource* > mAssignedSources;
    uint32_t mMaxSrcLayerNum;

    uint32_t mPrevAssignedState;
    int32_t mPrevAssignedDisplayType;
    int32_t mReservedDisplay;

    android::sp<ResourceManageThread> mResourceManageThread;
    float mCapacity;
    float mUsedCapacity;

    union {
        struct {
            float mUsedBaseCycles;
            uint32_t mRotatedSrcCropBW;
            uint32_t mNoRotatedSrcCropBW;
        };
    };

    bool mAllocOutBufFlag;
    bool mFreeOutBufFlag;
    bool mHWBusyFlag;
    /* For reuse previous frame */
    ExynosMPPFrameInfo mPrevFrameInfo;
    struct exynos_mpp_img_info mSrcImgs[NUM_MPP_SRC_BUFS];
    struct exynos_mpp_img_info mDstImgs[NUM_MPP_DST_BUFS_DEFAULT];
    int32_t mCurrentDstBuf;
    int32_t mPrivDstBuf;
    bool mNeedCompressedTarget;
    struct restriction_size mSrcSizeRestrictions[RESTRICTION_MAX];
    struct restriction_size mDstSizeRestrictions[RESTRICTION_MAX];

    // Force Dst buffer reallocation
    dst_alloc_buf_size_t mDstAllocatedSize;

    /* For libacryl */
    Acrylic *mAcrylicHandle;

    bool mUseM2MSrcFence;
    /* MPP's attribute bit (supported feature bit) */
    uint64_t    mAttr;

    uint32_t mAssignOrder;
    uint32_t mAXIPortId;
    uint32_t mHWBlockId;

    bool mNeedSolidColorLayer;

    ExynosMPP(ExynosResourceManager* resourceManager,
            uint32_t physicalType, uint32_t logicalType, const char *name,
            uint32_t physicalIndex, uint32_t logicalIndex, uint32_t preAssignInfo);
    virtual ~ExynosMPP();

    int32_t allocOutBuf(uint32_t w, uint32_t h, uint32_t format, uint64_t usage, uint32_t index);
    int32_t setOutBuf(buffer_handle_t outbuf, int32_t fence);
    int32_t freeOutBuf(exynos_mpp_img_info dst);
    int32_t doPostProcessing(struct exynos_image &src, struct exynos_image &dst);
    int32_t doPostProcessing(uint32_t totalImags, uint32_t imageIndex, struct exynos_image &src, struct exynos_image &dst);
    int32_t setupRestriction();
    int32_t getSrcReleaseFence(uint32_t srcIndex);
    int32_t resetSrcReleaseFence();
    int32_t getDstImageInfo(exynos_image *img);
    int32_t setDstAcquireFence(int releaseFence);
    int32_t resetDstReleaseFence();
    int32_t requestHWStateChange(uint32_t state);
    int32_t setHWStateFence(int32_t fence);
    virtual int64_t isSupported(ExynosDisplay &display, struct exynos_image &src, struct exynos_image &dst);

    bool isDataspaceSupportedByMPP(struct exynos_image &src, struct exynos_image &dst);
    bool isSupportedHDR(struct exynos_image &src, struct exynos_image &dst);
    bool isSupportedBlend(struct exynos_image &src);
    virtual bool isSupportedTransform(struct exynos_image &src);
    bool isSupportedCapability(ExynosDisplay &display, struct exynos_image &src);
    bool isSupportedDRM(struct exynos_image &src);
    virtual bool isSupportedHStrideCrop(struct exynos_image &src);
    bool checkDownscaleCap(const float resolution, const float displayRatio_V) const;
    virtual bool checkSpecificRestriction(const uint32_t __unused refreshRate,
                                          const struct exynos_image __unused &src,
                                          const struct exynos_image __unused &dst) {
        return false;
    }
    virtual uint32_t getDownscaleRestriction(const struct exynos_image &src,
                                             const struct exynos_image &dst) const;
    virtual uint32_t getMaxDownscale(const ExynosDisplay &display, const struct exynos_image &src,
                                     const struct exynos_image &dst) const;
    virtual uint32_t getMaxUpscale(const struct exynos_image &src,
                                   const struct exynos_image &dst) const;
    uint32_t getSrcMaxWidth(struct exynos_image &src);
    uint32_t getSrcMaxHeight(struct exynos_image &src);
    uint32_t getSrcMinWidth(struct exynos_image &src);
    uint32_t getSrcMinWidth(uint32_t idx);
    uint32_t getSrcMinHeight(struct exynos_image &src);
    uint32_t getSrcMinHeight(uint32_t idx);
    uint32_t getSrcWidthAlign(struct exynos_image &src);
    uint32_t getSrcHeightAlign(struct exynos_image &src);
    uint32_t getSrcMaxCropWidth(struct exynos_image &src);
    uint32_t getSrcMaxCropHeight(struct exynos_image &src);
    virtual uint32_t getSrcMaxCropSize(struct exynos_image &src);
    uint32_t getSrcMinCropWidth(struct exynos_image &src);
    uint32_t getSrcMinCropHeight(struct exynos_image &src);
    virtual uint32_t getSrcXOffsetAlign(struct exynos_image &src);
    uint32_t getSrcXOffsetAlign(uint32_t idx);
    uint32_t getSrcYOffsetAlign(struct exynos_image &src);
    uint32_t getSrcYOffsetAlign(uint32_t idx);
    uint32_t getSrcCropWidthAlign(const struct exynos_image &src) const;
    uint32_t getSrcCropWidthAlign(uint32_t idx) const;
    uint32_t getSrcCropHeightAlign(const struct exynos_image &src) const;
    uint32_t getSrcCropHeightAlign(uint32_t idx) const;
    virtual bool isSrcFormatSupported(struct exynos_image &src);
    virtual bool isDimLayerSupported();
    int32_t isSupportThis(uint32_t mSupportAttr);

    uint32_t getDstMaxWidth(struct exynos_image &dst);
    uint32_t getDstMaxHeight(struct exynos_image &dst);
    uint32_t getDstMinWidth(struct exynos_image &dst);
    uint32_t getDstMinHeight(struct exynos_image &dst);
    virtual uint32_t getDstWidthAlign(const struct exynos_image &dst) const;
    uint32_t getDstHeightAlign(const struct exynos_image &dst) const;
    uint32_t getDstXOffsetAlign(struct exynos_image &dst);
    uint32_t getDstYOffsetAlign(struct exynos_image &dst);
    uint32_t getOutBufAlign();
    virtual bool isDstFormatSupported(struct exynos_image &dst);
    int32_t isSupportLayerColorTransform(
            struct exynos_image &src, struct exynos_image &dst);
    uint32_t getSrcMaxBlendingNum(struct exynos_image &src, struct exynos_image &dst);
    uint32_t getAssignedSourceNum();

    /* Based on multi-resolution support */
    void setDstAllocSize(uint32_t width, uint32_t height);
    dst_alloc_buf_size_t getDstAllocSize();
    virtual bool needPreAllocation();

    int32_t resetMPP();
    int32_t resetAssignedState();
    int32_t resetAssignedState(ExynosMPPSource *mppSource);
    int32_t reserveMPP(int32_t displayType = -1);

    bool isAssignableState(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst);
    bool isAssignable(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst,
                      float totalUsedCapacity);
    int32_t assignMPP(ExynosDisplay *display, ExynosMPPSource* mppSource);

    bool hasEnoughCapa(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst,
                       float totalUsedCapa);
    float getRequiredCapacity(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst);
    int32_t updateUsedCapacity();
    void resetUsedCapacity();
    int prioritize(int priority);

    uint32_t getMPPClockKhz() { return mClockKhz; };

    void dump(String8& result);
    uint32_t increaseDstBuffIndex();
    bool canSkipProcessing();

    virtual bool isSupportedCompression(struct exynos_image &src);

    void closeFences();

    void reloadResourceForHWFC();
    void setTargetDisplayLuminance(uint16_t min, uint16_t max);
    void setTargetDisplayDevice(int device);

    virtual bool checkRotationCondition(struct exynos_image &src);
    void updateAttr();
    void updatePreassignedDisplay(uint32_t fromDisplayBit, uint32_t toDisplayBit);
    dstMetaInfo getDstMetaInfo(android_dataspace_t dstDataspace);
    float getAssignedCapacity();

    void setPPC(float ppc) { mPPC = ppc; };
    void setClockKhz(uint32_t clock) { mClockKhz = clock; };

    virtual void initTDMInfo(uint32_t hwBlockIndex, uint32_t axiPortIndex) {
        mHWBlockId = hwBlockIndex;
        mAXIPortId = axiPortIndex;
    }
    virtual uint32_t getHWBlockId() { return mHWBlockId; }
    virtual uint32_t getAXIPortId() { return mAXIPortId; }

protected:
    uint32_t getBufferType(uint64_t usage);
    uint32_t getBufferType(const buffer_handle_t handle);
    uint64_t getBufferUsage(uint64_t usage);
    bool needCompressDstBuf() const;
    bool needDstBufRealloc(struct exynos_image &dst, uint32_t index);
    bool canUsePrevFrame();
    int32_t setupDst(exynos_mpp_img_info *dstImgInfo);
    virtual int32_t doPostProcessingInternal();
    virtual int32_t setupLayer(exynos_mpp_img_info *srcImgInfo,
            struct exynos_image &src, struct exynos_image &dst);
    virtual int32_t setColorConversionInfo() { return NO_ERROR; };

    uint32_t getRestrictionClassification(const struct exynos_image &img) const;

    /*
     * getPPC for src, dst referencing mppSources in mAssignedSources and
     * assignCheckSrc, assignCheckDst that are likely to be added to the mAssignedSources
     */
    float getPPC(const struct exynos_image &src, const struct exynos_image &dst,
            const struct exynos_image &criteria,
            const struct exynos_image *assignCheckSrc = NULL,
            const struct exynos_image *assignCheckDst = NULL);
    float getPPC() { return mPPC; };

    /* format and rotation index are defined by indexImage */
    void getPPCIndex(const struct exynos_image &indexImage,
            const struct exynos_image &refImage,
            uint32_t &formatIndex, uint32_t &rotIndex, uint32_t &scaleIndex,
            const struct exynos_image &criteria);

    float getRequiredBaseCycles(struct exynos_image &src, struct exynos_image &dst);
    bool addCapacity(ExynosMPPSource* mppSource);
    bool removeCapacity(ExynosMPPSource* mppSource);
    /*
     * This should be called by isCSCSupportedByMPP()
     * This function checks additional restriction for color space conversion
     */
    virtual bool checkCSCRestriction(struct exynos_image &src, struct exynos_image &dst);

    /*
     * Check additional conditions those have a capacity exception.
     */
    virtual bool isCapacityExceptionCondition(float totalUsedCapacity, float requiredCapacity,
                                              struct exynos_image &src);

    uint32_t mClockKhz = 0;
    float mPPC = 0;
};

#endif //_EXYNOSMPP_H