From ac786968e3905b4398d860e9f12891ffa031c0b3 Mon Sep 17 00:00:00 2001 From: "Arun Kumar K.R" Date: Wed, 11 Apr 2012 16:03:21 -0700 Subject: [PATCH] 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 --- libgralloc/framebuffer.cpp | 61 +++++++------ libgralloc/gralloc_priv.h | 3 +- libhwcomposer/external_display_only.h | 4 +- libhwcomposer/hwcomposer.cpp | 120 +++++++++++++++----------- libqcomui/qcom_ui.h | 17 ++++ 5 files changed, 128 insertions(+), 77 deletions(-) diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index 64e3c23..2a863ef 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -50,6 +50,7 @@ #endif #include +#include #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( - 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( - 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( @@ -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( + 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; diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h index 19b03e0..e40a1cc 100644 --- a/libgralloc/gralloc_priv.h +++ b/libgralloc/gralloc_priv.h @@ -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; diff --git a/libhwcomposer/external_display_only.h b/libhwcomposer/external_display_only.h index 4f2e275..757f9dc 100644 --- a/libhwcomposer/external_display_only.h +++ b/libhwcomposer/external_display_only.h @@ -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(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 } diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 6aa922a..2dec501 100644 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -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( - 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( + 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 ; inumHwLayers; 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 ; inumHwLayers; 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 ; inumHwLayers; 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; diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h index baba17f..22dc448 100644 --- a/libqcomui/qcom_ui.h +++ b/libqcomui/qcom_ui.h @@ -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 */