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
This commit is contained in:
Saurabh Shah
2012-12-13 12:32:55 -08:00
parent bd6eea2dc4
commit cf053c6eda
7 changed files with 272 additions and 65 deletions

View File

@@ -93,9 +93,11 @@ static void reset(hwc_context_t *ctx, int numDisplays,
list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
} }
} }
if(ctx->mFBUpdate[i])
ctx->mFBUpdate[i]->reset();
} }
VideoOverlay::reset(); VideoOverlay::reset();
FBUpdate::reset();
} }
//clear prev layer prop flags and realloc for current frame //clear prev layer prop flags and realloc for current frame
@@ -115,20 +117,21 @@ static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
static int hwc_prepare_primary(hwc_composer_device_1 *dev, static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) { hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev); hwc_context_t* ctx = (hwc_context_t*)(dev);
const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list && list->numHwLayers > 1) && if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { ctx->dpyAttr[dpy].isActive) {
uint32_t last = list->numHwLayers - 1; uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) { if(fbLayer->handle) {
setListStats(ctx, list, HWC_DISPLAY_PRIMARY); setListStats(ctx, list, dpy);
reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY); reset_layer_prop(ctx, dpy);
if(!MDPComp::configure(ctx, list)) { if(!MDPComp::configure(ctx, list)) {
VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY); VideoOverlay::prepare(ctx, list, dpy);
FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY); ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
} }
ctx->mLayerCache[HWC_DISPLAY_PRIMARY]->updateLayerCache(list); ctx->mLayerCache[dpy]->updateLayerCache(list);
} }
} }
return 0; return 0;
@@ -137,20 +140,20 @@ static int hwc_prepare_primary(hwc_composer_device_1 *dev,
static int hwc_prepare_external(hwc_composer_device_1 *dev, static int hwc_prepare_external(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) { hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev); hwc_context_t* ctx = (hwc_context_t*)(dev);
const int dpy = HWC_DISPLAY_EXTERNAL;
if (LIKELY(list && list->numHwLayers > 1) && if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1; uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) { if(fbLayer->handle) {
setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); setListStats(ctx, list, dpy);
reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL); reset_layer_prop(ctx, dpy);
VideoOverlay::prepare(ctx, list, dpy);
VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL); ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL); ctx->mLayerCache[dpy]->updateLayerCache(list);
ctx->mLayerCache[HWC_DISPLAY_EXTERNAL]->updateLayerCache(list);
} }
} }
return 0; return 0;
@@ -173,15 +176,14 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
ret = hwc_prepare_primary(dev, list); ret = hwc_prepare_primary(dev, list);
break; break;
case HWC_DISPLAY_EXTERNAL: case HWC_DISPLAY_EXTERNAL:
ret = hwc_prepare_external(dev, list); ret = hwc_prepare_external(dev, list);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
} }
ctx->mOverlay->configDone();
ctx->mOverlay->configDone();
return ret; return ret;
} }
@@ -282,14 +284,15 @@ static int hwc_query(struct hwc_composer_device_1* dev,
static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
int ret = 0; int ret = 0;
const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list && list->numHwLayers > 1) && if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { ctx->dpyAttr[dpy].isActive) {
uint32_t last = list->numHwLayers - 1; uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_layer_1_t *fbLayer = &list->hwLayers[last];
hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY); hwc_sync(ctx, list, dpy);
if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) { if (!VideoOverlay::draw(ctx, list, dpy)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__); ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1; ret = -1;
} }
@@ -303,7 +306,7 @@ static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
private_handle_t *hnd = (private_handle_t *)fbLayer->handle; private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) { if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
if(!(fbLayer->flags & HWC_SKIP_LAYER)) { 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__); ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1; ret = -1;
} }
@@ -320,17 +323,19 @@ static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
static int hwc_set_external(hwc_context_t *ctx, static int hwc_set_external(hwc_context_t *ctx,
hwc_display_contents_1_t* list) { hwc_display_contents_1_t* list) {
int ret = 0; int ret = 0;
const int dpy = HWC_DISPLAY_EXTERNAL;
Locker::Autolock _l(ctx->mExtSetLock); Locker::Autolock _l(ctx->mExtSetLock);
if (LIKELY(list && list->numHwLayers > 1) && if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1; uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 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__); ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1; ret = -1;
} }
@@ -338,7 +343,7 @@ static int hwc_set_external(hwc_context_t *ctx,
private_handle_t *hnd = (private_handle_t *)fbLayer->handle; private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
!(fbLayer->flags & HWC_SKIP_LAYER) && hnd) { !(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__); ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1; ret = -1;
} }

View File

@@ -18,7 +18,7 @@
* limitations under the License. * limitations under the License.
*/ */
#define HWC_FB_UPDATE 0 #define DEBUG_FBUPDATE 0
#include <gralloc_priv.h> #include <gralloc_priv.h>
#include <fb_priv.h> #include <fb_priv.h>
#include "hwc_fbupdate.h" #include "hwc_fbupdate.h"
@@ -28,30 +28,38 @@ namespace qhwc {
namespace ovutils = overlay::utils; namespace ovutils = overlay::utils;
//Static Members IFBUpdate* IFBUpdate::getObject(const int& width, const int& dpy) {
bool FBUpdate::sModeOn[] = {false}; if(width > MAX_DISPLAY_DIM) {
ovutils::eDest FBUpdate::sDest[] = {ovutils::OV_INVALID}; return new FBUpdateHighRes(dpy);
}
void FBUpdate::reset() { return new FBUpdateLowRes(dpy);
sModeOn[HWC_DISPLAY_PRIMARY] = false;
sModeOn[HWC_DISPLAY_EXTERNAL] = false;
sDest[HWC_DISPLAY_PRIMARY] = ovutils::OV_INVALID;
sDest[HWC_DISPLAY_EXTERNAL] = ovutils::OV_INVALID;
} }
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) { 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__); __FUNCTION__);
return false; return false;
} }
mModeOn = configure(ctx, fblayer);
return (sModeOn[dpy] = configure(ctx, fblayer, dpy)); ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
return mModeOn;
} }
// Configure // 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; bool ret = false;
if (LIKELY(ctx->mOverlay)) { if (LIKELY(ctx->mOverlay)) {
@@ -64,12 +72,12 @@ bool FBUpdate::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
//Request an RGB pipe //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 if(dest == ovutils::OV_INVALID) { //None available
return false; return false;
} }
sDest[dpy] = dest; mDest = dest;
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
if(ctx->mSecureMode) { if(ctx->mSecureMode) {
@@ -112,14 +120,14 @@ bool FBUpdate::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
return ret; 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; return true;
} }
bool ret = true; bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay); overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eDest dest = sDest[dpy]; ovutils::eDest dest = mDest;
private_handle_t *hnd = (private_handle_t *)layer->handle; private_handle_t *hnd = (private_handle_t *)layer->handle;
if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) { if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
ALOGE("%s: queueBuffer failed for external", __FUNCTION__); ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
@@ -128,5 +136,138 @@ bool FBUpdate::draw(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
return ret; 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 }; //namespace qhwc

View File

@@ -28,22 +28,50 @@
namespace qhwc { namespace qhwc {
namespace ovutils = overlay::utils; namespace ovutils = overlay::utils;
//Framebuffer update //Framebuffer update Interface
class FBUpdate { class IFBUpdate {
public: public:
explicit IFBUpdate(const int& dpy) : mDpy(dpy) {}
virtual ~IFBUpdate() {};
// Sets up members and prepares overlay if conditions are met // Sets up members and prepares overlay if conditions are met
static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy); virtual bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) = 0;
// Draws layer if this feature is on // Draws layer
static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy); virtual bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer) = 0;
//Reset values //Reset values
static void reset(); 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: private:
//Configures overlay bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer, ovutils::eDest mDest; //pipe to draw on
int dpy); };
//Flags if this feature is on.
static bool sModeOn[HWC_NUM_DISPLAY_TYPES]; //High resolution (> 2048) panel handler.
static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES]; 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 }; //namespace qhwc

View File

@@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "hwc_utils.h" #include "hwc_utils.h"
#include "hwc_fbupdate.h"
#include "external.h" #include "external.h"
namespace qhwc { namespace qhwc {
@@ -67,8 +68,16 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected; ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
if (connected) { if (connected) {
ctx->mExtDisplay->processUEventOnline(udata); ctx->mExtDisplay->processUEventOnline(udata);
ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] =
IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
HWC_DISPLAY_EXTERNAL);
} else { } else {
ctx->mExtDisplay->processUEventOffline(udata); 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); ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on

View File

@@ -23,6 +23,7 @@
#include <overlay.h> #include <overlay.h>
#include "hwc_utils.h" #include "hwc_utils.h"
#include "hwc_mdpcomp.h" #include "hwc_mdpcomp.h"
#include "hwc_fbupdate.h"
#include "mdp_version.h" #include "mdp_version.h"
#include "external.h" #include "external.h"
#include "QService.h" #include "QService.h"
@@ -59,6 +60,12 @@ void initContext(hwc_context_t *ctx)
ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion(); ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay(); ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType(); 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); ctx->mExtDisplay = new ExternalDisplay(ctx);
for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++)
ctx->mLayerCache[i] = new LayerCache(); ctx->mLayerCache[i] = new LayerCache();
@@ -91,6 +98,13 @@ void closeContext(hwc_context_t *ctx)
ctx->mExtDisplay = NULL; 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_mutex_destroy(&(ctx->vstate.lock));
pthread_cond_destroy(&(ctx->vstate.cond)); pthread_cond_destroy(&(ctx->vstate.cond));
} }

View File

@@ -31,6 +31,7 @@
#define FINAL_TRANSFORM_MASK 0x000F #define FINAL_TRANSFORM_MASK 0x000F
#define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious #define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious
#define MAX_NUM_LAYERS 32 #define MAX_NUM_LAYERS 32
#define MAX_DISPLAY_DIM 2048
//Fwrd decls //Fwrd decls
struct hwc_context_t; struct hwc_context_t;
@@ -48,6 +49,7 @@ namespace qhwc {
//fwrd decl //fwrd decl
class QueuedBufferStore; class QueuedBufferStore;
class ExternalDisplay; class ExternalDisplay;
class IFBUpdate;
struct MDPInfo { struct MDPInfo {
int version; int version;
@@ -215,6 +217,9 @@ struct hwc_context_t {
overlay::Overlay *mOverlay; overlay::Overlay *mOverlay;
//QService object //QService object
qService::QService *mQService; qService::QService *mQService;
//Primary and external FB updater
qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
// External display related information // External display related information
qhwc::ExternalDisplay *mExtDisplay; qhwc::ExternalDisplay *mExtDisplay;
qhwc::MDPInfo mMDP; qhwc::MDPInfo mMDP;

View File

@@ -63,6 +63,10 @@
#define DEBUG_OVERLAY 0 #define DEBUG_OVERLAY 0
#define PROFILE_OVERLAY 0 #define PROFILE_OVERLAY 0
#ifndef MDSS_MDP_RIGHT_MIXER
#define MDSS_MDP_RIGHT_MIXER 0x100
#endif
namespace overlay { namespace overlay {
// fwd // fwd
@@ -297,6 +301,7 @@ enum eMdpFlags {
OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT, OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT,
OV_MDP_FLIP_H = MDP_FLIP_LR, OV_MDP_FLIP_H = MDP_FLIP_LR,
OV_MDP_FLIP_V = MDP_FLIP_UD, OV_MDP_FLIP_V = MDP_FLIP_UD,
OV_MDSS_MDP_RIGHT_MIXER = MDSS_MDP_RIGHT_MIXER,
}; };
enum eZorder { enum eZorder {