display: Enable vsync
* Use the vsync uevents from the kernel to start surfaceflinger composition. * This patch also does some code cleanup - Move copybit specific functions to copybit files. - Cleanup verbose logging. Change-Id: I8ca3cd7a7ceb53655ed0fcf39ac2cb35e6cbe890
This commit is contained in:
parent
9c552477aa
commit
9ccb3975c7
@ -10,6 +10,6 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay libgenlock \
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"hwcomposer\"
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
|
||||
LOCAL_SRC_FILES := hwc.cpp hwc_video.cpp hwc_utils.cpp \
|
||||
hwc_uimirror.cpp hwc_ext_observer.cpp \
|
||||
hwc_copybit.cpp
|
||||
hwc_uimirror.cpp hwc_external.cpp \
|
||||
hwc_uevents.cpp hwc_copybit.cpp
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
@ -20,8 +20,12 @@
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/atomic.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <overlay.h>
|
||||
#include <fb_priv.h>
|
||||
#include "hwc_utils.h"
|
||||
#include "hwc_qbuf.h"
|
||||
#include "hwc_video.h"
|
||||
#include "hwc_uimirror.h"
|
||||
#include "hwc_copybit.h"
|
||||
@ -92,6 +96,47 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hwc_eventControl(struct hwc_composer_device* dev,
|
||||
int event, int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
ctx->mFbDev->common.module);
|
||||
switch(event) {
|
||||
case HWC_EVENT_VSYNC:
|
||||
if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hwc_query(struct hwc_composer_device* dev,
|
||||
int param, int* value)
|
||||
{
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
ctx->mFbDev->common.module);
|
||||
|
||||
switch (param) {
|
||||
case HWC_BACKGROUND_LAYER_SUPPORTED:
|
||||
// Not supported for now
|
||||
value[0] = 0;
|
||||
break;
|
||||
case HWC_VSYNC_PERIOD:
|
||||
value[0] = 1000000000.0 / m->fps;
|
||||
ALOGI("fps: %d", value[0]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int hwc_set(hwc_composer_device_t *dev,
|
||||
hwc_display_t dpy,
|
||||
hwc_surface_t sur,
|
||||
@ -118,7 +163,7 @@ static int hwc_set(hwc_composer_device_t *dev,
|
||||
static int hwc_device_close(struct hw_device_t *dev)
|
||||
{
|
||||
if(!dev) {
|
||||
ALOGE("hwc_device_close null device pointer");
|
||||
ALOGE("%s: NULL device pointer", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
closeContext((hwc_context_t*)dev);
|
||||
@ -136,14 +181,25 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
|
||||
struct hwc_context_t *dev;
|
||||
dev = (hwc_context_t*)malloc(sizeof(*dev));
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
//Initialize hwc context
|
||||
initContext(dev);
|
||||
|
||||
//Setup HWC methods
|
||||
hwc_methods_t *methods;
|
||||
methods = (hwc_methods_t *)malloc(sizeof(*methods));
|
||||
memset(methods, 0, sizeof(*methods));
|
||||
methods->eventControl = hwc_eventControl;
|
||||
|
||||
dev->device.common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->device.common.version = 0;
|
||||
dev->device.common.version = HWC_DEVICE_API_VERSION_0_3;
|
||||
dev->device.common.module = const_cast<hw_module_t*>(module);
|
||||
dev->device.common.close = hwc_device_close;
|
||||
dev->device.prepare = hwc_prepare;
|
||||
dev->device.set = hwc_set;
|
||||
dev->device.registerProcs = hwc_registerProcs;
|
||||
dev->device.query = hwc_query;
|
||||
dev->device.methods = methods;
|
||||
*device = &dev->device.common;
|
||||
status = 0;
|
||||
}
|
||||
|
@ -18,8 +18,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <copybit.h>
|
||||
#include <genlock.h>
|
||||
#include "hwc_copybit.h"
|
||||
#include "hwc_copybitEngine.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
@ -71,6 +72,23 @@ bool CopyBit::sIsModeOn = false;
|
||||
bool CopyBit::sIsLayerSkip = false;
|
||||
void* CopyBit::egl_lib = NULL;
|
||||
|
||||
void CopyBit::openEglLibAndGethandle()
|
||||
{
|
||||
egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (!egl_lib) {
|
||||
return;
|
||||
}
|
||||
updateEglHandles(egl_lib);
|
||||
}
|
||||
void CopyBit::closeEglLib()
|
||||
{
|
||||
if(egl_lib)
|
||||
::dlclose(egl_lib);
|
||||
|
||||
egl_lib = NULL;
|
||||
updateEglHandles(NULL);
|
||||
}
|
||||
|
||||
void CopyBit::updateEglHandles(void* egl_lib)
|
||||
{
|
||||
if(egl_lib != NULL) {
|
||||
@ -365,7 +383,7 @@ bool CopyBit::canUseCopybit(hwc_context_t *ctx, const hwc_layer_list_t* list,
|
||||
if(ctx->hasOverlay)
|
||||
return false;
|
||||
|
||||
framebuffer_device_t* fbDev = ctx->mFbDevice->getFb();
|
||||
framebuffer_device_t* fbDev = ctx->mFbDev;
|
||||
if(!fbDev) {
|
||||
ALOGE("ERROR: canUseCopybit : fb device is invalid");
|
||||
return false;
|
||||
@ -402,27 +420,11 @@ bool CopyBit::canUseCopybit(hwc_context_t *ctx, const hwc_layer_list_t* list,
|
||||
|
||||
return (renderArea <= (2 * fb_w * fb_h));
|
||||
}
|
||||
void CopyBit::openEglLibAndGethandle()
|
||||
{
|
||||
egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (!egl_lib) {
|
||||
return;
|
||||
}
|
||||
updateEglHandles(egl_lib);
|
||||
}
|
||||
void CopyBit::closeEglLib()
|
||||
{
|
||||
if(egl_lib)
|
||||
::dlclose(egl_lib);
|
||||
|
||||
egl_lib = NULL;
|
||||
updateEglHandles(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//CopybitEngine Class functions
|
||||
CopybitEngine* CopybitEngine::sInstance = 0;;
|
||||
CopybitEngine* CopybitEngine::sInstance = 0;
|
||||
|
||||
struct copybit_device_t* CopybitEngine::getEngine() {
|
||||
return sEngine;
|
||||
@ -440,9 +442,11 @@ CopybitEngine::CopybitEngine(){
|
||||
} else {
|
||||
ALOGE("FATAL ERROR: copybit open failed.");
|
||||
}
|
||||
CopyBit::openEglLibAndGethandle();
|
||||
}
|
||||
CopybitEngine::~CopybitEngine()
|
||||
{
|
||||
CopyBit::closeEglLib();
|
||||
if(sEngine)
|
||||
{
|
||||
copybit_close(sEngine);
|
||||
|
@ -31,6 +31,11 @@
|
||||
|
||||
namespace qhwc {
|
||||
//Feature for using Copybit to display RGB layers.
|
||||
typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) (
|
||||
EGLDisplay dpy,
|
||||
EGLSurface draw);
|
||||
typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw);
|
||||
|
||||
class CopyBit {
|
||||
public:
|
||||
//Sets up members and prepares copybit if conditions are met
|
||||
@ -75,6 +80,20 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class CopybitEngine {
|
||||
public:
|
||||
~CopybitEngine();
|
||||
// API to get copybit engine(non static)
|
||||
struct copybit_device_t *getEngine();
|
||||
// API to get singleton
|
||||
static CopybitEngine* getInstance();
|
||||
private:
|
||||
CopybitEngine();
|
||||
struct copybit_device_t *sEngine;
|
||||
static CopybitEngine* sInstance; // singleton
|
||||
};
|
||||
|
||||
|
||||
inline void CopyBit::setStats(int yuvCount, int yuvLayerIndex,
|
||||
bool isYuvLayerSkip) {
|
||||
sYuvCount = yuvCount;
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are retained
|
||||
* for attribution purposes only.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef HWC_COPYBIT_ENGINE_H
|
||||
#define HWC_COPYBIT_ENGINE_H
|
||||
|
||||
namespace qhwc {
|
||||
class CopybitEngine {
|
||||
public:
|
||||
~CopybitEngine();
|
||||
// API to get copybit engine(non static)
|
||||
struct copybit_device_t *getEngine();
|
||||
// API to get singleton
|
||||
static CopybitEngine* getInstance();
|
||||
|
||||
private:
|
||||
CopybitEngine();
|
||||
struct copybit_device_t *sEngine;
|
||||
static CopybitEngine* sInstance; // singleton
|
||||
};
|
||||
|
||||
}; //namespace qhwc
|
||||
|
||||
#endif //HWC_COPYBIT_ENGINE_H
|
@ -18,9 +18,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
#include <ctype.h>
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <fcntl.h>
|
||||
#include <media/IAudioPolicyService.h>
|
||||
#include <media/AudioSystem.h>
|
||||
#include <utils/threads.h>
|
||||
@ -31,15 +31,13 @@
|
||||
#include <linux/fb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#include <hardware_legacy/uevent.h>
|
||||
#include <sys/resource.h>
|
||||
#include <cutils/properties.h>
|
||||
#include "hwc_utils.h"
|
||||
#include "hwc_ext_observer.h"
|
||||
#include "hwc_external.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
#define EXT_OBSERVER_DEBUG 1
|
||||
|
||||
#define DEVICE_ROOT "/sys/devices/virtual/graphics"
|
||||
#define DEVICE_NODE "fb1"
|
||||
@ -49,88 +47,19 @@ namespace qhwc {
|
||||
#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE "/hpd"
|
||||
|
||||
|
||||
android::sp<ExtDisplayObserver> ExtDisplayObserver::
|
||||
sExtDisplayObserverInstance(0);
|
||||
|
||||
ExtDisplayObserver::ExtDisplayObserver() : Thread(false),
|
||||
fd(-1), mCurrentID(-1), mHwcContext(NULL)
|
||||
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):fd(-1),
|
||||
mCurrentID(-1), mHwcContext(ctx)
|
||||
{
|
||||
//Enable HPD for HDMI
|
||||
writeHPDOption(1);
|
||||
}
|
||||
|
||||
ExtDisplayObserver::~ExtDisplayObserver() {
|
||||
ExternalDisplay::~ExternalDisplay()
|
||||
{
|
||||
if (fd > 0)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
ExtDisplayObserver *ExtDisplayObserver::getInstance() {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s ", __FUNCTION__);
|
||||
if(sExtDisplayObserverInstance.get() == NULL)
|
||||
sExtDisplayObserverInstance = new ExtDisplayObserver();
|
||||
return sExtDisplayObserverInstance.get();
|
||||
}
|
||||
|
||||
void ExtDisplayObserver::setHwcContext(hwc_context_t* hwcCtx) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s", __FUNCTION__);
|
||||
if(hwcCtx) {
|
||||
mHwcContext = hwcCtx;
|
||||
}
|
||||
return;
|
||||
}
|
||||
void ExtDisplayObserver::onFirstRef() {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s", __FUNCTION__);
|
||||
run("ExtDisplayObserver", ANDROID_PRIORITY_DISPLAY);
|
||||
}
|
||||
|
||||
int ExtDisplayObserver::readyToRun() {
|
||||
//Initialize the uevent
|
||||
uevent_init();
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: success", __FUNCTION__);
|
||||
return android::NO_ERROR;
|
||||
}
|
||||
|
||||
void ExtDisplayObserver::handleUEvent(char* str){
|
||||
int connected = 0;
|
||||
// TODO: check for fb2(WFD) driver also
|
||||
if(!strcasestr(str, DEVICE_NODE))
|
||||
{
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
// 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 parse the online or offline are important for us.
|
||||
if(!(strncmp(str,"online@",strlen("online@")))) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: external disp online", __FUNCTION__);
|
||||
connected = 1;
|
||||
readResolution();
|
||||
//Get the best mode and set
|
||||
// TODO: DO NOT call this for WFD
|
||||
setResolution(getBestMode());
|
||||
} else if(!(strncmp(str,"offline@",strlen("offline@")))) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: external disp online", __FUNCTION__);
|
||||
connected = 0;
|
||||
close(fd);
|
||||
}
|
||||
setExternalDisplayStatus(connected);
|
||||
}
|
||||
|
||||
bool ExtDisplayObserver::threadLoop()
|
||||
{
|
||||
static char uEventString[1024];
|
||||
memset(uEventString, 0, sizeof(uEventString));
|
||||
int count = uevent_next_event(uEventString, sizeof(uEventString));
|
||||
if(count) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: UeventString: %s len = %d",
|
||||
__FUNCTION__, uEventString, count);
|
||||
handleUEvent(uEventString);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct disp_mode_timing_type {
|
||||
int video_format;
|
||||
|
||||
@ -213,7 +142,8 @@ static struct disp_mode_timing_type supported_video_mode_lut[] = {
|
||||
{m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false},
|
||||
{m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false},
|
||||
};
|
||||
int ExtDisplayObserver::parseResolution(char* edidStr, int* edidModes, int len)
|
||||
|
||||
int ExternalDisplay::parseResolution(char* edidStr, int* edidModes, int len)
|
||||
{
|
||||
char delim = ',';
|
||||
int count = 0;
|
||||
@ -233,7 +163,7 @@ int ExtDisplayObserver::parseResolution(char* edidStr, int* edidModes, int len)
|
||||
}
|
||||
return count;
|
||||
}
|
||||
bool ExtDisplayObserver::readResolution()
|
||||
bool ExternalDisplay::readResolution()
|
||||
{
|
||||
int hdmiEDIDFile = open(SYSFS_EDID_MODES, O_RDONLY, 0);
|
||||
int len = -1;
|
||||
@ -242,16 +172,16 @@ bool ExtDisplayObserver::readResolution()
|
||||
memset(mEDIDModes, 0, sizeof(mEDIDModes));
|
||||
mModeCount = 0;
|
||||
if (hdmiEDIDFile < 0) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: edid_modes file '%s' not found",
|
||||
__FUNCTION__, SYSFS_EDID_MODES);
|
||||
ALOGD_IF(DEBUG, "%s: edid_modes file '%s' not found",
|
||||
__FUNCTION__, SYSFS_EDID_MODES);
|
||||
return false;
|
||||
} else {
|
||||
len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: EDID string: %s length = %d",
|
||||
__FUNCTION__, mEDIDs, len);
|
||||
ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
|
||||
__FUNCTION__, mEDIDs, len);
|
||||
if ( len <= 0) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: edid_modes file empty '%s'",
|
||||
__FUNCTION__, SYSFS_EDID_MODES);
|
||||
ALOGD_IF(DEBUG, "%s: edid_modes file empty '%s'",
|
||||
__FUNCTION__, SYSFS_EDID_MODES);
|
||||
}
|
||||
else {
|
||||
while (len > 1 && isspace(mEDIDs[len-1]))
|
||||
@ -263,26 +193,26 @@ bool ExtDisplayObserver::readResolution()
|
||||
if(len > 0) {
|
||||
// GEt EDID modes from the EDID strings
|
||||
mModeCount = parseResolution(mEDIDs, mEDIDModes, len);
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: mModeCount = %d", __FUNCTION__,
|
||||
mModeCount);
|
||||
ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
|
||||
mModeCount);
|
||||
}
|
||||
|
||||
return (strlen(mEDIDs) > 0);
|
||||
}
|
||||
|
||||
bool ExtDisplayObserver::openFramebuffer()
|
||||
bool ExternalDisplay::openFramebuffer()
|
||||
{
|
||||
if (fd == -1) {
|
||||
fd = open("/dev/graphics/fb1", O_RDWR);
|
||||
if (fd < 0)
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: /dev/graphics/fb1 not available"
|
||||
"\n", __FUNCTION__);
|
||||
ALOGD_IF(DEBUG, "%s: /dev/graphics/fb1 not available"
|
||||
"\n", __FUNCTION__);
|
||||
}
|
||||
return (fd > 0);
|
||||
}
|
||||
|
||||
|
||||
int ExtDisplayObserver::getModeOrder(int mode)
|
||||
int ExternalDisplay::getModeOrder(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
default:
|
||||
@ -320,11 +250,11 @@ int ExtDisplayObserver::getModeOrder(int mode)
|
||||
return 16; //1080p@50Hz
|
||||
case m1920x1080p60_16_9:
|
||||
return 17; //1080p@60Hz
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the best mode for the current HD TV
|
||||
int ExtDisplayObserver::getBestMode() {
|
||||
int ExternalDisplay::getBestMode() {
|
||||
int bestOrder = 0;
|
||||
int bestMode = m640x480p60_4_3;
|
||||
|
||||
@ -338,14 +268,14 @@ int ExtDisplayObserver::getBestMode() {
|
||||
}
|
||||
}
|
||||
return bestMode;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ExtDisplayObserver::isValidMode(int ID)
|
||||
inline bool ExternalDisplay::isValidMode(int ID)
|
||||
{
|
||||
return ((ID >= m640x480p60_4_3) && (ID <= m1920x1080p30_16_9));
|
||||
}
|
||||
|
||||
void ExtDisplayObserver::setResolution(int ID)
|
||||
void ExternalDisplay::setResolution(int ID)
|
||||
{
|
||||
struct fb_var_screeninfo info;
|
||||
if (!openFramebuffer())
|
||||
@ -353,29 +283,29 @@ void ExtDisplayObserver::setResolution(int ID)
|
||||
//If its a valid mode and its a new ID - update var_screeninfo
|
||||
if ((isValidMode(ID)) && mCurrentID != ID) {
|
||||
const struct disp_mode_timing_type *mode =
|
||||
&supported_video_mode_lut[0];
|
||||
&supported_video_mode_lut[0];
|
||||
unsigned count = sizeof(supported_video_mode_lut)/sizeof
|
||||
(*supported_video_mode_lut);
|
||||
(*supported_video_mode_lut);
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
const struct disp_mode_timing_type *cur =
|
||||
&supported_video_mode_lut[i];
|
||||
&supported_video_mode_lut[i];
|
||||
if (cur->video_format == ID)
|
||||
mode = cur;
|
||||
}
|
||||
ioctl(fd, FBIOGET_VSCREENINFO, &info);
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
|
||||
"(%d,%d,%d) %dMHz>", __FUNCTION__,
|
||||
info.reserved[3], info.xres, info.yres,
|
||||
info.right_margin, info.hsync_len, info.left_margin,
|
||||
info.lower_margin, info.vsync_len, info.upper_margin,
|
||||
info.pixclock/1000/1000);
|
||||
ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
|
||||
"(%d,%d,%d) %dMHz>", __FUNCTION__,
|
||||
info.reserved[3], info.xres, info.yres,
|
||||
info.right_margin, info.hsync_len, info.left_margin,
|
||||
info.lower_margin, info.vsync_len, info.upper_margin,
|
||||
info.pixclock/1000/1000);
|
||||
mode->set_info(info);
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx%d"
|
||||
"(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
|
||||
info.reserved[3], info.xres, info.yres,
|
||||
info.right_margin, info.hsync_len, info.left_margin,
|
||||
info.lower_margin, info.vsync_len, info.upper_margin,
|
||||
info.pixclock/1000/1000);
|
||||
ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx%d"
|
||||
"(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
|
||||
info.reserved[3], info.xres, info.yres,
|
||||
info.right_margin, info.hsync_len, info.left_margin,
|
||||
info.lower_margin, info.vsync_len, info.upper_margin,
|
||||
info.pixclock/1000/1000);
|
||||
info.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
|
||||
ioctl(fd, FBIOPUT_VSCREENINFO, &info);
|
||||
mCurrentID = ID;
|
||||
@ -389,53 +319,61 @@ void ExtDisplayObserver::setResolution(int ID)
|
||||
}
|
||||
|
||||
|
||||
int ExtDisplayObserver::getExternalDisplay() const
|
||||
int ExternalDisplay::getExternalDisplay() const
|
||||
{
|
||||
return mExternalDisplay;
|
||||
return mExternalDisplay;
|
||||
}
|
||||
|
||||
void ExtDisplayObserver::setExternalDisplayStatus(int connected)
|
||||
void ExternalDisplay::setExternalDisplayStatus(int connected)
|
||||
{
|
||||
|
||||
hwc_context_t* ctx = mHwcContext;
|
||||
if(ctx) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: status = %d", __FUNCTION__,
|
||||
connected);
|
||||
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());
|
||||
} else {
|
||||
close(fd);
|
||||
}
|
||||
// Store the external display
|
||||
mExternalDisplay = connected;//(external_display_type)value;
|
||||
mExternalDisplay = connected;
|
||||
//Invalidate
|
||||
hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0];
|
||||
if(!proc) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: HWC proc not registered",
|
||||
__FUNCTION__);
|
||||
ALOGD_IF(DEBUG, "%s: HWC proc not registered",
|
||||
__FUNCTION__);
|
||||
} else {
|
||||
/* Trigger redraw */
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: Invalidate !!", __FUNCTION__);
|
||||
ALOGD_IF(DEBUG, "%s: Invalidate !!", __FUNCTION__);
|
||||
proc->invalidate(proc);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool ExtDisplayObserver::writeHPDOption(int userOption) const
|
||||
bool ExternalDisplay::writeHPDOption(int userOption) const
|
||||
{
|
||||
bool ret = true;
|
||||
int hdmiHPDFile = open(SYSFS_HPD,O_RDWR, 0);
|
||||
if (hdmiHPDFile < 0) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: state file '%s' not found : ret%d"
|
||||
"err str: %s", __FUNCTION__, SYSFS_HPD, hdmiHPDFile, strerror(errno));
|
||||
ALOGD_IF(DEBUG, "%s: state file '%s' not found : ret%d"
|
||||
"err str: %s", __FUNCTION__, SYSFS_HPD, hdmiHPDFile, strerror(errno));
|
||||
ret = false;
|
||||
} else {
|
||||
int err = -1;
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: option = %d", __FUNCTION__,
|
||||
userOption);
|
||||
ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__,
|
||||
userOption);
|
||||
if(userOption)
|
||||
err = write(hdmiHPDFile, "1", 2);
|
||||
else
|
||||
err = write(hdmiHPDFile, "0" , 2);
|
||||
if (err <= 0) {
|
||||
ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: file write failed '%s'",
|
||||
__FUNCTION__, SYSFS_HPD);
|
||||
ALOGD_IF(DEBUG, "%s: file write failed '%s'",
|
||||
__FUNCTION__, SYSFS_HPD);
|
||||
ret = false;
|
||||
}
|
||||
close(hdmiHPDFile);
|
@ -18,16 +18,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HWC_EXT_OBSERVER_H
|
||||
#define HWC_EXT_OBSERVER_H
|
||||
|
||||
#include <utils/threads.h>
|
||||
#ifndef HWC_EXTERNAL_DISPLAY_H
|
||||
#define HWC_EXTERNAL_DISPLAY_H
|
||||
|
||||
struct hwc_context_t;
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
class ExtDisplayObserver : public android::Thread
|
||||
class ExternalDisplay
|
||||
{
|
||||
//Type of external display - OFF, HDMI, WFD
|
||||
enum external_display_type {
|
||||
@ -42,39 +40,31 @@ class ExtDisplayObserver : public android::Thread
|
||||
EXT_MIRRORING_ON,
|
||||
};
|
||||
public:
|
||||
/*Overrides*/
|
||||
virtual bool threadLoop();
|
||||
virtual int readyToRun();
|
||||
virtual void onFirstRef();
|
||||
|
||||
virtual ~ExtDisplayObserver();
|
||||
static ExtDisplayObserver *getInstance();
|
||||
int getExternalDisplay() const;
|
||||
void setHwcContext(hwc_context_t* hwcCtx);
|
||||
ExternalDisplay(hwc_context_t* ctx);
|
||||
~ExternalDisplay();
|
||||
int getExternalDisplay() const;
|
||||
void setExternalDisplayStatus(int connected);
|
||||
|
||||
private:
|
||||
ExtDisplayObserver();
|
||||
void setExternalDisplayStatus(int connected);
|
||||
bool readResolution();
|
||||
int parseResolution(char* edidStr, int* edidModes, int len);
|
||||
void setResolution(int ID);
|
||||
bool openFramebuffer();
|
||||
bool writeHPDOption(int userOption) const;
|
||||
bool isValidMode(int ID);
|
||||
void handleUEvent(char* str);
|
||||
int getModeOrder(int mode);
|
||||
int getBestMode();
|
||||
bool readResolution();
|
||||
int parseResolution(char* edidStr, int* edidModes, int len);
|
||||
void setResolution(int ID);
|
||||
bool openFramebuffer();
|
||||
bool writeHPDOption(int userOption) const;
|
||||
bool isValidMode(int ID);
|
||||
void handleUEvent(char* str, int len);
|
||||
int getModeOrder(int mode);
|
||||
int getBestMode();
|
||||
|
||||
int fd;
|
||||
int mExternalDisplay;
|
||||
int mCurrentID;
|
||||
char mEDIDs[128];
|
||||
int mEDIDModes[64];
|
||||
int mModeCount;
|
||||
hwc_context_t *mHwcContext;
|
||||
static android::sp<ExtDisplayObserver> sExtDisplayObserverInstance;
|
||||
int fd;
|
||||
int mExternalDisplay;
|
||||
int mCurrentID;
|
||||
char mEDIDs[128];
|
||||
int mEDIDModes[64];
|
||||
int mModeCount;
|
||||
hwc_context_t *mHwcContext;
|
||||
};
|
||||
|
||||
}; //qhwc
|
||||
// ---------------------------------------------------------------------------
|
||||
#endif //HWC_EXT_OBSERVER_H
|
||||
#endif //HWC_EXTERNAL_DISPLAY_H
|
@ -15,6 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gralloc_priv.h>
|
||||
#include <genlock.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// QueuedBufferStore
|
||||
//This class holds currently and previously queued buffers.
|
||||
|
105
libhwcomposer/hwc_uevents.cpp
Normal file
105
libhwcomposer/hwc_uevents.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are
|
||||
* retained for attribution purposes only.
|
||||
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define DEBUG 0
|
||||
#ifndef HWC_OBSERVER_H
|
||||
#define HWC_OBSERVER_H
|
||||
#include <hardware_legacy/uevent.h>
|
||||
#include <utils/Log.h>
|
||||
#include <sys/resource.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "hwc_utils.h"
|
||||
#include "hwc_external.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
const char* MSMFB_DEVICE_CHANGE = "change@/devices/virtual/graphics/fb0";
|
||||
const char* MSMFB_HDMI_NODE = "fb1";
|
||||
|
||||
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
||||
{
|
||||
int vsync;
|
||||
char* hdmi;
|
||||
int64_t timestamp = 0;
|
||||
const char *str = udata;
|
||||
hwc_procs* proc = reinterpret_cast<hwc_procs*>(ctx->device.reserved_proc[0]);
|
||||
|
||||
vsync = !strncmp(str, MSMFB_DEVICE_CHANGE, strlen(MSMFB_DEVICE_CHANGE));
|
||||
hdmi = strcasestr(str, MSMFB_HDMI_NODE);
|
||||
if(!vsync && !hdmi)
|
||||
return;
|
||||
if(vsync) {
|
||||
str += strlen(str) + 1;
|
||||
while(*str) {
|
||||
if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
|
||||
timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
|
||||
proc->vsync(proc, 0, timestamp);
|
||||
}
|
||||
str += strlen(str) + 1;
|
||||
if(str - udata >= len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
} else if(!(strncmp(str,"offline@",strlen("offline@")))) {
|
||||
connected = 0;
|
||||
}
|
||||
ctx->mExtDisplay->setExternalDisplayStatus(connected);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void *uevent_loop(void *param)
|
||||
{
|
||||
int len = 0;
|
||||
static char udata[4096];
|
||||
memset(udata, 0, sizeof(udata));
|
||||
hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
|
||||
|
||||
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
||||
uevent_init();
|
||||
|
||||
while(1) {
|
||||
len = uevent_next_event(udata, sizeof(udata) - 2);
|
||||
handle_uevent(ctx, udata, len);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void init_uevent_thread(hwc_context_t* ctx)
|
||||
{
|
||||
pthread_t uevent_thread;
|
||||
pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx);
|
||||
}
|
||||
|
||||
}; //namespace
|
||||
#endif //HWC_OBSERVER_H
|
@ -18,12 +18,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define HWC_UI_MIRROR 0
|
||||
#include <gralloc_priv.h>
|
||||
#include <fb_priv.h>
|
||||
#include "hwc_uimirror.h"
|
||||
#include "hwc_ext_observer.h"
|
||||
#include "hwc_external.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
#define HWC_UI_MIRROR 0
|
||||
|
||||
// Function to get the primary device orientation
|
||||
// Loops thru the hardware layers and returns the orientation of the max.
|
||||
@ -59,7 +61,7 @@ bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) {
|
||||
sState = ovutils::OV_CLOSED;
|
||||
sIsUiMirroringOn = false;
|
||||
// If external display is connected
|
||||
if(ctx->mExtDisplayObserver->getExternalDisplay()) {
|
||||
if(ctx->mExtDisplay->getExternalDisplay()) {
|
||||
sState = ovutils::OV_UI_MIRROR;
|
||||
configure(ctx, list);
|
||||
}
|
||||
@ -73,7 +75,7 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_list_t *list)
|
||||
overlay::Overlay& ov = *(ctx->mOverlay);
|
||||
// Set overlay state
|
||||
ov.setState(sState);
|
||||
framebuffer_device_t *fbDev = ctx->mFbDevice->getFb();
|
||||
framebuffer_device_t *fbDev = ctx->mFbDev;
|
||||
if(fbDev) {
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
fbDev->common.module);
|
||||
@ -143,7 +145,7 @@ bool UIMirrorOverlay::draw(hwc_context_t *ctx)
|
||||
overlay::Overlay& ov = *(ctx->mOverlay);
|
||||
ovutils::eOverlayState state = ov.getState();
|
||||
ovutils::eDest dest = ovutils::OV_PIPE_ALL;
|
||||
framebuffer_device_t *fbDev = ctx->mFbDevice->getFb();
|
||||
framebuffer_device_t *fbDev = ctx->mFbDev;
|
||||
if(fbDev) {
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
fbDev->common.module);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef HWC_UIMIRROR_H
|
||||
#define HWC_UIMIRROR_H
|
||||
#include "hwc_utils.h"
|
||||
#include "overlay.h"
|
||||
|
||||
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
||||
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
|
||||
|
@ -15,26 +15,39 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <overlay.h>
|
||||
#include "hwc_utils.h"
|
||||
#include "mdp_version.h"
|
||||
#include "hwc_video.h"
|
||||
#include "hwc_ext_observer.h"
|
||||
#include "hwc_qbuf.h"
|
||||
#include "hwc_copybit.h"
|
||||
#include "hwc_external.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
// Opens Framebuffer device
|
||||
static void openFramebufferDevice(hwc_context_t *ctx)
|
||||
{
|
||||
hw_module_t const *module;
|
||||
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
|
||||
framebuffer_open(module, &(ctx->mFbDev));
|
||||
}
|
||||
}
|
||||
|
||||
void initContext(hwc_context_t *ctx)
|
||||
{
|
||||
//XXX: target specific initializations here
|
||||
openFramebufferDevice(ctx);
|
||||
ctx->mOverlay = overlay::Overlay::getInstance();
|
||||
ctx->qbuf = new QueuedBufferStore();
|
||||
ctx->mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
|
||||
ctx->hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
|
||||
ALOGI("MDP version: %d",ctx->mdpVersion);
|
||||
|
||||
ctx->mExtDisplayObserver = ExtDisplayObserver::getInstance();
|
||||
ctx->mExtDisplayObserver->setHwcContext(ctx);
|
||||
ctx->mFbDevice = FbDevice::getInstance();
|
||||
ctx->mCopybitEngine = CopybitEngine::getInstance();
|
||||
CopyBit::openEglLibAndGethandle();
|
||||
ctx->mExtDisplay = new ExternalDisplay(ctx);
|
||||
|
||||
init_uevent_thread(ctx);
|
||||
|
||||
ALOGI("Initializing Qualcomm Hardware Composer");
|
||||
ALOGI("MDP version: %d", ctx->mdpVersion);
|
||||
}
|
||||
|
||||
void closeContext(hwc_context_t *ctx)
|
||||
@ -48,15 +61,25 @@ void closeContext(hwc_context_t *ctx)
|
||||
delete ctx->mCopybitEngine;
|
||||
ctx->mCopybitEngine = NULL;
|
||||
}
|
||||
if(ctx->mFbDevice) {
|
||||
delete ctx->mFbDevice;
|
||||
ctx->mFbDevice = NULL;
|
||||
|
||||
if(ctx->mFbDev) {
|
||||
framebuffer_close(ctx->mFbDev);
|
||||
ctx->mFbDev = NULL;
|
||||
}
|
||||
|
||||
if(ctx->qbuf) {
|
||||
delete ctx->qbuf;
|
||||
ctx->qbuf = NULL;
|
||||
}
|
||||
CopyBit::closeEglLib();
|
||||
|
||||
if(ctx->mExtDisplay) {
|
||||
delete ctx->mExtDisplay;
|
||||
ctx->mExtDisplay = NULL;
|
||||
}
|
||||
|
||||
|
||||
free(const_cast<hwc_methods_t *>(ctx->device.methods));
|
||||
|
||||
}
|
||||
|
||||
void dumpLayer(hwc_layer_t const* l)
|
||||
@ -163,33 +186,4 @@ void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
||||
}
|
||||
}
|
||||
|
||||
//FbDevice class functions
|
||||
FbDevice* FbDevice::sInstance = 0;;
|
||||
struct framebuffer_device_t* FbDevice::getFb() {
|
||||
return sFb;
|
||||
}
|
||||
|
||||
FbDevice* FbDevice::getInstance() {
|
||||
if(sInstance == NULL)
|
||||
sInstance = new FbDevice();
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
FbDevice::FbDevice(){
|
||||
hw_module_t const *module;
|
||||
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
|
||||
framebuffer_open(module, &sFb);
|
||||
} else {
|
||||
ALOGE("FATAL ERROR: framebuffer open failed.");
|
||||
}
|
||||
}
|
||||
FbDevice::~FbDevice()
|
||||
{
|
||||
if(sFb)
|
||||
{
|
||||
framebuffer_close(sFb);
|
||||
sFb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
};//namespace
|
||||
|
@ -17,28 +17,26 @@
|
||||
|
||||
#ifndef HWC_UTILS_H
|
||||
#define HWC_UTILS_H
|
||||
#include <cutils/log.h>
|
||||
#include <gralloc_priv.h>
|
||||
|
||||
#include <hardware/hwcomposer.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/gralloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fb_priv.h>
|
||||
#include <overlay.h>
|
||||
#include <copybit.h>
|
||||
#include <hwc_copybitEngine.h>
|
||||
#include <genlock.h>
|
||||
#include "hwc_qbuf.h"
|
||||
#include <EGL/egl.h>
|
||||
#include <gralloc_priv.h>
|
||||
|
||||
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
|
||||
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
||||
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
|
||||
#define FINAL_TRANSFORM_MASK 0x000F
|
||||
|
||||
//Fwrd decls
|
||||
struct hwc_context_t;
|
||||
struct framebuffer_device_t;
|
||||
|
||||
namespace overlay {
|
||||
class Overlay;
|
||||
}
|
||||
|
||||
namespace qhwc {
|
||||
//fwrd decl
|
||||
class QueuedBufferStore;
|
||||
|
||||
enum external_display_type {
|
||||
EXT_TYPE_NONE,
|
||||
@ -53,7 +51,8 @@ enum HWCCompositionType {
|
||||
};
|
||||
|
||||
|
||||
class ExtDisplayObserver;
|
||||
class ExternalDisplay;
|
||||
class CopybitEngine;
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility functions - implemented in hwc_utils.cpp
|
||||
void dumpLayer(hwc_layer_t const* l);
|
||||
@ -78,32 +77,12 @@ static inline bool isYuvBuffer(const private_handle_t* hnd) {
|
||||
static inline bool isBufferLocked(const private_handle_t* hnd) {
|
||||
return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
// Copybit specific - inline or implemented in hwc_copybit.cpp
|
||||
typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) (
|
||||
EGLDisplay dpy,
|
||||
EGLSurface draw);
|
||||
typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Singleton for Framebuffer device
|
||||
class FbDevice{
|
||||
public:
|
||||
~FbDevice();
|
||||
// API to get Fb device(non static)
|
||||
struct framebuffer_device_t *getFb();
|
||||
// API to get singleton
|
||||
static FbDevice* getInstance();
|
||||
|
||||
private:
|
||||
FbDevice();
|
||||
struct framebuffer_device_t *sFb;
|
||||
static FbDevice* sInstance; // singleton
|
||||
};
|
||||
// Initialize uevent thread
|
||||
void init_uevent_thread(hwc_context_t* ctx);
|
||||
|
||||
}; //qhwc namespace
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// HWC context
|
||||
// This structure contains overall state
|
||||
@ -115,7 +94,7 @@ struct hwc_context_t {
|
||||
int overlayInUse;
|
||||
|
||||
//Framebuffer device
|
||||
qhwc::FbDevice* mFbDevice;
|
||||
framebuffer_device_t *mFbDev;
|
||||
|
||||
//Copybit Engine
|
||||
qhwc::CopybitEngine* mCopybitEngine;
|
||||
@ -127,7 +106,8 @@ struct hwc_context_t {
|
||||
qhwc::QueuedBufferStore *qbuf;
|
||||
|
||||
// External display related information
|
||||
qhwc::ExtDisplayObserver*mExtDisplayObserver;
|
||||
qhwc::ExternalDisplay *mExtDisplay;
|
||||
|
||||
};
|
||||
|
||||
#endif //HWC_UTILS_H
|
||||
|
@ -15,13 +15,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define VIDEO_DEBUG 0
|
||||
#include <overlay.h>
|
||||
#include "hwc_qbuf.h"
|
||||
#include "hwc_video.h"
|
||||
#include "hwc_ext_observer.h"
|
||||
#include "hwc_external.h"
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
#define FINAL_TRANSFORM_MASK 0x000F
|
||||
#define VIDEO_DEBUG 0
|
||||
|
||||
//Static Members
|
||||
ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED;
|
||||
@ -62,12 +64,12 @@ void VideoOverlay::chooseState(hwc_context_t *ctx) {
|
||||
//Support 1 video layer
|
||||
if(sYuvCount == 1) {
|
||||
//Skip on primary, display on ext.
|
||||
if(sIsLayerSkip && ctx->mExtDisplayObserver->getExternalDisplay()) {
|
||||
if(sIsLayerSkip && ctx->mExtDisplay->getExternalDisplay()) {
|
||||
//TODO
|
||||
//VIDEO_ON_TV_ONLY
|
||||
} else if(sIsLayerSkip) { //skip on primary, no ext
|
||||
newState = ovutils::OV_CLOSED;
|
||||
} else if(ctx->mExtDisplayObserver->getExternalDisplay()) {
|
||||
} else if(ctx->mExtDisplay->getExternalDisplay()) {
|
||||
//display on both
|
||||
newState = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
|
||||
} else { //display on primary only
|
||||
|
Loading…
x
Reference in New Issue
Block a user