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:
parent
98a121aa91
commit
8630320433
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include "DisplayHardware.h"
|
||||
#include "Transform.h"
|
||||
#include "DisplayHardware/HWComposer.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user