Loading services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +17 −54 Original line number Diff line number Diff line Loading @@ -33,21 +33,12 @@ #include <ui/GraphicBuffer.h> #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- sp<FramebufferSurface> FramebufferSurface::create() { sp<FramebufferSurface> result = new FramebufferSurface(); if (result->fbDev == NULL) { result = NULL; } return result; } // ---------------------------------------------------------------------------- class GraphicBufferAlloc : public BnGraphicBufferAlloc { public: GraphicBufferAlloc() { }; Loading @@ -66,36 +57,21 @@ public: * */ FramebufferSurface::FramebufferSurface(): FramebufferSurface::FramebufferSurface(HWComposer& hwc) : ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())), fbDev(0), mCurrentBufferSlot(-1), mCurrentBuffer(0) mCurrentBuffer(0), mHwc(hwc) { hw_module_t const* module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { int stride; int err; int i; err = framebuffer_open(module, &fbDev); ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); // 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->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY)); mBufferQueue->setDefaultBufferSize(mHwc.getResolutionX(HWC_DISPLAY_PRIMARY), mHwc.getResolutionY(HWC_DISPLAY_PRIMARY)); mBufferQueue->setSynchronousMode(true); mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS); } else { ALOGE("Couldn't get gralloc module"); } } status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) { Loading Loading @@ -145,12 +121,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) { return NO_ERROR; } FramebufferSurface::~FramebufferSurface() { if (fbDev) { framebuffer_close(fbDev); } } // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. void FramebufferSurface::onFrameAvailable() { // XXX: The following code is here temporarily as part of the transition // away from the framebuffer HAL. Loading @@ -161,7 +132,7 @@ void FramebufferSurface::onFrameAvailable() { strerror(-err), err); return; } err = fbDev->post(fbDev, buf->handle); err = mHwc.fbPost(buf->handle); if (err != NO_ERROR) { ALOGE("error posting framebuffer: %d", err); } Loading @@ -181,19 +152,11 @@ status_t FramebufferSurface::setUpdateRectangle(const Rect& r) status_t FramebufferSurface::compositionComplete() { if (fbDev->compositionComplete) { return fbDev->compositionComplete(fbDev); } return INVALID_OPERATION; return mHwc.fbCompositionComplete(); } void FramebufferSurface::dump(String8& result) { if (fbDev->common.version >= 1 && fbDev->dump) { const size_t SIZE = 4096; char buffer[SIZE]; fbDev->dump(fbDev, buffer, SIZE); result.append(buffer); } mHwc.fbDump(result); ConsumerBase::dump(result); } Loading services/surfaceflinger/DisplayHardware/FramebufferSurface.h +6 −13 Original line number Diff line number Diff line Loading @@ -30,13 +30,13 @@ namespace android { class Rect; class String8; class HWComposer; // --------------------------------------------------------------------------- class FramebufferSurface : public ConsumerBase { public: static sp<FramebufferSurface> create(); FramebufferSurface(HWComposer& hwc); bool isUpdateOnDemand() const { return false; } status_t setUpdateRectangle(const Rect& updateRect); Loading @@ -49,22 +49,12 @@ public: // BufferQueue. The new buffer is returned in the 'buffer' argument. 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: FramebufferSurface(); virtual ~FramebufferSurface(); // this class cannot be overloaded virtual ~FramebufferSurface() { }; // this class cannot be overloaded virtual void onFrameAvailable(); virtual void freeBufferLocked(int slotIndex); framebuffer_device_t* fbDev; // mCurrentBufferIndex is the slot index of the current buffer or // INVALID_BUFFER_SLOT to indicate that either there is no current buffer // or the buffer is not associated with a slot. Loading @@ -73,6 +63,9 @@ private: // mCurrentBuffer is the current buffer or NULL to indicate that there is // no current buffer. sp<GraphicBuffer> mCurrentBuffer; // Hardware composer, owned by SurfaceFlinger. HWComposer& mHwc; }; // --------------------------------------------------------------------------- Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +142 −69 Original line number Diff line number Diff line Loading @@ -90,10 +90,9 @@ struct HWComposer::cb_context { HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler, framebuffer_device_t const* fbDev) EventHandler& handler) : mFlinger(flinger), mModule(0), mHwc(0), mNumDisplays(1), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mVSyncCount(0), mDebugForceFakeVSync(false) Loading @@ -107,22 +106,10 @@ HWComposer::HWComposer( mDebugForceFakeVSync = atoi(value); bool needVSyncThread = true; int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); if (err == 0) { err = hwc_open_1(mModule, &mHwc); ALOGE_IF(err, "%s device failed to initialize (%s)", HWC_HARDWARE_COMPOSER, strerror(-err)); if (err == 0) { 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; } } // Note: some devices may insist that the FB HAL be opened before HWC. loadFbHalModule(); loadHwcModule(); if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, Loading @@ -140,8 +127,9 @@ HWComposer::HWComposer( mHwc->registerProcs(mHwc, &mCBContext->procs); } // always turn vsync off when we start // don't need a vsync thread if we have a hardware composer needVSyncThread = false; // always turn vsync off when we start mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // these IDs are always reserved Loading @@ -161,17 +149,19 @@ HWComposer::HWComposer( mNumDisplays = 1; } } } if (fbDev) { if (mFbDev) { ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), "should only have fbdev if no hwc or hwc is 1.0"); DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); disp.xdpi = fbDev->xdpi; disp.ydpi = fbDev->ydpi; disp.xres = mFbDev->width; disp.yres = mFbDev->height; disp.format = mFbDev->format; disp.xdpi = mFbDev->xdpi; disp.ydpi = mFbDev->ydpi; 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); } if (disp.refresh == 0) { Loading @@ -197,9 +187,57 @@ HWComposer::~HWComposer() { if (mHwc) { hwc_close_1(mHwc); } if (mFbDev) { framebuffer_close(mFbDev); } 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 { return mHwc ? NO_ERROR : NO_INIT; } Loading Loading @@ -265,6 +303,7 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = { void HWComposer::queryDisplayProperties(int disp) { 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]; memset(values, 0, sizeof(values)); Loading @@ -283,12 +322,10 @@ void HWComposer::queryDisplayProperties(int disp) { mDisplayData[disp].refresh = nsecs_t(values[i]); break; case HWC_DISPLAY_RESOLUTION_X: // TODO: we'll probably want to remember this eventually w = values[i]; mDisplayData[disp].xres = values[i]; break; case HWC_DISPLAY_RESOLUTION_Y: // TODO: we'll probably want to remember this eventually h = values[i]; mDisplayData[disp].yres = values[i]; break; case HWC_DISPLAY_DPI_X: mDisplayData[disp].xdpi = values[i] / 1000.0f; Loading Loading @@ -336,25 +373,37 @@ status_t HWComposer::freeDisplayId(int32_t id) { return NO_ERROR; } nsecs_t HWComposer::getRefreshPeriod() const { return mDisplayData[HWC_DISPLAY_PRIMARY].refresh; nsecs_t HWComposer::getRefreshPeriod(int disp) const { return mDisplayData[disp].refresh; } nsecs_t HWComposer::getRefreshTimestamp() const { nsecs_t HWComposer::getRefreshTimestamp(int disp) const { // this returns the last refresh timestamp. // if the last one is not available, we estimate it based on // the refresh period and whatever closest timestamp we have. Mutex::Autolock _l(mLock); nsecs_t now = systemTime(CLOCK_MONOTONIC); return now - ((now - mLastHwVSync) % mDisplayData[HWC_DISPLAY_PRIMARY].refresh); return now - ((now - mLastHwVSync) % mDisplayData[disp].refresh); } uint32_t HWComposer::getResolutionX(int disp) const { return mDisplayData[disp].xres; } uint32_t HWComposer::getResolutionY(int disp) const { return mDisplayData[disp].yres; } uint32_t HWComposer::getFormat(int disp) const { return mDisplayData[disp].format; } float HWComposer::getDpiX() const { return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi; float HWComposer::getDpiX(int disp) const { return mDisplayData[disp].xdpi; } float HWComposer::getDpiY() const { return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi; float HWComposer::getDpiY(int disp) const { return mDisplayData[disp].ydpi; } void HWComposer::eventControl(int event, int enabled) { Loading Loading @@ -493,6 +542,30 @@ size_t HWComposer::getNumLayers(int32_t id) const { 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 * This holds the pointer to the concrete hwc layer type Loading Loading @@ -680,7 +753,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) : mHwc(hwc), mEnabled(false), mNextFakeVSync(0), mRefreshPeriod(hwc.getRefreshPeriod()) mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY)) { } Loading services/surfaceflinger/DisplayHardware/HWComposer.h +21 −7 Original line number Diff line number Diff line Loading @@ -64,8 +64,7 @@ public: HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler, framebuffer_device_t const* fbDev); EventHandler& handler); ~HWComposer(); Loading Loading @@ -107,6 +106,11 @@ public: // needed forward declarations 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. * This abstracts the HAL interface to layers which can evolve in Loading Loading @@ -208,10 +212,15 @@ public: void eventControl(int event, int enabled); nsecs_t getRefreshPeriod() const; nsecs_t getRefreshTimestamp() const; float getDpiX() const; float getDpiY() const; // Query display parameters. Pass in a display index (e.g. // HWC_DISPLAY_PRIMARY). nsecs_t getRefreshPeriod(int disp) 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 // have it. Loading @@ -236,6 +245,8 @@ public: const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; private: void loadHwcModule(); void loadFbHalModule(); LayerListIterator getLayerIterator(int32_t id, size_t index); size_t getNumLayers(int32_t id) const; Loading @@ -261,6 +272,9 @@ private: ~DisplayData() { free(list); } uint32_t xres; uint32_t yres; uint32_t format; // pixel format from FB hal, for pre-hwc-1.1 float xdpi; float ydpi; nsecs_t refresh; Loading @@ -271,7 +285,7 @@ private: }; sp<SurfaceFlinger> mFlinger; hw_module_t const* mModule; framebuffer_device_t* mFbDev; struct hwc_composer_device_1* mHwc; // invariant: mLists[0] != NULL iff mHwc != NULL // mLists[i>0] can be NULL. that display is to be ignored Loading services/surfaceflinger/Layer.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ void Layer::onPostComposition() { const size_t offset = mFrameLatencyOffset; mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp(); mFrameStats[offset].set = systemTime(); mFrameStats[offset].vsync = hwc.getRefreshTimestamp(); mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; mFrameLatencyNeeded = false; } Loading Loading @@ -726,7 +726,8 @@ void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const { LayerBaseClient::dumpStats(result, buffer, SIZE); 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); for (size_t i=0 ; i<128 ; i++) { const size_t index = (o+i) % 128; Loading Loading
services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +17 −54 Original line number Diff line number Diff line Loading @@ -33,21 +33,12 @@ #include <ui/GraphicBuffer.h> #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- sp<FramebufferSurface> FramebufferSurface::create() { sp<FramebufferSurface> result = new FramebufferSurface(); if (result->fbDev == NULL) { result = NULL; } return result; } // ---------------------------------------------------------------------------- class GraphicBufferAlloc : public BnGraphicBufferAlloc { public: GraphicBufferAlloc() { }; Loading @@ -66,36 +57,21 @@ public: * */ FramebufferSurface::FramebufferSurface(): FramebufferSurface::FramebufferSurface(HWComposer& hwc) : ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())), fbDev(0), mCurrentBufferSlot(-1), mCurrentBuffer(0) mCurrentBuffer(0), mHwc(hwc) { hw_module_t const* module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { int stride; int err; int i; err = framebuffer_open(module, &fbDev); ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); // 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->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY)); mBufferQueue->setDefaultBufferSize(mHwc.getResolutionX(HWC_DISPLAY_PRIMARY), mHwc.getResolutionY(HWC_DISPLAY_PRIMARY)); mBufferQueue->setSynchronousMode(true); mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS); } else { ALOGE("Couldn't get gralloc module"); } } status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) { Loading Loading @@ -145,12 +121,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) { return NO_ERROR; } FramebufferSurface::~FramebufferSurface() { if (fbDev) { framebuffer_close(fbDev); } } // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. void FramebufferSurface::onFrameAvailable() { // XXX: The following code is here temporarily as part of the transition // away from the framebuffer HAL. Loading @@ -161,7 +132,7 @@ void FramebufferSurface::onFrameAvailable() { strerror(-err), err); return; } err = fbDev->post(fbDev, buf->handle); err = mHwc.fbPost(buf->handle); if (err != NO_ERROR) { ALOGE("error posting framebuffer: %d", err); } Loading @@ -181,19 +152,11 @@ status_t FramebufferSurface::setUpdateRectangle(const Rect& r) status_t FramebufferSurface::compositionComplete() { if (fbDev->compositionComplete) { return fbDev->compositionComplete(fbDev); } return INVALID_OPERATION; return mHwc.fbCompositionComplete(); } void FramebufferSurface::dump(String8& result) { if (fbDev->common.version >= 1 && fbDev->dump) { const size_t SIZE = 4096; char buffer[SIZE]; fbDev->dump(fbDev, buffer, SIZE); result.append(buffer); } mHwc.fbDump(result); ConsumerBase::dump(result); } Loading
services/surfaceflinger/DisplayHardware/FramebufferSurface.h +6 −13 Original line number Diff line number Diff line Loading @@ -30,13 +30,13 @@ namespace android { class Rect; class String8; class HWComposer; // --------------------------------------------------------------------------- class FramebufferSurface : public ConsumerBase { public: static sp<FramebufferSurface> create(); FramebufferSurface(HWComposer& hwc); bool isUpdateOnDemand() const { return false; } status_t setUpdateRectangle(const Rect& updateRect); Loading @@ -49,22 +49,12 @@ public: // BufferQueue. The new buffer is returned in the 'buffer' argument. 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: FramebufferSurface(); virtual ~FramebufferSurface(); // this class cannot be overloaded virtual ~FramebufferSurface() { }; // this class cannot be overloaded virtual void onFrameAvailable(); virtual void freeBufferLocked(int slotIndex); framebuffer_device_t* fbDev; // mCurrentBufferIndex is the slot index of the current buffer or // INVALID_BUFFER_SLOT to indicate that either there is no current buffer // or the buffer is not associated with a slot. Loading @@ -73,6 +63,9 @@ private: // mCurrentBuffer is the current buffer or NULL to indicate that there is // no current buffer. sp<GraphicBuffer> mCurrentBuffer; // Hardware composer, owned by SurfaceFlinger. HWComposer& mHwc; }; // --------------------------------------------------------------------------- Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +142 −69 Original line number Diff line number Diff line Loading @@ -90,10 +90,9 @@ struct HWComposer::cb_context { HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler, framebuffer_device_t const* fbDev) EventHandler& handler) : mFlinger(flinger), mModule(0), mHwc(0), mNumDisplays(1), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mVSyncCount(0), mDebugForceFakeVSync(false) Loading @@ -107,22 +106,10 @@ HWComposer::HWComposer( mDebugForceFakeVSync = atoi(value); bool needVSyncThread = true; int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); if (err == 0) { err = hwc_open_1(mModule, &mHwc); ALOGE_IF(err, "%s device failed to initialize (%s)", HWC_HARDWARE_COMPOSER, strerror(-err)); if (err == 0) { 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; } } // Note: some devices may insist that the FB HAL be opened before HWC. loadFbHalModule(); loadHwcModule(); if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, Loading @@ -140,8 +127,9 @@ HWComposer::HWComposer( mHwc->registerProcs(mHwc, &mCBContext->procs); } // always turn vsync off when we start // don't need a vsync thread if we have a hardware composer needVSyncThread = false; // always turn vsync off when we start mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // these IDs are always reserved Loading @@ -161,17 +149,19 @@ HWComposer::HWComposer( mNumDisplays = 1; } } } if (fbDev) { if (mFbDev) { ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), "should only have fbdev if no hwc or hwc is 1.0"); DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); disp.xdpi = fbDev->xdpi; disp.ydpi = fbDev->ydpi; disp.xres = mFbDev->width; disp.yres = mFbDev->height; disp.format = mFbDev->format; disp.xdpi = mFbDev->xdpi; disp.ydpi = mFbDev->ydpi; 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); } if (disp.refresh == 0) { Loading @@ -197,9 +187,57 @@ HWComposer::~HWComposer() { if (mHwc) { hwc_close_1(mHwc); } if (mFbDev) { framebuffer_close(mFbDev); } 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 { return mHwc ? NO_ERROR : NO_INIT; } Loading Loading @@ -265,6 +303,7 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = { void HWComposer::queryDisplayProperties(int disp) { 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]; memset(values, 0, sizeof(values)); Loading @@ -283,12 +322,10 @@ void HWComposer::queryDisplayProperties(int disp) { mDisplayData[disp].refresh = nsecs_t(values[i]); break; case HWC_DISPLAY_RESOLUTION_X: // TODO: we'll probably want to remember this eventually w = values[i]; mDisplayData[disp].xres = values[i]; break; case HWC_DISPLAY_RESOLUTION_Y: // TODO: we'll probably want to remember this eventually h = values[i]; mDisplayData[disp].yres = values[i]; break; case HWC_DISPLAY_DPI_X: mDisplayData[disp].xdpi = values[i] / 1000.0f; Loading Loading @@ -336,25 +373,37 @@ status_t HWComposer::freeDisplayId(int32_t id) { return NO_ERROR; } nsecs_t HWComposer::getRefreshPeriod() const { return mDisplayData[HWC_DISPLAY_PRIMARY].refresh; nsecs_t HWComposer::getRefreshPeriod(int disp) const { return mDisplayData[disp].refresh; } nsecs_t HWComposer::getRefreshTimestamp() const { nsecs_t HWComposer::getRefreshTimestamp(int disp) const { // this returns the last refresh timestamp. // if the last one is not available, we estimate it based on // the refresh period and whatever closest timestamp we have. Mutex::Autolock _l(mLock); nsecs_t now = systemTime(CLOCK_MONOTONIC); return now - ((now - mLastHwVSync) % mDisplayData[HWC_DISPLAY_PRIMARY].refresh); return now - ((now - mLastHwVSync) % mDisplayData[disp].refresh); } uint32_t HWComposer::getResolutionX(int disp) const { return mDisplayData[disp].xres; } uint32_t HWComposer::getResolutionY(int disp) const { return mDisplayData[disp].yres; } uint32_t HWComposer::getFormat(int disp) const { return mDisplayData[disp].format; } float HWComposer::getDpiX() const { return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi; float HWComposer::getDpiX(int disp) const { return mDisplayData[disp].xdpi; } float HWComposer::getDpiY() const { return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi; float HWComposer::getDpiY(int disp) const { return mDisplayData[disp].ydpi; } void HWComposer::eventControl(int event, int enabled) { Loading Loading @@ -493,6 +542,30 @@ size_t HWComposer::getNumLayers(int32_t id) const { 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 * This holds the pointer to the concrete hwc layer type Loading Loading @@ -680,7 +753,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) : mHwc(hwc), mEnabled(false), mNextFakeVSync(0), mRefreshPeriod(hwc.getRefreshPeriod()) mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY)) { } Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +21 −7 Original line number Diff line number Diff line Loading @@ -64,8 +64,7 @@ public: HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler, framebuffer_device_t const* fbDev); EventHandler& handler); ~HWComposer(); Loading Loading @@ -107,6 +106,11 @@ public: // needed forward declarations 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. * This abstracts the HAL interface to layers which can evolve in Loading Loading @@ -208,10 +212,15 @@ public: void eventControl(int event, int enabled); nsecs_t getRefreshPeriod() const; nsecs_t getRefreshTimestamp() const; float getDpiX() const; float getDpiY() const; // Query display parameters. Pass in a display index (e.g. // HWC_DISPLAY_PRIMARY). nsecs_t getRefreshPeriod(int disp) 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 // have it. Loading @@ -236,6 +245,8 @@ public: const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; private: void loadHwcModule(); void loadFbHalModule(); LayerListIterator getLayerIterator(int32_t id, size_t index); size_t getNumLayers(int32_t id) const; Loading @@ -261,6 +272,9 @@ private: ~DisplayData() { free(list); } uint32_t xres; uint32_t yres; uint32_t format; // pixel format from FB hal, for pre-hwc-1.1 float xdpi; float ydpi; nsecs_t refresh; Loading @@ -271,7 +285,7 @@ private: }; sp<SurfaceFlinger> mFlinger; hw_module_t const* mModule; framebuffer_device_t* mFbDev; struct hwc_composer_device_1* mHwc; // invariant: mLists[0] != NULL iff mHwc != NULL // mLists[i>0] can be NULL. that display is to be ignored Loading
services/surfaceflinger/Layer.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ void Layer::onPostComposition() { const size_t offset = mFrameLatencyOffset; mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp(); mFrameStats[offset].set = systemTime(); mFrameStats[offset].vsync = hwc.getRefreshTimestamp(); mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; mFrameLatencyNeeded = false; } Loading Loading @@ -726,7 +726,8 @@ void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const { LayerBaseClient::dumpStats(result, buffer, SIZE); 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); for (size_t i=0 ; i<128 ; i++) { const size_t index = (o+i) % 128; Loading