1. Detect and account the number of secure RGB layers present. 2. Mark secure RGB layers for MDP comp in cache based stratergy. 3. If full MDP comp and partial MDP comp fails, Mark secure RGB layers for MDP composition. 4. In partial MDP comp reject load based composition, if secure layer is present to avoid GPU composition. 5. Disable idlefallback feature if secure RGB layer is present to avoid GPU composition. Change-Id: Idb4c4f09b081ec20240a2602aa3f20332fa49ad6
360 lines
14 KiB
C++
360 lines
14 KiB
C++
/*
|
|
* Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
|
|
*
|
|
* Not a Contribution, Apache license notifications and license are retained
|
|
* for attribution purposes only.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef HWC_MDP_COMP
|
|
#define HWC_MDP_COMP
|
|
|
|
#include <hwc_utils.h>
|
|
#include <idle_invalidator.h>
|
|
#include <cutils/properties.h>
|
|
#include <overlay.h>
|
|
|
|
#define DEFAULT_IDLE_TIME 70
|
|
#define MAX_PIPES_PER_MIXER 4
|
|
|
|
namespace overlay {
|
|
class Rotator;
|
|
};
|
|
|
|
namespace qhwc {
|
|
namespace ovutils = overlay::utils;
|
|
|
|
class MDPComp {
|
|
public:
|
|
explicit MDPComp(int);
|
|
virtual ~MDPComp(){};
|
|
/*sets up mdp comp for the current frame */
|
|
int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* draw */
|
|
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
|
|
//Reset values
|
|
void reset();
|
|
/* dumpsys */
|
|
void dump(android::String8& buf, hwc_context_t *ctx);
|
|
bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
|
|
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
|
|
/* Handler to invoke frame redraw on Idle Timer expiry */
|
|
static void timeout_handler(void *udata);
|
|
/* Initialize MDP comp*/
|
|
static bool init(hwc_context_t *ctx);
|
|
static void resetIdleFallBack() { sIdleFallBack = false; }
|
|
static bool isIdleFallback() { return sIdleFallBack; }
|
|
static void dynamicDebug(bool enable){ sDebugLogs = enable; }
|
|
|
|
protected:
|
|
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
|
|
|
|
enum ePipeType {
|
|
MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
|
|
MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
|
|
MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
|
|
MDPCOMP_OV_ANY,
|
|
};
|
|
|
|
//Simulation flags
|
|
enum {
|
|
MDPCOMP_AVOID_FULL_MDP = 0x001,
|
|
MDPCOMP_AVOID_CACHE_MDP = 0x002,
|
|
MDPCOMP_AVOID_LOAD_MDP = 0x004,
|
|
MDPCOMP_AVOID_VIDEO_ONLY = 0x008,
|
|
MDPCOMP_AVOID_MDP_ONLY_LAYERS = 0x010,
|
|
};
|
|
|
|
/* mdp pipe data */
|
|
struct MdpPipeInfo {
|
|
int zOrder;
|
|
virtual ~MdpPipeInfo(){};
|
|
};
|
|
|
|
struct MdpYUVPipeInfo : public MdpPipeInfo{
|
|
ovutils::eDest lIndex;
|
|
ovutils::eDest rIndex;
|
|
virtual ~MdpYUVPipeInfo(){};
|
|
};
|
|
|
|
/* per layer data */
|
|
struct PipeLayerPair {
|
|
MdpPipeInfo *pipeInfo;
|
|
overlay::Rotator* rot;
|
|
int listIndex;
|
|
};
|
|
|
|
/* per frame data */
|
|
struct FrameInfo {
|
|
/* maps layer list to mdp list */
|
|
int layerCount;
|
|
int layerToMDP[MAX_NUM_APP_LAYERS];
|
|
|
|
/* maps mdp list to layer list */
|
|
int mdpCount;
|
|
struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
|
|
|
|
/* layer composing on FB? */
|
|
int fbCount;
|
|
bool isFBComposed[MAX_NUM_APP_LAYERS];
|
|
/* layers lying outside ROI. Will
|
|
* be dropped off from the composition */
|
|
int dropCount;
|
|
bool drop[MAX_NUM_APP_LAYERS];
|
|
|
|
bool needsRedraw;
|
|
int fbZ;
|
|
|
|
/* c'tor */
|
|
FrameInfo();
|
|
/* clear old frame data */
|
|
void reset(const int& numLayers);
|
|
void map();
|
|
};
|
|
|
|
/* cached data */
|
|
struct LayerCache {
|
|
int layerCount;
|
|
buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
|
|
bool isFBComposed[MAX_NUM_APP_LAYERS];
|
|
bool drop[MAX_NUM_APP_LAYERS];
|
|
|
|
/* c'tor */
|
|
LayerCache();
|
|
/* clear caching info*/
|
|
void reset();
|
|
void cacheAll(hwc_display_contents_1_t* list);
|
|
void updateCounts(const FrameInfo&);
|
|
bool isSameFrame(const FrameInfo& curFrame,
|
|
hwc_display_contents_1_t* list);
|
|
};
|
|
|
|
/* allocates pipe from pipe book */
|
|
virtual bool allocLayerPipes(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list) = 0;
|
|
/* configures MPD pipes */
|
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& pipeLayerPair) = 0;
|
|
/* Increments mdpCount if 4k2k yuv layer split is enabled.
|
|
* updates framebuffer z order if fb lies above source-split layer */
|
|
virtual void adjustForSourceSplit(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list) = 0;
|
|
/* configures 4kx2k yuv layer*/
|
|
virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& PipeLayerPair) = 0;
|
|
/* generates ROI based on the modified area of the frame */
|
|
virtual void generateROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list) = 0;
|
|
/* validates the ROI generated for fallback conditions */
|
|
virtual bool validateAndApplyROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list) = 0;
|
|
/* Trims fbRect calculated against ROI generated */
|
|
virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) = 0;
|
|
|
|
/* set/reset flags for MDPComp */
|
|
void setMDPCompLayerFlags(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
void setRedraw(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* checks for conditions where mdpcomp is not possible */
|
|
bool isFrameDoable(hwc_context_t *ctx);
|
|
/* checks for conditions where RGB layers cannot be bypassed */
|
|
bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* checks if full MDP comp can be done */
|
|
bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* Full MDP Composition with Peripheral Tiny Overlap Removal */
|
|
bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list);
|
|
/* check if we can use layer cache to do at least partial MDP comp */
|
|
bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* Partial MDP comp that uses caching to save power as primary goal */
|
|
bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* Partial MDP comp that balances the load between MDP and GPU such that
|
|
* MDP is loaded to the max of its capacity. The lower z order layers are
|
|
* fed to MDP, whereas the upper ones to GPU, because the upper ones have
|
|
* lower number of pixels and can reduce GPU processing time */
|
|
bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
/* Checks if its worth doing load based partial comp */
|
|
bool isLoadBasedCompDoable(hwc_context_t *ctx);
|
|
/* checks for conditions where only video can be bypassed */
|
|
bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
|
|
bool secureOnly);
|
|
/* checks for conditions where only secure RGB and video can be bypassed */
|
|
bool tryMDPOnlyLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
bool mdpOnlyLayersComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
|
|
bool secureOnly);
|
|
/* checks for conditions where YUV layers cannot be bypassed */
|
|
bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
|
|
/* checks for conditions where Secure RGB layers cannot be bypassed */
|
|
bool isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
|
|
/* checks if MDP/MDSS can process current list w.r.to HW limitations
|
|
* All peculiar HW limitations should go here */
|
|
bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
|
/* Is debug enabled */
|
|
static bool isDebug() { return sDebugLogs ? true : false; };
|
|
/* Is feature enabled */
|
|
static bool isEnabled() { return sEnabled; };
|
|
/* checks for mdp comp dimension limitation */
|
|
bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
|
|
/* tracks non updating layers*/
|
|
void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
|
/* optimize layers for mdp comp*/
|
|
bool markLayersForCaching(hwc_context_t* ctx,
|
|
hwc_display_contents_1_t* list);
|
|
int getBatch(hwc_display_contents_1_t* list,
|
|
int& maxBatchStart, int& maxBatchEnd,
|
|
int& maxBatchCount);
|
|
bool canPushBatchToTop(const hwc_display_contents_1_t* list,
|
|
int fromIndex, int toIndex);
|
|
bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
|
|
int fromIndex, int toIndex, int targetLayerIndex);
|
|
|
|
/* updates cache map with YUV info */
|
|
void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
|
|
bool secureOnly);
|
|
/* updates cache map with secure RGB info */
|
|
void updateSecureRGB(hwc_context_t* ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* Validates if the GPU/MDP layer split chosen by a strategy is supported
|
|
* by MDP.
|
|
* Sets up MDP comp data structures to reflect covnversion from layers to
|
|
* overlay pipes.
|
|
* Configures overlay.
|
|
* Configures if GPU should redraw.
|
|
*/
|
|
bool postHeuristicsHandling(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
void reset(hwc_context_t *ctx);
|
|
bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
|
|
bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
|
hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* checks for conditions to enable partial udpate */
|
|
bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
|
|
|
int mDpy;
|
|
static bool sEnabled;
|
|
static bool sEnableMixedMode;
|
|
static int sSimulationFlags;
|
|
static bool sDebugLogs;
|
|
static bool sIdleFallBack;
|
|
/* Handles the timeout event from kernel, if the value is set to true */
|
|
static bool sHandleTimeout;
|
|
static int sMaxPipesPerMixer;
|
|
static bool sSrcSplitEnabled;
|
|
static IdleInvalidator *idleInvalidator;
|
|
struct FrameInfo mCurrentFrame;
|
|
struct LayerCache mCachedFrame;
|
|
//Enable 4kx2k yuv layer split
|
|
static bool sEnableYUVsplit;
|
|
bool mModeOn; // if prepare happened
|
|
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
|
|
};
|
|
|
|
class MDPCompNonSplit : public MDPComp {
|
|
public:
|
|
explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
|
|
virtual ~MDPCompNonSplit(){};
|
|
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
|
|
|
|
private:
|
|
struct MdpPipeInfoNonSplit : public MdpPipeInfo {
|
|
ovutils::eDest index;
|
|
virtual ~MdpPipeInfoNonSplit() {};
|
|
};
|
|
|
|
/* configure's overlay pipes for the frame */
|
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& pipeLayerPair);
|
|
|
|
/* allocates pipes to selected candidates */
|
|
virtual bool allocLayerPipes(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
|
|
/* Increments mdpCount if 4k2k yuv layer split is enabled.
|
|
* updates framebuffer z order if fb lies above source-split layer */
|
|
virtual void adjustForSourceSplit(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
|
|
/* configures 4kx2k yuv layer to 2 VG pipes*/
|
|
virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& PipeLayerPair);
|
|
/* generates ROI based on the modified area of the frame */
|
|
virtual void generateROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* validates the ROI generated for fallback conditions */
|
|
virtual bool validateAndApplyROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* Trims fbRect calculated against ROI generated */
|
|
virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
|
|
};
|
|
|
|
class MDPCompSplit : public MDPComp {
|
|
public:
|
|
explicit MDPCompSplit(int dpy):MDPComp(dpy){};
|
|
virtual ~MDPCompSplit(){};
|
|
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
|
|
|
|
protected:
|
|
struct MdpPipeInfoSplit : public MdpPipeInfo {
|
|
ovutils::eDest lIndex;
|
|
ovutils::eDest rIndex;
|
|
virtual ~MdpPipeInfoSplit() {};
|
|
};
|
|
|
|
virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
|
MdpPipeInfoSplit& pipe_info);
|
|
|
|
/* configure's overlay pipes for the frame */
|
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& pipeLayerPair);
|
|
|
|
/* allocates pipes to selected candidates */
|
|
virtual bool allocLayerPipes(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
private:
|
|
/* Increments mdpCount if 4k2k yuv layer split is enabled.
|
|
* updates framebuffer z order if fb lies above source-split layer */
|
|
virtual void adjustForSourceSplit(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
|
|
/* configures 4kx2k yuv layer*/
|
|
virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& PipeLayerPair);
|
|
/* generates ROI based on the modified area of the frame */
|
|
virtual void generateROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* validates the ROI generated for fallback conditions */
|
|
virtual bool validateAndApplyROI(hwc_context_t *ctx,
|
|
hwc_display_contents_1_t* list);
|
|
/* Trims fbRect calculated against ROI generated */
|
|
virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
|
|
};
|
|
|
|
class MDPCompSrcSplit : public MDPCompSplit {
|
|
public:
|
|
explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
|
|
virtual ~MDPCompSrcSplit(){};
|
|
private:
|
|
virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
|
MdpPipeInfoSplit& pipe_info);
|
|
|
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|
PipeLayerPair& pipeLayerPair);
|
|
};
|
|
|
|
}; //namespace
|
|
#endif
|