qcom/display: add perform function to fb/hwc HALS

- Add perform function to framebuffer and HWComposer HALS
- This will be used communicate custom events(external display,
  video overlay, orientation, etc.,) to HALS
- remove setActionsafe API(not used)

CRs-Fixed: 341947
(cherry picked from commit 31999628ddd4a6c0996e22e9fbf1f311d6efb160)

Change-Id: I221f2ab49770e8db7602bb1881ef9972567b7780
This commit is contained in:
Arun Kumar K.R 2012-04-11 16:03:21 -07:00 committed by Andrew Sutherland
parent 5e6e965be7
commit ac786968e3
5 changed files with 128 additions and 77 deletions

View File

@ -50,6 +50,7 @@
#endif
#include <utils/profiler.h>
#include <qcom_ui.h>
#define FB_DEBUG 0
@ -286,6 +287,12 @@ static void *hdmi_ui_loop(void *ptr)
if (m->trueMirrorSupport)
flags &= ~WAIT_FOR_VSYNC;
// External display connected during secure video playback
// Open secure UI session
// NOTE: when external display is already connected and then secure
// playback is started, we dont have to do anything
if(m->secureVideoOverlay)
flags |= SECURE_OVERLAY_SESSION;
// start the overlay Channel for mirroring
// m->enableHDMIOutput corresponds to the fbnum
if (pTemp->startChannel(info, m->enableHDMIOutput,
@ -383,27 +390,6 @@ static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltyp
return 0;
}
static int fb_setActionSafeWidthRatio(struct framebuffer_device_t* dev, float asWidthRatio)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
pthread_mutex_lock(&m->overlayLock);
m->actionsafeWidthRatio = asWidthRatio;
pthread_mutex_unlock(&m->overlayLock);
return 0;
}
static int fb_setActionSafeHeightRatio(struct framebuffer_device_t* dev, float asHeightRatio)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
pthread_mutex_lock(&m->overlayLock);
m->actionsafeHeightRatio = asHeightRatio;
pthread_mutex_unlock(&m->overlayLock);
return 0;
}
static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
@ -415,6 +401,33 @@ static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientati
}
#endif
/* fb_perform - used to add custom event and handle them in fb HAL
* Used for external display related functions as of now
*/
static int fb_perform(struct framebuffer_device_t* dev, int event, int value)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
switch(event) {
#if defined(HDMI_DUAL_DISPLAY)
case EVENT_EXTERNAL_DISPLAY:
fb_enableHDMIOutput(dev, value);
break;
case EVENT_VIDEO_OVERLAY:
fb_videoOverlayStarted(dev, value);
break;
case EVENT_ORIENTATION_CHANGE:
fb_orientationChanged(dev, value);
break;
#endif
default:
LOGE("In %s: UNKNOWN Event = %d!!!", __FUNCTION__, event);
break;
}
return 0;
}
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
{
if (private_handle_t::validate(buffer) < 0)
@ -859,11 +872,7 @@ int fb_device_open(hw_module_t const* module, const char* name,
dev->device.compositionComplete = fb_compositionComplete;
dev->device.lockBuffer = fb_lockBuffer;
#if defined(HDMI_DUAL_DISPLAY)
dev->device.orientationChanged = fb_orientationChanged;
dev->device.videoOverlayStarted = fb_videoOverlayStarted;
dev->device.enableHDMIOutput = fb_enableHDMIOutput;
dev->device.setActionSafeWidthRatio = fb_setActionSafeWidthRatio;
dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
dev->device.perform = fb_perform;
#endif
private_module_t* m = (private_module_t*)module;

View File

@ -301,7 +301,8 @@ struct private_module_t {
#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
Overlay* pobjOverlay;
int orientation;
bool videoOverlay;
int videoOverlay; // VIDEO_OVERLAY - 2D or 3D
int secureVideoOverlay; // VideoOverlay is secure
uint32_t currentOffset;
int enableHDMIOutput; // holds the type of external display
bool trueMirrorSupport;

View File

@ -268,7 +268,7 @@ inline void ExtDispOnly::startDefaultMirror(hwc_context_t* ctx) {
framebuffer_device_t *fbDev = hwcModule->fbDevice;
if (fbDev) {
//mHDMIEnabled could be HDMI/WFD/NO EXTERNAL
fbDev->enableHDMIOutput(fbDev, ctx->mHDMIEnabled);
fbDev->perform(fbDev, EVENT_EXTERNAL_DISPLAY, ctx->mHDMIEnabled);
}
#endif
}
@ -280,7 +280,7 @@ inline void ExtDispOnly::stopDefaultMirror(hwc_context_t* ctx) {
reinterpret_cast<private_hwc_module_t*>(dev->common.module);
framebuffer_device_t *fbDev = hwcModule->fbDevice;
if (fbDev) {
fbDev->enableHDMIOutput(fbDev, EXT_TYPE_NONE);
fbDev->perform(fbDev, EVENT_EXTERNAL_DISPLAY, EXT_TYPE_NONE);
}
#endif
}

View File

@ -86,6 +86,7 @@ struct hwc_context_t {
native_handle_t *previousOverlayHandle;
native_handle_t *currentOverlayHandle;
int yuvBufferCount;
int numLayersNotUpdating;
#ifdef COMPOSITION_BYPASS
overlay::OverlayUI* mOvUI[MAX_BYPASS_LAYERS];
native_handle_t* previousBypassHandle[MAX_BYPASS_LAYERS];
@ -625,7 +626,6 @@ void closeExtraPipes(hwc_context_t* ctx) {
}
#endif //COMPOSITION_BYPASS
// Returns true if external panel is connected
static inline bool isExternalConnected(const hwc_context_t* ctx) {
#if defined HDMI_DUAL_DISPLAY
@ -672,10 +672,10 @@ static inline void markForGPUComp(const hwc_context_t *ctx,
}
static int setVideoOverlayStatusInGralloc(hwc_context_t* ctx, const bool enable) {
static int setVideoOverlayStatusInGralloc(hwc_context_t* ctx, const int value) {
#if defined HDMI_DUAL_DISPLAY
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
ctx->device.common.module);
ctx->device.common.module);
if(!hwcModule) {
LOGE("%s: invalid params", __FUNCTION__);
return -1;
@ -687,8 +687,8 @@ static int setVideoOverlayStatusInGralloc(hwc_context_t* ctx, const bool enable)
return -1;
}
// Inform the gralloc to stop or start UI mirroring
fbDev->videoOverlayStarted(fbDev, enable);
// Inform the gralloc about the video overlay
fbDev->perform(fbDev, EVENT_VIDEO_OVERLAY, value);
#endif
return 0;
}
@ -707,7 +707,7 @@ static int hwc_closeOverlayChannels(hwc_context_t* ctx) {
// gralloc to start UI mirroring
ovLibObject->closeChannel();
// Inform the gralloc that video overlay has stopped.
setVideoOverlayStatusInGralloc(ctx, false);
setVideoOverlayStatusInGralloc(ctx, VIDEO_OVERLAY_ENDED);
ctx->hwcOverlayStatus = HWC_OVERLAY_CLOSED;
}
#endif
@ -838,7 +838,7 @@ bool canSkipComposition(hwc_context_t* ctx, int yuvBufferCount, int currentLayer
return false;
//Video / Camera case
if (yuvBufferCount == 1) {
if (ctx->yuvBufferCount == 1) {
//If the previousLayerCount is anything other than the current count, it
//means something changed and we need to compose atleast once to FB.
if (currentLayerCount != ctx->previousLayerCount) {
@ -896,7 +896,7 @@ static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype)
if(ExtDispOnly::isModeOn() == false) {
framebuffer_device_t *fbDev = hwcModule->fbDevice;
if (fbDev) {
fbDev->enableHDMIOutput(fbDev, externaltype);
fbDev->perform(fbDev, EVENT_EXTERNAL_DISPLAY, externaltype);
}
// Yield - Allows the UI channel(with zorder 0) to be opened first
sched_yield();
@ -953,6 +953,26 @@ static void hwc_enableHDMIOutput(hwc_composer_device_t *dev, int externaltype) {
#endif
}
/* function to handle the custom events to hwc.
* event - type of event
* value - value associated with the event
*/
static void hwc_perform(hwc_composer_device_t *dev, int event, int value) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
dev->common.module);
switch(event) {
#if defined HDMI_DUAL_DISPLAY
case EVENT_EXTERNAL_DISPLAY:
hwc_enableHDMIOutput(dev, value);
break;
#endif
default:
LOGE("In hwc:perform UNKNOWN EVENT = %d!!", event);
break;
}
return;
}
static bool isValidDestination(const framebuffer_device_t* fbDev, const hwc_rect_t& rect)
{
if (!fbDev) {
@ -979,20 +999,6 @@ static bool isValidDestination(const framebuffer_device_t* fbDev, const hwc_rect
return true;
}
static int getYUVBufferCount (const hwc_layer_list_t* list) {
int yuvBufferCount = 0;
if (list) {
for (size_t i=0 ; i<list->numHwLayers; i++) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
!(list->hwLayers[i].flags & HWC_DO_NOT_USE_OVERLAY)) {
yuvBufferCount++;
}
}
}
return yuvBufferCount;
}
static int getS3DVideoFormat (const hwc_layer_list_t* list) {
int s3dFormat = 0;
if (list) {
@ -1048,18 +1054,37 @@ static void markUILayerForS3DComposition (hwc_layer_t &layer, int s3dVideoFormat
return;
}
static int getLayersNotUpdatingCount(const hwc_layer_list_t* list) {
int numLayersNotUpdating = 0;
if (list) {
for (size_t i=0 ; i<list->numHwLayers; i++) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
if (hnd && (hnd->bufferType != BUFFER_TYPE_VIDEO) &&
list->hwLayers[i].flags & HWC_LAYER_NOT_UPDATING)
numLayersNotUpdating++;
}
}
return numLayersNotUpdating;
}
/*
* This function loops thru the list of hwc layers and caches the
* layer details - such as yuvBuffer count, secure layer count etc.,(can
* add more in future)
* */
static void statCount(hwc_context_t *ctx, hwc_layer_list_t* list) {
int yuvBufCount = 0;
int secureLayerCnt = 0;
int layersNotUpdatingCount = 0;
if (list) {
for (size_t i=0 ; i<list->numHwLayers; i++) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
!(list->hwLayers[i].flags & HWC_DO_NOT_USE_OVERLAY)) {
yuvBufCount++;
}
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) ) {
secureLayerCnt++;
}
if (hnd && (hnd->bufferType != BUFFER_TYPE_VIDEO) &&
list->hwLayers[i].flags & HWC_LAYER_NOT_UPDATING) {
layersNotUpdatingCount++;
}
}
}
ctx->yuvBufferCount = yuvBufCount;
ctx->numLayersNotUpdating = layersNotUpdatingCount;
return;
}
static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
@ -1085,28 +1110,25 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
return -1;
}
int yuvBufferCount = 0;
int layerType = 0;
bool isS3DCompositionNeeded = false;
int s3dVideoFormat = 0;
int numLayersNotUpdating = 0;
bool useCopybit = false;
bool isSkipLayerPresent = false;
bool skipComposition = false;
if (list) {
useCopybit = canUseCopybit(hwcModule->fbDevice, list);
ctx->yuvBufferCount = getYUVBufferCount(list);
yuvBufferCount = ctx->yuvBufferCount;
numLayersNotUpdating = getLayersNotUpdatingCount(list);
skipComposition = canSkipComposition(ctx, yuvBufferCount,
list->numHwLayers, numLayersNotUpdating);
// cache the number of layer(like YUV, SecureBuffer, notupdating etc.,)
statCount(ctx, list);
skipComposition = canSkipComposition(ctx, ctx->yuvBufferCount,
list->numHwLayers, ctx->numLayersNotUpdating);
if ((yuvBufferCount == 0) && (ctx->hwcOverlayStatus == HWC_OVERLAY_OPEN)) {
if ((ctx->yuvBufferCount == 0) && (ctx->hwcOverlayStatus == HWC_OVERLAY_OPEN)) {
ctx->hwcOverlayStatus = HWC_OVERLAY_PREPARE_TO_CLOSE;
}
if (yuvBufferCount == 1) {
if (ctx->yuvBufferCount == 1) {
s3dVideoFormat = getS3DVideoFormat(list);
if (s3dVideoFormat)
isS3DCompositionNeeded = isS3DCompositionRequired();
@ -1145,13 +1167,14 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
markForGPUComp(ctx, list, i);
} else if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (yuvBufferCount == 1)) {
setVideoOverlayStatusInGralloc(ctx, true);
} else if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (ctx->yuvBufferCount == 1)) {
int flags = WAIT_FOR_VSYNC;
flags |= (hnd->flags &
private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
SECURE_OVERLAY_SESSION : 0;
flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
int videoStarted = VIDEO_2D_OVERLAY_STARTED;
setVideoOverlayStatusInGralloc(ctx, videoStarted);
if (!isValidDestination(hwcModule->fbDevice, list->hwLayers[i].displayFrame)) {
list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
@ -1187,12 +1210,13 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
skipComposition = false;
}
} else if (getLayerS3DFormat(list->hwLayers[i])) {
setVideoOverlayStatusInGralloc(ctx, true);
int flags = WAIT_FOR_VSYNC;
flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
flags |= (hnd->flags &
private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
SECURE_OVERLAY_SESSION : 0;
int videoStarted = VIDEO_3D_OVERLAY_STARTED;
setVideoOverlayStatusInGralloc(ctx, videoStarted);
#ifdef USE_OVERLAY
if(prepareOverlay(ctx, &(list->hwLayers[i]), flags) == 0) {
list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
@ -1232,7 +1256,7 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
#ifdef COMPOSITION_BYPASS
bool isBypassUsed = true;
bool isDoable = isBypassDoable(dev, yuvBufferCount, list);
bool isDoable = isBypassDoable(dev, ctx->yuvBufferCount, list);
//Check if bypass is feasible
if(isDoable && !isSkipLayerPresent) {
if(setupBypass(ctx, list)) {
@ -1863,7 +1887,7 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.registerProcs = hwc_registerProcs;
dev->device.enableHDMIOutput = hwc_enableHDMIOutput;
dev->device.perform = hwc_perform;
*device = &dev->device.common;
status = 0;

View File

@ -106,6 +106,23 @@ enum external_display_type {
EXT_TYPE_WIFI
};
/* Events to the Display HAL perform function
As of now used for external display related such as
connect, disconnect, orientation, video started etc.,
*/
enum {
EVENT_EXTERNAL_DISPLAY, // External display on/off Event
EVENT_VIDEO_OVERLAY, // Video Overlay start/stop Event
EVENT_ORIENTATION_CHANGE, // Orientation Change Event
};
// Video information sent to framebuffer HAl
// used for handling UI mirroring.
enum {
VIDEO_OVERLAY_ENDED = 0,
VIDEO_2D_OVERLAY_STARTED,
VIDEO_3D_OVERLAY_STARTED
};
/*
* Structure to hold the buffer geometry
*/