diff options
-rw-r--r-- | common.mk | 1 | ||||
-rw-r--r-- | libhwcomposer/hwc_utils.cpp | 7 | ||||
-rw-r--r-- | liboverlay/overlay.cpp | 88 | ||||
-rw-r--r-- | liboverlay/overlay.h | 23 | ||||
-rw-r--r-- | liboverlay/overlayUtils.cpp | 52 | ||||
-rw-r--r-- | liboverlay/overlayUtils.h | 79 | ||||
-rw-r--r-- | libqdutils/mdp_version.cpp | 25 | ||||
-rw-r--r-- | libqdutils/mdp_version.h | 10 |
8 files changed, 154 insertions, 131 deletions
@@ -27,6 +27,7 @@ endif ifeq ($(call is-board-platform-in-list, msm8974 msm8226), true) common_flags += -DVENUS_COLOR_FORMAT + common_flags += -DMDSS_TARGET endif common_deps := diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index 74ab9e04..11f7dc57 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -70,12 +70,13 @@ static void openFramebufferDevice(hwc_context_t *ctx) void initContext(hwc_context_t *ctx) { openFramebufferDevice(ctx); - overlay::Overlay::initOverlay(); - ctx->mOverlay = overlay::Overlay::getInstance(); - ctx->mRotMgr = new RotMgr(); ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion(); ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay(); ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType(); + overlay::Overlay::initOverlay(); + ctx->mOverlay = overlay::Overlay::getInstance(); + ctx->mRotMgr = new RotMgr(); + //Is created and destroyed only once for primary //For external it could get created and destroyed multiple times depending //on what external we connect to. diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp index 5341c905..d22aedb1 100644 --- a/liboverlay/overlay.cpp +++ b/liboverlay/overlay.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. +* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -37,12 +37,7 @@ namespace overlay { using namespace utils; Overlay::Overlay() { - int numPipes = 0; - int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); - if (mdpVersion > qdutils::MDP_V3_1) numPipes = 4; - if (mdpVersion >= qdutils::MDSS_V5) numPipes = 8; - - PipeBook::NUM_PIPES = numPipes; + PipeBook::NUM_PIPES = qdutils::MDPVersion::getInstance().getTotalPipes(); for(int i = 0; i < PipeBook::NUM_PIPES; i++) { mPipeBook[i].init(); } @@ -74,8 +69,8 @@ void Overlay::configDone() { //fds if(mPipeBook[i].valid()) { char str[32]; - sprintf(str, "Unset pipe=%s dpy=%d; ", getDestStr((eDest)i), - mPipeBook[i].mDisplay); + sprintf(str, "Unset pipe=%s dpy=%d; ", + PipeBook::getDestStr((eDest)i), mPipeBook[i].mDisplay); strncat(mDumpStr, str, strlen(str)); } mPipeBook[i].destroy(); @@ -90,7 +85,7 @@ eDest Overlay::nextPipe(eMdpPipeType type, int dpy) { for(int i = 0; i < PipeBook::NUM_PIPES; i++) { //Match requested pipe type - if(type == OV_MDP_PIPE_ANY || type == getPipeType((eDest)i)) { + if(type == OV_MDP_PIPE_ANY || type == PipeBook::getPipeType((eDest)i)) { //If the pipe is not allocated to any display or used by the //requesting display already in previous round. if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED || @@ -111,7 +106,8 @@ eDest Overlay::nextPipe(eMdpPipeType type, int dpy) { if(not mPipeBook[index].valid()) { mPipeBook[index].mPipe = new GenericPipe(dpy); char str[32]; - snprintf(str, 32, "Set pipe=%s dpy=%d; ", getDestStr(dest), dpy); + snprintf(str, 32, "Set pipe=%s dpy=%d; ", + PipeBook::getDestStr(dest), dpy); strncat(mDumpStr, str, strlen(str)); } } else { @@ -183,13 +179,13 @@ void Overlay::setSource(const utils::PipeArgs args, validate(index); PipeArgs newArgs(args); - if(dest == OV_VG0 || dest == OV_VG1) { + if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_VG) { setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE); } else { clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE); } - if(dest == OV_DMA0 || dest == OV_DMA1) { + if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_DMA) { setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA); } else { clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA); @@ -205,10 +201,68 @@ Overlay* Overlay::getInstance() { return sInstance; } -void Overlay::initOverlay() { - if(utils::initOverlay() == -1) { - ALOGE("%s failed", __FUNCTION__); +// Clears any VG pipes allocated to the fb devices +// Generates a LUT for pipe types. +int Overlay::initOverlay() { + int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); + int numPipesXType[OV_MDP_PIPE_ANY] = {0}; + numPipesXType[OV_MDP_PIPE_RGB] = + qdutils::MDPVersion::getInstance().getRGBPipes(); + numPipesXType[OV_MDP_PIPE_VG] = + qdutils::MDPVersion::getInstance().getVGPipes(); + numPipesXType[OV_MDP_PIPE_DMA] = + qdutils::MDPVersion::getInstance().getDMAPipes(); + + int index = 0; + for(int X = 0; X < (int)OV_MDP_PIPE_ANY; X++) { //iterate over types + for(int j = 0; j < numPipesXType[X]; j++) { //iterate over num + PipeBook::pipeTypeLUT[index] = (utils::eMdpPipeType)X; + index++; + } + } + + if (mdpVersion < qdutils::MDSS_V5) { + msmfb_mixer_info_req req; + mdp_mixer_info *minfo = NULL; + char name[64]; + int fd = -1; + for(int i = 0; i < NUM_FB_DEVICES; i++) { + snprintf(name, 64, FB_DEVICE_TEMPLATE, i); + ALOGD("initoverlay:: opening the device:: %s", name); + fd = ::open(name, O_RDWR, 0); + if(fd < 0) { + ALOGE("cannot open framebuffer(%d)", i); + return -1; + } + //Get the mixer configuration */ + req.mixer_num = i; + if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) { + ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed"); + close(fd); + return -1; + } + minfo = req.info; + for (int j = 0; j < req.cnt; j++) { + ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum, + minfo->z_order); + // except the RGB base layer with z_order of -1, clear any + // other pipes connected to mixer. + if((minfo->z_order) != -1) { + int index = minfo->pndx; + ALOGD("Unset overlay with index: %d at mixer %d", index, i); + if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) { + ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed"); + close(fd); + return -1; + } + } + minfo++; + } + close(fd); + fd = -1; + } } + return 0; } void Overlay::dump() const { @@ -254,5 +308,7 @@ int Overlay::PipeBook::NUM_PIPES = 0; int Overlay::PipeBook::sPipeUsageBitmap = 0; int Overlay::PipeBook::sLastUsageBitmap = 0; int Overlay::PipeBook::sAllocatedBitmap = 0; +utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] = + {utils::OV_MDP_PIPE_ANY}; }; // namespace overlay diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h index 0f15baa5..aa12b76a 100644 --- a/liboverlay/overlay.h +++ b/liboverlay/overlay.h @@ -68,7 +68,7 @@ public: bool queueBuffer(int fd, uint32_t offset, utils::eDest dest); /* Closes open pipes, called during startup */ - static void initOverlay(); + static int initOverlay(); /* Returns the singleton instance of overlay */ static Overlay* getInstance(); /* Returns available ("unallocated") pipes for a display */ @@ -116,7 +116,12 @@ private: static bool isAllocated(int index); static bool isNotAllocated(int index); + static utils::eMdpPipeType getPipeType(utils::eDest dest); + static const char* getDestStr(utils::eDest dest); + static int NUM_PIPES; + static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX]; + private: //usage tracks if a successful commit happened. So a pipe could be @@ -146,7 +151,7 @@ inline void Overlay::validate(int index) { OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \ "%s, Index out of bounds: %d", __FUNCTION__, index); OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s", - utils::getDestStr((utils::eDest)index)); + PipeBook::getDestStr((utils::eDest)index)); } inline int Overlay::availablePipes(int dpy) { @@ -212,6 +217,20 @@ inline bool Overlay::PipeBook::isNotAllocated(int index) { return !isAllocated(index); } +inline utils::eMdpPipeType Overlay::PipeBook::getPipeType(utils::eDest dest) { + return pipeTypeLUT[(int)dest]; +} + +inline const char* Overlay::PipeBook::getDestStr(utils::eDest dest) { + switch(getPipeType(dest)) { + case utils::OV_MDP_PIPE_RGB: return "RGB"; + case utils::OV_MDP_PIPE_VG: return "VG"; + case utils::OV_MDP_PIPE_DMA: return "DMA"; + default: return "Invalid"; + } + return "Invalid"; +} + }; // overlay #endif // OVERLAY_H diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp index 907597e8..4cc7a371 100644 --- a/liboverlay/overlayUtils.cpp +++ b/liboverlay/overlayUtils.cpp @@ -84,58 +84,6 @@ const char* const Res::barrierFile = namespace utils { -//------------------ defines ----------------------------- -#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u" -#define NUM_FB_DEVICES 3 - -//-------------------------------------------------------- - -/* clears any VG pipes allocated to the fb devices */ -int initOverlay() { - int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); - if (mdpVersion < qdutils::MDSS_V5) { - msmfb_mixer_info_req req; - mdp_mixer_info *minfo = NULL; - char name[64]; - int fd = -1; - for(int i = 0; i < NUM_FB_DEVICES; i++) { - snprintf(name, 64, FB_DEVICE_TEMPLATE, i); - ALOGD("initoverlay:: opening the device:: %s", name); - fd = ::open(name, O_RDWR, 0); - if(fd < 0) { - ALOGE("cannot open framebuffer(%d)", i); - return -1; - } - //Get the mixer configuration */ - req.mixer_num = i; - if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) { - ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed"); - close(fd); - return -1; - } - minfo = req.info; - for (int j = 0; j < req.cnt; j++) { - ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum, - minfo->z_order); - // except the RGB base layer with z_order of -1, clear any - // other pipes connected to mixer. - if((minfo->z_order) != -1) { - int index = minfo->pndx; - ALOGD("Unset overlay with index: %d at mixer %d", index, i); - if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) { - ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed"); - close(fd); - return -1; - } - } - minfo++; - } - close(fd); - fd = -1; - } - } - return 0; -} //-------------------------------------------------------- //Refer to graphics.h, gralloc_priv.h, msm_mdp.h diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index 555232a5..5eb0e1e5 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -77,6 +77,9 @@ #define MDP_OV_PIPE_FORCE_DMA 0x4000 #endif +#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u" +#define NUM_FB_DEVICES 3 + namespace overlay { // fwd @@ -127,11 +130,6 @@ enum { INPUT_3D_MASK = 0xFFFF0000, enum { BARRIER_LAND = 1, BARRIER_PORT = 2 }; -/* if SurfaceFlinger process gets killed in bypass mode, In initOverlay() - * close all the pipes if it is opened after reboot. - */ -int initOverlay(void); - inline uint32_t format3D(uint32_t x) { return x & 0xFF000; } inline uint32_t format3DOutput(uint32_t x) { return (x & 0xF000) >> SHIFT_OUT_3D; } @@ -274,24 +272,27 @@ enum eZorder { }; enum eMdpPipeType { - OV_MDP_PIPE_RGB, + OV_MDP_PIPE_RGB = 0, OV_MDP_PIPE_VG, OV_MDP_PIPE_DMA, OV_MDP_PIPE_ANY, //Any }; -/* Used to identify destination pipes - */ +// Identify destination pipes +// TODO Names useless, replace with int and change all interfaces enum eDest { - OV_VG0 = 0, - OV_RGB0, - OV_VG1, - OV_RGB1, - OV_VG2, - OV_RGB2, - OV_DMA0, - OV_DMA1, + OV_P0 = 0, + OV_P1, + OV_P2, + OV_P3, + OV_P4, + OV_P5, + OV_P6, + OV_P7, + OV_P8, + OV_P9, OV_INVALID, + OV_MAX = OV_INVALID, }; /* Used when a buffer is split over 2 pipes and sent to display */ @@ -350,6 +351,12 @@ struct PipeArgs { eRotFlags rotFlags; }; +// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time +// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define +enum { HW_OV_MAGNIFICATION_LIMIT = 20, + HW_OV_MINIFICATION_LIMIT = 8 +}; + inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) { f = static_cast<eMdpFlags>(setBit(f, v)); } @@ -390,12 +397,6 @@ int getDownscaleFactor(const int& src_w, const int& src_h, int getMdpOrient(eTransform rotation); const char* getFormatString(int format); -// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time -// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define -enum { HW_OV_MAGNIFICATION_LIMIT = 20, - HW_OV_MINIFICATION_LIMIT = 8 -}; - template <class T> inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); } @@ -687,40 +688,6 @@ inline void even_floor(T& value) { value--; } -inline const char* getDestStr(eDest dest) { - switch(dest) { - case OV_VG0: return "VG0"; - case OV_RGB0: return "RGB0"; - case OV_VG1: return "VG1"; - case OV_RGB1: return "RGB1"; - case OV_VG2: return "VG2"; - case OV_RGB2: return "RGB2"; - case OV_DMA0: return "DMA0"; - case OV_DMA1: return "DMA1"; - default: return "Invalid"; - } - return "Invalid"; -} - -inline eMdpPipeType getPipeType(eDest dest) { - switch(dest) { - case OV_VG0: - case OV_VG1: - case OV_VG2: - return OV_MDP_PIPE_VG; - case OV_RGB0: - case OV_RGB1: - case OV_RGB2: - return OV_MDP_PIPE_RGB; - case OV_DMA0: - case OV_DMA1: - return OV_MDP_PIPE_DMA; - default: - return OV_MDP_PIPE_ANY; - } - return OV_MDP_PIPE_ANY; -} - void preRotateSource(eTransform& tr, Whf& whf, Dim& srcCrop); void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov); void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov); diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp index 49f0927a..cd214906 100644 --- a/libqdutils/mdp_version.cpp +++ b/libqdutils/mdp_version.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,7 +28,9 @@ */ #include <cutils/log.h> #include <fcntl.h> +#include <sys/ioctl.h> #include <linux/fb.h> +#include <linux/msm_mdp.h> #include "mdp_version.h" ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion); @@ -40,6 +42,11 @@ MDPVersion::MDPVersion() int mdp_version = MDP_V_UNKNOWN; char panel_type = 0; struct fb_fix_screeninfo fb_finfo; + + mMdpRev = 0; + mRGBPipes = mVGPipes = 0; + mDMAPipes = 0; + if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) { ALOGE("FBIOGET_FSCREENINFO failed"); mdp_version = MDP_V_UNKNOWN; @@ -57,8 +64,24 @@ MDPVersion::MDPVersion() if (mdp_version < 100) mdp_version *= 10; + mRGBPipes = mVGPipes = 2; + } else if (!strncmp(fb_finfo.id, "mdssfb", 6)) { mdp_version = MDSS_V5; +#ifdef MDSS_TARGET + struct msmfb_metadata metadata; + memset(&metadata, 0 , sizeof(metadata)); + metadata.op = metadata_op_get_caps; + if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) { + ALOGE("Error retrieving MDP revision and pipes info"); + mdp_version = MDP_V_UNKNOWN; + } else { + mMdpRev = metadata.data.caps.mdp_rev; + mRGBPipes = metadata.data.caps.rgb_pipes; + mVGPipes = metadata.data.caps.vig_pipes; + mDMAPipes = metadata.data.caps.dma_pipes; + } +#endif } else { mdp_version = MDP_V_UNKNOWN; } diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h index 515d7679..98de3710 100644 --- a/libqdutils/mdp_version.h +++ b/libqdutils/mdp_version.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -72,10 +72,18 @@ public: int getMDPVersion() {return mMDPVersion;} char getPanelType() {return mPanelType;} bool hasOverlay() {return mHasOverlay;} + uint8_t getTotalPipes() { return (mRGBPipes + mVGPipes + mDMAPipes);} + uint8_t getRGBPipes() { return mRGBPipes; } + uint8_t getVGPipes() { return mVGPipes; } + uint8_t getDMAPipes() { return mDMAPipes; } private: int mMDPVersion; char mPanelType; bool mHasOverlay; + uint32_t mMdpRev; + uint8_t mRGBPipes; + uint8_t mVGPipes; + uint8_t mDMAPipes; }; }; //namespace qdutils #endif //INCLUDE_LIBQCOMUTILS_MDPVER |