Bug 885620 - Support FB fallback when HWC is not available, r=vlad
authorMichael Wu <mwu@mozilla.com>
Fri, 21 Jun 2013 00:04:53 -0400
changeset 147368 6ab7e5820bb98b4a3954fd838541bfdc9ce67bad
parent 147367 7972d8009245593d681a51cd7b6794bb499835df
child 147369 d86e7ee8f564aa2dfb45889d9c5c5f5f6933b212
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad
bugs885620
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 885620 - Support FB fallback when HWC is not available, r=vlad
widget/gonk/libdisplay/GonkDisplayJB.cpp
widget/gonk/libdisplay/GonkDisplayJB.h
--- a/widget/gonk/libdisplay/GonkDisplayJB.cpp
+++ b/widget/gonk/libdisplay/GonkDisplayJB.cpp
@@ -27,78 +27,105 @@ using namespace android;
 
 namespace mozilla {
 
 static GonkDisplayJB* sGonkDisplay = nullptr;
 
 GonkDisplayJB::GonkDisplayJB()
     : mList(nullptr)
     , mModule(nullptr)
+    , mFBModule(nullptr)
     , mHwc(nullptr)
+    , mFBDevice(nullptr)
 {
-    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
-    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
-    if (err)
-        return;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mFBModule);
+    ALOGW_IF(err, "%s module not found", GRALLOC_HARDWARE_MODULE_ID);
+    if (!err) {
+        err = framebuffer_open(mFBModule, &mFBDevice);
+        ALOGW_IF(err, "could not open framebuffer");
+    }
 
-    err = hwc_open_1(mModule, &mHwc);
-    ALOGE_IF(err, "%s device failed to initialize (%s)",
-             HWC_HARDWARE_COMPOSER, strerror(-err));
+    if (!err) {
+        mWidth = mFBDevice->width;
+        mHeight = mFBDevice->height;
+        xdpi = mFBDevice->xdpi;
+        surfaceformat = HAL_PIXEL_FORMAT_RGBX_8888;
+    }
 
-    int32_t values[3];
-    const uint32_t attrs[] = {
-        HWC_DISPLAY_WIDTH,
-        HWC_DISPLAY_HEIGHT,
-        HWC_DISPLAY_DPI_X,
-        HWC_DISPLAY_NO_ATTRIBUTE
-    };
-    mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values);
+    err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
+    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
+    if (!err) {
+        err = hwc_open_1(mModule, &mHwc);
+        ALOGE_IF(err, "%s device failed to initialize (%s)",
+                 HWC_HARDWARE_COMPOSER, strerror(-err));
+    }
+
+    if (!err) {
+        if (mFBDevice) {
+            framebuffer_close(mFBDevice);
+            mFBDevice = nullptr;
+        }
 
-    mWidth = values[0];
-    mHeight = values[1];
-    xdpi = values[2];
-    surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888;
+        int32_t values[3];
+        const uint32_t attrs[] = {
+            HWC_DISPLAY_WIDTH,
+            HWC_DISPLAY_HEIGHT,
+            HWC_DISPLAY_DPI_X,
+            HWC_DISPLAY_NO_ATTRIBUTE
+        };
+        mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values);
+
+        mWidth = values[0];
+        mHeight = values[1];
+        xdpi = values[2];
+        surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888;
+    }
 
     mAlloc = new GraphicBufferAlloc();
     mFBSurface = new FramebufferSurface(0, mWidth, mHeight, surfaceformat, mAlloc);
 
     sp<SurfaceTextureClient> stc = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(mFBSurface->getBufferQueue()));
     mSTClient = stc;
 
     mList = (hwc_display_contents_1_t *)malloc(sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
-    mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0);
+    SetEnabled(true);
 
     status_t error;
     mBootAnimBuffer = mAlloc->createGraphicBuffer(mWidth, mHeight, surfaceformat, GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER, &error);
     StartBootAnimation();
 }
 
 GonkDisplayJB::~GonkDisplayJB()
 {
     if (mHwc)
         hwc_close_1(mHwc);
+    if (mFBDevice)
+        framebuffer_close(mFBDevice);
     free(mList);
 }
 
 ANativeWindow*
 GonkDisplayJB::GetNativeWindow()
 {
     return mSTClient.get();
 }
 
 void
 GonkDisplayJB::SetEnabled(bool enabled)
 {
-    if (enabled) {
+    if (enabled)
         autosuspend_disable();
-        mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, false);
-    } else {
-        mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, true);
+
+    if (mHwc)
+        mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled);
+    else if (mFBDevice->enableScreen)
+        mFBDevice->enableScreen(mFBDevice, enabled);
+
+    if (!enabled)
         autosuspend_enable();
-    }
 }
 
 void*
 GonkDisplayJB::GetHWCDevice()
 {
     return mHwc;
 }
 
@@ -112,16 +139,22 @@ GonkDisplayJB::SwapBuffers(EGLDisplay dp
     mList->sur = sur;
     eglSwapBuffers(dpy, sur);
     return Post(mFBSurface->lastHandle, mFBSurface->lastFenceFD);
 }
 
 bool
 GonkDisplayJB::Post(buffer_handle_t buf, int fence)
 {
+    if (!mHwc) {
+        if (fence >= 0)
+            close(fence);
+        return !mFBDevice->post(mFBDevice, buf);
+    }
+
     hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
     const hwc_rect_t r = { 0, 0, mWidth, mHeight };
     displays[HWC_DISPLAY_PRIMARY] = mList;
     mList->retireFenceFd = -1;
     mList->numHwLayers = 2;
     mList->flags = HWC_GEOMETRY_CHANGED;
     mList->hwLayers[0].compositionType = HWC_BACKGROUND;
     mList->hwLayers[0].hints = 0;
--- a/widget/gonk/libdisplay/GonkDisplayJB.h
+++ b/widget/gonk/libdisplay/GonkDisplayJB.h
@@ -39,17 +39,19 @@ public:
     virtual ANativeWindowBuffer* DequeueBuffer();
 
     virtual bool QueueBuffer(ANativeWindowBuffer* buf);
 
     bool Post(buffer_handle_t buf, int fence);
 
 private:
     hw_module_t const*        mModule;
+    hw_module_t const*        mFBModule;
     hwc_composer_device_1_t*  mHwc;
+    framebuffer_device_t*     mFBDevice;
     android::sp<android::FramebufferSurface> mFBSurface;
     android::sp<ANativeWindow> mSTClient;
     android::sp<android::IGraphicBufferAlloc> mAlloc;
     android::sp<android::GraphicBuffer> mBootAnimBuffer;
     hwc_display_contents_1_t* mList;
     uint32_t mWidth;
     uint32_t mHeight;
 };