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
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index dca27ba..5c125c8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -90,10 +90,9 @@
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)
@@ -107,71 +106,62 @@
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,
+ (hwcApiVersion(mHwc) >> 24) & 0xff,
+ (hwcApiVersion(mHwc) >> 16) & 0xff);
+ 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);
}
- if (mHwc) {
- ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
- (hwcApiVersion(mHwc) >> 24) & 0xff,
- (hwcApiVersion(mHwc) >> 16) & 0xff);
- 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);
- }
+ // 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);
- // always turn vsync off when we start
- needVSyncThread = false;
- mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
+ // these IDs are always reserved
+ for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
+ mAllocatedDisplayIDs.markBit(i);
+ }
- // these IDs are always reserved
- for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
- mAllocatedDisplayIDs.markBit(i);
- }
-
- // the number of displays we actually have depends on the
- // hw composer version
- if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
- // 1.2 adds support for virtual displays
- mNumDisplays = MAX_DISPLAYS;
- } 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;
- }
+ // the number of displays we actually have depends on the
+ // hw composer version
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
+ // 1.2 adds support for virtual displays
+ mNumDisplays = MAX_DISPLAYS;
+ } 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)),
"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) {
@@ -197,9 +187,57 @@
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;
}
@@ -265,6 +303,7 @@
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));
@@ -283,12 +322,10 @@
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;
@@ -336,25 +373,37 @@
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);
}
-float HWComposer::getDpiX() const {
- return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi;
+uint32_t HWComposer::getResolutionX(int disp) const {
+ return mDisplayData[disp].xres;
}
-float HWComposer::getDpiY() const {
- return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi;
+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(int disp) const {
+ return mDisplayData[disp].xdpi;
+}
+
+float HWComposer::getDpiY(int disp) const {
+ return mDisplayData[disp].ydpi;
}
void HWComposer::eventControl(int event, int enabled) {
@@ -493,6 +542,30 @@
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
@@ -680,7 +753,7 @@
HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
: mHwc(hwc), mEnabled(false),
mNextFakeVSync(0),
- mRefreshPeriod(hwc.getRefreshPeriod())
+ mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY))
{
}