Handle overlay setup failure

Separate overlay setup and overlay play.
On setup failure, mark the layer to use C2D if enabled.
Else mark the layer to use GPU.

CRs-fixed: 292398
(cherry picked from commit b1459b0b1106ed66810b1c5a09878fae353c123c)

Change-Id: Id4c27384193612ab13e87d18492b0fef662eb8b4
This commit is contained in:
Saurabh Shah 2011-06-16 15:35:56 -07:00 committed by Govind Surti
parent fc966d1448
commit cb098e76e8

View File

@ -41,6 +41,8 @@
/*****************************************************************************/
#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
// Enum containing the supported composition types
enum {
@ -181,6 +183,88 @@ static int hwc_updateOverlayStatus(hwc_context_t* ctx, int layerType) {
return 0;
}
/*
* Configures mdp pipes
*/
static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer) {
int ret = 0;
if (LIKELY(ctx && ctx->mOverlayLibObject)) {
private_hwc_module_t* hwcModule =
reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
if (UNLIKELY(!hwcModule)) {
LOGE("prepareOverlay null module ");
return -1;
}
private_handle_t *hnd = (private_handle_t *)layer->handle;
overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
int orientation = 0;
if (OVERLAY_CHANNEL_UP == ovLibObject->getChannelStatus())
ovLibObject->getOrientation(orientation);
if ((OVERLAY_CHANNEL_DOWN == ovLibObject->getChannelStatus())
|| (layer->transform != orientation) ||
(hnd->flags & private_handle_t::PRIV_FLAGS_FORMAT_CHANGED)) {
// Overlay channel is not started, or we have an orientation change
// or there is a format change, call setSource to open the overlay
// if necessary
ret = ovLibObject->setSource(hnd->width, hnd->height, hnd->format,
layer->transform, (ovLibObject->getHDMIStatus()?true:false),
false);
if (!ret) {
LOGE("prepareOverlay setSource failed");
return -1;
}
// Reset this flag so that we don't keep opening and closing channels
// unnecessarily
hnd->flags &= ~private_handle_t::PRIV_FLAGS_FORMAT_CHANGED;
} else {
// The overlay goemetry may have changed, we only need to update the
// overlay
ret = ovLibObject->updateOverlaySource(hnd->width, hnd->height,
hnd->format, layer->transform);
if (!ret) {
LOGE("prepareOverlay updateOverlaySource failed");
return -1;
}
}
hwc_rect_t sourceCrop = layer->sourceCrop;
ret = ovLibObject->setCrop(sourceCrop.left, sourceCrop.top,
(sourceCrop.right - sourceCrop.left),
(sourceCrop.bottom - sourceCrop.top));
if (!ret) {
LOGE("prepareOverlay setCrop failed");
return -1;
}
if (layer->flags == HWC_USE_ORIGINAL_RESOLUTION) {
framebuffer_device_t* fbDev = hwcModule->fbDevice;
ret = ovLibObject->setPosition(0, 0,
fbDev->width, fbDev->height);
} else {
hwc_rect_t displayFrame = layer->displayFrame;
ret = ovLibObject->setPosition(displayFrame.left, displayFrame.top,
(displayFrame.right - displayFrame.left),
(displayFrame.bottom - displayFrame.top));
}
if (!ret) {
LOGE("prepareOverlay setPosition failed");
return -1;
}
ovLibObject->getOrientation(orientation);
if (orientation != layer->transform)
ret = ovLibObject->setParameter(OVERLAY_TRANSFORM, layer->transform);
if (!ret) {
LOGE("prepareOverlay setParameter failed transform %x",
layer->transform);
return -1;
}
}
return 0;
}
static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
@ -220,8 +304,19 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
// If there is a single Fullscreen layer, we can bypass it - TBD
// If there is only one video/camera buffer, we can bypass itn
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (yuvBufferCount == 1)) {
list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
if(prepareOverlay(ctx, &(list->hwLayers[i])) == 0) {
list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
} else if (hwcModule->compositionType & (COMPOSITION_TYPE_C2D)) {
//Fail safe path: If drawing with overlay fails,
//Use C2D if available.
list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
yuvBufferCount = 0;
} else {
//If C2D is not enabled fall back to GPU.
list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
yuvBufferCount = 0;
}
} else if (list->hwLayers[i].flags == HWC_USE_ORIGINAL_RESOLUTION) {
list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
@ -371,83 +466,22 @@ static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer,
static int drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
{
int ret = 0;
if (ctx && ctx->mOverlayLibObject) {
if (ctx && ctx->mOverlayLibObject) {
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
if (!hwcModule) {
LOGE("drawLayerUsingLayer null module ");
return -1;
}
private_handle_t *hnd = (private_handle_t *)layer->handle;
overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
int orientation = 0;
if (OVERLAY_CHANNEL_UP == ovLibObject->getChannelStatus())
ovLibObject->getOrientation(orientation);
if ((OVERLAY_CHANNEL_DOWN == ovLibObject->getChannelStatus())
|| (layer->transform != orientation) ||
(hnd->flags & private_handle_t::PRIV_FLAGS_FORMAT_CHANGED)) {
// Overlay channel is not started, or we have an orientation change or there is a
// format change, call setSource to open the overlay if necessary
ret = ovLibObject->setSource(hnd->width, hnd->height, hnd->format, layer->transform,
(ovLibObject->getHDMIStatus()?true:false), false);
if (!ret) {
LOGE("drawLayerUsingOverlay setSource failed");
return -1;
}
// Reset this flag so that we don't keep opening and closing channels unnecessarily
hnd->flags &= ~private_handle_t::PRIV_FLAGS_FORMAT_CHANGED;
} else {
// The overlay goemetry may have changed, we only need to update the overlay
ret = ovLibObject->updateOverlaySource(hnd->width, hnd->height, hnd->format,
layer->transform);
if (!ret) {
LOGE("drawLayerUsingOverlay updateOverlaySource failed");
return -1;
}
}
hwc_rect_t sourceCrop = layer->sourceCrop;
ret = ovLibObject->setCrop(sourceCrop.left, sourceCrop.top,
(sourceCrop.right - sourceCrop.left),
(sourceCrop.bottom-sourceCrop.top));
if (!ret) {
LOGE("drawLayerUsingOverlay setCrop failed");
return -1;
}
if (layer->flags == HWC_USE_ORIGINAL_RESOLUTION) {
framebuffer_device_t* fbDev = hwcModule->fbDevice;
ret = ovLibObject->setPosition(0, 0,
fbDev->width, fbDev->height);
} else {
hwc_rect_t displayFrame = layer->displayFrame;
ret = ovLibObject->setPosition(displayFrame.left, displayFrame.top,
(displayFrame.right - displayFrame.left),
(displayFrame.bottom-displayFrame.top));
}
if (!ret) {
LOGE("drawLayerUsingOverlay setPosition failed");
return -1;
}
ovLibObject->getOrientation(orientation);
if (orientation != layer->transform)
ret = ovLibObject->setParameter(OVERLAY_TRANSFORM, layer->transform);
if (!ret) {
LOGE("drawLayerUsingOverlay setParameter failed transform %x", layer->transform);
return -1;
}
int ret = 0;
ret = ovLibObject->queueBuffer(hnd);
if (!ret) {
LOGE("drawLayerUsingOverlay queueBuffer failed");
return -1;
}
return 0;
}
return -1;
return 0;
}
static int hwc_set(hwc_composer_device_t *dev,
@ -472,7 +506,6 @@ static int hwc_set(hwc_composer_device_t *dev,
if (list->hwLayers[i].flags == HWC_SKIP_LAYER) {
continue;
}
if (list->hwLayers[i].compositionType == HWC_USE_OVERLAY) {
drawLayerUsingOverlay(ctx, &(list->hwLayers[i]));
} else if (list->flags & HWC_SKIP_COMPOSITION) {