summaryrefslogtreecommitdiffstats
path: root/libhwcomposer/hwc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libhwcomposer/hwc.cpp')
-rw-r--r--libhwcomposer/hwc.cpp125
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) {