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
diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp
index f982794..067a54f 100644
--- a/services/surfaceflinger/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware.cpp
@@ -106,7 +106,6 @@
: DisplayHardwareBase(display),
mFlinger(flinger),
mDisplayId(display),
- mHwc(0),
mNativeWindow(surface),
mFlags(0),
mSecureLayerVisible(false)
@@ -227,12 +226,6 @@
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 @@
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 @@
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 @@
}
mPageFlipCount++;
-
- if (mHwc->initCheck() == NO_ERROR) {
- mHwc->commit();
- } else {
- eglSwapBuffers(dpy, surface);
- }
- checkEGLErrors("eglSwapBuffers");
}
uint32_t DisplayHardware::getFlags() const
diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h
index a1a4764..88a8c0d 100644
--- a/services/surfaceflinger/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware.h
@@ -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 @@
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 @@
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 @@
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 @@
mutable uint32_t mPageFlipCount;
nsecs_t mRefreshPeriod;
- mutable nsecs_t mLastHwVSync;
-
/*
* Can only accessed from the main thread, these members
@@ -171,7 +146,7 @@
* protected by mLock
*/
mutable Mutex mLock;
- wp<VSyncHandler> mVSyncHandler;
+ mutable nsecs_t mLastHwVSync;
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6d0631d..1742f1b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -276,9 +276,14 @@
}
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;
}
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index fe9efa6..3d79577 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -36,7 +36,7 @@
// ---------------------------------------------------------------------------
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 @@
}
void EventThread::onFirstRef() {
- mHw.setVSyncHandler(this);
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
@@ -251,13 +250,15 @@
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;
}
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 92c92de..2f10cdb 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -28,6 +28,7 @@
#include <utils/SortedVector.h>
#include "DisplayHardware.h"
+#include "DisplayHardware/PowerHAL.h"
// ---------------------------------------------------------------------------
namespace android {
@@ -38,7 +39,7 @@
// ---------------------------------------------------------------------------
-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 @@
// 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;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index aeafe4f..7bf634e 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -35,6 +35,7 @@
#include "DisplayHardware.h"
#include "Transform.h"
+#include "DisplayHardware/HWComposer.h"
namespace android {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8f94325..2ecdeb8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -406,6 +406,14 @@
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 @@
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 @@
// 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 @@
}
hw.flip(mSwapRegion);
+ hwc.commit();
if (hwc.initCheck() == NO_ERROR) {
HWComposer::LayerListIterator cur = hwc.begin();
@@ -1027,7 +1046,7 @@
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::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::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 @@
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 @@
if (hw.isScreenAcquired()) {
mEventThread->onScreenReleased();
hw.releaseScreen();
+ getHwComposer().release();
// from this point on, SF will stop drawing
}
}
@@ -1842,7 +1863,7 @@
/*
* 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 @@
}
// 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();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3ecaa7f..6418122 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -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 @@
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 @@
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 @@
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;
@@ -194,6 +208,11 @@
virtual void onFirstRef();
/* ------------------------------------------------------------------------
+ * HWComposer::EventHandler interface
+ */
+ virtual void onVSyncReceived(int dpy, nsecs_t timestamp);
+
+ /* ------------------------------------------------------------------------
* Message handling
*/
void waitForEvent();
@@ -308,6 +327,12 @@
}
/* ------------------------------------------------------------------------
+ * H/W composer
+ */
+
+ HWComposer& getHwComposer() const { return *mHwc; }
+
+ /* ------------------------------------------------------------------------
* Compositing
*/
void invalidateHwcGeometry();
@@ -359,6 +384,7 @@
// constant members (no synchronization needed for access)
sp<IMemoryHeap> mServerHeap;
surface_flinger_cblk_t* mServerCblk;
+ HWComposer* mHwc;
GLuint mWormholeTexName;
GLuint mProtectedTexName;
nsecs_t mBootTime;