Merge "gralloc: Do not map framebuffer memory unless needed"
diff --git a/common.mk b/common.mk
index 74d6032..cefe060 100644
--- a/common.mk
+++ b/common.mk
@@ -37,10 +37,9 @@
# Executed only on QCOM BSPs
ifeq ($(TARGET_USES_QCOM_BSP),true)
-# On jb_mr2- dont enable QCOM Display features
-ifneq ($(call is-platform-sdk-version-at-least,18),true)
-# This flag is used to compile out any features that depend on framework changes
+# Enable QCOM Display features
common_flags += -DQCOM_BSP
+ifneq ($(call is-platform-sdk-version-at-least,18),true)
common_flags += -DANDROID_JELLYBEAN_MR1=1
endif
endif
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 23b336c..5fd68da 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -129,10 +129,10 @@
case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888;
case HAL_PIXEL_FORMAT_RGBA_8888: return MDP_RGBA_8888;
case HAL_PIXEL_FORMAT_BGRA_8888: return MDP_BGRA_8888;
- case HAL_PIXEL_FORMAT_YCrCb_422_SP: return MDP_Y_CBCR_H2V1;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CBCR_H2V2;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CRCB_H2V1;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CRCB_H2V2;
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP: return MDP_Y_CRCB_H2V1;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CRCB_H2V2;
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CBCR_H2V1;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CBCR_H2V2;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_ADRENO;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 244e0d6..e322357 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -105,6 +105,8 @@
ctx->mFBUpdate[i]->reset();
if(ctx->mCopyBit[i])
ctx->mCopyBit[i]->reset();
+ if(ctx->mLayerRotMap[i])
+ ctx->mLayerRotMap[i]->reset();
}
}
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index a2d6405..31de9ee 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -21,7 +21,7 @@
#define HWC_COPYBIT_H
#include "hwc_utils.h"
-#define NUM_RENDER_BUFFERS 2
+#define NUM_RENDER_BUFFERS 3
namespace qhwc {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d4ce253..2103cb4 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -52,6 +52,7 @@
void MDPComp::dump(android::String8& buf)
{
+ Locker::Autolock _l(mMdpCompLock);
dumpsys_log(buf,"HWC Map for Dpy: %s \n",
mDpy ? "\"EXTERNAL\"" : "\"PRIMARY\"");
dumpsys_log(buf,"PREV_FRAME: layerCount:%2d mdpCount:%2d \
@@ -756,6 +757,9 @@
__FUNCTION__);
return 0;
}
+
+ Locker::Autolock _l(mMdpCompLock);
+
//reset old data
mCurrentFrame.reset(numLayers);
@@ -894,6 +898,8 @@
return false;
}
+ Locker::Autolock _l(mMdpCompLock);
+
/* reset Invalidator */
if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
@@ -1077,6 +1083,8 @@
return false;
}
+ Locker::Autolock _l(mMdpCompLock);
+
/* reset Invalidator */
if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 908a658..ea7c7b1 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -174,6 +174,7 @@
static IdleInvalidator *idleInvalidator;
struct FrameInfo mCurrentFrame;
struct LayerCache mCachedFrame;
+ mutable Locker mMdpCompLock;
};
class MDPCompLowRes : public MDPComp {
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 46e25dc..90038f2 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -157,7 +157,9 @@
for (uint32_t i = 0; i < MAX_DISPLAYS; i++) {
ctx->mHwcDebug[i] = new HwcDebug(i);
+ ctx->mLayerRotMap[i] = new LayerRotMap();
}
+
MDPComp::init(ctx);
ctx->vstate.enable = false;
@@ -227,6 +229,10 @@
delete ctx->mHwcDebug[i];
ctx->mHwcDebug[i] = NULL;
}
+ if(ctx->mLayerRotMap[i]) {
+ delete ctx->mLayerRotMap[i];
+ ctx->mLayerRotMap[i] = NULL;
+ }
}
@@ -620,18 +626,25 @@
}
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
- int fd) {
+ int fd) {
int ret = 0;
- struct mdp_buf_sync data;
int acquireFd[MAX_NUM_APP_LAYERS];
int count = 0;
int releaseFd = -1;
int fbFd = -1;
- memset(&data, 0, sizeof(data));
+ int rotFd = -1;
bool swapzero = false;
+ int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+
+ struct mdp_buf_sync data;
+ memset(&data, 0, sizeof(data));
+ //Until B-family supports sync for rotator
+#ifdef MDSS_TARGET
data.flags = MDP_BUF_SYNC_FLAG_WAIT;
+#endif
data.acq_fen_fd = acquireFd;
data.rel_fen_fd = &releaseFd;
+
char property[PROPERTY_VALUE_MAX];
if(property_get("debug.egl.swapinterval", property, "1") > 0) {
if(atoi(property) == 0)
@@ -641,10 +654,35 @@
if(dpy)
isExtAnimating = ctx->listStats[dpy].isDisplayAnimating;
- //Accumulate acquireFenceFds
+ //Send acquireFenceFds to rotator
+#ifdef MDSS_TARGET
+ //TODO B-family
+#else
+ //A-family
+ int rotFd = ctx->mRotMgr->getRotDevFd();
+ struct msm_rotator_buf_sync rotData;
+
+ for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
+ memset(&rotData, 0, sizeof(rotData));
+ int& acquireFenceFd =
+ ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd;
+ rotData.acq_fen_fd = acquireFenceFd;
+ rotData.session_id = ctx->mLayerRotMap[dpy]->getRot(i)->getSessId();
+ ioctl(rotFd, MSM_ROTATOR_IOCTL_BUFFER_SYNC, &rotData);
+ close(acquireFenceFd);
+ //For MDP to wait on.
+ acquireFenceFd = dup(rotData.rel_fen_fd);
+ //A buffer is free to be used by producer as soon as its copied to
+ //rotator.
+ ctx->mLayerRotMap[dpy]->getLayer(i)->releaseFenceFd =
+ rotData.rel_fen_fd;
+ }
+#endif
+
+ //Accumulate acquireFenceFds for MDP
for(uint32_t i = 0; i < list->numHwLayers; i++) {
if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
- list->hwLayers[i].acquireFenceFd != -1) {
+ list->hwLayers[i].acquireFenceFd >= 0) {
if(UNLIKELY(swapzero))
acquireFd[count++] = -1;
else
@@ -653,19 +691,20 @@
if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
if(UNLIKELY(swapzero))
acquireFd[count++] = -1;
- else if(fd != -1) {
+ else if(fd >= 0) {
//set the acquireFD from fd - which is coming from c2d
acquireFd[count++] = fd;
// Buffer sync IOCTL should be async when using c2d fence is
// used
data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
- } else if(list->hwLayers[i].acquireFenceFd != -1)
+ } else if(list->hwLayers[i].acquireFenceFd >= 0)
acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
}
}
data.acq_fen_fd_cnt = count;
fbFd = ctx->dpyAttr[dpy].fd;
+
//Waits for acquire fences, returns a release fence
if(LIKELY(!swapzero)) {
uint64_t start = systemTime();
@@ -686,9 +725,9 @@
if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
//Populate releaseFenceFds.
- if(UNLIKELY(swapzero))
+ if(UNLIKELY(swapzero)) {
list->hwLayers[i].releaseFenceFd = -1;
- else if(isExtAnimating) {
+ } else if(isExtAnimating) {
// Release all the app layer fds immediately,
// if animation is in progress.
hwc_layer_1_t const* layer = &list->hwLayers[i];
@@ -697,8 +736,10 @@
list->hwLayers[i].releaseFenceFd = dup(releaseFd);
} else
list->hwLayers[i].releaseFenceFd = -1;
- } else
+ } else if(list->hwLayers[i].releaseFenceFd < 0) {
+ //If rotator has not already populated this field.
list->hwLayers[i].releaseFenceFd = dup(releaseFd);
+ }
}
}
@@ -709,11 +750,22 @@
if (ctx->mCopyBit[dpy])
ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
+
+#ifdef MDSS_TARGET
+ //TODO When B is implemented remove #ifdefs from here
+ //The API called applies to RotMem buffers
+#else
+ //A-family
+ //Signals when MDP finishes reading rotator buffers.
+ ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd);
+#endif
+
// if external is animating, close the relaseFd
if(isExtAnimating) {
close(releaseFd);
releaseFd = -1;
}
+
if(UNLIKELY(swapzero)){
list->retireFenceFd = -1;
close(releaseFd);
@@ -950,6 +1002,7 @@
ctx->mOverlay->clear(dpy);
return -1;
}
+ ctx->mLayerRotMap[dpy]->add(layer, *rot);
whf.format = (*rot)->getDstFormat();
updateSource(orient, whf, crop);
rotFlags |= ovutils::ROT_PREROTATED;
@@ -1025,6 +1078,7 @@
ctx->mOverlay->clear(dpy);
return -1;
}
+ ctx->mLayerRotMap[dpy]->add(layer, *rot);
whf.format = (*rot)->getDstFormat();
updateSource(orient, whf, crop);
rotFlags |= ROT_PREROTATED;
@@ -1158,4 +1212,25 @@
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
}
+void LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) {
+ if(mCount >= MAX_SESS) return;
+ mLayer[mCount] = layer;
+ mRot[mCount] = rot;
+ mCount++;
+}
+
+void LayerRotMap::reset() {
+ for (int i = 0; i < MAX_SESS; i++) {
+ mLayer[i] = 0;
+ mRot[i] = 0;
+ }
+ mCount = 0;
+}
+
+void LayerRotMap::setReleaseFd(const int& fence) {
+ for(uint32_t i = 0; i < mCount; i++) {
+ mRot[i]->setReleaseFd(dup(fence));
+ }
+}
+
};//namespace qhwc
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 916a59d..4146787 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -121,6 +121,36 @@
HWC_COPYBIT = 0x00000002,
};
+class LayerRotMap {
+public:
+ LayerRotMap() { reset(); }
+ enum { MAX_SESS = 3 };
+ void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
+ void reset();
+ uint32_t getCount() const;
+ hwc_layer_1_t* getLayer(uint32_t index) const;
+ overlay::Rotator* getRot(uint32_t index) const;
+ void setReleaseFd(const int& fence);
+private:
+ hwc_layer_1_t* mLayer[MAX_SESS];
+ overlay::Rotator* mRot[MAX_SESS];
+ uint32_t mCount;
+};
+
+inline uint32_t LayerRotMap::getCount() const {
+ return mCount;
+}
+
+inline hwc_layer_1_t* LayerRotMap::getLayer(uint32_t index) const {
+ if(index >= mCount) return NULL;
+ return mLayer[index];
+}
+
+inline overlay::Rotator* LayerRotMap::getRot(uint32_t index) const {
+ if(index >= mCount) return NULL;
+ return mRot[index];
+}
+
// -----------------------------------------------------------------------------
// Utility functions - implemented in hwc_utils.cpp
void dumpLayer(hwc_layer_1_t const* l);
@@ -301,7 +331,6 @@
hwc_rect_t mPrevCropVideo;
hwc_rect_t mPrevDestVideo;
int mPrevTransformVideo;
-
//Securing in progress indicator
bool mSecuring;
//External Display configuring progress indicator
@@ -318,6 +347,7 @@
int mExtOrientation;
//Flags the transition of a video session
bool mVideoTransFlag;
+ qhwc::LayerRotMap *mLayerRotMap[MAX_DISPLAYS];
};
namespace qhwc {
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
index ed2f503..a375284 100644
--- a/liboverlay/Android.mk
+++ b/liboverlay/Android.mk
@@ -6,7 +6,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libmemalloc
+LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libmemalloc libsync
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdoverlay\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := \
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
index 3861297..2995580 100644
--- a/liboverlay/overlayRotator.cpp
+++ b/liboverlay/overlayRotator.cpp
@@ -26,6 +26,8 @@
namespace overlay {
+//============Rotator=========================
+
Rotator::~Rotator() {}
Rotator* Rotator::getRotator() {
@@ -56,6 +58,9 @@
return TYPE_MDP;
}
+
+//============RotMem=========================
+
bool RotMem::close() {
bool ret = true;
for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
@@ -70,11 +75,46 @@
return ret;
}
+RotMem::Mem::Mem() : mCurrOffset(0) {
+ utils::memset0(mRotOffset);
+ for(int i = 0; i < ROT_NUM_BUFS; i++) {
+ mRelFence[i] = -1;
+ }
+}
+
+RotMem::Mem::~Mem() {
+ for(int i = 0; i < ROT_NUM_BUFS; i++) {
+ ::close(mRelFence[i]);
+ mRelFence[i] = -1;
+ }
+}
+
+void RotMem::Mem::setReleaseFd(const int& fence) {
+ int ret = 0;
+
+ if(mRelFence[mCurrOffset] >= 0) {
+ //Wait for previous usage of this buffer to be over.
+ //Can happen if rotation takes > vsync and a fast producer. i.e queue
+ //happens in subsequent vsyncs either because content is 60fps or
+ //because the producer is hasty sometimes.
+ ret = sync_wait(mRelFence[mCurrOffset], 1000);
+ if(ret < 0) {
+ ALOGE("%s: sync_wait error!! error no = %d err str = %s",
+ __FUNCTION__, errno, strerror(errno));
+ }
+ ::close(mRelFence[mCurrOffset]);
+ }
+ mRelFence[mCurrOffset] = fence;
+}
+
+//============RotMgr=========================
+
RotMgr::RotMgr() {
for(int i = 0; i < MAX_ROT_SESS; i++) {
mRot[i] = 0;
}
mUseCount = 0;
+ mRotDevFd = -1;
}
RotMgr::~RotMgr() {
@@ -118,6 +158,8 @@
}
}
mUseCount = 0;
+ ::close(mRotDevFd);
+ mRotDevFd = -1;
}
void RotMgr::getDump(char *buf, size_t len) {
@@ -131,4 +173,15 @@
strncat(buf, str, strlen(str));
}
+int RotMgr::getRotDevFd() {
+ //2nd check just in case
+ if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDP) {
+ mRotDevFd = ::open("/dev/msm_rotator", O_RDWR, 0);
+ if(mRotDevFd < 0) {
+ ALOGE("%s failed to open rotator device", __FUNCTION__);
+ }
+ }
+ return mRotDevFd;
+}
+
}
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index 120721c..7f90160 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -38,6 +38,45 @@
namespace overlay {
+/*
+ Manages the case where new rotator memory needs to be
+ allocated, before previous is freed, due to resolution change etc. If we make
+ rotator memory to be always max size, irrespctive of source resolution then
+ we don't need this RotMem wrapper. The inner class is sufficient.
+*/
+struct RotMem {
+ // Max rotator memory allocations
+ enum { MAX_ROT_MEM = 2};
+
+ //Manages the rotator buffer offsets.
+ struct Mem {
+ Mem();
+ ~Mem();
+ bool valid() { return m.valid(); }
+ bool close() { return m.close(); }
+ uint32_t size() const { return m.bufSz(); }
+ void setReleaseFd(const int& fence);
+ // Max rotator buffers
+ enum { ROT_NUM_BUFS = 2 };
+ // rotator data info dst offset
+ uint32_t mRotOffset[ROT_NUM_BUFS];
+ int mRelFence[ROT_NUM_BUFS];
+ // current offset slot from mRotOffset
+ uint32_t mCurrOffset;
+ OvMem m;
+ };
+
+ RotMem() : _curr(0) {}
+ Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
+ const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
+ Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
+ RotMem& operator++() { ++_curr; return *this; }
+ void setReleaseFd(const int& fence) { curr().setReleaseFd(fence); }
+ bool close();
+ uint32_t _curr;
+ Mem m[MAX_ROT_MEM];
+};
+
class Rotator
{
public:
@@ -56,50 +95,19 @@
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
virtual void dump() const = 0;
virtual void getDump(char *buf, size_t len) const = 0;
+ void setReleaseFd(const int& fence) { mMem.setReleaseFd(fence); }
static Rotator *getRotator();
protected:
+ /* Rotator memory manager */
+ RotMem mMem;
explicit Rotator() {}
static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
private:
/*Returns rotator h/w type */
static int getRotatorHwType();
-};
-
-/*
- Manages the case where new rotator memory needs to be
- allocated, before previous is freed, due to resolution change etc. If we make
- rotator memory to be always max size, irrespctive of source resolution then
- we don't need this RotMem wrapper. The inner class is sufficient.
-*/
-struct RotMem {
- // Max rotator memory allocations
- enum { MAX_ROT_MEM = 2};
-
- //Manages the rotator buffer offsets.
- struct Mem {
- Mem() : mCurrOffset(0) {utils::memset0(mRotOffset); }
- bool valid() { return m.valid(); }
- bool close() { return m.close(); }
- uint32_t size() const { return m.bufSz(); }
- // Max rotator buffers
- enum { ROT_NUM_BUFS = 2 };
- // rotator data info dst offset
- uint32_t mRotOffset[ROT_NUM_BUFS];
- // current offset slot from mRotOffset
- uint32_t mCurrOffset;
- OvMem m;
- };
-
- RotMem() : _curr(0) {}
- Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
- const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
- Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
- RotMem& operator++() { ++_curr; return *this; }
- bool close();
- uint32_t _curr;
- Mem m[MAX_ROT_MEM];
+ friend class RotMgr;
};
/*
@@ -155,8 +163,6 @@
utils::eTransform mOrientation;
/* rotator fd */
OvFD mFd;
- /* Rotator memory manager */
- RotMem mMem;
friend Rotator* Rotator::getRotator();
};
@@ -209,8 +215,6 @@
utils::eTransform mOrientation;
/* rotator fd */
OvFD mFd;
- /* Rotator memory manager */
- RotMem mMem;
/* Enable/Disable Mdss Rot*/
bool mEnabled;
@@ -233,9 +237,11 @@
* Expects a NULL terminated buffer of big enough size.
*/
void getDump(char *buf, size_t len);
+ int getRotDevFd(); //Called on A-fam only
private:
overlay::Rotator *mRot[MAX_ROT_SESS];
int mUseCount;
+ int mRotDevFd; //A-fam
};
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 9bfa34e..c3d00f1 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -368,11 +368,6 @@
return fmt3D;
}
-bool isMdssRotator() {
- int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
- return (mdpVersion >= qdutils::MDSS_V5);
-}
-
void getDump(char *buf, size_t len, const char *prefix,
const mdp_overlay& ov) {
char str[256] = {'\0'};
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index f5d4475..3ab0d19 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -33,8 +33,8 @@
namespace overlay {
-GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRot(0), mRotUsed(false),
- mRotDownscaleOpt(false), mPreRotated(false), pipeState(CLOSED) {
+GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRotDownscaleOpt(false),
+ pipeState(CLOSED) {
init();
}
@@ -45,9 +45,7 @@
bool GenericPipe::init()
{
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
- mRotUsed = false;
mRotDownscaleOpt = false;
- mPreRotated = false;
if(mFbNum)
mFbNum = Overlay::getInstance()->getExtFbNum();
@@ -63,9 +61,6 @@
return false;
}
- //get a new rotator object, take ownership
- mRot = Rotator::getRotator();
-
return true;
}
@@ -81,21 +76,12 @@
ret = false;
}
- delete mRot;
- mRot = 0;
-
setClosed();
return ret;
}
void GenericPipe::setSource(const utils::PipeArgs& args) {
- //Cache if user wants 0-rotation
- mRotUsed = args.rotFlags & utils::ROT_0_ENABLED;
mRotDownscaleOpt = args.rotFlags & utils::ROT_DOWNSCALE_ENABLED;
- mPreRotated = args.rotFlags & utils::ROT_PREROTATED;
- if(mPreRotated) mRotUsed = false;
- mRot->setSource(args.whf);
- mRot->setFlags(args.mdpFlags);
mCtrlData.ctrl.setSource(args);
}
@@ -104,10 +90,6 @@
}
void GenericPipe::setTransform(const utils::eTransform& orient) {
- //Rotation could be enabled by user for zero-rot or the layer could have
- //some transform. Mark rotation enabled in either case.
- mRotUsed |= ((orient & utils::OVERLAY_TRANSFORM_ROT_90) && !mPreRotated);
- mRot->setTransform(orient);
mCtrlData.ctrl.setTransform(orient);
}
@@ -129,39 +111,11 @@
ovutils::Dim dst(mCtrlData.ctrl.getPosition());
downscale_factor = ovutils::getDownscaleFactor(
src.w, src.h, dst.w, dst.h);
- mRotUsed |= (downscale_factor && !mPreRotated);
- }
-
-
- if(mRotUsed) {
- mRot->setDownscale(downscale_factor);
- //If wanting to use rotator, start it.
- if(!mRot->commit()) {
- ALOGE("GenPipe Rotator commit failed");
- //If rot commit fails, flush rotator session, memory, fd and create
- //a hollow rotator object
- delete mRot;
- mRot = Rotator::getRotator();
- pipeState = CLOSED;
- return false;
- }
- /* Set the mdp src format to the output format of the rotator.
- * The output format of the rotator might be different depending on
- * whether fastyuv mode is enabled in the rotator.
- */
- mCtrlData.ctrl.updateSrcFormat(mRot->getDstFormat());
}
mCtrlData.ctrl.setDownscale(downscale_factor);
ret = mCtrlData.ctrl.commit();
- //If mdp commit fails, flush rotator session, memory, fd and create a hollow
- //rotator object
- if(ret == false) {
- delete mRot;
- mRot = Rotator::getRotator();
- }
-
pipeState = ret ? OPEN : CLOSED;
return ret;
}
@@ -174,26 +128,7 @@
// set pipe id from ctrl to data
mCtrlData.data.setPipeId(pipeId);
- int finalFd = fd;
- uint32_t finalOffset = offset;
- //If rotator is to be used, queue to it, so it can ROTATE.
- if(mRotUsed) {
- if(!mRot->queueBuffer(fd, offset)) {
- ALOGE("GenPipe Rotator play failed");
- return false;
- }
- //Configure MDP's source buffer as the current output buffer of rotator
- if(mRot->getDstMemId() != -1) {
- finalFd = mRot->getDstMemId();
- finalOffset = mRot->getDstOffset();
- } else {
- //Could be -1 for NullRotator, if queue above succeeds.
- //Need an actual rotator. Modify overlay State Traits.
- //Not fatal, keep queuing to MDP without rotation.
- ALOGE("Null rotator in use, where an actual is required");
- }
- }
- return mCtrlData.data.queueBuffer(finalFd, finalOffset);
+ return mCtrlData.data.queueBuffer(fd, offset);
}
int GenericPipe::getCtrlFd() const {
@@ -209,18 +144,15 @@
{
ALOGE("== Dump Generic pipe start ==");
ALOGE("pipe state = %d", (int)pipeState);
- OVASSERT(mRot, "GenericPipe should have a valid Rot");
mCtrlData.ctrl.dump();
mCtrlData.data.dump();
- mRot->dump();
+
ALOGE("== Dump Generic pipe end ==");
}
void GenericPipe::getDump(char *buf, size_t len) {
mCtrlData.ctrl.getDump(buf, len);
mCtrlData.data.getDump(buf, len);
- if(mRotUsed && mRot)
- mRot->getDump(buf, len);
}
bool GenericPipe::isClosed() const {
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 5463eb8..9a66632 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -31,7 +31,6 @@
#define OVERLAY_GENERIC_PIPE_H
#include "overlayUtils.h"
-#include "overlayRotator.h"
#include "overlayCtrlData.h"
namespace overlay {
@@ -86,14 +85,9 @@
int mFbNum;
/* Ctrl/Data aggregator */
CtrlData mCtrlData;
- Rotator* mRot;
- //Whether rotator is used for 0-rot or otherwise
- bool mRotUsed;
//Whether we will do downscale opt. This is just a request. If the frame is
//not a candidate, we might not do it.
bool mRotDownscaleOpt;
- //Whether the source is prerotated.
- bool mPreRotated;
/* Pipe open or closed */
enum ePipeState {
CLOSED,
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index 04dcf9f..1dd317f 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -50,6 +50,7 @@
mFeatures = 0;
//TODO get this from driver, default for A-fam to 8
mMDPDownscale = 8;
+ mFd = fb_fd;
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) {
ALOGE("FBIOGET_FSCREENINFO failed");
@@ -103,7 +104,6 @@
panel_type = *ptype;
}
mPanelType = panel_type;
- close(fb_fd);
mMDPVersion = mdp_version;
mHasOverlay = false;
if((mMDPVersion >= MDP_V4_0) ||
@@ -135,6 +135,10 @@
}
}
+MDPVersion::~MDPVersion() {
+ close(mFd);
+}
+
bool MDPVersion::supportsDecimation() {
return mFeatures & MDP_DECIMATION_EN;
}
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index e26f4d3..316899f 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -89,7 +89,7 @@
{
public:
MDPVersion();
- ~MDPVersion() { }
+ ~MDPVersion();
int getMDPVersion() {return mMDPVersion;}
char getPanelType() {return mPanelType;}
bool hasOverlay() {return mHasOverlay;}
@@ -104,6 +104,7 @@
int getLeftSplit() { return mSplit.left(); }
int getRightSplit() { return mSplit.right(); }
private:
+ int mFd;
int mMDPVersion;
char mPanelType;
bool mHasOverlay;