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:
parent
5e6e965be7
commit
ac786968e3
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user