Bug 911391 - Add Jellybean support to HwcComposer2D. r=mwu

This commit is contained in:
Diego Wilson 2013-09-11 15:10:33 +02:00
Родитель 38917fb465
Коммит 8dd43184bd
6 изменённых файлов: 129 добавлений и 23 удалений

Просмотреть файл

@ -276,7 +276,7 @@ public:
#ifdef DEBUG
printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION <= 15
#if defined(MOZ_WIDGET_GONK)
if (!mIsOffscreen) {
mHwc = HwcComposer2D::GetInstance();
MOZ_ASSERT(!mHwc->Initialized());

Просмотреть файл

@ -11,6 +11,7 @@ endif
ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
LOCAL_INCLUDES = -I$(topsrcdir)/widget/gonk
LOCAL_INCLUDES += -I$(ANDROID_SOURCE)/hardware/libhardware/include
endif
ifdef MOZ_ANDROID_OMTC

Просмотреть файл

@ -27,6 +27,10 @@
#include "mozilla/StaticPtr.h"
#include "cutils/properties.h"
#if ANDROID_VERSION >= 18
#include "libdisplay/FramebufferSurface.h"
#endif
#define LOG_TAG "HWComposer"
#if (LOG_NDEBUG == 0)
@ -62,7 +66,7 @@ HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur)
{
MOZ_ASSERT(!Initialized());
mHwc = (hwc_composer_device_t*)GetGonkDisplay()->GetHWCDevice();
mHwc = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
if (!mHwc) {
LOGE("Failed to initialize hwc");
return -1;
@ -96,10 +100,10 @@ HwcComposer2D::GetInstance()
bool
HwcComposer2D::ReallocLayerList()
{
int size = sizeof(hwc_layer_list_t) +
((mMaxLayerCount + LAYER_COUNT_INCREMENTS) * sizeof(hwc_layer_t));
int size = sizeof(HwcList) +
((mMaxLayerCount + LAYER_COUNT_INCREMENTS) * sizeof(HwcLayer));
hwc_layer_list_t* listrealloc = (hwc_layer_list_t*)realloc(mList, size);
HwcList* listrealloc = (HwcList*)realloc(mList, size);
if (!listrealloc) {
return false;
@ -151,8 +155,8 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
// HWC supports only the following 2D transformations:
//
// Scaling via the sourceCrop and displayFrame in hwc_layer_t
// Translation via the sourceCrop and displayFrame in hwc_layer_t
// Scaling via the sourceCrop and displayFrame in HwcLayer
// Translation via the sourceCrop and displayFrame in HwcLayer
// Rotation (in square angles only) via the HWC_TRANSFORM_ROT_* flags
// Reflection (horizontal and vertical) via the HWC_TRANSFORM_FLIP_* flags
//
@ -229,7 +233,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
}
}
hwc_layer_t& hwcLayer = mList->hwLayers[current];
HwcLayer& hwcLayer = mList->hwLayers[current];
if(!HwcUtils::PrepareLayerRects(visibleRect,
transform * aGLWorldTransform,
@ -247,7 +251,15 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
hwcLayer.flags = 0;
hwcLayer.hints = 0;
hwcLayer.blending = HWC_BLENDING_PREMULT;
#if ANDROID_VERSION >= 18
hwcLayer.compositionType = HWC_FRAMEBUFFER;
hwcLayer.acquireFenceFd = -1;
hwcLayer.releaseFenceFd = -1;
hwcLayer.planeAlpha = 0xFF; // Until plane alpha is enabled
#else
hwcLayer.compositionType = HwcUtils::HWC_USE_COPYBIT;
#endif
if (!fillColor) {
if (state.FormatRBSwapped()) {
@ -402,6 +414,93 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
return true;
}
#if ANDROID_VERSION >= 18
bool
HwcComposer2D::TryHwComposition()
{
FramebufferSurface* fbsurface = (FramebufferSurface*)(GetGonkDisplay()->GetFBSurface());
if (!fbsurface) {
LOGE("H/W Composition failed. FBSurface not initialized.");
return false;
}
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
const hwc_rect_t r = {0, 0, mScreenRect.width, mScreenRect.height};
int idx = mList->numHwLayers;
displays[HWC_DISPLAY_PRIMARY] = mList;
mList->flags = HWC_GEOMETRY_CHANGED;
mList->retireFenceFd = -1;
mList->hwLayers[idx].hints = 0;
mList->hwLayers[idx].flags = 0;
mList->hwLayers[idx].transform = 0;
mList->hwLayers[idx].handle = fbsurface->lastHandle;
mList->hwLayers[idx].blending = HWC_BLENDING_PREMULT;
mList->hwLayers[idx].compositionType = HWC_FRAMEBUFFER_TARGET;
mList->hwLayers[idx].sourceCrop = r;
mList->hwLayers[idx].displayFrame = r;
mList->hwLayers[idx].visibleRegionScreen.numRects = 1;
mList->hwLayers[idx].visibleRegionScreen.rects = &mList->hwLayers[idx].sourceCrop;
mList->hwLayers[idx].acquireFenceFd = -1;
mList->hwLayers[idx].releaseFenceFd = -1;
mList->hwLayers[idx].planeAlpha = 0xFF;
mList->numHwLayers++;
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
for (int j = 0; j < idx; j++) {
if (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER) {
LOGD("GPU or Partial MDP Composition");
return false;
}
}
// Full MDP Composition
mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
for (int i = 0; i <= MAX_HWC_LAYERS; i++) {
if (mPrevRelFd[i] <= 0) {
break;
}
if (!i) {
// Wait for previous retire Fence to signal.
// Denotes contents on display have been replaced.
// For buffer-sync, framework should not over-write
// prev buffers until we close prev releaseFenceFds
sp<Fence> fence = new Fence(mPrevRelFd[i]);
if (fence->wait(1000) == -ETIME) {
LOGE("Wait timed-out for retireFenceFd %d", mPrevRelFd[i]);
}
}
close(mPrevRelFd[i]);
mPrevRelFd[i] = -1;
}
mPrevRelFd[0] = mList->retireFenceFd;
for (uint32_t j = 0; j < idx; j++) {
if (mList->hwLayers[j].compositionType == HWC_OVERLAY) {
mPrevRelFd[j + 1] = mList->hwLayers[j].releaseFenceFd;
mList->hwLayers[j].releaseFenceFd = -1;
}
}
close(mList->hwLayers[idx].releaseFenceFd);
mList->hwLayers[idx].releaseFenceFd = -1;
mList->retireFenceFd = -1;
mList->numHwLayers = 0;
return true;
}
#else
bool
HwcComposer2D::TryHwComposition()
{
return !mHwc->set(mHwc, mDpy, mSur, mList);
}
#endif
bool
HwcComposer2D::TryRender(Layer* aRoot,
const gfxMatrix& aGLWorldTransform)
@ -429,9 +528,10 @@ HwcComposer2D::TryRender(Layer* aRoot,
return false;
}
if (mHwc->set(mHwc, mDpy, mSur, mList)) {
LOGE("Hardware device failed to render");
return false;
if (!TryHwComposition()) {
// Full MDP Composition
LOGE("H/W Composition failed");
return false;
}
LOGD("Frame rendered");

Просмотреть файл

@ -22,7 +22,9 @@
#include <vector>
#include <list>
#include "hardware/hwcomposer.h"
#include <hardware/hwcomposer.h>
#define MAX_HWC_LAYERS 15
namespace mozilla {
@ -34,6 +36,15 @@ class Layer;
//Holds a dynamically allocated vector of rectangles
//used to decribe the complex visible region of a layer
typedef std::vector<hwc_rect_t> RectVector;
#if ANDROID_VERSION >= 18
typedef hwc_composer_device_1_t HwcDevice;
typedef hwc_display_contents_1_t HwcList;
typedef hwc_layer_1_t HwcLayer;
#else
typedef hwc_composer_device_t HwcDevice;
typedef hwc_layer_list_t HwcList;
typedef hwc_layer_t HwcLayer;
#endif
class HwcComposer2D : public mozilla::layers::Composer2D {
public:
@ -52,12 +63,13 @@ public:
bool TryRender(layers::Layer* aRoot, const gfxMatrix& aGLWorldTransform) MOZ_OVERRIDE;
private:
bool TryHwComposition();
bool ReallocLayerList();
bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip,
const gfxMatrix& aParentTransform, const gfxMatrix& aGLWorldTransform);
hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList;
HwcDevice* mHwc;
HwcList* mList;
hwc_display_t mDpy;
hwc_surface_t mSur;
nsIntRect mScreenRect;
@ -66,6 +78,7 @@ private:
//Holds all the dynamically allocated RectVectors needed
//to render the current frame
std::list<RectVector> mVisibleRegions;
int mPrevRelFd[MAX_HWC_LAYERS + 1];
};
} // namespace mozilla

Просмотреть файл

@ -56,13 +56,9 @@ CPP_SOURCES += [
'nsLookAndFeel.cpp',
'nsWidgetFactory.cpp',
'nsWindow.cpp',
'HwcComposer2D.cpp'
]
if CONFIG['ANDROID_VERSION'] == '15':
CPP_SOURCES += [
'HwcComposer2D.cpp'
]
LIBXUL_LIBRARY = True
LIBRARY_NAME = 'widget_gonk'

Просмотреть файл

@ -44,9 +44,7 @@
#include "libdisplay/GonkDisplay.h"
#include "pixelflinger/format.h"
#if ANDROID_VERSION == 15
#include "HwcComposer2D.h"
#endif
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
@ -703,11 +701,9 @@ nsWindow::GetComposer2D()
return nullptr;
}
#if ANDROID_VERSION == 15
if (HwcComposer2D* hwc = HwcComposer2D::GetInstance()) {
return hwc->Initialized() ? hwc : nullptr;
}
#endif
return nullptr;
}