diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk index 51f1e00..63d2ea8 100644 --- a/libhwcomposer/Android.mk +++ b/libhwcomposer/Android.mk @@ -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) diff --git a/libhwcomposer/hwc_external.cpp b/libhwcomposer/hwc_external.cpp index 70421a6..54eb083 100644 --- a/libhwcomposer/hwc_external.cpp +++ b/libhwcomposer/hwc_external.cpp @@ -35,6 +35,9 @@ #include #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]; diff --git a/libhwcomposer/hwc_external.h b/libhwcomposer/hwc_external.h index dfe93c5..e40fbd9 100644 --- a/libhwcomposer/hwc_external.h +++ b/libhwcomposer/hwc_external.h @@ -21,7 +21,8 @@ #ifndef HWC_EXTERNAL_DISPLAY_H #define HWC_EXTERNAL_DISPLAY_H -#include +#include +#include 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; diff --git a/libhwcomposer/hwc_service.cpp b/libhwcomposer/hwc_service.cpp new file mode 100644 index 0000000..59b78ff --- /dev/null +++ b/libhwcomposer/hwc_service.cpp @@ -0,0 +1,104 @@ +#include +#include + +#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 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; + } +} +} diff --git a/libhwcomposer/hwc_service.h b/libhwcomposer/hwc_service.h new file mode 100644 index 0000000..58da74b --- /dev/null +++ b/libhwcomposer/hwc_service.h @@ -0,0 +1,41 @@ +#ifndef ANDROID_HWCOMPOSER_SERVICE_H +#define ANDROID_HWCOMPOSER_SERVICE_H + +#include +#include +#include +#include +#include +#include + + +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 diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index 8bc8bfc..88512fe 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -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(); diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index 71592c4..37c52c8 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -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; diff --git a/libhwcomposer/ihwc.cpp b/libhwcomposer/ihwc.cpp new file mode 100644 index 0000000..edf1d00 --- /dev/null +++ b/libhwcomposer/ihwc.cpp @@ -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 +#include +#include + +#include +#include +#include +#include + +using namespace android; + +// --------------------------------------------------------------------------- + +namespace hwcService { + +class BpHWComposer : public BpInterface +{ +public: + BpHWComposer(const sp& impl) + : BpInterface(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 diff --git a/libhwcomposer/ihwc.h b/libhwcomposer/ihwc.h new file mode 100644 index 0000000..8313ff0 --- /dev/null +++ b/libhwcomposer/ihwc.h @@ -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 +#include + +#include +#include + +#include + + +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 +{ +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 diff --git a/liboverlay/overlayCtrl.cpp b/liboverlay/overlayCtrl.cpp index bb91529..5151b54 100644 --- a/liboverlay/overlayCtrl.cpp +++ b/liboverlay/overlayCtrl.cpp @@ -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); diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index 66c5df7..bdc9eee 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -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 }; /**