From 67016af1e480a5f338555355638fc2a23e15c746 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 2 Feb 2012 15:14:13 -0800 Subject: [PATCH] fix an issue where SF would spin if /sys/power/wait_for_fb_xxx don't exist we now exit the Display thread on any error happening on these files. also refactor the code and remove a lot of unused stuff. Change-Id: I8d080c35b211890ca20ae09fa36fbdccdf5669a8 --- .../DisplayHardware/DisplayHardwareBase.cpp | 125 ++++++++---------- .../DisplayHardware/DisplayHardwareBase.h | 42 ++---- 2 files changed, 69 insertions(+), 98 deletions(-) diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp index f4afeeaa0..09f190629 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -14,7 +14,6 @@ * limitations under the License. */ -#include #include #include #include @@ -22,15 +21,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - -#include #include @@ -45,39 +35,30 @@ static char const * const kWakeFileName = "/sys/power/wait_for_fb_wake"; // ---------------------------------------------------------------------------- -DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase( +DisplayHardwareBase::DisplayEventThread::DisplayEventThread( const sp& flinger) : Thread(false), mFlinger(flinger) { } -DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() { +DisplayHardwareBase::DisplayEventThread::~DisplayEventThread() { } -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayEventThread::DisplayEventThread( - const sp& flinger) - : DisplayEventThreadBase(flinger) -{ +void DisplayHardwareBase::DisplayEventThread::onFirstRef() { + if (initCheck() == NO_ERROR) { + run("DisplayEventThread", PRIORITY_URGENT_DISPLAY); + } else { + ALOGW("/sys/power/wait_for_fb_{wake|sleep} don't exist"); + } } -DisplayHardwareBase::DisplayEventThread::~DisplayEventThread() -{ +status_t DisplayHardwareBase::DisplayEventThread::initCheck() const { + return ((access(kSleepFileName, R_OK) == 0 && + access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT; } -bool DisplayHardwareBase::DisplayEventThread::threadLoop() -{ - int err = 0; - char buf; - int fd; +bool DisplayHardwareBase::DisplayEventThread::threadLoop() { - fd = open(kSleepFileName, O_RDONLY, 0); - do { - err = read(fd, &buf, 1); - } while (err < 0 && errno == EINTR); - close(fd); - ALOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno)); - if (err >= 0) { + if (waitForFbSleep() == NO_ERROR) { sp flinger = mFlinger.promote(); ALOGD("About to give-up screen, flinger = %p", flinger.get()); if (flinger != 0) { @@ -85,39 +66,51 @@ bool DisplayHardwareBase::DisplayEventThread::threadLoop() flinger->screenReleased(0); mBarrier.wait(); } + if (waitForFbWake() == NO_ERROR) { + sp flinger = mFlinger.promote(); + ALOGD("Screen about to return, flinger = %p", flinger.get()); + if (flinger != 0) { + flinger->screenAcquired(0); + } + return true; + } } - fd = open(kWakeFileName, O_RDONLY, 0); + + // error, exit the thread + return false; +} + +status_t DisplayHardwareBase::DisplayEventThread::waitForFbSleep() { + int err = 0; + char buf; + int fd = open(kSleepFileName, O_RDONLY, 0); + // if the file doesn't exist, the error will be caught in read() below do { - err = read(fd, &buf, 1); + err = read(fd, &buf, 1); } while (err < 0 && errno == EINTR); close(fd); - ALOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno)); - if (err >= 0) { - sp flinger = mFlinger.promote(); - ALOGD("Screen about to return, flinger = %p", flinger.get()); - if (flinger != 0) - flinger->screenAcquired(0); - } - return true; + ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno)); + return err < 0 ? -errno : int(NO_ERROR); } -status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const -{ +status_t DisplayHardwareBase::DisplayEventThread::waitForFbWake() { + int err = 0; + char buf; + int fd = open(kWakeFileName, O_RDONLY, 0); + // if the file doesn't exist, the error will be caught in read() below + do { + err = read(fd, &buf, 1); + } while (err < 0 && errno == EINTR); + close(fd); + ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno)); + return err < 0 ? -errno : int(NO_ERROR); +} + +status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const { mBarrier.open(); return NO_ERROR; } -status_t DisplayHardwareBase::DisplayEventThread::readyToRun() -{ - return NO_ERROR; -} - -status_t DisplayHardwareBase::DisplayEventThread::initCheck() const -{ - return ((access(kSleepFileName, R_OK) == 0 && - access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT; -} - // ---------------------------------------------------------------------------- DisplayHardwareBase::DisplayHardwareBase(const sp& flinger, @@ -127,35 +120,27 @@ DisplayHardwareBase::DisplayHardwareBase(const sp& flinger, mDisplayEventThread = new DisplayEventThread(flinger); } -DisplayHardwareBase::~DisplayHardwareBase() -{ +DisplayHardwareBase::~DisplayHardwareBase() { // request exit mDisplayEventThread->requestExitAndWait(); } -bool DisplayHardwareBase::canDraw() const -{ +bool DisplayHardwareBase::canDraw() const { return mScreenAcquired; } -void DisplayHardwareBase::releaseScreen() const -{ +void DisplayHardwareBase::releaseScreen() const { status_t err = mDisplayEventThread->releaseScreen(); if (err >= 0) { mScreenAcquired = false; } } -void DisplayHardwareBase::acquireScreen() const -{ - status_t err = mDisplayEventThread->acquireScreen(); - if (err >= 0) { - mScreenAcquired = true; - } +void DisplayHardwareBase::acquireScreen() const { + mScreenAcquired = true; } -bool DisplayHardwareBase::isScreenAcquired() const -{ +bool DisplayHardwareBase::isScreenAcquired() const { return mScreenAcquired; } diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h index ef2df432c..91ea60298 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include "Barrier.h" namespace android { @@ -31,11 +29,11 @@ class SurfaceFlinger; class DisplayHardwareBase { public: - DisplayHardwareBase( - const sp& flinger, - uint32_t displayIndex); + DisplayHardwareBase( + const sp& flinger, + uint32_t displayIndex); - ~DisplayHardwareBase(); + ~DisplayHardwareBase(); // console management void releaseScreen() const; @@ -46,34 +44,22 @@ public: private: - class DisplayEventThreadBase : public Thread { - protected: + class DisplayEventThread : public Thread { wp mFlinger; - public: - DisplayEventThreadBase(const sp& flinger); - virtual ~DisplayEventThreadBase(); - virtual void onFirstRef() { - run("DisplayEventThread", PRIORITY_URGENT_DISPLAY); - } - virtual status_t acquireScreen() const { return NO_ERROR; }; - virtual status_t releaseScreen() const { return NO_ERROR; }; - virtual status_t initCheck() const = 0; - }; - - class DisplayEventThread : public DisplayEventThreadBase - { mutable Barrier mBarrier; + status_t waitForFbSleep(); + status_t waitForFbWake(); public: - DisplayEventThread(const sp& flinger); + DisplayEventThread(const sp& flinger); virtual ~DisplayEventThread(); + virtual void onFirstRef(); virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual status_t releaseScreen() const; - virtual status_t initCheck() const; + status_t releaseScreen() const; + status_t initCheck() const; }; - sp mDisplayEventThread; - mutable int mScreenAcquired; + sp mDisplayEventThread; + mutable int mScreenAcquired; }; }; // namespace android