Merge remote-tracking branch 'caf/jb' into temp

This commit is contained in:
Andrew Sutherland 2012-08-09 22:38:37 -05:00
commit c8b3f3bce8
7 changed files with 194 additions and 90 deletions

View File

@ -77,6 +77,9 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
hwc_context_t* ctx = (hwc_context_t*)(dev);
ctx->overlayInUse = false;
if(ctx->mExtDisplay->getExternalDisplay())
ovutils::setExtType(ctx->mExtDisplay->getExternalDisplay());
//Prepare is called after a vsync, so unlock previous buffers here.
ctx->qbuf->unlockAllPrevious();
@ -110,7 +113,7 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
}
static int hwc_eventControl(struct hwc_composer_device* dev,
int event, int enabled)
int event, int value)
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
@ -118,13 +121,16 @@ static int hwc_eventControl(struct hwc_composer_device* dev,
ctx->mFbDev->common.module);
switch(event) {
case HWC_EVENT_VSYNC:
if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0)
if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &value) < 0)
ret = -errno;
if(ctx->mExtDisplay->getExternalDisplay()) {
ret = ctx->mExtDisplay->enableHDMIVsync(enabled);
ret = ctx->mExtDisplay->enableHDMIVsync(value);
}
break;
case HWC_EVENT_ORIENTATION:
ctx->deviceOrientation = value;
break;
default:
ret = -EINVAL;
}
@ -213,9 +219,9 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
methods->eventControl = hwc_eventControl;
dev->device.common.tag = HARDWARE_DEVICE_TAG;
//XXX: This disables hardware vsync on 7x27A, 8x25 and 8x55
// Fix when HW vsync is available on those targets
if(dev->mMDP.version < 410)
//XXX: This disables hardware vsync on 8x55
// Fix when HW vsync is available on 8x55
if(dev->mMDP.version == 400)
dev->device.common.version = 0;
else
dev->device.common.version = HWC_DEVICE_API_VERSION_0_3;

View File

@ -38,20 +38,20 @@
namespace qhwc {
#define DEVICE_ROOT "/sys/devices/virtual/graphics"
#define DEVICE_NODE "fb1"
#define SYSFS_EDID_MODES DEVICE_ROOT "/" DEVICE_NODE "/edid_modes"
#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE "/hpd"
static const char *extPanelName[MAX_DISPLAY_EXTERNAL_DEVICES] = {
HDMI_PANEL,
WFD_PANEL
};
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mHwcContext(ctx)
{
memset(&mVInfo, 0, sizeof(mVInfo));
//Enable HPD for HDMI
writeHPDOption(1);
if(isHDMIConfigured()) {
writeHPDOption(1);
}
}
ExternalDisplay::~ExternalDisplay()
@ -197,12 +197,16 @@ bool ExternalDisplay::readResolution()
return (strlen(mEDIDs) > 0);
}
bool ExternalDisplay::openFramebuffer()
const char* msmFbDevicePath[2] = { "/dev/graphics/fb1",
"/dev/graphics/fb2"};
bool ExternalDisplay::openFrameBuffer(int fbNum)
{
if (mFd == -1) {
mFd = open("/dev/graphics/fb1", O_RDWR);
mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
if (mFd < 0)
ALOGE("%s: /dev/graphics/fb1 not available", __FUNCTION__);
ALOGE("%s: %s not available", __FUNCTION__, msmFbDevicePath[fbNum-1]);
}
return (mFd > 0);
}
@ -294,7 +298,7 @@ void ExternalDisplay::setResolution(int ID)
{
struct fb_var_screeninfo info;
int ret = 0;
if (!openFramebuffer())
if (!openFrameBuffer(EXTERN_DISPLAY_FB1))
return;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
if(ret < 0) {
@ -354,32 +358,85 @@ void ExternalDisplay::setResolution(int ID)
}
}
/*
* This function queries the msm_fb_type for fb1 and checks whether it is
* HDMI or not
*
* Returns:
* 0 -> WFD device
* 1 -> HDMI device
*/
bool ExternalDisplay::isHDMIConfigured() {
bool configured = false;
FILE *displayDeviceFP = NULL;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
int ExternalDisplay::getExternalDisplay() const
{
return mExternalDisplay;
displayDeviceFP = fopen("/sys/class/graphics/fb1/msm_fb_type", "r");
if(displayDeviceFP) {
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE, displayDeviceFP);
if(!strncmp(fbType, extPanelName[0], sizeof(extPanelName[0]))) {
configured = true;
}
fclose(displayDeviceFP);
}
return configured;
}
void ExternalDisplay::processUEventOffline(const char *str) {
const char *s1 = str + (strlen(str)-strlen(DEVICE_NODE_FB1));
// check if it is for FB1
if(strncmp(s1,DEVICE_NODE_FB1, strlen(DEVICE_NODE_FB1))== 0) {
enableHDMIVsync(EXTERN_DISPLAY_NONE);
closeFrameBuffer();
resetInfo();
setExternalDisplay(EXTERN_DISPLAY_NONE);
}
else if(strncmp(s1, DEVICE_NODE_FB2, strlen(DEVICE_NODE_FB2)) == 0) {
closeFrameBuffer();
setExternalDisplay(EXTERN_DISPLAY_NONE);
}
}
void ExternalDisplay::processUEventOnline(const char *str) {
const char *s1 = str + (strlen(str)-strlen(DEVICE_NODE_FB1));
// check if it is for FB1
if(strncmp(s1,DEVICE_NODE_FB1, strlen(DEVICE_NODE_FB1))== 0) {
if(isHDMIConfigured()) {
// HDMI connect event.
// Tear-down WFD if it is active.
if(mExternalDisplay == EXTERN_DISPLAY_FB2) {
closeFrameBuffer();
setExternalDisplay(EXTERN_DISPLAY_NONE);
}
}
readResolution();
//Get the best mode and set
setResolution(getBestMode());
enableHDMIVsync(EXTERN_DISPLAY_FB1);
setExternalDisplay(EXTERN_DISPLAY_FB1);
}
else if(strncmp(s1, DEVICE_NODE_FB2, strlen(DEVICE_NODE_FB2)) == 0) {
// WFD connect event
if(mExternalDisplay == EXTERN_DISPLAY_FB1) {
// HDMI has higher priority.
// Do Not Override.
}else {
// WFD is connected
openFrameBuffer(EXTERN_DISPLAY_FB2);
setExternalDisplay(EXTERN_DISPLAY_FB2);
}
}
}
void ExternalDisplay::setExternalDisplay(int connected)
{
hwc_context_t* ctx = mHwcContext;
if(ctx) {
ALOGD_IF(DEBUG, "%s: status = %d", __FUNCTION__,
connected);
if(connected) {
readResolution();
//Get the best mode and set
// TODO: DO NOT call this for WFD
setResolution(getBestMode());
//enable hdmi vsync
enableHDMIVsync(connected);
} else {
// Disable the hdmi vsync
enableHDMIVsync(connected);
closeFrameBuffer();
resetInfo();
}
// Store the external display
mExternalDisplay = connected;
const char* prop = (connected) ? "1" : "0";
@ -388,8 +445,7 @@ void ExternalDisplay::setExternalDisplay(int connected)
//Invalidate
hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0];
if(!proc) {
ALOGE("%s: HWC proc not registered",
__FUNCTION__);
ALOGE("%s: HWC proc not registered", __FUNCTION__);
} else {
/* Trigger redraw */
ALOGD_IF(DEBUG, "%s: Invalidate !!", __FUNCTION__);

View File

@ -27,6 +27,25 @@ struct hwc_context_t;
namespace qhwc {
#define DEVICE_ROOT "/sys/devices/virtual/graphics"
#define DEVICE_NODE_FB1 "fb1"
#define DEVICE_NODE_FB2 "fb2"
#define HDMI_PANEL "dtv panel"
#define WFD_PANEL "writeback panel"
#define EXTERN_DISPLAY_NONE 0
#define EXTERN_DISPLAY_FB1 1
#define EXTERN_DISPLAY_FB2 2
#define MAX_FRAME_BUFFER_NAME_SIZE 80
#define MAX_DISPLAY_EXTERNAL_DEVICES 2
#define HPD_ENABLE 1
#define HPD_DISABLE 0
#define DEVICE_ONLINE true
#define DEVICE_OFFLINE false
#define SYSFS_EDID_MODES DEVICE_ROOT "/" DEVICE_NODE_FB1 "/edid_modes"
#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE_FB1 "/hpd"
class ExternalDisplay
{
//Type of external display - OFF, HDMI, WFD
@ -44,16 +63,19 @@ class ExternalDisplay
public:
ExternalDisplay(hwc_context_t* ctx);
~ExternalDisplay();
int getExternalDisplay() const;
inline int getExternalDisplay() { return mExternalDisplay; }
void setExternalDisplay(int connected);
bool commit();
int enableHDMIVsync(int enable);
void processUEventOnline(const char *str);
void processUEventOffline(const char *str);
bool isHDMIConfigured();
private:
bool readResolution();
int parseResolution(char* edidStr, int* edidModes);
void setResolution(int ID);
bool openFramebuffer();
bool openFrameBuffer(int fbNum);
bool closeFrameBuffer();
bool writeHPDOption(int userOption) const;
bool isValidMode(int ID);

View File

@ -18,8 +18,8 @@
* limitations under the License.
*/
#define DEBUG 0
#ifndef HWC_OBSERVER_H
#define HWC_OBSERVER_H
#ifndef HWC_UEVENTS_H
#define HWC_UEVENTS_H
#include <hardware_legacy/uevent.h>
#include <utils/Log.h>
#include <sys/resource.h>
@ -32,12 +32,11 @@ namespace qhwc {
const char* MSMFB_DEVICE_FB0 = "change@/devices/virtual/graphics/fb0";
const char* MSMFB_DEVICE_FB1 = "change@/devices/virtual/graphics/fb1";
const char* MSMFB_HDMI_NODE = "fb1";
const char* MSMFB_FB_NODE = "fb";
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
{
int vsync = 0;
char* hdmi;
int64_t timestamp = 0;
const char *str = udata;
hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0];
@ -48,12 +47,12 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
return;
}
if(hdmiconnected)
if(ctx->mExtDisplay->isHDMIConfigured() &&
(hdmiconnected == EXTERN_DISPLAY_FB1))
vsync = !strncmp(str, MSMFB_DEVICE_FB1, strlen(MSMFB_DEVICE_FB1));
else
vsync = !strncmp(str, MSMFB_DEVICE_FB0, strlen(MSMFB_DEVICE_FB0));
hdmi = strcasestr(str, MSMFB_HDMI_NODE);
if(vsync) {
str += strlen(str) + 1;
while(*str) {
@ -68,24 +67,18 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
return;
}
if(hdmi) {
// parse HDMI events
// The event will be of the form:
// change@/devices/virtual/graphics/fb1 ACTION=change
// DEVPATH=/devices/virtual/graphics/fb1
// SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
// for now just parsing onlin/offline info is enough
str = udata;
int connected = 0;
if(!(strncmp(str,"online@",strlen("online@")))) {
connected = 1;
ctx->mExtDisplay->setExternalDisplay(connected);
} else if(!(strncmp(str,"offline@",strlen("offline@")))) {
connected = 0;
ctx->mExtDisplay->setExternalDisplay(connected);
}
// parse HDMI events
// The event will be of the form:
// change@/devices/virtual/graphics/fb1 ACTION=change
// DEVPATH=/devices/virtual/graphics/fb1
// SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
// for now just parsing onlin/offline info is enough
str = udata;
if(!(strncmp(str,"online@",strlen("online@")))) {
ctx->mExtDisplay->processUEventOnline(str);
} else if(!(strncmp(str,"offline@",strlen("offline@")))) {
ctx->mExtDisplay->processUEventOffline(str);
}
}
static void *uevent_loop(void *param)
@ -113,4 +106,4 @@ void init_uevent_thread(hwc_context_t* ctx)
}
}; //namespace
#endif //HWC_OBSERVER_H
#endif //HWC_UEVENTS_H

View File

@ -27,30 +27,6 @@
namespace qhwc {
// Function to get the primary device orientation
// Loops thru the hardware layers and returns the orientation of the max.
// number of layers
int getDeviceOrientation(hwc_context_t* ctx, hwc_layer_list_t *list) {
int orientation = list->hwLayers[0].transform;
if(!ctx) {
ALOGE("In %s: ctx is NULL!!", __FUNCTION__);
return -1;
}
for(size_t i=0; i <= list->numHwLayers;i++ )
{
for(size_t j=i+1; j <= list->numHwLayers; j++)
{
// Should we not check for the video layer orientation as it might
// source orientation(?)
if(list->hwLayers[i].transform == list->hwLayers[j].transform)
{
orientation = list->hwLayers[i].transform;
}
}
}
return orientation;
}
//Static Members
ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED;
bool UIMirrorOverlay::sIsUiMirroringOn = false;
@ -120,10 +96,8 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_list_t *list)
// x,y,w,h
ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres);
ov.setCrop(dcrop, dest);
//Get the current orientation on primary panel
int transform = getDeviceOrientation(ctx, list);
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
static_cast<ovutils::eTransform>(ctx->deviceOrientation);
ov.setTransform(orient, dest);
ovutils::Dim dim;

View File

@ -124,6 +124,7 @@ struct hwc_context_t {
hwc_composer_device_t device;
int numHwLayers;
int overlayInUse;
int deviceOrientation;
//Framebuffer device
framebuffer_device_t *mFbDev;

52
libqdutils/gpuformats.h Normal file
View File

@ -0,0 +1,52 @@
/* 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
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QCOM_GPUFORMATS_H
#define QCOM_GPUFORMATS_H
#include <gralloc_priv.h>
namespace qdutils {
/*
* Checks if the format is supported by the GPU.
*
* @param: format to check
*
* @return true if the format is supported by the GPU.
*/
static inline bool isGPUSupportedFormat(int format)
{
if ((format == HAL_PIXEL_FORMAT_RGB_888) ||
(format == HAL_PIXEL_FORMAT_YCrCb_422_SP) ||
(format == HAL_PIXEL_FORMAT_YCbCr_422_SP)) {
return false;
}
return true;
}
}; //namespace qdutils
#endif /* end of include guard: QCOM_GPUFORMATS_H */