hwc: Support 4kx2k FB for Primary and External.
Add support for 4kx2k FB for primary and external panels.
Change class design to create appropriate version of FBUpdate on boot up based
on the panel resolution.
Change-Id: I216d815d9b81c610aa39e351f7b55736dfa48b43
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 78f6788..7e15b8f 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..d302049 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));
}
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;