am 81cd5d3b
: make sure we don\'t call into the HWC HAL when not needed
* commit '81cd5d3b94d21253a0be925f4ae58cc7f4afeef7': make sure we don't call into the HWC HAL when not needed
This commit is contained in:
commit
64a224236d
@ -147,7 +147,7 @@ HWComposer::HWComposer(
|
|||||||
// don't need a vsync thread if we have a hardware composer
|
// don't need a vsync thread if we have a hardware composer
|
||||||
needVSyncThread = false;
|
needVSyncThread = false;
|
||||||
// always turn vsync off when we start
|
// always turn vsync off when we start
|
||||||
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
|
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
|
||||||
|
|
||||||
// these IDs are always reserved
|
// these IDs are always reserved
|
||||||
for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
|
for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
|
||||||
@ -202,7 +202,7 @@ HWComposer::HWComposer(
|
|||||||
|
|
||||||
HWComposer::~HWComposer() {
|
HWComposer::~HWComposer() {
|
||||||
if (mHwc) {
|
if (mHwc) {
|
||||||
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
|
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
|
||||||
}
|
}
|
||||||
if (mVSyncThread != NULL) {
|
if (mVSyncThread != NULL) {
|
||||||
mVSyncThread->requestExitAndWait();
|
mVSyncThread->requestExitAndWait();
|
||||||
@ -443,16 +443,32 @@ bool HWComposer::isConnected(int disp) const {
|
|||||||
return mDisplayData[disp].connected;
|
return mDisplayData[disp].connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWComposer::eventControl(int event, int enabled) {
|
void HWComposer::eventControl(int disp, int event, int enabled) {
|
||||||
|
if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
status_t err = NO_ERROR;
|
status_t err = NO_ERROR;
|
||||||
if (mHwc) {
|
if (mHwc && !mDebugForceFakeVSync) {
|
||||||
if (!mDebugForceFakeVSync) {
|
// NOTE: we use our own internal lock here because we have to call
|
||||||
err = mHwc->eventControl(mHwc, 0, event, enabled);
|
// into the HWC with the lock held, and we want to make sure
|
||||||
// error here should not happen -- not sure what we should
|
// that even if HWC blocks (which it shouldn't), it won't
|
||||||
// do if it does.
|
// affect other threads.
|
||||||
ALOGE_IF(err, "eventControl(%d, %d) failed %s",
|
Mutex::Autolock _l(mEventControlLock);
|
||||||
event, enabled, strerror(-err));
|
const int32_t eventBit = 1UL << event;
|
||||||
|
const int32_t newValue = enabled ? eventBit : 0;
|
||||||
|
const int32_t oldValue = mDisplayData[disp].events & eventBit;
|
||||||
|
if (newValue != oldValue) {
|
||||||
|
ATRACE_CALL();
|
||||||
|
err = mHwc->eventControl(mHwc, disp, event, enabled);
|
||||||
|
if (!err) {
|
||||||
|
int32_t& events(mDisplayData[disp].events);
|
||||||
|
events = (events & ~eventBit) | newValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 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) {
|
if (err == NO_ERROR && mVSyncThread != NULL) {
|
||||||
@ -652,16 +668,16 @@ status_t HWComposer::commit() {
|
|||||||
return (status_t)err;
|
return (status_t)err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t HWComposer::release(int disp) const {
|
status_t HWComposer::release(int disp) {
|
||||||
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
|
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
|
||||||
if (mHwc) {
|
if (mHwc) {
|
||||||
mHwc->eventControl(mHwc, disp, HWC_EVENT_VSYNC, 0);
|
eventControl(disp, HWC_EVENT_VSYNC, 0);
|
||||||
return (status_t)mHwc->blank(mHwc, disp, 1);
|
return (status_t)mHwc->blank(mHwc, disp, 1);
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t HWComposer::acquire(int disp) const {
|
status_t HWComposer::acquire(int disp) {
|
||||||
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
|
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
|
||||||
if (mHwc) {
|
if (mHwc) {
|
||||||
return (status_t)mHwc->blank(mHwc, disp, 0);
|
return (status_t)mHwc->blank(mHwc, disp, 0);
|
||||||
@ -965,8 +981,10 @@ HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
|
|||||||
|
|
||||||
void HWComposer::VSyncThread::setEnabled(bool enabled) {
|
void HWComposer::VSyncThread::setEnabled(bool enabled) {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
mEnabled = enabled;
|
if (mEnabled != enabled) {
|
||||||
mCondition.signal();
|
mEnabled = enabled;
|
||||||
|
mCondition.signal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWComposer::VSyncThread::onFirstRef() {
|
void HWComposer::VSyncThread::onFirstRef() {
|
||||||
|
@ -92,10 +92,10 @@ public:
|
|||||||
status_t commit();
|
status_t commit();
|
||||||
|
|
||||||
// release hardware resources and blank screen
|
// release hardware resources and blank screen
|
||||||
status_t release(int disp) const;
|
status_t release(int disp);
|
||||||
|
|
||||||
// acquire hardware resources and unblank screen
|
// acquire hardware resources and unblank screen
|
||||||
status_t acquire(int disp) const;
|
status_t acquire(int disp);
|
||||||
|
|
||||||
// reset state when an external, non-virtual display is disconnected
|
// reset state when an external, non-virtual display is disconnected
|
||||||
void disconnectDisplay(int disp);
|
void disconnectDisplay(int disp);
|
||||||
@ -226,7 +226,7 @@ public:
|
|||||||
EVENT_VSYNC = HWC_EVENT_VSYNC
|
EVENT_VSYNC = HWC_EVENT_VSYNC
|
||||||
};
|
};
|
||||||
|
|
||||||
void eventControl(int event, int enabled);
|
void eventControl(int disp, int event, int enabled);
|
||||||
|
|
||||||
// Query display parameters. Pass in a display index (e.g.
|
// Query display parameters. Pass in a display index (e.g.
|
||||||
// HWC_DISPLAY_PRIMARY).
|
// HWC_DISPLAY_PRIMARY).
|
||||||
@ -289,7 +289,7 @@ private:
|
|||||||
DisplayData() : xdpi(0), ydpi(0), refresh(0),
|
DisplayData() : xdpi(0), ydpi(0), refresh(0),
|
||||||
connected(false), hasFbComp(false), hasOvComp(false),
|
connected(false), hasFbComp(false), hasOvComp(false),
|
||||||
capacity(0), list(NULL),
|
capacity(0), list(NULL),
|
||||||
framebufferTarget(NULL), fbTargetHandle(NULL) { }
|
framebufferTarget(NULL), fbTargetHandle(NULL), events(0) { }
|
||||||
~DisplayData() {
|
~DisplayData() {
|
||||||
free(list);
|
free(list);
|
||||||
}
|
}
|
||||||
@ -306,6 +306,8 @@ private:
|
|||||||
hwc_display_contents_1* list;
|
hwc_display_contents_1* list;
|
||||||
hwc_layer_1* framebufferTarget;
|
hwc_layer_1* framebufferTarget;
|
||||||
buffer_handle_t fbTargetHandle;
|
buffer_handle_t fbTargetHandle;
|
||||||
|
// protected by mEventControlLock
|
||||||
|
int32_t events;
|
||||||
};
|
};
|
||||||
|
|
||||||
sp<SurfaceFlinger> mFlinger;
|
sp<SurfaceFlinger> mFlinger;
|
||||||
@ -327,6 +329,9 @@ private:
|
|||||||
// protected by mLock
|
// protected by mLock
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
mutable nsecs_t mLastHwVSync;
|
mutable nsecs_t mLastHwVSync;
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
|
mutable Mutex mEventControlLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -308,14 +308,14 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
|
|||||||
void EventThread::enableVSyncLocked() {
|
void EventThread::enableVSyncLocked() {
|
||||||
if (!mUseSoftwareVSync) {
|
if (!mUseSoftwareVSync) {
|
||||||
// never enable h/w VSYNC when screen is off
|
// never enable h/w VSYNC when screen is off
|
||||||
mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, true);
|
mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
|
||||||
mPowerHAL.vsyncHint(true);
|
mPowerHAL.vsyncHint(true);
|
||||||
}
|
}
|
||||||
mDebugVsyncEnabled = true;
|
mDebugVsyncEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventThread::disableVSyncLocked() {
|
void EventThread::disableVSyncLocked() {
|
||||||
mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, false);
|
mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
|
||||||
mPowerHAL.vsyncHint(false);
|
mPowerHAL.vsyncHint(false);
|
||||||
mDebugVsyncEnabled = false;
|
mDebugVsyncEnabled = false;
|
||||||
}
|
}
|
||||||
|
@ -777,8 +777,8 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::eventControl(int event, int enabled) {
|
void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
|
||||||
getHwComposer().eventControl(event, enabled);
|
getHwComposer().eventControl(disp, event, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::onMessageReceived(int32_t what) {
|
void SurfaceFlinger::onMessageReceived(int32_t what) {
|
||||||
|
@ -123,7 +123,7 @@ public:
|
|||||||
|
|
||||||
// enable/disable h/w composer event
|
// enable/disable h/w composer event
|
||||||
// TODO: this should be made accessible only to EventThread
|
// TODO: this should be made accessible only to EventThread
|
||||||
void eventControl(int event, int enabled);
|
void eventControl(int disp, int event, int enabled);
|
||||||
|
|
||||||
// called on the main thread by MessageQueue when an internal message
|
// called on the main thread by MessageQueue when an internal message
|
||||||
// is received
|
// is received
|
||||||
|
Loading…
Reference in New Issue
Block a user