diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 8b1645661..6f7a7e1ff 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \ DisplayHardware/DisplayHardware.cpp \ DisplayHardware/DisplayHardwareBase.cpp \ DisplayHardware/HWComposer.cpp \ + DisplayHardware/PowerHAL.cpp \ GLExtensions.cpp \ MessageQueue.cpp \ SurfaceFlinger.cpp \ diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 48651b60b..bb93215e0 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -358,6 +358,13 @@ void DisplayHardware::setVSyncHandler(const sp& handler) { mVSyncHandler = handler; } +void DisplayHardware::eventControl(int event, int enabled) { + if (event == EVENT_VSYNC) { + mPowerHAL.vsyncHint(enabled); + } + mHwc->eventControl(event, enabled); +} + void DisplayHardware::onVSyncReceived(int dpy, nsecs_t timestamp) { sp handler; { // scope for the lock diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h index f1dee91be..0604031fc 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -31,6 +31,7 @@ #include "DisplayHardware/DisplayHardwareBase.h" #include "HWComposer.h" +#include "PowerHAL.h" namespace android { @@ -86,6 +87,12 @@ public: void setVSyncHandler(const sp& handler); + enum { + EVENT_VSYNC = HWC_EVENT_VSYNC + }; + + void eventControl(int event, int enabled); + uint32_t getPageFlipCount() const; EGLDisplay getEGLDisplay() const { return mDisplay; } @@ -129,6 +136,8 @@ private: // constant once set HWComposer* mHwc; + PowerHAL mPowerHAL; + mutable Mutex mLock; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index b87e191da..65763db8d 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -125,19 +125,21 @@ void HWComposer::vsync(int dpy, int64_t timestamp) { mEventHandler.onVSyncReceived(dpy, timestamp); } -status_t HWComposer::eventControl(int event, int enabled) { +void HWComposer::eventControl(int event, int enabled) { status_t err = NO_ERROR; if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { if (!mDebugForceFakeVSync) { err = mHwc->methods->eventControl(mHwc, event, enabled); + // error here should not happen -- not sure what we should + // do if it does. + ALOGE_IF(err, "eventControl(%d, %d) failed %s", + event, enabled, strerror(-err)); } } if (err == NO_ERROR && mVSyncThread != NULL) { mVSyncThread->setEnabled(enabled); } - - return err; } void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 76aadf88b..aada3cd06 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -86,7 +86,7 @@ public: EVENT_VSYNC = HWC_EVENT_VSYNC }; - status_t eventControl(int event, int enabled); + void eventControl(int event, int enabled); // this class is only used to fake the VSync event on systems that don't // have it. diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp new file mode 100644 index 000000000..0cb47d59a --- /dev/null +++ b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 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 "PowerHAL.h" + +namespace android { +// --------------------------------------------------------------------------- + +PowerHAL::PowerHAL() : mPowerModule(0) { + int err = hw_get_module(POWER_HARDWARE_MODULE_ID, + (const hw_module_t **)&mPowerModule); + ALOGW_IF(err, "%s module not found", POWER_HARDWARE_MODULE_ID); +} + +PowerHAL::~PowerHAL() { +} + +status_t PowerHAL::initCheck() const { + return mPowerModule ? NO_ERROR : NO_INIT; +} + +status_t PowerHAL::vsyncHint(bool enabled) { + if (!mPowerModule) { + return NO_INIT; + } + if (mPowerModule->common.module_api_version >= POWER_MODULE_API_VERSION_0_2) { + if (mPowerModule->powerHint) { + mPowerModule->powerHint(mPowerModule, POWER_HINT_VSYNC, (void*)enabled); + } + } + return NO_ERROR; +} + +// --------------------------------------------------------------------------- +}; // namespace android + diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.h b/services/surfaceflinger/DisplayHardware/PowerHAL.h new file mode 100644 index 000000000..929bc0396 --- /dev/null +++ b/services/surfaceflinger/DisplayHardware/PowerHAL.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 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_SF_POWER_HAL_H +#define ANDROID_SF_POWER_HAL_H + +#include +#include + +#include + +namespace android { +// --------------------------------------------------------------------------- + +class PowerHAL +{ +public: + PowerHAL(); + ~PowerHAL(); + + status_t initCheck() const; + status_t vsyncHint(bool enabled); + +private: + power_module_t* mPowerModule; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_SF_POWER_HAL_H diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 21634ee97..47fa2f3df 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -253,13 +253,13 @@ bool EventThread::threadLoop() { void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off - mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true); + mHw.eventControl(DisplayHardware::EVENT_VSYNC, true); } mDebugVsyncEnabled = true; } void EventThread::disableVSyncLocked() { - mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false); + mHw.eventControl(DisplayHardware::EVENT_VSYNC, false); mDebugVsyncEnabled = false; }