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; 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 // invariant: our GL context should be current here, I don't think we can
// assert it though // assert it though
} }

View File

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

View File

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

View File

@ -434,6 +434,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
hwcLayer.transform = colorLayer->GetColor().Packed(); hwcLayer.transform = colorLayer->GetColor().Packed();
} }
mHwcLayerMap.AppendElement(static_cast<LayerComposite*>(aLayer->ImplData()));
mList->numHwLayers++; mList->numHwLayers++;
return true; return true;
} }
@ -461,13 +462,29 @@ HwcComposer2D::TryHwComposition()
Prepare(fbsurface->lastHandle, -1); Prepare(fbsurface->lastHandle, -1);
bool fullHwcComposite = true;
for (int j = 0; j < idx; j++) { for (int j = 0; j < idx; j++) {
if (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER) { 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"); 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 // Full HWC Composition
Commit(); Commit();
@ -554,28 +571,26 @@ HwcComposer2D::Commit()
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays); int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
for (int i = 0; i <= MAX_HWC_LAYERS; i++) { if (!mPrevReleaseFds.IsEmpty()) {
if (mPrevRelFd[i] <= 0) { // Wait for previous retire Fence to signal.
break; // 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. for (int i = 0; i < mPrevReleaseFds.Length(); i++) {
// Denotes contents on display have been replaced. close(mPrevReleaseFds[i]);
// 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]); mPrevReleaseFds.Clear();
mPrevRelFd[i] = -1;
} }
mPrevRelFd[0] = mList->retireFenceFd; mPrevReleaseFds.AppendElement(mList->retireFenceFd);
for (uint32_t j = 0; j < (mList->numHwLayers - 1); j++) { for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
if (mList->hwLayers[j].compositionType == HWC_OVERLAY) { 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; mList->hwLayers[j].releaseFenceFd = -1;
} }
} }
@ -609,12 +624,14 @@ HwcComposer2D::TryRender(Layer* aRoot,
MOZ_ASSERT(Initialized()); MOZ_ASSERT(Initialized());
if (mList) { if (mList) {
mList->numHwLayers = 0; mList->numHwLayers = 0;
mHwcLayerMap.Clear();
} }
// XXX: The clear() below means all rect vectors will be have to be // XXX: The clear() below means all rect vectors will be have to be
// reallocated. We may want to avoid this if possible // reallocated. We may want to avoid this if possible
mVisibleRegions.clear(); mVisibleRegions.clear();
MOZ_ASSERT(mHwcLayerMap.IsEmpty());
if (!PrepareLayerList(aRoot, if (!PrepareLayerList(aRoot,
mScreenRect, mScreenRect,
gfxMatrix(), gfxMatrix(),

View File

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