Reshuffle FramebufferSurface

FramebufferSurface no longer speaks directly to the FB HAL.  Now
everything goes through HWComposer (which may or may not be
connected to a hardware composer).

Added display index arg to some query methods.

Change-Id: Id3e157d2d4e3555d33afbb703e518b6e92e2d6d5
This commit is contained in:
Andy McFadden 2012-09-10 14:08:09 -07:00
parent 1fc4f80fc3
commit b0d1dd36f1
6 changed files with 202 additions and 158 deletions

View File

@ -33,21 +33,12 @@
#include <ui/GraphicBuffer.h> #include <ui/GraphicBuffer.h>
#include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
namespace android { namespace android {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
sp<FramebufferSurface> FramebufferSurface::create() {
sp<FramebufferSurface> result = new FramebufferSurface();
if (result->fbDev == NULL) {
result = NULL;
}
return result;
}
// ----------------------------------------------------------------------------
class GraphicBufferAlloc : public BnGraphicBufferAlloc { class GraphicBufferAlloc : public BnGraphicBufferAlloc {
public: public:
GraphicBufferAlloc() { }; GraphicBufferAlloc() { };
@ -66,36 +57,21 @@ public:
* *
*/ */
FramebufferSurface::FramebufferSurface(): FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())), ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
fbDev(0),
mCurrentBufferSlot(-1), mCurrentBufferSlot(-1),
mCurrentBuffer(0) mCurrentBuffer(0),
mHwc(hwc)
{ {
hw_module_t const* module; mName = "FramebufferSurface";
mBufferQueue->setConsumerName(mName);
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
int stride; GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER);
int err; mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY));
int i; mBufferQueue->setDefaultBufferSize(mHwc.getResolutionX(HWC_DISPLAY_PRIMARY),
err = framebuffer_open(module, &fbDev); mHwc.getResolutionY(HWC_DISPLAY_PRIMARY));
ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); mBufferQueue->setSynchronousMode(true);
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
// bail out if we can't initialize the modules
if (!fbDev)
return;
mName = "FramebufferSurface";
mBufferQueue->setConsumerName(mName);
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER);
mBufferQueue->setDefaultBufferFormat(fbDev->format);
mBufferQueue->setDefaultBufferSize(fbDev->width, fbDev->height);
mBufferQueue->setSynchronousMode(true);
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
} else {
ALOGE("Couldn't get gralloc module");
}
} }
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) { status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
@ -145,12 +121,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
return NO_ERROR; return NO_ERROR;
} }
FramebufferSurface::~FramebufferSurface() { // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
if (fbDev) {
framebuffer_close(fbDev);
}
}
void FramebufferSurface::onFrameAvailable() { void FramebufferSurface::onFrameAvailable() {
// XXX: The following code is here temporarily as part of the transition // XXX: The following code is here temporarily as part of the transition
// away from the framebuffer HAL. // away from the framebuffer HAL.
@ -161,7 +132,7 @@ void FramebufferSurface::onFrameAvailable() {
strerror(-err), err); strerror(-err), err);
return; return;
} }
err = fbDev->post(fbDev, buf->handle); err = mHwc.fbPost(buf->handle);
if (err != NO_ERROR) { if (err != NO_ERROR) {
ALOGE("error posting framebuffer: %d", err); ALOGE("error posting framebuffer: %d", err);
} }
@ -181,19 +152,11 @@ status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
status_t FramebufferSurface::compositionComplete() status_t FramebufferSurface::compositionComplete()
{ {
if (fbDev->compositionComplete) { return mHwc.fbCompositionComplete();
return fbDev->compositionComplete(fbDev);
}
return INVALID_OPERATION;
} }
void FramebufferSurface::dump(String8& result) { void FramebufferSurface::dump(String8& result) {
if (fbDev->common.version >= 1 && fbDev->dump) { mHwc.fbDump(result);
const size_t SIZE = 4096;
char buffer[SIZE];
fbDev->dump(fbDev, buffer, SIZE);
result.append(buffer);
}
ConsumerBase::dump(result); ConsumerBase::dump(result);
} }

View File

@ -30,13 +30,13 @@ namespace android {
class Rect; class Rect;
class String8; class String8;
class HWComposer;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class FramebufferSurface : public ConsumerBase { class FramebufferSurface : public ConsumerBase {
public: public:
FramebufferSurface(HWComposer& hwc);
static sp<FramebufferSurface> create();
bool isUpdateOnDemand() const { return false; } bool isUpdateOnDemand() const { return false; }
status_t setUpdateRectangle(const Rect& updateRect); status_t setUpdateRectangle(const Rect& updateRect);
@ -49,22 +49,12 @@ public:
// BufferQueue. The new buffer is returned in the 'buffer' argument. // BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>* buffer); status_t nextBuffer(sp<GraphicBuffer>* buffer);
// FIXME: currently there are information we can only get from the
// FB HAL, and FB HAL can only be instantiated once on some devices.
// Eventually this functionality will have to move in HWC or somewhere else.
const framebuffer_device_t* getFbHal() const {
return fbDev;
}
private: private:
FramebufferSurface(); virtual ~FramebufferSurface() { }; // this class cannot be overloaded
virtual ~FramebufferSurface(); // this class cannot be overloaded
virtual void onFrameAvailable(); virtual void onFrameAvailable();
virtual void freeBufferLocked(int slotIndex); virtual void freeBufferLocked(int slotIndex);
framebuffer_device_t* fbDev;
// mCurrentBufferIndex is the slot index of the current buffer or // mCurrentBufferIndex is the slot index of the current buffer or
// INVALID_BUFFER_SLOT to indicate that either there is no current buffer // INVALID_BUFFER_SLOT to indicate that either there is no current buffer
// or the buffer is not associated with a slot. // or the buffer is not associated with a slot.
@ -73,6 +63,9 @@ private:
// mCurrentBuffer is the current buffer or NULL to indicate that there is // mCurrentBuffer is the current buffer or NULL to indicate that there is
// no current buffer. // no current buffer.
sp<GraphicBuffer> mCurrentBuffer; sp<GraphicBuffer> mCurrentBuffer;
// Hardware composer, owned by SurfaceFlinger.
HWComposer& mHwc;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -90,10 +90,9 @@ struct HWComposer::cb_context {
HWComposer::HWComposer( HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger, const sp<SurfaceFlinger>& flinger,
EventHandler& handler, EventHandler& handler)
framebuffer_device_t const* fbDev)
: mFlinger(flinger), : mFlinger(flinger),
mModule(0), mHwc(0), mNumDisplays(1), mFbDev(0), mHwc(0), mNumDisplays(1),
mCBContext(new cb_context), mCBContext(new cb_context),
mEventHandler(handler), mEventHandler(handler),
mVSyncCount(0), mDebugForceFakeVSync(false) mVSyncCount(0), mDebugForceFakeVSync(false)
@ -107,71 +106,62 @@ HWComposer::HWComposer(
mDebugForceFakeVSync = atoi(value); mDebugForceFakeVSync = atoi(value);
bool needVSyncThread = true; bool needVSyncThread = true;
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); // Note: some devices may insist that the FB HAL be opened before HWC.
if (err == 0) { loadFbHalModule();
err = hwc_open_1(mModule, &mHwc); loadHwcModule();
ALOGE_IF(err, "%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err)); if (mHwc) {
if (err == 0) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) || (hwcApiVersion(mHwc) >> 24) & 0xff,
hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION || (hwcApiVersion(mHwc) >> 16) & 0xff);
hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) { if (mHwc->registerProcs) {
ALOGE("%s device version %#x unsupported, will not be used", mCBContext->hwc = this;
HWC_HARDWARE_COMPOSER, mHwc->common.version); mCBContext->procs.invalidate = &hook_invalidate;
hwc_close_1(mHwc); mCBContext->procs.vsync = &hook_vsync;
mHwc = NULL; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
} mCBContext->procs.hotplug = &hook_hotplug;
else
mCBContext->procs.hotplug = NULL;
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
mHwc->registerProcs(mHwc, &mCBContext->procs);
} }
if (mHwc) { // don't need a vsync thread if we have a hardware composer
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, needVSyncThread = false;
(hwcApiVersion(mHwc) >> 24) & 0xff, // always turn vsync off when we start
(hwcApiVersion(mHwc) >> 16) & 0xff); mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
if (mHwc->registerProcs) {
mCBContext->hwc = this;
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
mCBContext->procs.hotplug = &hook_hotplug;
else
mCBContext->procs.hotplug = NULL;
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
mHwc->registerProcs(mHwc, &mCBContext->procs);
}
// always turn vsync off when we start // these IDs are always reserved
needVSyncThread = false; for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); mAllocatedDisplayIDs.markBit(i);
}
// these IDs are always reserved // the number of displays we actually have depends on the
for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) { // hw composer version
mAllocatedDisplayIDs.markBit(i); if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
} // 1.2 adds support for virtual displays
mNumDisplays = MAX_DISPLAYS;
// the number of displays we actually have depends on the } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// hw composer version // 1.1 adds support for multiple displays
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) { mNumDisplays = HWC_NUM_DISPLAY_TYPES;
// 1.2 adds support for virtual displays } else {
mNumDisplays = MAX_DISPLAYS; mNumDisplays = 1;
} else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// 1.1 adds support for multiple displays
mNumDisplays = HWC_NUM_DISPLAY_TYPES;
} else {
mNumDisplays = 1;
}
} }
} }
if (fbDev) { if (mFbDev) {
ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
"should only have fbdev if no hwc or hwc is 1.0"); "should only have fbdev if no hwc or hwc is 1.0");
DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
disp.xdpi = fbDev->xdpi; disp.xres = mFbDev->width;
disp.ydpi = fbDev->ydpi; disp.yres = mFbDev->height;
disp.format = mFbDev->format;
disp.xdpi = mFbDev->xdpi;
disp.ydpi = mFbDev->ydpi;
if (disp.refresh == 0) { if (disp.refresh == 0) {
disp.refresh = nsecs_t(1e9 / fbDev->fps); disp.refresh = nsecs_t(1e9 / mFbDev->fps);
ALOGW("getting VSYNC period from fb HAL: %lld", disp.refresh); ALOGW("getting VSYNC period from fb HAL: %lld", disp.refresh);
} }
if (disp.refresh == 0) { if (disp.refresh == 0) {
@ -197,9 +187,57 @@ HWComposer::~HWComposer() {
if (mHwc) { if (mHwc) {
hwc_close_1(mHwc); hwc_close_1(mHwc);
} }
if (mFbDev) {
framebuffer_close(mFbDev);
}
delete mCBContext; delete mCBContext;
} }
// Load and prepare the hardware composer module. Sets mHwc.
void HWComposer::loadHwcModule()
{
hw_module_t const* module;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
return;
}
int err = hwc_open_1(module, &mHwc);
if (err) {
ALOGE("%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
return;
}
if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
ALOGE("%s device version %#x unsupported, will not be used",
HWC_HARDWARE_COMPOSER, mHwc->common.version);
hwc_close_1(mHwc);
mHwc = NULL;
return;
}
}
// Load and prepare the FB HAL, which uses the gralloc module. Sets mFbDev.
void HWComposer::loadFbHalModule()
{
hw_module_t const* module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {
ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
return;
}
int err = framebuffer_open(module, &mFbDev);
if (err) {
ALOGE("framebuffer_open failed (%s)", strerror(-err));
return;
}
}
status_t HWComposer::initCheck() const { status_t HWComposer::initCheck() const {
return mHwc ? NO_ERROR : NO_INIT; return mHwc ? NO_ERROR : NO_INIT;
} }
@ -265,6 +303,7 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = {
void HWComposer::queryDisplayProperties(int disp) { void HWComposer::queryDisplayProperties(int disp) {
ALOG_ASSERT(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)); ALOG_ASSERT(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
// use zero as default value for unspecified attributes
int32_t values[NUM_DISPLAY_ATTRIBUTES - 1]; int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
memset(values, 0, sizeof(values)); memset(values, 0, sizeof(values));
@ -283,12 +322,10 @@ void HWComposer::queryDisplayProperties(int disp) {
mDisplayData[disp].refresh = nsecs_t(values[i]); mDisplayData[disp].refresh = nsecs_t(values[i]);
break; break;
case HWC_DISPLAY_RESOLUTION_X: case HWC_DISPLAY_RESOLUTION_X:
// TODO: we'll probably want to remember this eventually mDisplayData[disp].xres = values[i];
w = values[i];
break; break;
case HWC_DISPLAY_RESOLUTION_Y: case HWC_DISPLAY_RESOLUTION_Y:
// TODO: we'll probably want to remember this eventually mDisplayData[disp].yres = values[i];
h = values[i];
break; break;
case HWC_DISPLAY_DPI_X: case HWC_DISPLAY_DPI_X:
mDisplayData[disp].xdpi = values[i] / 1000.0f; mDisplayData[disp].xdpi = values[i] / 1000.0f;
@ -336,25 +373,37 @@ status_t HWComposer::freeDisplayId(int32_t id) {
return NO_ERROR; return NO_ERROR;
} }
nsecs_t HWComposer::getRefreshPeriod() const { nsecs_t HWComposer::getRefreshPeriod(int disp) const {
return mDisplayData[HWC_DISPLAY_PRIMARY].refresh; return mDisplayData[disp].refresh;
} }
nsecs_t HWComposer::getRefreshTimestamp() const { nsecs_t HWComposer::getRefreshTimestamp(int disp) const {
// this returns the last refresh timestamp. // this returns the last refresh timestamp.
// if the last one is not available, we estimate it based on // if the last one is not available, we estimate it based on
// the refresh period and whatever closest timestamp we have. // the refresh period and whatever closest timestamp we have.
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
nsecs_t now = systemTime(CLOCK_MONOTONIC); nsecs_t now = systemTime(CLOCK_MONOTONIC);
return now - ((now - mLastHwVSync) % mDisplayData[HWC_DISPLAY_PRIMARY].refresh); return now - ((now - mLastHwVSync) % mDisplayData[disp].refresh);
} }
float HWComposer::getDpiX() const { uint32_t HWComposer::getResolutionX(int disp) const {
return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi; return mDisplayData[disp].xres;
} }
float HWComposer::getDpiY() const { uint32_t HWComposer::getResolutionY(int disp) const {
return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi; return mDisplayData[disp].yres;
}
uint32_t HWComposer::getFormat(int disp) const {
return mDisplayData[disp].format;
}
float HWComposer::getDpiX(int disp) const {
return mDisplayData[disp].xdpi;
}
float HWComposer::getDpiY(int disp) const {
return mDisplayData[disp].ydpi;
} }
void HWComposer::eventControl(int event, int enabled) { void HWComposer::eventControl(int event, int enabled) {
@ -493,6 +542,30 @@ size_t HWComposer::getNumLayers(int32_t id) const {
mDisplayData[id].list->numHwLayers : 0; mDisplayData[id].list->numHwLayers : 0;
} }
int HWComposer::fbPost(buffer_handle_t buffer)
{
return mFbDev->post(mFbDev, buffer);
}
int HWComposer::fbCompositionComplete()
{
if (mFbDev->compositionComplete) {
return mFbDev->compositionComplete(mFbDev);
} else {
return INVALID_OPERATION;
}
}
void HWComposer::fbDump(String8& result) {
if (mFbDev->common.version >= 1 && mFbDev->dump) {
const size_t SIZE = 4096;
char buffer[SIZE];
mFbDev->dump(mFbDev, buffer, SIZE);
result.append(buffer);
}
}
/* /*
* Helper template to implement a concrete HWCLayer * Helper template to implement a concrete HWCLayer
* This holds the pointer to the concrete hwc layer type * This holds the pointer to the concrete hwc layer type
@ -680,7 +753,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
: mHwc(hwc), mEnabled(false), : mHwc(hwc), mEnabled(false),
mNextFakeVSync(0), mNextFakeVSync(0),
mRefreshPeriod(hwc.getRefreshPeriod()) mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY))
{ {
} }

View File

@ -64,8 +64,7 @@ public:
HWComposer( HWComposer(
const sp<SurfaceFlinger>& flinger, const sp<SurfaceFlinger>& flinger,
EventHandler& handler, EventHandler& handler);
framebuffer_device_t const* fbDev);
~HWComposer(); ~HWComposer();
@ -107,6 +106,11 @@ public:
// needed forward declarations // needed forward declarations
class LayerListIterator; class LayerListIterator;
// Forwarding to FB HAL for pre-HWC-1.1 code (see FramebufferSurface).
int fbPost(buffer_handle_t buffer);
int fbCompositionComplete();
void fbDump(String8& result);
/* /*
* Interface to hardware composer's layers functionality. * Interface to hardware composer's layers functionality.
* This abstracts the HAL interface to layers which can evolve in * This abstracts the HAL interface to layers which can evolve in
@ -208,10 +212,15 @@ public:
void eventControl(int event, int enabled); void eventControl(int event, int enabled);
nsecs_t getRefreshPeriod() const; // Query display parameters. Pass in a display index (e.g.
nsecs_t getRefreshTimestamp() const; // HWC_DISPLAY_PRIMARY).
float getDpiX() const; nsecs_t getRefreshPeriod(int disp) const;
float getDpiY() const; nsecs_t getRefreshTimestamp(int disp) const;
uint32_t getResolutionX(int disp) const;
uint32_t getResolutionY(int disp) const;
uint32_t getFormat(int disp) const;
float getDpiX(int disp) const;
float getDpiY(int disp) const;
// this class is only used to fake the VSync event on systems that don't // this class is only used to fake the VSync event on systems that don't
// have it. // have it.
@ -236,6 +245,8 @@ public:
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
private: private:
void loadHwcModule();
void loadFbHalModule();
LayerListIterator getLayerIterator(int32_t id, size_t index); LayerListIterator getLayerIterator(int32_t id, size_t index);
size_t getNumLayers(int32_t id) const; size_t getNumLayers(int32_t id) const;
@ -261,6 +272,9 @@ private:
~DisplayData() { ~DisplayData() {
free(list); free(list);
} }
uint32_t xres;
uint32_t yres;
uint32_t format; // pixel format from FB hal, for pre-hwc-1.1
float xdpi; float xdpi;
float ydpi; float ydpi;
nsecs_t refresh; nsecs_t refresh;
@ -271,7 +285,7 @@ private:
}; };
sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger;
hw_module_t const* mModule; framebuffer_device_t* mFbDev;
struct hwc_composer_device_1* mHwc; struct hwc_composer_device_1* mHwc;
// invariant: mLists[0] != NULL iff mHwc != NULL // invariant: mLists[0] != NULL iff mHwc != NULL
// mLists[i>0] can be NULL. that display is to be ignored // mLists[i>0] can be NULL. that display is to be ignored

View File

@ -515,7 +515,7 @@ void Layer::onPostComposition() {
const size_t offset = mFrameLatencyOffset; const size_t offset = mFrameLatencyOffset;
mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp(); mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
mFrameStats[offset].set = systemTime(); mFrameStats[offset].set = systemTime();
mFrameStats[offset].vsync = hwc.getRefreshTimestamp(); mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
mFrameLatencyNeeded = false; mFrameLatencyNeeded = false;
} }
@ -726,7 +726,8 @@ void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
{ {
LayerBaseClient::dumpStats(result, buffer, SIZE); LayerBaseClient::dumpStats(result, buffer, SIZE);
const size_t o = mFrameLatencyOffset; const size_t o = mFrameLatencyOffset;
const nsecs_t period = mFlinger->getHwComposer().getRefreshPeriod(); const nsecs_t period =
mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
result.appendFormat("%lld\n", period); result.appendFormat("%lld\n", period);
for (size_t i=0 ; i<128 ; i++) { for (size_t i=0 ; i<128 ; i++) {
const size_t index = (o+i) % 128; const size_t index = (o+i) % 128;

View File

@ -366,13 +366,18 @@ status_t SurfaceFlinger::readyToRun()
ALOGI( "SurfaceFlinger's main thread ready to run. " ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W..."); "Initializing graphics H/W...");
// initialize EGL // initialize EGL for the default display
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL); eglInitialize(mEGLDisplay, NULL, NULL);
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
// Initialize the main display // Initialize the main display
// create native window to main display // create native window to main display
sp<FramebufferSurface> fbs = FramebufferSurface::create(); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
if (fbs == NULL) { if (fbs == NULL) {
ALOGE("Display subsystem failed to initialize. check logs. exiting..."); ALOGE("Display subsystem failed to initialize. check logs. exiting...");
exit(0); exit(0);
@ -408,11 +413,6 @@ status_t SurfaceFlinger::readyToRun()
mEventThread = new EventThread(this); mEventThread = new EventThread(this);
mEventQueue.setEventThread(mEventThread); mEventQueue.setEventThread(mEventThread);
// initialize the H/W composer
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this),
fbs->getFbHal());
// initialize our drawing state // initialize our drawing state
mDrawingState = mCurrentState; mDrawingState = mCurrentState;
@ -500,8 +500,8 @@ status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo*
} }
const HWComposer& hwc(getHwComposer()); const HWComposer& hwc(getHwComposer());
float xdpi = hwc.getDpiX(); float xdpi = hwc.getDpiX(HWC_DISPLAY_PRIMARY);
float ydpi = hwc.getDpiY(); float ydpi = hwc.getDpiY(HWC_DISPLAY_PRIMARY);
// TODO: Not sure if display density should handled by SF any longer // TODO: Not sure if display density should handled by SF any longer
class Density { class Density {
@ -538,7 +538,7 @@ status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo*
info->h = hw->getHeight(); info->h = hw->getHeight();
info->xdpi = xdpi; info->xdpi = xdpi;
info->ydpi = ydpi; info->ydpi = ydpi;
info->fps = float(1e9 / hwc.getRefreshPeriod()); info->fps = float(1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY));
info->density = density; info->density = density;
info->orientation = hw->getOrientation(); info->orientation = hw->getOrientation();
// TODO: this needs to go away (currently needed only by webkit) // TODO: this needs to go away (currently needed only by webkit)
@ -2018,9 +2018,9 @@ void SurfaceFlinger::dumpAllLocked(
mLastSwapBufferTime/1000.0, mLastSwapBufferTime/1000.0,
mLastTransactionTime/1000.0, mLastTransactionTime/1000.0,
mTransactionFlags, mTransactionFlags,
1e9 / hwc.getRefreshPeriod(), 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
hwc.getDpiX(), hwc.getDpiX(HWC_DISPLAY_PRIMARY),
hwc.getDpiY()); hwc.getDpiY(HWC_DISPLAY_PRIMARY));
result.append(buffer); result.append(buffer);
snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",