diff options
Diffstat (limited to 'libhwcomposer/hwc.cpp')
-rw-r--r-- | libhwcomposer/hwc.cpp | 125 |
1 files changed, 73 insertions, 52 deletions
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index 62cf16d7e..830c067c4 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -27,12 +27,12 @@ #include <mdp_version.h> #include "hwc_utils.h" #include "hwc_video.h" -#include "hwc_uimirror.h" -#include "external.h" +#include "hwc_fbupdate.h" #include "hwc_mdpcomp.h" +#include "external.h" -#define VSYNC_DEBUG 0 using namespace qhwc; +#define VSYNC_DEBUG 0 static int hwc_device_open(const struct hw_module_t* module, const char* name, @@ -77,11 +77,38 @@ static void hwc_registerProcs(struct hwc_composer_device_1* dev, } //Helper -static void reset(hwc_context_t *ctx, int numDisplays) { +static void reset(hwc_context_t *ctx, int numDisplays, + hwc_display_contents_1_t** displays) { memset(ctx->listStats, 0, sizeof(ctx->listStats)); for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){ - ctx->overlayInUse[i] = false; ctx->listStats[i].yuvIndex = -1; + hwc_display_contents_1_t *list = displays[i]; + // XXX:SurfaceFlinger no longer guarantees that this + // value is reset on every prepare. However, for the layer + // cache we need to reset it. + // We can probably rethink that later on + if (LIKELY(list && list->numHwLayers > 1)) { + for(uint32_t j = 0; j < list->numHwLayers; j++) { + if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) + list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; + } + } + } + VideoOverlay::reset(); + FBUpdate::reset(); +} + +//clear prev layer prop flags and realloc for current frame +static void reset_layer_prop(hwc_context_t* ctx, int dpy) { + int layer_count = ctx->listStats[dpy].numAppLayers; + + if(ctx->layerProp[dpy]) { + delete[] ctx->layerProp[dpy]; + ctx->layerProp[dpy] = NULL; + } + + if(layer_count) { + ctx->layerProp[dpy] = new LayerProp[layer_count]; } } @@ -96,13 +123,12 @@ static int hwc_prepare_primary(hwc_composer_device_1 *dev, hwc_layer_1_t *fbLayer = &list->hwLayers[last]; if(fbLayer->handle) { setListStats(ctx, list, HWC_DISPLAY_PRIMARY); - if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true; - } else if(MDPComp::configure(ctx, list)) { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true; - } else { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false; + reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY); + if(!MDPComp::configure(ctx, list)) { + VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY); + FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY); } + ctx->mLayerCache[HWC_DISPLAY_PRIMARY]->updateLayerCache(list); } } return 0; @@ -116,21 +142,15 @@ static int hwc_prepare_external(hwc_composer_device_1 *dev, ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { - setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); - uint32_t last = list->numHwLayers - 1; hwc_layer_1_t *fbLayer = &list->hwLayers[last]; if(fbLayer->handle) { - if(UIMirrorOverlay::prepare(ctx, fbLayer)) { - ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true; - } + setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); + reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL); - if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL)) { - ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true; - } else { - ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState( - ovutils::OV_UI_MIRROR); - } + VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL); + FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL); + ctx->mLayerCache[HWC_DISPLAY_EXTERNAL]->updateLayerCache(list); } } return 0; @@ -141,29 +161,27 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); - reset(ctx, numDisplays); + Locker::Autolock _l(ctx->mBlankLock); + reset(ctx, numDisplays, displays); - //If securing of h/w in progress skip comp using overlay. - if(ctx->mSecuring == true) return 0; + ctx->mOverlay->configBegin(); - for (uint32_t i = 0; i < numDisplays; i++) { + for (int32_t i = numDisplays - 1; i >= 0; i--) { hwc_display_contents_1_t *list = displays[i]; - if(list && list->numHwLayers) { - uint32_t last = list->numHwLayers - 1; - if(list->hwLayers[last].handle != NULL) { - switch(i) { - case HWC_DISPLAY_PRIMARY: - ret = hwc_prepare_primary(dev, list); - break; - case HWC_DISPLAY_EXTERNAL: - ret = hwc_prepare_external(dev, list); - break; - default: - ret = -EINVAL; - } - } + switch(i) { + case HWC_DISPLAY_PRIMARY: + ret = hwc_prepare_primary(dev, list); + break; + case HWC_DISPLAY_EXTERNAL: + + ret = hwc_prepare_external(dev, list); + break; + default: + ret = -EINVAL; } } + ctx->mOverlay->configDone(); + return ret; } @@ -197,13 +215,14 @@ static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); + Locker::Autolock _l(ctx->mBlankLock); int ret = 0; ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); switch(dpy) { case HWC_DISPLAY_PRIMARY: if(blank) { - Locker::Autolock _l(ctx->mBlankLock); - ctx->mOverlay[dpy]->setState(ovutils::OV_CLOSED); + ctx->mOverlay->configBegin(); + ctx->mOverlay->configDone(); ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN); } else { ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK); @@ -267,18 +286,25 @@ static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY); - if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) { ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__); ret = -1; } - if (MDPComp::draw(ctx, list)) { + if (!MDPComp::draw(ctx, list)) { ALOGE("%s: MDPComp::draw fail!", __FUNCTION__); ret = -1; } + //TODO We dont check for SKIP flag on this layer because we need PAN //always. Last layer is always FB - if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) { + 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)) { + ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); + ret = -1; + } + } if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) { ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__); return -1; @@ -309,8 +335,8 @@ static int hwc_set_external(hwc_context_t *ctx, private_handle_t *hnd = (private_handle_t *)fbLayer->handle; if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) { - if (!UIMirrorOverlay::draw(ctx, fbLayer)) { - ALOGE("%s: UIMirrorOverlay::draw fail!", __FUNCTION__); + if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) { + ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); ret = -1; } } @@ -330,11 +356,6 @@ static int hwc_set(hwc_composer_device_1 *dev, hwc_context_t* ctx = (hwc_context_t*)(dev); Locker::Autolock _l(ctx->mBlankLock); - for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { - if(!ctx->overlayInUse[i]) - ctx->mOverlay[i]->setState(ovutils::OV_CLOSED); - } - for (uint32_t i = 0; i < numDisplays; i++) { hwc_display_contents_1_t* list = displays[i]; switch(i) { |