split HWComposer out of DisplayHardware

we will only ever have a single instance of HWComposer, so
it's now an attribute of SurfaceFlinger, instead of being part
of DisplayHardware.

DisplayHardware now just represents a "display" (it should be renamed).

Change-Id: Iec191e57686868e1df6daa8b880a286c9fefde56
This commit is contained in:
Mathias Agopian 2012-07-24 22:46:10 -07:00
parent 98a121aa91
commit 8630320433
8 changed files with 92 additions and 115 deletions

View File

@ -106,7 +106,6 @@ DisplayHardware::DisplayHardware(
: DisplayHardwareBase(display),
mFlinger(flinger),
mDisplayId(display),
mHwc(0),
mNativeWindow(surface),
mFlags(0),
mSecureLayerVisible(false)
@ -227,12 +226,6 @@ void DisplayHardware::init(EGLConfig config)
mFormat = format;
mPageFlipCount = 0;
// initialize the H/W composer
mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod);
if (mHwc->initCheck() == NO_ERROR) {
mHwc->setFrameBuffer(mDisplay, mSurface);
}
// initialize the shared control block
surface_flinger_cblk_t* const scblk = mFlinger->getControlBlock();
scblk->connected |= 1 << mDisplayId;
@ -248,53 +241,6 @@ void DisplayHardware::init(EGLConfig config)
DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault);
}
void DisplayHardware::setVSyncHandler(const sp<VSyncHandler>& handler) {
Mutex::Autolock _l(mLock);
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<VSyncHandler> handler;
{ // scope for the lock
Mutex::Autolock _l(mLock);
mLastHwVSync = timestamp;
if (mVSyncHandler != NULL) {
handler = mVSyncHandler.promote();
}
}
if (handler != NULL) {
handler->onVSyncReceived(dpy, timestamp);
}
}
HWComposer& DisplayHardware::getHwComposer() const {
return *mHwc;
}
void DisplayHardware::releaseScreen() const
{
DisplayHardwareBase::releaseScreen();
if (mHwc->initCheck() == NO_ERROR) {
mHwc->release();
}
}
void DisplayHardware::acquireScreen() const
{
if (mHwc->initCheck() == NO_ERROR) {
mHwc->acquire();
}
DisplayHardwareBase::acquireScreen();
}
uint32_t DisplayHardware::getPageFlipCount() const {
return mPageFlipCount;
}
@ -319,6 +265,11 @@ status_t DisplayHardware::compositionComplete() const {
return mFramebufferSurface->compositionComplete();
}
void DisplayHardware::onVSyncReceived(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mLastHwVSync = timestamp;
}
void DisplayHardware::flip(const Region& dirty) const
{
checkGLErrors();
@ -342,13 +293,6 @@ void DisplayHardware::flip(const Region& dirty) const
}
mPageFlipCount++;
if (mHwc->initCheck() == NO_ERROR) {
mHwc->commit();
} else {
eglSwapBuffers(dpy, surface);
}
checkEGLErrors("eglSwapBuffers");
}
uint32_t DisplayHardware::getFlags() const

View File

@ -27,30 +27,24 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
#include "Transform.h"
#include "DisplayHardware/DisplayHardwareBase.h"
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/PowerHAL.h"
namespace android {
class FramebufferSurface;
class LayerBase;
class SurfaceFlinger;
class SurfaceTextureClient;
class DisplayHardware :
public DisplayHardwareBase,
public HWComposer::EventHandler
class DisplayHardware : public DisplayHardwareBase
{
public:
class VSyncHandler : virtual public RefBase {
friend class DisplayHardware;
virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0;
protected:
virtual ~VSyncHandler() {}
};
enum {
PARTIAL_UPDATES = 0x00020000, // video driver feature
SWAP_RECTANGLE = 0x00080000,
@ -64,13 +58,12 @@ public:
virtual ~DisplayHardware();
void releaseScreen() const;
void acquireScreen() const;
// Flip the front and back buffers if the back buffer is "dirty". Might
// be instantaneous, might involve copying the frame buffer around.
void flip(const Region& dirty) const;
void onVSyncReceived(nsecs_t timestamp);
float getDpiX() const;
float getDpiY() const;
float getRefreshRate() const;
@ -92,23 +85,11 @@ public:
int getOrientation() const { return mOrientation; }
const Transform& getTransform() const { return mGlobalTransform; }
void setVSyncHandler(const sp<VSyncHandler>& handler);
enum {
EVENT_VSYNC = HWC_EVENT_VSYNC
};
void eventControl(int event, int enabled);
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
void dump(String8& res) const;
// Hardware Composer
HWComposer& getHwComposer() const;
status_t compositionComplete() const;
Rect getBounds() const {
@ -119,15 +100,11 @@ public:
private:
void init(EGLConfig config);
virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
/*
* Constants, set during initialization
*/
sp<SurfaceFlinger> mFlinger;
int mDisplayId;
HWComposer* mHwc;
PowerHAL mPowerHAL;
// ANativeWindow this display is rendering into
sp<SurfaceTextureClient> mNativeWindow;
// set if mNativeWindow is a FramebufferSurface
@ -148,8 +125,6 @@ private:
mutable uint32_t mPageFlipCount;
nsecs_t mRefreshPeriod;
mutable nsecs_t mLastHwVSync;
/*
* Can only accessed from the main thread, these members
@ -171,7 +146,7 @@ private:
* protected by mLock
*/
mutable Mutex mLock;
wp<VSyncHandler> mVSyncHandler;
mutable nsecs_t mLastHwVSync;
};
}; // namespace android

View File

@ -276,9 +276,14 @@ size_t HWComposer::getLayerCount(int type) const {
}
status_t HWComposer::commit() const {
int err = mHwc->set(mHwc, mDpy, mSur, mList);
if (mList) {
mList->flags &= ~HWC_GEOMETRY_CHANGED;
int err = NO_ERROR;
if (mHwc) {
err = mHwc->set(mHwc, mDpy, mSur, mList);
if (mList) {
mList->flags &= ~HWC_GEOMETRY_CHANGED;
}
} else {
eglSwapBuffers(mDpy, mSur);
}
return (status_t)err;
}

View File

@ -36,7 +36,7 @@ namespace android {
// ---------------------------------------------------------------------------
EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
: mHw(const_cast<DisplayHardware&>(flinger->getDefaultDisplayHardware())), // XXX: eventthread will need rework
: mFlinger(flinger),
mLastVSyncTimestamp(0),
mVSyncTimestamp(0),
mUseSoftwareVSync(false),
@ -45,7 +45,6 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
}
void EventThread::onFirstRef() {
mHw.setVSyncHandler(this);
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
@ -251,13 +250,15 @@ bool EventThread::threadLoop() {
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screen is off
mHw.eventControl(DisplayHardware::EVENT_VSYNC, true);
mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, true);
mPowerHAL.vsyncHint(true);
}
mDebugVsyncEnabled = true;
}
void EventThread::disableVSyncLocked() {
mHw.eventControl(DisplayHardware::EVENT_VSYNC, false);
mFlinger->eventControl(SurfaceFlinger::EVENT_VSYNC, false);
mPowerHAL.vsyncHint(false);
mDebugVsyncEnabled = false;
}

View File

@ -28,6 +28,7 @@
#include <utils/SortedVector.h>
#include "DisplayHardware.h"
#include "DisplayHardware/PowerHAL.h"
// ---------------------------------------------------------------------------
namespace android {
@ -38,7 +39,7 @@ class String8;
// ---------------------------------------------------------------------------
class EventThread : public Thread, public DisplayHardware::VSyncHandler {
class EventThread : public Thread {
class Connection : public BnDisplayEventConnection {
public:
Connection(const sp<EventThread>& eventThread);
@ -77,20 +78,23 @@ public:
// called after the screen is turned on from main thread
void onScreenAcquired();
// called when receiving a vsync event
void onVSyncReceived(int display, nsecs_t timestamp);
void dump(String8& result, char* buffer, size_t SIZE) const;
private:
virtual bool threadLoop();
virtual status_t readyToRun();
virtual void onFirstRef();
virtual void onVSyncReceived(int, nsecs_t timestamp);
void removeDisplayEventConnection(const wp<Connection>& connection);
void enableVSyncLocked();
void disableVSyncLocked();
// constants
DisplayHardware& mHw;
sp<SurfaceFlinger> mFlinger;
PowerHAL mPowerHAL;
mutable Mutex mLock;
mutable Condition mCondition;

View File

@ -35,6 +35,7 @@
#include "DisplayHardware.h"
#include "Transform.h"
#include "DisplayHardware/HWComposer.h"
namespace android {

View File

@ -406,6 +406,14 @@ status_t SurfaceFlinger::readyToRun()
EGLSurface surface = hw->getEGLSurface();
initializeGL(display, surface);
// initialize the H/W composer
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this),
hw->getRefreshPeriod());
if (mHwc->initCheck() == NO_ERROR) {
mHwc->setFrameBuffer(display, surface);
}
// start the EventThread
mEventThread = new EventThread(this);
mEventQueue.setEventThread(mEventThread);
@ -555,6 +563,16 @@ bool SurfaceFlinger::threadLoop() {
return true;
}
void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
hw.onVSyncReceived(timestamp);
mEventThread->onVSyncReceived(dpy, timestamp);
}
void SurfaceFlinger::eventControl(int event, int enabled) {
getHwComposer().eventControl(event, enabled);
}
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
@ -705,7 +723,7 @@ void SurfaceFlinger::postFramebuffer()
// h/w composer.
const DisplayHardware& hw(getDefaultDisplayHardware());
HWComposer& hwc(hw.getHwComposer());
HWComposer& hwc(getHwComposer());
const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
size_t numLayers = layers.size();
const nsecs_t now = systemTime();
@ -724,6 +742,7 @@ void SurfaceFlinger::postFramebuffer()
}
hw.flip(mSwapRegion);
hwc.commit();
if (hwc.initCheck() == NO_ERROR) {
HWComposer::LayerListIterator cur = hwc.begin();
@ -1027,7 +1046,7 @@ void SurfaceFlinger::handleRefresh()
void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
{
mHwWorkListDirty = false;
HWComposer& hwc(hw.getHwComposer());
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
@ -1089,7 +1108,7 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw)
void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
{
HWComposer& hwc(hw.getHwComposer());
HWComposer& hwc(getHwComposer());
HWComposer::LayerListIterator cur = hwc.begin();
const HWComposer::LayerListIterator end = hwc.end();
if (cur == end) {
@ -1122,7 +1141,7 @@ void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
{
HWComposer& hwc(hw.getHwComposer());
HWComposer& hwc(getHwComposer());
HWComposer::LayerListIterator cur = hwc.begin();
const HWComposer::LayerListIterator end = hwc.end();
@ -1578,6 +1597,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(
void SurfaceFlinger::onScreenAcquired() {
ALOGD("Screen about to return, flinger = %p", this);
const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
getHwComposer().acquire();
hw.acquireScreen();
mEventThread->onScreenAcquired();
// this is a temporary work-around, eventually this should be called
@ -1593,6 +1613,7 @@ void SurfaceFlinger::onScreenReleased() {
if (hw.isScreenAcquired()) {
mEventThread->onScreenReleased();
hw.releaseScreen();
getHwComposer().release();
// from this point on, SF will stop drawing
}
}
@ -1842,7 +1863,7 @@ void SurfaceFlinger::dumpAllLocked(
/*
* Dump HWComposer state
*/
HWComposer& hwc(hw.getHwComposer());
HWComposer& hwc(getHwComposer());
snprintf(buffer, SIZE, "h/w composer state:\n");
result.append(buffer);
snprintf(buffer, SIZE, " h/w composer %s and %s\n",
@ -2430,7 +2451,7 @@ status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
}
// turn off hwc while we're doing the animation
hw.getHwComposer().disable();
getHwComposer().disable();
// and make sure to turn it back on (if needed) next time we compose
invalidateHwcGeometry();

View File

@ -41,11 +41,15 @@
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h>
#include <hardware/hwcomposer_defs.h>
#include <private/gui/LayerState.h>
#include "Barrier.h"
#include "MessageQueue.h"
#include "DisplayHardware/HWComposer.h"
namespace android {
// ---------------------------------------------------------------------------
@ -81,7 +85,8 @@ enum {
class SurfaceFlinger : public BinderService<SurfaceFlinger>,
public BnSurfaceComposer,
private IBinder::DeathRecipient,
private Thread
private Thread,
private HWComposer::EventHandler
{
public:
static char const* getServiceName() {
@ -90,6 +95,10 @@ public:
SurfaceFlinger();
enum {
EVENT_VSYNC = HWC_EVENT_VSYNC
};
// post an asynchronous message to the main thread
status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0,
uint32_t flags = 0);
@ -114,14 +123,19 @@ public:
return getDisplayHardware(0);
}
// utility function to delete a texture on the main thread
void deleteTextureAsync(GLuint texture);
// enable/disable h/w composer event
// TODO: this should be made accessible only to EventThread
void eventControl(int event, int enabled);
// called on the main thread by MessageQueue when an internal message
// is received
// TODO: this should be made accessible only to MessageQueue
void onMessageReceived(int32_t what);
// utility function to delete a texture on the main thread
void deleteTextureAsync(GLuint texture);
private:
friend class Client;
friend class DisplayEventConnection;
@ -193,6 +207,11 @@ private:
virtual status_t readyToRun();
virtual void onFirstRef();
/* ------------------------------------------------------------------------
* HWComposer::EventHandler interface
*/
virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
/* ------------------------------------------------------------------------
* Message handling
*/
@ -308,6 +327,12 @@ private:
}
/* ------------------------------------------------------------------------
* H/W composer
*/
HWComposer& getHwComposer() const { return *mHwc; }
/* ------------------------------------------------------------------------
* Compositing
*/
void invalidateHwcGeometry();
@ -359,6 +384,7 @@ private:
// constant members (no synchronization needed for access)
sp<IMemoryHeap> mServerHeap;
surface_flinger_cblk_t* mServerCblk;
HWComposer* mHwc;
GLuint mWormholeTexName;
GLuint mProtectedTexName;
nsecs_t mBootTime;