qcom/display: Add support for WFD

- HDMI has priority over Wifi display, if HDMI is connected during
  Wifi, close the session for Wifi and start one for HDMI.
- the enableHDMIOutput parameter externaltype - HDMI/WIFI/OFF

Change-Id: If2cd9143fc7a953db49f38a6c166f9425ba5266e

Conflicts:

	libqcomui/qcom_ui.cpp
This commit is contained in:
Arun Kumar K.R 2011-12-16 15:46:50 -08:00 committed by Andrew Sutherland
parent f7154c6f4c
commit 37c2692006
7 changed files with 116 additions and 34 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -255,8 +255,9 @@ static void *hdmi_ui_loop(void *ptr)
if (m->trueMirrorSupport)
waitForVsync = false;
if (pTemp->startChannel(info, FRAMEBUFFER_1,
// start the overlay Channel for mirroring
// m->enableHDMIOutput corresponds to the fbnum
if (pTemp->startChannel(info, m->enableHDMIOutput,
false, true, 0, VG0_PIPE, waitForVsync)) {
pTemp->setFd(m->framebuffer->fd);
pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
@ -400,21 +401,22 @@ static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
return 0;
}
static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int enable)
static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltype)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
pthread_mutex_lock(&m->overlayLock);
Overlay* pTemp = m->pobjOverlay;
m->enableHDMIOutput = enable;
if(enable) {
m->enableHDMIOutput = externaltype;
LOGE("In fb_enableHDMIOutput: externaltype = %d", m->enableHDMIOutput);
if(externaltype) {
if (m->trueMirrorSupport) {
m->hdmiMirroringState = HDMI_UI_MIRRORING;
} else {
if(!m->videoOverlay)
m->hdmiMirroringState = HDMI_UI_MIRRORING;
}
} else if (!enable && pTemp) {
} else if (!externaltype && pTemp) {
m->hdmiMirroringState = HDMI_NO_MIRRORING;
closeHDMIChannel(m);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -284,7 +284,7 @@ struct private_module_t {
int orientation;
bool videoOverlay;
uint32_t currentOffset;
bool enableHDMIOutput;
int enableHDMIOutput; // holds the type of external display
bool trueMirrorSupport;
bool exitHDMIUILoop;
float actionsafeWidthRatio;

View File

@ -90,7 +90,7 @@ struct hwc_context_t {
BypassState bypassState;
#endif
#if defined HDMI_DUAL_DISPLAY
bool mHDMIEnabled;
external_display mHDMIEnabled; // Type of external display
bool pendingHDMI;
#endif
int previousLayerCount;
@ -285,8 +285,13 @@ static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer, const bool wai
info.secure = (hnd->flags &
private_handle_t::PRIV_FLAGS_SECURE_BUFFER)? true:false;
int hdmiConnected = 0;
#if defined HDMI_DUAL_DISPLAY
hdmiConnected = (int)ctx->mHDMIEnabled;
#endif
ret = ovLibObject->setSource(info, layer->transform,
(ovLibObject->getHDMIStatus()?true:false), waitForVsync);
hdmiConnected, waitForVsync);
if (!ret) {
LOGE("prepareOverlay setSource failed");
return -1;
@ -661,20 +666,20 @@ void storeLockedBypassHandle(hwc_layer_list_t* list, hwc_context_t* ctx) {
#endif //COMPOSITION_BYPASS
static void handleHDMIStateChange(hwc_composer_device_t *dev) {
static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype) {
#if defined HDMI_DUAL_DISPLAY
hwc_context_t* ctx = (hwc_context_t*)(dev);
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
dev->common.module);
framebuffer_device_t *fbDev = hwcModule->fbDevice;
if (fbDev) {
fbDev->enableHDMIOutput(fbDev, ctx->mHDMIEnabled);
fbDev->enableHDMIOutput(fbDev, externaltype);
}
if(ctx && ctx->mOverlayLibObject) {
overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
ovLibObject->setHDMIStatus(ctx->mHDMIEnabled);
if (!(ctx->mHDMIEnabled)) {
ovLibObject->setHDMIStatus(externaltype);
if (!externaltype) {
// Close the overlay channels if HDMI is disconnected
ovLibObject->closeChannel();
}
@ -683,15 +688,29 @@ static void handleHDMIStateChange(hwc_composer_device_t *dev) {
}
/* Just mark flags and do stuff after eglSwapBuffers */
static void hwc_enableHDMIOutput(hwc_composer_device_t *dev, bool enable) {
/*
* function to set the status of external display in hwc
* Just mark flags and do stuff after eglSwapBuffers
* externaltype - can be HDMI, WIFI or OFF
*/
static void hwc_enableHDMIOutput(hwc_composer_device_t *dev, int externaltype) {
#if defined HDMI_DUAL_DISPLAY
hwc_context_t* ctx = (hwc_context_t*)(dev);
ctx->mHDMIEnabled = enable;
if(enable) { //On connect, allow bypass to draw once to FB
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
dev->common.module);
framebuffer_device_t *fbDev = hwcModule->fbDevice;
overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
if(externaltype && (externaltype != ctx->mHDMIEnabled)) {
// Close the current external display - as the SF will
// prioritize and send the correct external display
handleHDMIStateChange(dev, 0);
}
// Store the external display
ctx->mHDMIEnabled = (external_display)externaltype;
if(ctx->mHDMIEnabled) { //On connect, allow bypass to draw once to FB
ctx->pendingHDMI = true;
} else { //On disconnect, close immediately (there will be no bypass)
handleHDMIStateChange(dev);
handleHDMIStateChange(dev, ctx->mHDMIEnabled);
}
#endif
}
@ -1323,7 +1342,7 @@ static int hwc_set(hwc_composer_device_t *dev,
#endif
#if defined HDMI_DUAL_DISPLAY
if(ctx->pendingHDMI) {
handleHDMIStateChange(dev);
handleHDMIStateChange(dev, ctx->mHDMIEnabled);
ctx->pendingHDMI = false;
}
#endif
@ -1452,7 +1471,7 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
#endif
#if defined HDMI_DUAL_DISPLAY
dev->mHDMIEnabled = false;
dev->mHDMIEnabled = EXT_DISPLAY_OFF;
dev->pendingHDMI = false;
#endif
dev->previousOverlayHandle = NULL;

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -211,6 +211,7 @@ int ZOrderManager::getZ(int fbnum){
}
break;
case FRAMEBUFFER_1:
case FRAMEBUFFER_2:
for (int i = 0;i < mMaxPipes; i++) {
if(mFB1Pipes[i] == false) {
mFB1Pipes[i]= true;
@ -238,6 +239,7 @@ void ZOrderManager::decZ(int fbnum, int zorder){
mFB0Pipes[zorder] = false;
break;
case FRAMEBUFFER_1:
case FRAMEBUFFER_2:
LOG_ASSERT(!mFB1Pipes[zorder],"channel with ZOrder does not exist");
LOGE("decZ: freeing the pipe with zorder = %d for fbdev = %d", zorder, fbnum);
mFB1Pipes[zorder] = false;
@ -636,7 +638,7 @@ int Overlay::getS3DFormat(int format) {
}
bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
bool hdmiConnected, bool waitForVsync, int num_buffers) {
int hdmiConnected, bool waitForVsync, int num_buffers) {
// Separate the color format from the 3D format.
// If there is 3D content; the effective format passed by the client is:
// effectiveFormat = 3D_IN | 3D_OUT | ColorFormat
@ -661,6 +663,7 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
// We always enable the rotator for the primary.
bool noRot = false;
bool uiChannel = false;
int fbnum = 0;
switch(mState) {
case OV_2D_VIDEO_ON_PANEL:
case OV_3D_VIDEO_2D_PANEL:
@ -684,12 +687,16 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
case OV_2D_VIDEO_ON_TV:
case OV_3D_VIDEO_2D_TV:
for (int i=0; i<NUM_CHANNELS; i++) {
if (FRAMEBUFFER_1 == i) {
// Disable rotation for HDMI
fbnum = i;
//start two channels for one for primary and external.
if (fbnum) {
// Disable rotation for external
noRot = true;
waitForVsync = false;
//set fbnum to hdmiConnected, which holds the ext display
fbnum = hdmiConnected;
}
if(!startChannel(info, i, noRot, false, mS3DFormat,
if(!startChannel(info, fbnum, noRot, false, mS3DFormat,
i, waitForVsync, num_buffers)) {
LOGE("%s:failed to open channel %d", __FUNCTION__, i);
return false;
@ -1095,7 +1102,6 @@ bool OverlayControlChannel::openDevices(int fbnum) {
"/dev/graphics/fb%u";
char dev_name[64];
snprintf(dev_name, 64, device_template, fbnum);
mFD = open(dev_name, O_RDWR, 0);
if (mFD < 0) {
reportError("Cant open framebuffer ");

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -58,6 +58,7 @@
#define NUM_CHANNELS 2
#define FRAMEBUFFER_0 0
#define FRAMEBUFFER_1 1
#define FRAMEBUFFER_2 2
#define NUM_SHARPNESS_VALS 256
#define SHARPNESS_RANGE 1.0f
#define HUE_RANGE 180
@ -387,7 +388,8 @@ public:
class Overlay {
bool mChannelUP;
bool mHDMIConnected;
////stores the connected external display
int mHDMIConnected;
unsigned int mS3DFormat;
//Actual cropped source width and height of overlay
int mCroppedSrcWidth;
@ -421,7 +423,7 @@ public:
int getFBHeight(int channel = 0) const;
bool getOrientation(int& orientation, int channel = 0) const;
bool queueBuffer(buffer_handle_t buffer);
bool setSource(const overlay_buffer_info& info, int orientation, bool hdmiConnected,
bool setSource(const overlay_buffer_info& info, int orientation, int hdmiConnected,
bool ignoreFB = false, int numBuffers = 2);
bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
bool updateWaitForVsyncFlags(bool waitForVsync);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -489,9 +489,42 @@ int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
dst += stride;
} while(--h);
}
return 0;
}
/*
* Handles the externalDisplay event
* HDMI has highest priority compared to WifiDisplay
* Based on the current and the new display event, decides the
* external display to be enabled
*
* @param: newEvent - new external event
* @param: currEvent - currently enabled external event
* @return: external display to be enabled
*
*/
external_display handleEventHDMI(external_display newState, external_display
currState)
{
external_display retState = currState;
switch(newState) {
case EXT_DISPLAY_HDMI:
retState = EXT_DISPLAY_HDMI;
break;
case EXT_DISPLAY_WIFI:
if(currState != EXT_DISPLAY_HDMI) {
retState = EXT_DISPLAY_WIFI;
}
break;
case EXT_DISPLAY_OFF:
retState = EXT_DISPLAY_OFF;
break;
default:
LOGE("handleEventHDMI: unknown Event");
break;
}
return retState;
}
#ifdef DEBUG_CALC_FPS
ANDROID_SINGLETON_STATIC_INSTANCE(CalcFps) ;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -89,6 +89,12 @@ enum HWCCompositionType {
HWC_USE_COPYBIT // This layer is to be handled by copybit
};
enum external_display {
EXT_DISPLAY_OFF,
EXT_DISPLAY_HDMI,
EXT_DISPLAY_WIFI
};
/*
* Structure to hold the buffer geometry
*/
@ -334,4 +340,18 @@ int getCompositionType();
* @return 0 on success
*/
int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur);
/*
* Handles the externalDisplay event
* HDMI has highest priority compared to WifiDisplay
* Based on the current and the new display event, decides the
* external display to be enabled
*
* @param: newEvent - new external event
* @param: currEvent - currently enabled external event
* @return: external display to be enabled
*
*/
external_display handleEventHDMI(external_display newEvent, external_display
currEvent);
#endif // INCLUDE_LIBQCOM_UI