Merge "hwc: Handle ext display device conn/disconn requests"
diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk
index 55d421b..73bfa86 100644
--- a/libcopybit/Android.mk
+++ b/libcopybit/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright (C) 2008 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.
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 823c1ae..669ea08 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -235,6 +235,11 @@
alignedh = height;
size = ALIGN(alignedw * alignedh * 2, 4096);
break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ alignedw = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+ break;
default:
ALOGE("unrecognized pixel format: 0x%x", format);
return -EINVAL;
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 59fbd30..4f6445d 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -96,6 +96,7 @@
enum {
/* OEM specific HAL formats */
HAL_PIXEL_FORMAT_NV12_ENCODEABLE = 0x102,
+ HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS = 0x7FA30C04,
HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x7FA30C03,
HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01,
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index b9b9717..8cee7fd 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -69,14 +69,18 @@
struct ion_handle_data handle_data;
struct ion_fd_data fd_data;
struct ion_allocation_data ionAllocData;
-
void *base = 0;
ionAllocData.len = data.size;
ionAllocData.align = data.align;
- ionAllocData.heap_mask = data.flags;
+ ionAllocData.heap_mask = data.flags & ~ION_SECURE;
ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED;
+ // ToDo: replace usage of alloc data structure with
+ // ionallocdata structure.
+ if (data.flags & ION_SECURE)
+ ionAllocData.flags |= ION_SECURE;
+
err = open_device();
if (err)
return err;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a0a0c82..c8410c9 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -93,9 +93,11 @@
list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
}
}
+
+ if(ctx->mFBUpdate[i])
+ ctx->mFBUpdate[i]->reset();
}
VideoOverlay::reset();
- FBUpdate::reset();
}
//clear prev layer prop flags and realloc for current frame
@@ -115,20 +117,21 @@
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
+ const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list && list->numHwLayers > 1) &&
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
+ ctx->dpyAttr[dpy].isActive) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
- setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
- reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY);
+ setListStats(ctx, list, dpy);
+ reset_layer_prop(ctx, dpy);
if(!MDPComp::configure(ctx, list)) {
- VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
- FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY);
+ VideoOverlay::prepare(ctx, list, dpy);
+ ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
}
- ctx->mLayerCache[HWC_DISPLAY_PRIMARY]->updateLayerCache(list);
+ ctx->mLayerCache[dpy]->updateLayerCache(list);
}
}
return 0;
@@ -137,20 +140,20 @@
static int hwc_prepare_external(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
+ const int dpy = HWC_DISPLAY_EXTERNAL;
if (LIKELY(list && list->numHwLayers > 1) &&
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
+ ctx->dpyAttr[dpy].isActive &&
+ ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
- setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
- reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL);
-
- VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
- FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
- ctx->mLayerCache[HWC_DISPLAY_EXTERNAL]->updateLayerCache(list);
+ setListStats(ctx, list, dpy);
+ reset_layer_prop(ctx, dpy);
+ VideoOverlay::prepare(ctx, list, dpy);
+ ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
+ ctx->mLayerCache[dpy]->updateLayerCache(list);
}
}
return 0;
@@ -173,15 +176,14 @@
ret = hwc_prepare_primary(dev, list);
break;
case HWC_DISPLAY_EXTERNAL:
-
ret = hwc_prepare_external(dev, list);
break;
default:
ret = -EINVAL;
}
}
- ctx->mOverlay->configDone();
+ ctx->mOverlay->configDone();
return ret;
}
@@ -282,14 +284,15 @@
static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
int ret = 0;
+ const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list && list->numHwLayers > 1) &&
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
+ ctx->dpyAttr[dpy].isActive) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
- if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) {
+ hwc_sync(ctx, list, dpy);
+ if (!VideoOverlay::draw(ctx, list, dpy)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1;
}
@@ -303,7 +306,7 @@
private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
- if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) {
+ if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1;
}
@@ -320,17 +323,19 @@
static int hwc_set_external(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
int ret = 0;
+ const int dpy = HWC_DISPLAY_EXTERNAL;
+
Locker::Autolock _l(ctx->mExtSetLock);
if (LIKELY(list && list->numHwLayers > 1) &&
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
+ ctx->dpyAttr[dpy].isActive &&
+ ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
+ hwc_sync(ctx, list, dpy);
- if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_EXTERNAL)) {
+ if (!VideoOverlay::draw(ctx, list, dpy)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1;
}
@@ -338,7 +343,7 @@
private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
!(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
- if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) {
+ if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1;
}
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 0d0787e..ecbf813 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -18,7 +18,7 @@
* limitations under the License.
*/
-#define HWC_FB_UPDATE 0
+#define DEBUG_FBUPDATE 0
#include <gralloc_priv.h>
#include <fb_priv.h>
#include "hwc_fbupdate.h"
@@ -28,30 +28,38 @@
namespace ovutils = overlay::utils;
-//Static Members
-bool FBUpdate::sModeOn[] = {false};
-ovutils::eDest FBUpdate::sDest[] = {ovutils::OV_INVALID};
-
-void FBUpdate::reset() {
- sModeOn[HWC_DISPLAY_PRIMARY] = false;
- sModeOn[HWC_DISPLAY_EXTERNAL] = false;
- sDest[HWC_DISPLAY_PRIMARY] = ovutils::OV_INVALID;
- sDest[HWC_DISPLAY_EXTERNAL] = ovutils::OV_INVALID;
+IFBUpdate* IFBUpdate::getObject(const int& width, const int& dpy) {
+ if(width > MAX_DISPLAY_DIM) {
+ return new FBUpdateHighRes(dpy);
+ }
+ return new FBUpdateLowRes(dpy);
}
-bool FBUpdate::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy) {
+inline void IFBUpdate::reset() {
+ mModeOn = false;
+}
+
+//================= Low res====================================
+FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {}
+
+inline void FBUpdateLowRes::reset() {
+ IFBUpdate::reset();
+ mDest = ovutils::OV_INVALID;
+}
+
+bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
if(!ctx->mMDP.hasOverlay) {
- ALOGD_IF(HWC_FB_UPDATE, "%s, this hw doesnt support mirroring",
+ ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
__FUNCTION__);
return false;
}
-
- return (sModeOn[dpy] = configure(ctx, fblayer, dpy));
-
+ mModeOn = configure(ctx, fblayer);
+ ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
+ return mModeOn;
}
// Configure
-bool FBUpdate::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
+bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
{
bool ret = false;
if (LIKELY(ctx->mOverlay)) {
@@ -64,12 +72,12 @@
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
//Request an RGB pipe
- ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
+ ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
if(dest == ovutils::OV_INVALID) { //None available
return false;
}
- sDest[dpy] = dest;
+ mDest = dest;
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
if(ctx->mSecureMode) {
@@ -112,14 +120,14 @@
return ret;
}
-bool FBUpdate::draw(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
+bool FBUpdateLowRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
{
- if(!sModeOn[dpy]) {
+ if(!mModeOn) {
return true;
}
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
- ovutils::eDest dest = sDest[dpy];
+ ovutils::eDest dest = mDest;
private_handle_t *hnd = (private_handle_t *)layer->handle;
if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
@@ -128,5 +136,138 @@
return ret;
}
+//================= High res====================================
+FBUpdateHighRes::FBUpdateHighRes(const int& dpy): IFBUpdate(dpy) {}
+
+inline void FBUpdateHighRes::reset() {
+ IFBUpdate::reset();
+ mDestLeft = ovutils::OV_INVALID;
+ mDestRight = ovutils::OV_INVALID;
+}
+
+bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
+ if(!ctx->mMDP.hasOverlay) {
+ ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
+ __FUNCTION__);
+ return false;
+ }
+ ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
+ mModeOn = configure(ctx, fblayer);
+ return mModeOn;
+}
+
+// Configure
+bool FBUpdateHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
+{
+ bool ret = false;
+ if (LIKELY(ctx->mOverlay)) {
+ overlay::Overlay& ov = *(ctx->mOverlay);
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if (!hnd) {
+ ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
+ return false;
+ }
+ ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
+
+ //Request left RGB pipe
+ ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+ if(destL == ovutils::OV_INVALID) { //None available
+ return false;
+ }
+ //Request right RGB pipe
+ ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+ if(destR == ovutils::OV_INVALID) { //None available
+ return false;
+ }
+
+ mDestLeft = destL;
+ mDestRight = destR;
+
+ ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
+ if(ctx->mSecureMode) {
+ ovutils::setMdpFlags(mdpFlagsL,
+ ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+ }
+
+ ovutils::PipeArgs pargL(mdpFlagsL,
+ info,
+ ovutils::ZORDER_0,
+ ovutils::IS_FG_SET,
+ ovutils::ROT_FLAG_DISABLED);
+ ov.setSource(pargL, destL);
+
+ ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
+ ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
+ ovutils::PipeArgs pargR(mdpFlagsR,
+ info,
+ ovutils::ZORDER_0,
+ ovutils::IS_FG_SET,
+ ovutils::ROT_FLAG_DISABLED);
+ ov.setSource(pargR, destR);
+
+ hwc_rect_t sourceCrop = layer->sourceCrop;
+ ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
+ (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.bottom - sourceCrop.top);
+ ovutils::Dim dcropR(
+ sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.top,
+ (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.bottom - sourceCrop.top);
+ ov.setCrop(dcropL, destL);
+ ov.setCrop(dcropR, destR);
+
+ int transform = layer->transform;
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(transform);
+ ov.setTransform(orient, destL);
+ ov.setTransform(orient, destR);
+
+ hwc_rect_t displayFrame = layer->displayFrame;
+ //For FB left, top will always be 0
+ //That should also be the case if using 2 mixers for single display
+ ovutils::Dim dpos(displayFrame.left,
+ displayFrame.top,
+ (displayFrame.right - displayFrame.left) / 2,
+ displayFrame.bottom - displayFrame.top);
+ ov.setPosition(dpos, destL);
+ ov.setPosition(dpos, destR);
+
+ ret = true;
+ if (!ov.commit(destL)) {
+ ALOGE("%s: commit fails for left", __FUNCTION__);
+ ret = false;
+ }
+ if (!ov.commit(destR)) {
+ ALOGE("%s: commit fails for right", __FUNCTION__);
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+bool FBUpdateHighRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
+{
+ if(!mModeOn) {
+ return true;
+ }
+ bool ret = true;
+ overlay::Overlay& ov = *(ctx->mOverlay);
+ ovutils::eDest destL = mDestLeft;
+ ovutils::eDest destR = mDestRight;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
+ ALOGE("%s: queue failed for left of dpy = %d",
+ __FUNCTION__, mDpy);
+ ret = false;
+ }
+ if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
+ ALOGE("%s: queue failed for right of dpy = %d",
+ __FUNCTION__, mDpy);
+ ret = false;
+ }
+ return ret;
+}
+
//---------------------------------------------------------------------
}; //namespace qhwc
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index 708eb6f..a30a3af 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -28,22 +28,50 @@
namespace qhwc {
namespace ovutils = overlay::utils;
-//Framebuffer update
-class FBUpdate {
- public:
- // Sets up members and prepares overlay if conditions are met
- static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy);
- // Draws layer if this feature is on
- static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy);
- //Reset values
- static void reset();
- private:
- //Configures overlay
- static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer,
- int dpy);
- //Flags if this feature is on.
- static bool sModeOn[HWC_NUM_DISPLAY_TYPES];
- static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES];
+//Framebuffer update Interface
+class IFBUpdate {
+public:
+ explicit IFBUpdate(const int& dpy) : mDpy(dpy) {}
+ virtual ~IFBUpdate() {};
+ // Sets up members and prepares overlay if conditions are met
+ virtual bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) = 0;
+ // Draws layer
+ virtual bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer) = 0;
+ //Reset values
+ virtual void reset();
+ //Factory method that returns a low-res or high-res version
+ static IFBUpdate *getObject(const int& width, const int& dpy);
+
+protected:
+ const int mDpy; // display to update
+ bool mModeOn; // if prepare happened
+};
+
+//Low resolution (<= 2048) panel handler.
+class FBUpdateLowRes : public IFBUpdate {
+public:
+ explicit FBUpdateLowRes(const int& dpy);
+ virtual ~FBUpdateLowRes() {};
+ bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ void reset();
+private:
+ bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ ovutils::eDest mDest; //pipe to draw on
+};
+
+//High resolution (> 2048) panel handler.
+class FBUpdateHighRes : public IFBUpdate {
+public:
+ explicit FBUpdateHighRes(const int& dpy);
+ virtual ~FBUpdateHighRes() {};
+ bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ void reset();
+private:
+ bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+ ovutils::eDest mDestLeft; //left pipe to draw on
+ ovutils::eDest mDestRight; //right pipe to draw on
};
}; //namespace qhwc
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 398634a..3d121ef 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -26,6 +26,7 @@
#include <string.h>
#include <stdlib.h>
#include "hwc_utils.h"
+#include "hwc_fbupdate.h"
#include "external.h"
namespace qhwc {
@@ -65,10 +66,18 @@
if(connected != -1) { //either we got switch_state connected or disconnect
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
- if(connected) {
+ if (connected) {
ctx->mExtDisplay->processUEventOnline(udata);
- }else {
+ ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] =
+ IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
+ HWC_DISPLAY_EXTERNAL);
+ } else {
ctx->mExtDisplay->processUEventOffline(udata);
+ if(ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL]) {
+ Locker::Autolock _l(ctx->mExtSetLock);
+ delete ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL];
+ ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] = NULL;
+ }
}
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 2f35567..7ae4afd 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -23,6 +23,7 @@
#include <overlay.h>
#include "hwc_utils.h"
#include "hwc_mdpcomp.h"
+#include "hwc_fbupdate.h"
#include "mdp_version.h"
#include "external.h"
#include "QService.h"
@@ -59,6 +60,12 @@
ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
+ //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.
+ ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
+ IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
+ HWC_DISPLAY_PRIMARY);
ctx->mExtDisplay = new ExternalDisplay(ctx);
for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++)
ctx->mLayerCache[i] = new LayerCache();
@@ -91,6 +98,13 @@
ctx->mExtDisplay = NULL;
}
+ for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+ if(ctx->mFBUpdate[i]) {
+ delete ctx->mFBUpdate[i];
+ ctx->mFBUpdate[i] = NULL;
+ }
+ }
+
pthread_mutex_destroy(&(ctx->vstate.lock));
pthread_cond_destroy(&(ctx->vstate.cond));
}
@@ -238,15 +252,25 @@
int count = 0;
int releaseFd = -1;
int fbFd = -1;
+ bool swapzero = false;
data.flags = MDP_BUF_SYNC_FLAG_WAIT;
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)
+ swapzero = true;
+ }
+
//Accumulate acquireFenceFds
for(uint32_t i = 0; i < list->numHwLayers; i++) {
if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) &&
list->hwLayers[i].acquireFenceFd != -1 ){
- acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ if(UNLIKELY(swapzero))
+ acquireFd[count++] = -1;
+ else
+ acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
}
}
@@ -254,7 +278,8 @@
fbFd = ctx->dpyAttr[dpy].fd;
//Waits for acquire fences, returns a release fence
- ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
+ if(LIKELY(!swapzero))
+ ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
if(ret < 0) {
ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s",
strerror(errno));
@@ -269,10 +294,18 @@
list->hwLayers[i].acquireFenceFd = -1;
}
//Populate releaseFenceFds.
- list->hwLayers[i].releaseFenceFd = dup(releaseFd);
+ if(UNLIKELY(swapzero))
+ list->hwLayers[i].releaseFenceFd = -1;
+ else
+ list->hwLayers[i].releaseFenceFd = dup(releaseFd);
}
}
- list->retireFenceFd = releaseFd;
+ if(UNLIKELY(swapzero)){
+ list->retireFenceFd = -1;
+ close(releaseFd);
+ } else {
+ list->retireFenceFd = releaseFd;
+ }
return ret;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index d7200b0..f3a0fd6 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -31,6 +31,7 @@
#define FINAL_TRANSFORM_MASK 0x000F
#define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious
#define MAX_NUM_LAYERS 32
+#define MAX_DISPLAY_DIM 2048
//Fwrd decls
struct hwc_context_t;
@@ -48,6 +49,7 @@
//fwrd decl
class QueuedBufferStore;
class ExternalDisplay;
+class IFBUpdate;
struct MDPInfo {
int version;
@@ -215,6 +217,9 @@
overlay::Overlay *mOverlay;
//QService object
qService::QService *mQService;
+
+ //Primary and external FB updater
+ qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
// External display related information
qhwc::ExternalDisplay *mExtDisplay;
qhwc::MDPInfo mMDP;
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index ee6af28..7f7bb1f 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -112,9 +112,11 @@
if(!fakevsync) {
for(int i = 0; i < MAX_RETRY_COUNT; i++) {
len = pread(fd_timestamp, vdata, MAX_DATA, 0);
- if(len < 0 && (errno == EAGAIN || errno == EINTR)) {
- ALOGW("%s: vsync read: EAGAIN, retry (%d/%d).",
- __FUNCTION__, i, MAX_RETRY_COUNT);
+ if(len < 0 && (errno == EAGAIN ||
+ errno == EINTR ||
+ errno == EBUSY)) {
+ ALOGW("%s: vsync read: %s, retry (%d/%d).",
+ __FUNCTION__, strerror(errno), i, MAX_RETRY_COUNT);
continue;
} else {
break;
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index cb3c48f..60d63a2 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -119,6 +119,7 @@
bool MdssRot::commit() {
doTransform();
+ setBufSize(mRotInfo.src.format);
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
ALOGE("MdssRot commit failed!");
@@ -248,4 +249,10 @@
ALOGE("== Dump MdssRot end ==");
}
+void MdssRot::setBufSize(int format) {
+ if (format == MDP_Y_CBCR_H2V2_VENUS) {
+ mBufSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mRotInfo.dst_rect.w,
+ mRotInfo.dst_rect.h);
+ }
+}
} // namespace overlay
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index 4ef33f3..ca71402 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -199,6 +199,7 @@
void doTransform();
/* reset underlying data, basically memset 0 */
void reset();
+ void setBufSize(int format);
/* MdssRot info structure */
mdp_overlay mRotInfo;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index d0f9457..49a1eaf 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -231,7 +231,8 @@
return MDP_Y_CBCR_H1V1;
case HAL_PIXEL_FORMAT_YCrCb_444_SP:
return MDP_Y_CRCB_H1V1;
-
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ return MDP_Y_CBCR_H2V2_VENUS;
default:
//Unsupported by MDP
//---graphics.h--------
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index f9fcca8..28d2b67 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -44,6 +44,10 @@
#include <utils/Log.h>
#include "gralloc_priv.h" //for interlace
+#ifndef MDP_Y_CBCR_H2V2_VENUS
+#define MDP_Y_CBCR_H2V2_VENUS (MDP_IMGTYPE_LIMIT2 + 1)
+#endif
+
/*
*
* Collection of utilities functions/structs/enums etc...
@@ -63,6 +67,10 @@
#define DEBUG_OVERLAY 0
#define PROFILE_OVERLAY 0
+#ifndef MDSS_MDP_RIGHT_MIXER
+#define MDSS_MDP_RIGHT_MIXER 0x100
+#endif
+
namespace overlay {
// fwd
@@ -297,6 +305,7 @@
OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT,
OV_MDP_FLIP_H = MDP_FLIP_LR,
OV_MDP_FLIP_V = MDP_FLIP_UD,
+ OV_MDSS_MDP_RIGHT_MIXER = MDSS_MDP_RIGHT_MIXER,
};
enum eZorder {
@@ -487,6 +496,7 @@
case MDP_Y_CBCR_H2V2_TILE:
case MDP_Y_CR_CB_H2V2:
case MDP_Y_CR_CB_GH2V2:
+ case MDP_Y_CBCR_H2V2_VENUS:
return true;
default:
return false;
@@ -534,6 +544,8 @@
"MDP_YCRCB_H1V1",
"MDP_YCBCR_H1V1",
"MDP_BGR_565",
+ "MDP_BGR_888",
+ "MDP_Y_CBCR_H2V2_VENUS",
"MDP_IMGTYPE_LIMIT",
"MDP_RGB_BORDERFILL",
"MDP_FB_FORMAT",