Bug 915729 - Add mixed HWC and GPU Composition. r=ncameron, r=dwilson

This commit is contained in:
Sushil Chauhan 2013-10-15 14:01:42 -07:00
parent 09cd3f6fd8
commit 2217191e09
5 changed files with 52 additions and 22 deletions

View File

@ -198,7 +198,13 @@ ContainerRender(ContainerT* aContainer,
continue;
}
layerToRender->RenderLayer(childOffset, clipRect);
if (layerToRender->HasLayerBeenComposited()) {
// Composer2D will compose this layer so skip GPU composition
// this time & reset composition flag for next composition phase
layerToRender->SetLayerComposited(false);
} else {
layerToRender->RenderLayer(childOffset, clipRect);
}
// invariant: our GL context should be current here, I don't think we can
// assert it though
}

View File

@ -726,6 +726,7 @@ LayerComposite::LayerComposite(LayerManagerComposite *aManager)
, mUseShadowClipRect(false)
, mShadowTransformSetByAnimation(false)
, mDestroyed(false)
, mLayerComposited(false)
{ }
LayerComposite::~LayerComposite()

View File

@ -381,12 +381,18 @@ public:
mShadowTransformSetByAnimation = aSetByAnimation;
}
void SetLayerComposited(bool value)
{
mLayerComposited = value;
}
// These getters can be used anytime.
float GetShadowOpacity() { return mShadowOpacity; }
const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; }
const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
bool HasLayerBeenComposited() { return mLayerComposited; }
protected:
gfx3DMatrix mShadowTransform;
@ -398,6 +404,7 @@ protected:
bool mUseShadowClipRect;
bool mShadowTransformSetByAnimation;
bool mDestroyed;
bool mLayerComposited;
};

View File

@ -434,6 +434,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
hwcLayer.transform = colorLayer->GetColor().Packed();
}
mHwcLayerMap.AppendElement(static_cast<LayerComposite*>(aLayer->ImplData()));
mList->numHwLayers++;
return true;
}
@ -461,13 +462,29 @@ HwcComposer2D::TryHwComposition()
Prepare(fbsurface->lastHandle, -1);
bool fullHwcComposite = true;
for (int j = 0; j < idx; j++) {
if (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER) {
// After prepare, if there is an HWC_FRAMEBUFFER layer,
// it means full HWC Composition is not possible this time
LOGD("GPU or Partial HWC Composition");
return false;
fullHwcComposite = false;
break;
}
}
if (!fullHwcComposite) {
for (int k=0; k < idx; k++) {
if (mList->hwLayers[k].compositionType == HWC_OVERLAY) {
// HWC will compose HWC_OVERLAY layers in partial
// HWC Composition, so set layer composition flag
// on mapped LayerComposite to skip GPU composition
mHwcLayerMap[k]->SetLayerComposited(true);
}
}
return false;
}
// Full HWC Composition
Commit();
@ -554,28 +571,26 @@ HwcComposer2D::Commit()
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
for (int i = 0; i <= MAX_HWC_LAYERS; i++) {
if (mPrevRelFd[i] <= 0) {
break;
if (!mPrevReleaseFds.IsEmpty()) {
// 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(mPrevReleaseFds[0]);
if (fence->wait(1000) == -ETIME) {
LOGE("Wait timed-out for retireFenceFd %d", mPrevReleaseFds[0]);
}
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]);
}
for (int i = 0; i < mPrevReleaseFds.Length(); i++) {
close(mPrevReleaseFds[i]);
}
close(mPrevRelFd[i]);
mPrevRelFd[i] = -1;
mPrevReleaseFds.Clear();
}
mPrevRelFd[0] = mList->retireFenceFd;
for (uint32_t j = 0; j < (mList->numHwLayers - 1); j++) {
mPrevReleaseFds.AppendElement(mList->retireFenceFd);
for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
if (mList->hwLayers[j].compositionType == HWC_OVERLAY) {
mPrevRelFd[j + 1] = mList->hwLayers[j].releaseFenceFd;
mPrevReleaseFds.AppendElement(mList->hwLayers[j].releaseFenceFd);
mList->hwLayers[j].releaseFenceFd = -1;
}
}
@ -609,12 +624,14 @@ HwcComposer2D::TryRender(Layer* aRoot,
MOZ_ASSERT(Initialized());
if (mList) {
mList->numHwLayers = 0;
mHwcLayerMap.Clear();
}
// XXX: The clear() below means all rect vectors will be have to be
// reallocated. We may want to avoid this if possible
mVisibleRegions.clear();
MOZ_ASSERT(mHwcLayerMap.IsEmpty());
if (!PrepareLayerList(aRoot,
mScreenRect,
gfxMatrix(),

View File

@ -24,8 +24,6 @@
#include <hardware/hwcomposer.h>
#define MAX_HWC_LAYERS 15
namespace mozilla {
namespace layers {
@ -83,7 +81,8 @@ private:
//Holds all the dynamically allocated RectVectors needed
//to render the current frame
std::list<RectVector> mVisibleRegions;
int mPrevRelFd[MAX_HWC_LAYERS + 1];
nsTArray<int> mPrevReleaseFds;
nsTArray<layers::LayerComposite*> mHwcLayerMap;
};
} // namespace mozilla