2013-05-08 07:58:22 +04:00
|
|
|
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "GonkDisplayJB.h"
|
2013-09-12 06:24:47 +04:00
|
|
|
#if ANDROID_VERSION == 17
|
|
|
|
#include <gui/SurfaceTextureClient.h>
|
|
|
|
#else
|
2013-07-30 21:36:53 +04:00
|
|
|
#include <gui/Surface.h>
|
2013-09-18 06:04:03 +04:00
|
|
|
#include <gui/GraphicBufferAlloc.h>
|
2013-09-12 06:24:47 +04:00
|
|
|
#endif
|
2013-05-08 07:58:22 +04:00
|
|
|
|
|
|
|
#include <hardware/hardware.h>
|
|
|
|
#include <hardware/hwcomposer.h>
|
2013-07-09 22:51:09 +04:00
|
|
|
#include <hardware/power.h>
|
2013-05-08 07:58:22 +04:00
|
|
|
#include <suspend/autosuspend.h>
|
|
|
|
|
2015-11-13 08:09:58 +03:00
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
#include "VirtualDisplaySurface.h"
|
|
|
|
#endif
|
2015-04-23 16:49:40 +03:00
|
|
|
#include "FramebufferSurface.h"
|
2013-09-18 06:04:03 +04:00
|
|
|
#if ANDROID_VERSION == 17
|
2013-05-08 07:58:22 +04:00
|
|
|
#include "GraphicBufferAlloc.h"
|
2013-09-18 06:04:03 +04:00
|
|
|
#endif
|
2015-06-05 06:29:30 +03:00
|
|
|
#include "mozilla/Assertions.h"
|
|
|
|
|
|
|
|
#define DEFAULT_XDPI 75.0
|
2013-05-08 07:58:22 +04:00
|
|
|
|
|
|
|
using namespace android;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
static GonkDisplayJB* sGonkDisplay = nullptr;
|
|
|
|
|
|
|
|
GonkDisplayJB::GonkDisplayJB()
|
2014-08-27 09:17:00 +04:00
|
|
|
: mModule(nullptr)
|
2013-06-21 08:04:53 +04:00
|
|
|
, mFBModule(nullptr)
|
2013-05-08 07:58:22 +04:00
|
|
|
, mHwc(nullptr)
|
2013-06-21 08:04:53 +04:00
|
|
|
, mFBDevice(nullptr)
|
2013-07-09 22:51:09 +04:00
|
|
|
, mPowerModule(nullptr)
|
2014-08-27 09:17:00 +04:00
|
|
|
, mList(nullptr)
|
2015-05-27 10:41:53 +03:00
|
|
|
, mWidth(0)
|
|
|
|
, mHeight(0)
|
2014-08-27 09:17:00 +04:00
|
|
|
, mEnabledCallback(nullptr)
|
2013-05-08 07:58:22 +04:00
|
|
|
{
|
2013-06-21 08:04:53 +04:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2013-09-12 06:07:53 +04:00
|
|
|
if (!err && mFBDevice) {
|
2013-06-21 08:04:53 +04:00
|
|
|
mWidth = mFBDevice->width;
|
2014-08-27 09:17:00 +04:00
|
|
|
mHeight = mFBDevice->height;
|
|
|
|
xdpi = mFBDevice->xdpi;
|
2013-06-21 08:16:37 +04:00
|
|
|
/* The emulator actually reports RGBA_8888, but EGL doesn't return
|
|
|
|
* any matching configuration. We force RGBX here to fix it. */
|
2013-06-21 08:04:53 +04:00
|
|
|
surfaceformat = HAL_PIXEL_FORMAT_RGBX_8888;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
|
2013-05-08 07:58:22 +04:00
|
|
|
ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
|
2013-06-21 08:04:53 +04:00
|
|
|
if (!err) {
|
|
|
|
err = hwc_open_1(mModule, &mHwc);
|
|
|
|
ALOGE_IF(err, "%s device failed to initialize (%s)",
|
|
|
|
HWC_HARDWARE_COMPOSER, strerror(-err));
|
|
|
|
}
|
|
|
|
|
2013-07-11 10:14:35 +04:00
|
|
|
/* Fallback on the FB rendering path instead of trying to support HWC 1.0 */
|
|
|
|
if (!err && mHwc->common.version == HWC_DEVICE_API_VERSION_1_0) {
|
|
|
|
hwc_close_1(mHwc);
|
|
|
|
mHwc = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!err && mHwc) {
|
2013-06-21 08:04:53 +04:00
|
|
|
if (mFBDevice) {
|
|
|
|
framebuffer_close(mFBDevice);
|
|
|
|
mFBDevice = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2013-07-17 04:57:41 +04:00
|
|
|
xdpi = values[2] / 1000.0f;
|
2013-06-21 08:04:53 +04:00
|
|
|
surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888;
|
|
|
|
}
|
2013-05-08 07:58:22 +04:00
|
|
|
|
2013-07-09 22:51:09 +04:00
|
|
|
err = hw_get_module(POWER_HARDWARE_MODULE_ID,
|
|
|
|
(hw_module_t const**)&mPowerModule);
|
|
|
|
if (!err)
|
|
|
|
mPowerModule->init(mPowerModule);
|
|
|
|
ALOGW_IF(err, "Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
mAlloc = new GraphicBufferAlloc();
|
2013-10-03 06:26:30 +04:00
|
|
|
|
2015-11-13 08:09:58 +03:00
|
|
|
CreateFramebufferSurface(mSTClient, mDispSurface, mWidth, mHeight);
|
2013-05-08 07:58:22 +04:00
|
|
|
|
2015-05-27 10:41:53 +03:00
|
|
|
mList = (hwc_display_contents_1_t *)calloc(1, sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
|
2015-04-27 05:39:00 +03:00
|
|
|
|
|
|
|
uint32_t usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
|
|
|
|
if (mFBDevice) {
|
|
|
|
// If device uses fb, they can not use single buffer for boot animation
|
|
|
|
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2);
|
|
|
|
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE, usage);
|
|
|
|
} else if (mHwc) {
|
2015-06-05 06:29:30 +03:00
|
|
|
PowerOnDisplay(HWC_DISPLAY_PRIMARY);
|
2015-04-27 05:39:00 +03:00
|
|
|
// For devices w/ hwc v1.0 or no hwc, this buffer can not be created,
|
|
|
|
// only create this buffer for devices w/ hwc version > 1.0.
|
2015-11-13 08:09:58 +03:00
|
|
|
CreateFramebufferSurface(mBootAnimSTClient, mBootAnimDispSurface, mWidth, mHeight);
|
2015-02-05 23:30:54 +03:00
|
|
|
}
|
2013-05-08 07:58:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
GonkDisplayJB::~GonkDisplayJB()
|
|
|
|
{
|
|
|
|
if (mHwc)
|
|
|
|
hwc_close_1(mHwc);
|
2013-06-21 08:04:53 +04:00
|
|
|
if (mFBDevice)
|
|
|
|
framebuffer_close(mFBDevice);
|
2013-05-08 07:58:22 +04:00
|
|
|
free(mList);
|
|
|
|
}
|
|
|
|
|
2015-05-17 18:30:00 +03:00
|
|
|
void
|
2015-11-13 08:09:58 +03:00
|
|
|
GonkDisplayJB::CreateFramebufferSurface(android::sp<ANativeWindow>& aNativeWindow,
|
|
|
|
android::sp<android::DisplaySurface>& aDisplaySurface,
|
|
|
|
uint32_t aWidth,
|
|
|
|
uint32_t aHeight)
|
2015-05-17 18:30:00 +03:00
|
|
|
{
|
|
|
|
#if ANDROID_VERSION >= 21
|
|
|
|
sp<IGraphicBufferProducer> producer;
|
|
|
|
sp<IGraphicBufferConsumer> consumer;
|
|
|
|
BufferQueue::createBufferQueue(&producer, &consumer, mAlloc);
|
|
|
|
#elif ANDROID_VERSION >= 19
|
|
|
|
sp<BufferQueue> consumer = new BufferQueue(mAlloc);
|
|
|
|
sp<IGraphicBufferProducer> producer = consumer;
|
|
|
|
#elif ANDROID_VERSION >= 18
|
|
|
|
sp<BufferQueue> consumer = new BufferQueue(true, mAlloc);
|
|
|
|
sp<IGraphicBufferProducer> producer = consumer;
|
|
|
|
#else
|
|
|
|
sp<BufferQueue> consumer = new BufferQueue(true, mAlloc);
|
|
|
|
#endif
|
|
|
|
|
2015-06-05 06:29:30 +03:00
|
|
|
aDisplaySurface = new FramebufferSurface(0, aWidth, aHeight, surfaceformat, consumer);
|
2015-05-17 18:30:00 +03:00
|
|
|
|
|
|
|
#if ANDROID_VERSION == 17
|
|
|
|
aNativeWindow = new SurfaceTextureClient(
|
|
|
|
static_cast<sp<ISurfaceTexture>>(aDisplaySurface->getBufferQueue()));
|
|
|
|
#else
|
|
|
|
aNativeWindow = new Surface(producer);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-11-13 08:09:58 +03:00
|
|
|
void
|
|
|
|
GonkDisplayJB::CreateVirtualDisplaySurface(android::IGraphicBufferProducer* aSink,
|
|
|
|
android::sp<ANativeWindow>& aNativeWindow,
|
|
|
|
android::sp<android::DisplaySurface>& aDisplaySurface)
|
|
|
|
{
|
|
|
|
#if ANDROID_VERSION >= 21
|
|
|
|
sp<IGraphicBufferProducer> producer;
|
|
|
|
sp<IGraphicBufferConsumer> consumer;
|
|
|
|
BufferQueue::createBufferQueue(&producer, &consumer, mAlloc);
|
|
|
|
#elif ANDROID_VERSION >= 19
|
|
|
|
sp<BufferQueue> consumer = new BufferQueue(mAlloc);
|
|
|
|
sp<IGraphicBufferProducer> producer = consumer;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
sp<VirtualDisplaySurface> virtualDisplay;
|
|
|
|
virtualDisplay = new VirtualDisplaySurface(-1, aSink, producer, consumer, String8("VirtualDisplaySurface"));
|
|
|
|
aDisplaySurface = virtualDisplay;
|
|
|
|
aNativeWindow = new Surface(virtualDisplay);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
void
|
|
|
|
GonkDisplayJB::SetEnabled(bool enabled)
|
|
|
|
{
|
2013-07-09 22:51:09 +04:00
|
|
|
if (enabled) {
|
2013-05-08 07:58:22 +04:00
|
|
|
autosuspend_disable();
|
2013-07-09 22:51:09 +04:00
|
|
|
mPowerModule->setInteractive(mPowerModule, true);
|
|
|
|
}
|
2013-06-21 08:04:53 +04:00
|
|
|
|
2014-08-27 09:17:00 +04:00
|
|
|
if (!enabled && mEnabledCallback) {
|
|
|
|
mEnabledCallback(enabled);
|
|
|
|
}
|
|
|
|
|
2015-02-05 23:30:54 +03:00
|
|
|
#if ANDROID_VERSION >= 21
|
|
|
|
if (mHwc) {
|
|
|
|
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) {
|
|
|
|
mHwc->setPowerMode(mHwc, HWC_DISPLAY_PRIMARY,
|
|
|
|
(enabled ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF));
|
|
|
|
} else {
|
|
|
|
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled);
|
|
|
|
}
|
|
|
|
} else if (mFBDevice && mFBDevice->enableScreen) {
|
|
|
|
mFBDevice->enableScreen(mFBDevice, enabled);
|
|
|
|
}
|
|
|
|
#else
|
2014-08-27 09:17:00 +04:00
|
|
|
if (mHwc && mHwc->blank) {
|
2013-06-21 08:04:53 +04:00
|
|
|
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled);
|
2014-08-27 09:17:00 +04:00
|
|
|
} else if (mFBDevice && mFBDevice->enableScreen) {
|
2013-06-21 08:04:53 +04:00
|
|
|
mFBDevice->enableScreen(mFBDevice, enabled);
|
2014-08-27 09:17:00 +04:00
|
|
|
}
|
2015-02-05 23:30:54 +03:00
|
|
|
#endif
|
2013-06-21 08:04:53 +04:00
|
|
|
|
2014-08-27 09:17:00 +04:00
|
|
|
if (enabled && mEnabledCallback) {
|
2013-07-02 03:03:17 +04:00
|
|
|
mEnabledCallback(enabled);
|
2014-08-27 09:17:00 +04:00
|
|
|
}
|
2013-07-02 03:03:17 +04:00
|
|
|
|
2013-07-09 22:51:09 +04:00
|
|
|
if (!enabled) {
|
2013-05-08 07:58:22 +04:00
|
|
|
autosuspend_enable();
|
2013-07-09 22:51:09 +04:00
|
|
|
mPowerModule->setInteractive(mPowerModule, false);
|
|
|
|
}
|
2013-05-08 07:58:22 +04:00
|
|
|
}
|
|
|
|
|
2013-07-02 03:03:17 +04:00
|
|
|
void
|
|
|
|
GonkDisplayJB::OnEnabled(OnEnabledCallbackType callback)
|
|
|
|
{
|
|
|
|
mEnabledCallback = callback;
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
void*
|
|
|
|
GonkDisplayJB::GetHWCDevice()
|
|
|
|
{
|
|
|
|
return mHwc;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
|
|
|
|
{
|
2013-08-19 16:43:16 +04:00
|
|
|
// Should be called when composition rendering is complete for a frame.
|
|
|
|
// Only HWC v1.0 needs this call.
|
|
|
|
// HWC > v1.0 case, do not call compositionComplete().
|
|
|
|
// mFBDevice is present only when HWC is v1.0.
|
|
|
|
if (mFBDevice && mFBDevice->compositionComplete) {
|
|
|
|
mFBDevice->compositionComplete(mFBDevice);
|
|
|
|
}
|
2015-04-23 16:49:40 +03:00
|
|
|
return Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd());
|
2013-05-08 07:58:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GonkDisplayJB::Post(buffer_handle_t buf, int fence)
|
|
|
|
{
|
2013-06-21 08:04:53 +04:00
|
|
|
if (!mHwc) {
|
|
|
|
if (fence >= 0)
|
|
|
|
close(fence);
|
|
|
|
return !mFBDevice->post(mFBDevice, buf);
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
|
2014-08-27 09:17:00 +04:00
|
|
|
const hwc_rect_t r = { 0, 0, static_cast<int>(mWidth), static_cast<int>(mHeight) };
|
2013-05-08 07:58:22 +04:00
|
|
|
displays[HWC_DISPLAY_PRIMARY] = mList;
|
|
|
|
mList->retireFenceFd = -1;
|
|
|
|
mList->numHwLayers = 2;
|
|
|
|
mList->flags = HWC_GEOMETRY_CHANGED;
|
2015-04-09 08:17:28 +03:00
|
|
|
#if ANDROID_VERSION >= 18
|
|
|
|
mList->outbuf = nullptr;
|
|
|
|
mList->outbufAcquireFenceFd = -1;
|
|
|
|
#endif
|
2014-03-28 22:05:43 +04:00
|
|
|
mList->hwLayers[0].compositionType = HWC_FRAMEBUFFER;
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[0].hints = 0;
|
2013-07-30 21:36:53 +04:00
|
|
|
/* Skip this layer so the hwc module doesn't complain about null handles */
|
|
|
|
mList->hwLayers[0].flags = HWC_SKIP_LAYER;
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[0].backgroundColor = {0};
|
2013-12-03 04:58:39 +04:00
|
|
|
mList->hwLayers[0].acquireFenceFd = -1;
|
|
|
|
mList->hwLayers[0].releaseFenceFd = -1;
|
2013-07-30 21:36:53 +04:00
|
|
|
/* hwc module checks displayFrame even though it shouldn't */
|
|
|
|
mList->hwLayers[0].displayFrame = r;
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[1].compositionType = HWC_FRAMEBUFFER_TARGET;
|
|
|
|
mList->hwLayers[1].hints = 0;
|
|
|
|
mList->hwLayers[1].flags = 0;
|
|
|
|
mList->hwLayers[1].handle = buf;
|
|
|
|
mList->hwLayers[1].transform = 0;
|
2014-07-01 09:21:50 +04:00
|
|
|
mList->hwLayers[1].blending = HWC_BLENDING_NONE;
|
2014-02-06 02:55:00 +04:00
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_3) {
|
|
|
|
mList->hwLayers[1].sourceCropf.left = 0;
|
|
|
|
mList->hwLayers[1].sourceCropf.top = 0;
|
|
|
|
mList->hwLayers[1].sourceCropf.right = mWidth;
|
|
|
|
mList->hwLayers[1].sourceCropf.bottom = mHeight;
|
|
|
|
} else {
|
|
|
|
mList->hwLayers[1].sourceCrop = r;
|
|
|
|
}
|
|
|
|
#else
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[1].sourceCrop = r;
|
2014-02-06 02:55:00 +04:00
|
|
|
#endif
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[1].displayFrame = r;
|
|
|
|
mList->hwLayers[1].visibleRegionScreen.numRects = 1;
|
2014-02-06 02:55:00 +04:00
|
|
|
mList->hwLayers[1].visibleRegionScreen.rects = &mList->hwLayers[1].displayFrame;
|
2013-05-08 07:58:22 +04:00
|
|
|
mList->hwLayers[1].acquireFenceFd = fence;
|
|
|
|
mList->hwLayers[1].releaseFenceFd = -1;
|
2014-07-01 09:21:50 +04:00
|
|
|
#if ANDROID_VERSION >= 18
|
2013-07-30 21:36:53 +04:00
|
|
|
mList->hwLayers[1].planeAlpha = 0xFF;
|
2013-09-12 06:24:47 +04:00
|
|
|
#endif
|
2013-05-08 07:58:22 +04:00
|
|
|
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
|
|
|
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
2015-08-25 04:20:24 +03:00
|
|
|
|
|
|
|
if (!mBootAnimDispSurface.get()) {
|
|
|
|
mDispSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd);
|
|
|
|
} else {
|
|
|
|
mBootAnimDispSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd);
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
if (mList->retireFenceFd >= 0)
|
|
|
|
close(mList->retireFenceFd);
|
|
|
|
return !err;
|
|
|
|
}
|
|
|
|
|
|
|
|
ANativeWindowBuffer*
|
|
|
|
GonkDisplayJB::DequeueBuffer()
|
|
|
|
{
|
2015-05-17 18:30:00 +03:00
|
|
|
// Check for bootAnim or normal display flow.
|
|
|
|
sp<ANativeWindow> nativeWindow =
|
|
|
|
!mBootAnimSTClient.get() ? mSTClient : mBootAnimSTClient;
|
|
|
|
|
2014-08-21 02:57:00 +04:00
|
|
|
ANativeWindowBuffer *buf;
|
2015-05-14 20:22:07 +03:00
|
|
|
int fenceFd = -1;
|
2015-05-17 18:30:00 +03:00
|
|
|
nativeWindow->dequeueBuffer(nativeWindow.get(), &buf, &fenceFd);
|
2015-05-14 20:22:07 +03:00
|
|
|
sp<Fence> fence(new Fence(fenceFd));
|
|
|
|
#if ANDROID_VERSION == 17
|
|
|
|
fence->waitForever(1000, "GonkDisplayJB_DequeueBuffer");
|
|
|
|
// 1000 is what Android uses. It is a warning timeout in ms.
|
|
|
|
// This timeout was removed in ANDROID_VERSION 18.
|
|
|
|
#else
|
|
|
|
fence->waitForever("GonkDisplayJB_DequeueBuffer");
|
|
|
|
#endif
|
2014-08-21 02:57:00 +04:00
|
|
|
return buf;
|
2013-05-08 07:58:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf)
|
|
|
|
{
|
2015-05-17 18:30:00 +03:00
|
|
|
bool success = false;
|
2015-10-27 08:43:07 +03:00
|
|
|
int error = DoQueueBuffer(buf);
|
2015-05-17 18:30:00 +03:00
|
|
|
// Check for bootAnim or normal display flow.
|
|
|
|
if (!mBootAnimSTClient.get()) {
|
|
|
|
success = Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd());
|
|
|
|
} else {
|
|
|
|
success = Post(mBootAnimDispSurface->lastHandle, mBootAnimDispSurface->GetPrevDispAcquireFd());
|
2015-04-27 05:39:00 +03:00
|
|
|
}
|
2014-08-21 02:57:00 +04:00
|
|
|
return error == 0 && success;
|
2013-05-08 07:58:22 +04:00
|
|
|
}
|
|
|
|
|
2015-10-27 08:43:07 +03:00
|
|
|
int
|
|
|
|
GonkDisplayJB::DoQueueBuffer(ANativeWindowBuffer* buf)
|
|
|
|
{
|
|
|
|
int error = 0;
|
|
|
|
// Check for bootAnim or normal display flow.
|
|
|
|
if (!mBootAnimSTClient.get()) {
|
|
|
|
error = mSTClient->queueBuffer(mSTClient.get(), buf, -1);
|
|
|
|
} else {
|
|
|
|
error = mBootAnimSTClient->queueBuffer(mBootAnimSTClient.get(), buf, -1);
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2013-10-08 19:29:35 +04:00
|
|
|
void
|
2015-04-23 16:49:40 +03:00
|
|
|
GonkDisplayJB::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur)
|
2013-10-08 19:29:35 +04:00
|
|
|
{
|
2015-10-27 08:43:07 +03:00
|
|
|
if (sur != EGL_NO_SURFACE) {
|
|
|
|
eglSwapBuffers(dpy, sur);
|
|
|
|
} else {
|
|
|
|
// When BasicCompositor is used as Compositor,
|
|
|
|
// EGLSurface does not exit.
|
|
|
|
ANativeWindowBuffer* buf = DequeueBuffer();
|
|
|
|
DoQueueBuffer(buf);
|
|
|
|
}
|
2013-10-08 19:29:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-06-10 17:55:28 +03:00
|
|
|
GonkDisplayJB::NotifyBootAnimationStopped()
|
2013-10-08 19:29:35 +04:00
|
|
|
{
|
2015-06-05 06:29:30 +03:00
|
|
|
if (mBootAnimSTClient.get()) {
|
|
|
|
mBootAnimSTClient = nullptr;
|
|
|
|
mBootAnimDispSurface = nullptr;
|
|
|
|
}
|
2013-10-08 19:29:35 +04:00
|
|
|
}
|
|
|
|
|
2015-06-05 06:29:30 +03:00
|
|
|
void
|
|
|
|
GonkDisplayJB::PowerOnDisplay(int aDpy)
|
2014-03-18 05:36:56 +04:00
|
|
|
{
|
2016-01-22 18:58:49 +03:00
|
|
|
MOZ_ASSERT(mHwc);
|
2015-06-05 06:29:30 +03:00
|
|
|
#if ANDROID_VERSION >= 21
|
|
|
|
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) {
|
|
|
|
mHwc->setPowerMode(mHwc, aDpy, HWC_POWER_MODE_NORMAL);
|
|
|
|
} else {
|
|
|
|
mHwc->blank(mHwc, aDpy, 0);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
mHwc->blank(mHwc, aDpy, 0);
|
|
|
|
#endif
|
2014-03-18 05:36:56 +04:00
|
|
|
}
|
|
|
|
|
2015-06-05 06:29:30 +03:00
|
|
|
GonkDisplay::NativeData
|
|
|
|
GonkDisplayJB::GetNativeData(GonkDisplay::DisplayType aDisplayType,
|
2015-11-13 08:09:58 +03:00
|
|
|
android::IGraphicBufferProducer* aSink)
|
2015-05-05 17:32:00 +03:00
|
|
|
{
|
2015-06-05 06:29:30 +03:00
|
|
|
NativeData data;
|
|
|
|
|
|
|
|
if (aDisplayType == DISPLAY_PRIMARY) {
|
|
|
|
data.mNativeWindow = mSTClient;
|
|
|
|
data.mDisplaySurface = mDispSurface;
|
|
|
|
data.mXdpi = xdpi;
|
|
|
|
} else if (aDisplayType == DISPLAY_EXTERNAL) {
|
|
|
|
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, aDisplayType, 0, attrs, values);
|
|
|
|
int width = values[0];
|
|
|
|
int height = values[1];
|
|
|
|
// FIXME!! values[2] returns 0 for external display, which doesn't
|
|
|
|
// sound right, Bug 1169176 is the follow-up bug for this issue.
|
|
|
|
data.mXdpi = values[2] ? values[2] / 1000.f : DEFAULT_XDPI;
|
|
|
|
PowerOnDisplay(HWC_DISPLAY_EXTERNAL);
|
2015-11-13 08:09:58 +03:00
|
|
|
CreateFramebufferSurface(data.mNativeWindow,
|
|
|
|
data.mDisplaySurface,
|
|
|
|
width,
|
|
|
|
height);
|
2015-06-05 06:29:30 +03:00
|
|
|
} else if (aDisplayType == DISPLAY_VIRTUAL) {
|
2015-11-13 08:09:58 +03:00
|
|
|
data.mXdpi = xdpi;
|
|
|
|
CreateVirtualDisplaySurface(aSink,
|
|
|
|
data.mNativeWindow,
|
|
|
|
data.mDisplaySurface);
|
2015-05-05 17:32:00 +03:00
|
|
|
}
|
2015-06-05 06:29:30 +03:00
|
|
|
|
|
|
|
return data;
|
2015-05-05 17:32:00 +03:00
|
|
|
}
|
|
|
|
|
2013-05-08 07:58:22 +04:00
|
|
|
__attribute__ ((visibility ("default")))
|
|
|
|
GonkDisplay*
|
|
|
|
GetGonkDisplay()
|
|
|
|
{
|
|
|
|
if (!sGonkDisplay)
|
|
|
|
sGonkDisplay = new GonkDisplayJB();
|
|
|
|
return sGonkDisplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mozilla
|