display: Add binder interface between hwcservice and its clients.

Add hwc_service.cpp and ihwc.cpp file to enable direct communication
to hwcomposer by the clients to set hwc system wide properties.

Create hwcomposer service singleton object in hwc_context_t structure.

Change-Id: I0d0879475951a618a453a23ee254ea651e8c6b88
This commit is contained in:
Ramkumar Radhakrishnan 2012-08-07 15:27:06 -07:00 committed by Andrew Sutherland
parent 56da81b668
commit 060e7797ed
11 changed files with 485 additions and 11 deletions

View File

@ -6,7 +6,9 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay libgenlock \
libqdutils libhardware_legacy libdl libmemalloc
libqdutils libhardware_legacy libdl \
libmemalloc libbinder
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"hwcomposer\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := hwc.cpp \
@ -17,6 +19,8 @@ LOCAL_SRC_FILES := hwc.cpp \
hwc_uevents.cpp \
hwc_copybit.cpp \
hwc_mdpcomp.cpp \
hwc_service.cpp \
ihwc.cpp \
hwc_extonly.cpp
include $(BUILD_SHARED_LIBRARY)

View File

@ -35,6 +35,9 @@
#include <cutils/properties.h>
#include "hwc_utils.h"
#include "hwc_external.h"
#include "overlayUtils.h"
using namespace android;
namespace qhwc {
@ -44,7 +47,7 @@ static const char *extPanelName[MAX_DISPLAY_EXTERNAL_DEVICES] = {
};
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mHwcContext(ctx)
mCurrentMode(-1), mExternalDisplay(0), mModeCount(0), mHwcContext(ctx)
{
memset(&mVInfo, 0, sizeof(mVInfo));
@ -54,6 +57,48 @@ ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
}
}
void ExternalDisplay::setEDIDMode(int resMode) {
ALOGD_IF(DEBUG,"resMode=%d ", resMode);
int extDispType;
{
Mutex::Autolock lock(mExtDispLock);
extDispType = mExternalDisplay;
setExternalDisplay(0);
setResolution(resMode);
}
setExternalDisplay(extDispType);
}
void ExternalDisplay::setHPDStatus(int enabled) {
ALOGD_IF(DEBUG,"HPD enabled=%d", enabled);
writeHPDOption(enabled);
}
void ExternalDisplay::setActionSafeDimension(int w, int h) {
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
Mutex::Autolock lock(mExtDispLock);
overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
setExternalDisplay(mExternalDisplay);
}
int ExternalDisplay::getModeCount() const {
ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
Mutex::Autolock lock(mExtDispLock);
return mModeCount;
}
void ExternalDisplay::getEDIDModes(int *out) const {
Mutex::Autolock lock(mExtDispLock);
for(int i = 0;i < mModeCount;i++) {
out[i] = mEDIDModes[i];
}
}
int ExternalDisplay::getExternalDisplay() const {
Mutex::Autolock lock(mExtDispLock);
return mExternalDisplay;
}
ExternalDisplay::~ExternalDisplay()
{
closeFrameBuffer();
@ -276,7 +321,7 @@ int ExternalDisplay::getModeOrder(int mode)
int ExternalDisplay::getBestMode() {
int bestOrder = 0;
int bestMode = m640x480p60_4_3;
Mutex::Autolock lock(mExtDispLock);
// for all the edid read, get the best mode
for(int i = 0; i < mModeCount; i++) {
int mode = mEDIDModes[i];

View File

@ -21,7 +21,8 @@
#ifndef HWC_EXTERNAL_DISPLAY_H
#define HWC_EXTERNAL_DISPLAY_H
#include <fb_priv.h>
#include <utils/threads.h>
#include <linux/fb.h>
struct hwc_context_t;
@ -63,10 +64,15 @@ class ExternalDisplay
public:
ExternalDisplay(hwc_context_t* ctx);
~ExternalDisplay();
inline int getExternalDisplay() { return mExternalDisplay; }
int getModeCount() const;
void getEDIDModes(int *out) const;
int getExternalDisplay() const;
void setExternalDisplay(int connected);
bool commit();
int enableHDMIVsync(int enable);
void setHPDStatus(int enabled);
void setEDIDMode(int resMode);
void setActionSafeDimension(int w, int h);
void processUEventOnline(const char *str);
void processUEventOffline(const char *str);
bool isHDMIConfigured();
@ -84,9 +90,11 @@ class ExternalDisplay
int getBestMode();
void resetInfo();
mutable android::Mutex mExtDispLock;
int mFd;
int mExternalDisplay;
int mCurrentMode;
int mExternalDisplay;
int mResolutionMode;
char mEDIDs[128];
int mEDIDModes[64];
int mModeCount;

View File

@ -0,0 +1,104 @@
#include <hwc_service.h>
#include <hwc_utils.h>
#define HWC_SERVICE_DEBUG 0
using namespace android;
namespace hwcService {
HWComposerService* HWComposerService::sHwcService = NULL;
// ----------------------------------------------------------------------------
HWComposerService::HWComposerService():mHwcContext(0)
{
ALOGD_IF(HWC_SERVICE_DEBUG, "HWComposerService Constructor invoked");
}
HWComposerService::~HWComposerService()
{
ALOGD_IF(HWC_SERVICE_DEBUG,"HWComposerService Destructor invoked");
}
status_t HWComposerService::setHPDStatus(int hpdStatus) {
ALOGD_IF(HWC_SERVICE_DEBUG, "hpdStatus=%d", hpdStatus);
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
externalDisplay->setHPDStatus(hpdStatus);
return NO_ERROR;
}
status_t HWComposerService::setResolutionMode(int resMode) {
ALOGD_IF(HWC_SERVICE_DEBUG, "resMode=%d", resMode);
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
if(externalDisplay->getExternalDisplay()) {
externalDisplay->setEDIDMode(resMode);
} else {
ALOGE("External Display not connected");
}
return NO_ERROR;
}
status_t HWComposerService::setActionSafeDimension(int w, int h) {
ALOGD_IF(HWC_SERVICE_DEBUG, "w=%d h=%d", w, h);
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
if((w > MAX_ACTIONSAFE_WIDTH) && (h > MAX_ACTIONSAFE_HEIGHT)) {
ALOGE_IF(HWC_SERVICE_DEBUG,
"ActionSafe Width and Height exceeded the limit! w=%d h=%d", w, h);
return NO_ERROR;
}
if(externalDisplay->getExternalDisplay()) {
externalDisplay->setActionSafeDimension(w, h);
} else {
ALOGE("External Display not connected");
}
return NO_ERROR;
}
status_t HWComposerService::getResolutionModeCount(int *resModeCount) {
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
if(externalDisplay->getExternalDisplay()) {
*resModeCount = externalDisplay->getModeCount();
} else {
ALOGE("External Display not connected");
}
ALOGD_IF(HWC_SERVICE_DEBUG, "resModeCount=%d", *resModeCount);
return NO_ERROR;
}
status_t HWComposerService::getResolutionModes(int *resModes, int count) {
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
if(externalDisplay->getExternalDisplay()) {
externalDisplay->getEDIDModes(resModes);
} else {
ALOGE("External Display not connected");
}
return NO_ERROR;
}
status_t HWComposerService::getExternalDisplay(int *dispType) {
qhwc::ExternalDisplay *externalDisplay = mHwcContext->mExtDisplay;
*dispType = externalDisplay->getExternalDisplay();
ALOGD_IF(HWC_SERVICE_DEBUG, "dispType=%d", *dispType);
return NO_ERROR;
}
HWComposerService* HWComposerService::getInstance()
{
if(!sHwcService) {
sHwcService = new HWComposerService();
sp<IServiceManager> sm = defaultServiceManager();
sm->addService(String16("display.hwcservice"), sHwcService);
if(sm->checkService(String16("display.hwcservice")) != NULL)
ALOGD_IF(HWC_SERVICE_DEBUG, "adding display.hwcservice succeeded");
else
ALOGD_IF(HWC_SERVICE_DEBUG, "adding display.hwcservice failed");
}
return sHwcService;
}
void HWComposerService::setHwcContext(hwc_context_t *hwcCtx) {
ALOGD_IF(HWC_SERVICE_DEBUG, "hwcCtx=0x%x", (int)hwcCtx);
if(hwcCtx) {
mHwcContext = hwcCtx;
}
}
}

View File

@ -0,0 +1,41 @@
#ifndef ANDROID_HWCOMPOSER_SERVICE_H
#define ANDROID_HWCOMPOSER_SERVICE_H
#include <utils/Errors.h>
#include <sys/types.h>
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <ihwc.h>
#include <hwc_external.h>
namespace hwcService {
// ----------------------------------------------------------------------------
class HWComposerService : public BnHWComposer {
enum {
MAX_ACTIONSAFE_WIDTH = 10,
MAX_ACTIONSAFE_HEIGHT = MAX_ACTIONSAFE_WIDTH,
};
private:
HWComposerService();
public:
~HWComposerService();
static HWComposerService* getInstance();
virtual android::status_t getResolutionModeCount(int *modeCount);
virtual android::status_t getResolutionModes(int *EDIDModes, int count = 1);
virtual android::status_t getExternalDisplay(int *extDisp);
virtual android::status_t setHPDStatus(int enable);
virtual android::status_t setResolutionMode(int resMode);
virtual android::status_t setActionSafeDimension(int w, int h);
void setHwcContext(hwc_context_t *hwcCtx);
private:
static HWComposerService *sHwcService;
hwc_context_t *mHwcContext;
};
}; // namespace hwcService
#endif // ANDROID_HWCOMPOSER_SERVICE_H

View File

@ -24,6 +24,7 @@
#include "hwc_external.h"
#include "hwc_mdpcomp.h"
#include "hwc_extonly.h"
#include "hwc_service.h"
namespace qhwc {
@ -40,6 +41,8 @@ void initContext(hwc_context_t *ctx)
{
openFramebufferDevice(ctx);
ctx->mOverlay = overlay::Overlay::getInstance();
ctx->mHwcService = hwcService::HWComposerService::getInstance();
ctx->mHwcService->setHwcContext(ctx);
ctx->qbuf = new QueuedBufferStore();
ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();

View File

@ -30,6 +30,10 @@
struct hwc_context_t;
struct framebuffer_device_t;
namespace hwcService {
class HWComposerService;
}
namespace overlay {
class Overlay;
}
@ -138,6 +142,9 @@ struct hwc_context_t {
//QueuedBufferStore to hold buffers for overlay
qhwc::QueuedBufferStore *qbuf;
//HWComposerService object
hwcService::HWComposerService *mHwcService;
// External display related information
qhwc::ExternalDisplay *mExtDisplay;

171
libhwcomposer/ihwc.cpp Normal file
View File

@ -0,0 +1,171 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.
*/
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <ihwc.h>
using namespace android;
// ---------------------------------------------------------------------------
namespace hwcService {
class BpHWComposer : public BpInterface<IHWComposer>
{
public:
BpHWComposer(const sp<IBinder>& impl)
: BpInterface<IHWComposer>(impl)
{
}
virtual status_t setHPDStatus(int hpdStatus) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
data.writeInt32(hpdStatus);
status_t result = remote()->transact(SET_EXT_HPD_ENABLE,
data, &reply);
result = reply.readInt32();
return result;
}
virtual status_t setResolutionMode(int resMode) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
data.writeInt32(resMode);
status_t result = remote()->transact(SET_EXT_DISPLAY_RESOLUTION_MODE,
data, &reply);
result = reply.readInt32();
return result;
}
virtual status_t setActionSafeDimension(int w, int h) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
data.writeInt32(w);
data.writeInt32(h);
status_t result =
remote()->transact(SET_EXT_DISPLAY_ACTIONSAFE_DIMENSIONS,
data, &reply);
result = reply.readInt32();
return result;
}
virtual status_t getExternalDisplay(int *extDispType) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
status_t result = remote()->transact(GET_EXT_DISPLAY_TYPE,
data, &reply);
*extDispType = reply.readInt32();
result = reply.readInt32();
return result;
}
virtual status_t getResolutionModes(int *resModes, int count) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
data.writeInt32(count);
status_t result = remote()->transact(GET_EXT_DISPLAY_RESOLUTION_MODES,
data, &reply);
for(int i = 0;i < count;i++) {
resModes[i] = reply.readInt32();
}
result = reply.readInt32();
return result;
}
virtual status_t getResolutionModeCount(int *resModeCount) {
Parcel data, reply;
data.writeInterfaceToken(IHWComposer::getInterfaceDescriptor());
status_t result = remote()->transact(
GET_EXT_DISPLAY_RESOLUTION_MODE_COUNT, data, &reply);
*resModeCount = reply.readInt32();
result = reply.readInt32();
return result;
}
};
IMPLEMENT_META_INTERFACE(HWComposer, "android.display.IHWComposer");
// ----------------------------------------------------------------------
status_t BnHWComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// codes that don't require permission check
switch(code) {
case SET_EXT_HPD_ENABLE: {
CHECK_INTERFACE(IHWComposer, data, reply);
int hpdStatus = data.readInt32();
status_t res = setHPDStatus(hpdStatus);
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_EXT_DISPLAY_RESOLUTION_MODE: {
CHECK_INTERFACE(IHWComposer, data, reply);
int resMode = data.readInt32();
status_t res = setResolutionMode(resMode);
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_EXT_DISPLAY_ACTIONSAFE_DIMENSIONS: {
CHECK_INTERFACE(IHWComposer, data, reply);
int w = data.readInt32();
int h = data.readInt32();
status_t res = setActionSafeDimension(w, h);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_EXT_DISPLAY_TYPE: {
CHECK_INTERFACE(IHWComposer, data, reply);
int extDispType;
status_t res = getExternalDisplay(&extDispType);
reply->writeInt32(extDispType);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_EXT_DISPLAY_RESOLUTION_MODES: {
CHECK_INTERFACE(IHWComposer, data, reply);
int count = data.readInt32();
int resModes[64];
status_t res = getResolutionModes(&resModes[0]);
for(int i = 0;i < count;i++) {
reply->writeInt32(resModes[i]);
}
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_EXT_DISPLAY_RESOLUTION_MODE_COUNT: {
CHECK_INTERFACE(IHWComposer, data, reply);
int resModeCount;
status_t res = getResolutionModeCount(&resModeCount);
reply->writeInt32(resModeCount);
reply->writeInt32(res);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}; // namespace hwcService

69
libhwcomposer/ihwc.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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 ANDROID_IHWCOMPOSER_H
#define ANDROID_IHWCOMPOSER_H
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <binder/IInterface.h>
namespace hwcService {
// ----------------------------------------------------------------------------
enum {
SET_EXT_HPD_ENABLE = 0,
SET_EXT_DISPLAY_RESOLUTION_MODE,
SET_EXT_DISPLAY_ACTIONSAFE_DIMENSIONS,
GET_EXT_DISPLAY_TYPE,
GET_EXT_DISPLAY_RESOLUTION_MODES,
GET_EXT_DISPLAY_RESOLUTION_MODE_COUNT,
};
class IHWComposer : public android::IInterface
{
public:
DECLARE_META_INTERFACE(HWComposer);
virtual android::status_t getResolutionModeCount(int *modeCount) = 0;
virtual android::status_t getResolutionModes(int *EDIDModes,
int count = 1) = 0;
virtual android::status_t getExternalDisplay(int *extDisp) = 0;
virtual android::status_t setHPDStatus(int enable) = 0;
virtual android::status_t setResolutionMode(int resMode) = 0;
virtual android::status_t setActionSafeDimension(int w, int h) = 0;
};
// ----------------------------------------------------------------------------
class BnHWComposer : public android::BnInterface<IHWComposer>
{
public:
virtual android::status_t onTransact( uint32_t code,
const android::Parcel& data,
android::Parcel* reply,
uint32_t flags = 0);
};
// ----------------------------------------------------------------------------
}; // namespace hwcService
#endif // ANDROID_IHWCOMPOSER_H

View File

@ -75,6 +75,8 @@ bool Ctrl::setCrop(const utils::Dim& d)
return true;
}
utils::ActionSafe* utils::ActionSafe::sActionSafe = NULL;
utils::Dim Ctrl::getAspectRatio(const utils::Whf& whf) const
{
utils::Whf inWhf(whf.w, whf.h, mMdp.getSrcWhf().format);
@ -107,11 +109,9 @@ utils::Dim Ctrl::getAspectRatio(const utils::Whf& whf) const
if (inWhf.w > fbWidth) inWhf.w = fbWidth;
if (inWhf.h > fbHeight) inWhf.h = fbHeight;
char value[PROPERTY_VALUE_MAX];
property_get("hw.actionsafe.width", value, "0");
float asWidth = atof(value);
property_get("hw.actionsafe.height", value, "0");
float asHeight = atof(value);
float asWidth = utils::ActionSafe::getInstance()->getHeight();
float asHeight = utils::ActionSafe::getInstance()->getWidth();
inWhf.w = inWhf.w * (1.0f - asWidth / 100.0f);
inWhf.h = inWhf.h * (1.0f - asHeight / 100.0f);

View File

@ -228,6 +228,28 @@ struct Whf {
uint32_t size;
};
class ActionSafe {
private:
ActionSafe() : mWidth(0.0f), mHeight(0.0f) { };
float mWidth;
float mHeight;
static ActionSafe *sActionSafe;
public:
~ActionSafe() { };
static ActionSafe* getInstance() {
if(!sActionSafe) {
sActionSafe = new ActionSafe();
}
return sActionSafe;
}
void setDimension(int w, int h) {
mWidth = (float)w;
mHeight = (float)h;
}
float getWidth() { return mWidth; }
float getHeight() { return mHeight; }
};
enum { MAX_PATH_LEN = 256 };
/**