widget/gonk/libdisplay/GonkDisplayJB.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Copyright 2013 Mozilla Foundation and Mozilla contributors
     2  *
     3  * Licensed under the Apache License, Version 2.0 (the "License");
     4  * you may not use this file except in compliance with the License.
     5  * You may obtain a copy of the License at
     6  *
     7  *     http://www.apache.org/licenses/LICENSE-2.0
     8  *
     9  * Unless required by applicable law or agreed to in writing, software
    10  * distributed under the License is distributed on an "AS IS" BASIS,
    11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  * See the License for the specific language governing permissions and
    13  * limitations under the License.
    14  */
    16 #include "GonkDisplayJB.h"
    17 #if ANDROID_VERSION == 17
    18 #include <gui/SurfaceTextureClient.h>
    19 #else
    20 #include <gui/Surface.h>
    21 #include <gui/GraphicBufferAlloc.h>
    22 #endif
    24 #include <hardware/hardware.h>
    25 #include <hardware/hwcomposer.h>
    26 #include <hardware/power.h>
    27 #include <suspend/autosuspend.h>
    29 #if ANDROID_VERSION == 17
    30 #include "GraphicBufferAlloc.h"
    31 #endif
    32 #include "BootAnimation.h"
    34 using namespace android;
    36 namespace mozilla {
    38 static GonkDisplayJB* sGonkDisplay = nullptr;
    40 GonkDisplayJB::GonkDisplayJB()
    41     : mList(nullptr)
    42     , mModule(nullptr)
    43     , mFBModule(nullptr)
    44     , mHwc(nullptr)
    45     , mFBDevice(nullptr)
    46     , mEnabledCallback(nullptr)
    47     , mPowerModule(nullptr)
    48 {
    49     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mFBModule);
    50     ALOGW_IF(err, "%s module not found", GRALLOC_HARDWARE_MODULE_ID);
    51     if (!err) {
    52         err = framebuffer_open(mFBModule, &mFBDevice);
    53         ALOGW_IF(err, "could not open framebuffer");
    54     }
    56     if (!err && mFBDevice) {
    57         mWidth = mFBDevice->width;
    58 	 mHeight = mFBDevice->height;
    59 	 xdpi = mFBDevice->xdpi;
    60         /* The emulator actually reports RGBA_8888, but EGL doesn't return
    61          * any matching configuration. We force RGBX here to fix it. */
    62         surfaceformat = HAL_PIXEL_FORMAT_RGBX_8888;
    63     }
    65     err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
    66     ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
    67     if (!err) {
    68         err = hwc_open_1(mModule, &mHwc);
    69         ALOGE_IF(err, "%s device failed to initialize (%s)",
    70                  HWC_HARDWARE_COMPOSER, strerror(-err));
    71     }
    73     /* Fallback on the FB rendering path instead of trying to support HWC 1.0 */
    74     if (!err && mHwc->common.version == HWC_DEVICE_API_VERSION_1_0) {
    75         hwc_close_1(mHwc);
    76         mHwc = nullptr;
    77     }
    79     if (!err && mHwc) {
    80         if (mFBDevice) {
    81             framebuffer_close(mFBDevice);
    82             mFBDevice = nullptr;
    83         }
    85         int32_t values[3];
    86         const uint32_t attrs[] = {
    87             HWC_DISPLAY_WIDTH,
    88             HWC_DISPLAY_HEIGHT,
    89             HWC_DISPLAY_DPI_X,
    90             HWC_DISPLAY_NO_ATTRIBUTE
    91         };
    92         mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values);
    94         mWidth = values[0];
    95         mHeight = values[1];
    96         xdpi = values[2] / 1000.0f;
    97         surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888;
    98     }
   100     err = hw_get_module(POWER_HARDWARE_MODULE_ID,
   101                                            (hw_module_t const**)&mPowerModule);
   102     if (!err)
   103         mPowerModule->init(mPowerModule);
   104     ALOGW_IF(err, "Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
   106     mAlloc = new GraphicBufferAlloc();
   108     status_t error;
   109     uint32_t usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
   110     mBootAnimBuffer = mAlloc->createGraphicBuffer(mWidth, mHeight, surfaceformat, usage, &error);
   111     if (error != NO_ERROR || !mBootAnimBuffer.get()) {
   112         ALOGI("Trying to create BRGA format framebuffer");
   113         surfaceformat = HAL_PIXEL_FORMAT_BGRA_8888;
   114         mBootAnimBuffer = mAlloc->createGraphicBuffer(mWidth, mHeight, surfaceformat, usage, &error);
   115     }
   117 #if ANDROID_VERSION >= 19
   118     sp<BufferQueue> bq = new BufferQueue(mAlloc);
   119 #else
   120     sp<BufferQueue> bq = new BufferQueue(true, mAlloc);
   121 #endif
   122     mFBSurface = new FramebufferSurface(0, mWidth, mHeight, surfaceformat, bq);
   124 #if ANDROID_VERSION == 17
   125     sp<SurfaceTextureClient> stc = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(mFBSurface->getBufferQueue()));
   126 #else
   127     sp<Surface> stc = new Surface(static_cast<sp<IGraphicBufferProducer> >(bq));
   128 #endif
   129     mSTClient = stc;
   131     mList = (hwc_display_contents_1_t *)malloc(sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
   132     if (mHwc)
   133         mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0);
   135     if (error == NO_ERROR && mBootAnimBuffer.get()) {
   136         ALOGI("Starting bootanimation with (%d) format framebuffer", surfaceformat);
   137         StartBootAnimation();
   138     } else
   139         ALOGW("Couldn't show bootanimation (%s)", strerror(-error));
   140 }
   142 GonkDisplayJB::~GonkDisplayJB()
   143 {
   144     if (mHwc)
   145         hwc_close_1(mHwc);
   146     if (mFBDevice)
   147         framebuffer_close(mFBDevice);
   148     free(mList);
   149 }
   151 ANativeWindow*
   152 GonkDisplayJB::GetNativeWindow()
   153 {
   154     return mSTClient.get();
   155 }
   157 void
   158 GonkDisplayJB::SetEnabled(bool enabled)
   159 {
   160     if (enabled) {
   161         autosuspend_disable();
   162         mPowerModule->setInteractive(mPowerModule, true);
   163     }
   165     if (mHwc)
   166         mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled);
   167     else if (mFBDevice->enableScreen)
   168         mFBDevice->enableScreen(mFBDevice, enabled);
   170     if (mEnabledCallback)
   171         mEnabledCallback(enabled);
   173     if (!enabled) {
   174         autosuspend_enable();
   175         mPowerModule->setInteractive(mPowerModule, false);
   176     }
   177 }
   179 void
   180 GonkDisplayJB::OnEnabled(OnEnabledCallbackType callback)
   181 {
   182     mEnabledCallback = callback;
   183 }
   185 void*
   186 GonkDisplayJB::GetHWCDevice()
   187 {
   188     return mHwc;
   189 }
   191 void*
   192 GonkDisplayJB::GetFBSurface()
   193 {
   194     return mFBSurface.get();
   195 }
   197 bool
   198 GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
   199 {
   200     StopBootAnimation();
   201     mBootAnimBuffer = nullptr;
   203     // Should be called when composition rendering is complete for a frame.
   204     // Only HWC v1.0 needs this call.
   205     // HWC > v1.0 case, do not call compositionComplete().
   206     // mFBDevice is present only when HWC is v1.0.
   207     if (mFBDevice && mFBDevice->compositionComplete) {
   208         mFBDevice->compositionComplete(mFBDevice);
   209     }
   211 #if ANDROID_VERSION == 17
   212     mList->dpy = dpy;
   213     mList->sur = sur;
   214 #else
   215     mList->outbuf = nullptr;
   216     mList->outbufAcquireFenceFd = -1;
   217 #endif
   218     eglSwapBuffers(dpy, sur);
   219     return Post(mFBSurface->lastHandle, mFBSurface->GetPrevFBAcquireFd());
   220 }
   222 bool
   223 GonkDisplayJB::Post(buffer_handle_t buf, int fence)
   224 {
   225     if (!mHwc) {
   226         if (fence >= 0)
   227             close(fence);
   228         return !mFBDevice->post(mFBDevice, buf);
   229     }
   231     hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
   232     const hwc_rect_t r = { 0, 0, mWidth, mHeight };
   233     displays[HWC_DISPLAY_PRIMARY] = mList;
   234     mList->retireFenceFd = -1;
   235     mList->numHwLayers = 2;
   236     mList->flags = HWC_GEOMETRY_CHANGED;
   237     mList->hwLayers[0].compositionType = HWC_FRAMEBUFFER;
   238     mList->hwLayers[0].hints = 0;
   239     /* Skip this layer so the hwc module doesn't complain about null handles */
   240     mList->hwLayers[0].flags = HWC_SKIP_LAYER;
   241     mList->hwLayers[0].backgroundColor = {0};
   242     mList->hwLayers[0].acquireFenceFd = -1;
   243     mList->hwLayers[0].releaseFenceFd = -1;
   244     /* hwc module checks displayFrame even though it shouldn't */
   245     mList->hwLayers[0].displayFrame = r;
   246     mList->hwLayers[1].compositionType = HWC_FRAMEBUFFER_TARGET;
   247     mList->hwLayers[1].hints = 0;
   248     mList->hwLayers[1].flags = 0;
   249     mList->hwLayers[1].handle = buf;
   250     mList->hwLayers[1].transform = 0;
   251     mList->hwLayers[1].blending = HWC_BLENDING_PREMULT;
   252 #if ANDROID_VERSION >= 19
   253     if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_3) {
   254         mList->hwLayers[1].sourceCropf.left = 0;
   255         mList->hwLayers[1].sourceCropf.top = 0;
   256         mList->hwLayers[1].sourceCropf.right = mWidth;
   257         mList->hwLayers[1].sourceCropf.bottom = mHeight;
   258     } else {
   259         mList->hwLayers[1].sourceCrop = r;
   260     }
   261 #else
   262     mList->hwLayers[1].sourceCrop = r;
   263 #endif
   264     mList->hwLayers[1].displayFrame = r;
   265     mList->hwLayers[1].visibleRegionScreen.numRects = 1;
   266     mList->hwLayers[1].visibleRegionScreen.rects = &mList->hwLayers[1].displayFrame;
   267     mList->hwLayers[1].acquireFenceFd = fence;
   268     mList->hwLayers[1].releaseFenceFd = -1;
   269 #if ANDROID_VERSION == 18
   270     mList->hwLayers[1].planeAlpha = 0xFF;
   271 #endif
   272     mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
   273     int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
   274     mFBSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd);
   275     if (mList->retireFenceFd >= 0)
   276         close(mList->retireFenceFd);
   277     return !err;
   278 }
   280 ANativeWindowBuffer*
   281 GonkDisplayJB::DequeueBuffer()
   282 {
   283     return static_cast<ANativeWindowBuffer*>(mBootAnimBuffer.get());
   284 }
   286 bool
   287 GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf)
   288 {
   289     bool success = Post(buf->handle, -1);
   290     return success;
   291 }
   293 void
   294 GonkDisplayJB::UpdateFBSurface(EGLDisplay dpy, EGLSurface sur)
   295 {
   296     StopBootAnimation();
   297     mBootAnimBuffer = nullptr;
   298     eglSwapBuffers(dpy, sur);
   299 }
   301 void
   302 GonkDisplayJB::SetFBReleaseFd(int fd)
   303 {
   304     mFBSurface->setReleaseFenceFd(fd);
   305 }
   307 int
   308 GonkDisplayJB::GetPrevFBAcquireFd()
   309 {
   310     return mFBSurface->GetPrevFBAcquireFd();
   311 }
   313 __attribute__ ((visibility ("default")))
   314 GonkDisplay*
   315 GetGonkDisplay()
   316 {
   317     if (!sGonkDisplay)
   318         sGonkDisplay = new GonkDisplayJB();
   319     return sGonkDisplay;
   320 }
   322 } // namespace mozilla

mercurial