Bug 1049296 - Handle Sideband stream compositing in HwcComposer2D r=mwu,nical
This commit is contained in:
@@ -119,6 +119,7 @@ namespace layers {
|
|||||||
struct Effect;
|
struct Effect;
|
||||||
struct EffectChain;
|
struct EffectChain;
|
||||||
class Image;
|
class Image;
|
||||||
|
class ImageHostOverlay;
|
||||||
class Layer;
|
class Layer;
|
||||||
class TextureSource;
|
class TextureSource;
|
||||||
class DataTextureSource;
|
class DataTextureSource;
|
||||||
@@ -453,6 +454,12 @@ public:
|
|||||||
// these methods properly.
|
// these methods properly.
|
||||||
virtual nsIWidget* GetWidget() const { return nullptr; }
|
virtual nsIWidget* GetWidget() const { return nullptr; }
|
||||||
|
|
||||||
|
virtual bool HasImageHostOverlays() { return false; }
|
||||||
|
|
||||||
|
virtual void AddImageHostOverlay(ImageHostOverlay* aOverlay) {}
|
||||||
|
|
||||||
|
virtual void RemoveImageHostOverlay(ImageHostOverlay* aOverlay) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug-build assertion that can be called to ensure code is running on the
|
* Debug-build assertion that can be called to ensure code is running on the
|
||||||
* compositor thread.
|
* compositor thread.
|
||||||
|
|||||||
@@ -441,6 +441,9 @@ ImageHost::SetCompositor(Compositor* aCompositor)
|
|||||||
img.mFrontBuffer->SetCompositor(aCompositor);
|
img.mFrontBuffer->SetCompositor(aCompositor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mImageHostOverlay) {
|
||||||
|
mImageHostOverlay->SetCompositor(aCompositor);
|
||||||
|
}
|
||||||
CompositableHost::SetCompositor(aCompositor);
|
CompositableHost::SetCompositor(aCompositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,6 +589,9 @@ ImageHostOverlay::ImageHostOverlay()
|
|||||||
|
|
||||||
ImageHostOverlay::~ImageHostOverlay()
|
ImageHostOverlay::~ImageHostOverlay()
|
||||||
{
|
{
|
||||||
|
if (mCompositor) {
|
||||||
|
mCompositor->RemoveImageHostOverlay(this);
|
||||||
|
}
|
||||||
MOZ_COUNT_DTOR(ImageHostOverlay);
|
MOZ_COUNT_DTOR(ImageHostOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,6 +607,18 @@ ImageHostOverlay::IsValid(OverlaySource aOverlay)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageHostOverlay::SetCompositor(Compositor* aCompositor)
|
||||||
|
{
|
||||||
|
if (mCompositor && (mCompositor != aCompositor)) {
|
||||||
|
mCompositor->RemoveImageHostOverlay(this);
|
||||||
|
}
|
||||||
|
if (aCompositor) {
|
||||||
|
aCompositor->AddImageHostOverlay(this);
|
||||||
|
}
|
||||||
|
mCompositor = aCompositor;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImageHostOverlay::Composite(Compositor* aCompositor,
|
ImageHostOverlay::Composite(Compositor* aCompositor,
|
||||||
uint32_t aFlashCounter,
|
uint32_t aFlashCounter,
|
||||||
@@ -612,6 +630,8 @@ ImageHostOverlay::Composite(Compositor* aCompositor,
|
|||||||
const gfx::Rect& aClipRect,
|
const gfx::Rect& aClipRect,
|
||||||
const nsIntRegion* aVisibleRegion)
|
const nsIntRegion* aVisibleRegion)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mCompositor == aCompositor);
|
||||||
|
|
||||||
if (mOverlay.handle().type() == OverlayHandle::Tnull_t) {
|
if (mOverlay.handle().type() == OverlayHandle::Tnull_t) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ public:
|
|||||||
|
|
||||||
static bool IsValid(OverlaySource aOverlay);
|
static bool IsValid(OverlaySource aOverlay);
|
||||||
|
|
||||||
|
void SetCompositor(Compositor* aCompositor);
|
||||||
|
|
||||||
virtual void Composite(Compositor* aCompositor,
|
virtual void Composite(Compositor* aCompositor,
|
||||||
uint32_t aFlashCounter,
|
uint32_t aFlashCounter,
|
||||||
LayerComposite* aLayer,
|
LayerComposite* aLayer,
|
||||||
@@ -173,6 +175,7 @@ public:
|
|||||||
virtual gfx::IntSize GetImageSize() const;
|
virtual gfx::IntSize GetImageSize() const;
|
||||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
|
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
|
||||||
protected:
|
protected:
|
||||||
|
RefPtr<Compositor> mCompositor;
|
||||||
gfx::IntRect mPictureRect;
|
gfx::IntRect mPictureRect;
|
||||||
OverlaySource mOverlay;
|
OverlaySource mOverlay;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -809,7 +809,9 @@ LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion)
|
|||||||
if (!mTarget && !haveLayerEffects &&
|
if (!mTarget && !haveLayerEffects &&
|
||||||
gfxPrefs::Composer2DCompositionEnabled() &&
|
gfxPrefs::Composer2DCompositionEnabled() &&
|
||||||
composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot,
|
composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot,
|
||||||
mCompositor->GetWidget(), mGeometryChanged))
|
mCompositor->GetWidget(),
|
||||||
|
mGeometryChanged,
|
||||||
|
mCompositor->HasImageHostOverlays()))
|
||||||
{
|
{
|
||||||
LayerScope::SetHWComposed();
|
LayerScope::SetHWComposed();
|
||||||
if (mFPS) {
|
if (mFPS) {
|
||||||
|
|||||||
@@ -49,8 +49,10 @@ public:
|
|||||||
* Currently, when TryRender() returns true, the entire framebuffer
|
* Currently, when TryRender() returns true, the entire framebuffer
|
||||||
* must have been rendered.
|
* must have been rendered.
|
||||||
*/
|
*/
|
||||||
virtual bool TryRenderWithHwc(Layer* aRoot, nsIWidget* aWidget,
|
virtual bool TryRenderWithHwc(Layer* aRoot,
|
||||||
bool aGeometryChanged) = 0;
|
nsIWidget* aWidget,
|
||||||
|
bool aGeometryChanged,
|
||||||
|
bool aHasImageHostOverlays) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if Composer2D does composition. Return false if Composer2D
|
* Return true if Composer2D does composition. Return false if Composer2D
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
#include "nscore.h" // for NS_IMETHOD
|
#include "nscore.h" // for NS_IMETHOD
|
||||||
#include "gfxVR.h"
|
#include "gfxVR.h"
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
#include "nsTHashtable.h" // for nsTHashtable
|
||||||
|
#endif
|
||||||
|
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -48,6 +52,11 @@ class TextureSource;
|
|||||||
struct Effect;
|
struct Effect;
|
||||||
struct EffectChain;
|
struct EffectChain;
|
||||||
class GLBlitTextureImageHelper;
|
class GLBlitTextureImageHelper;
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
class ImageHostOverlay;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for pools of temporary gl textures for the compositor.
|
* Interface for pools of temporary gl textures for the compositor.
|
||||||
* The textures are fully owned by the pool, so the latter is responsible
|
* The textures are fully owned by the pool, so the latter is responsible
|
||||||
@@ -268,6 +277,29 @@ public:
|
|||||||
|
|
||||||
virtual nsIWidget* GetWidget() const override { return mWidget; }
|
virtual nsIWidget* GetWidget() const override { return mWidget; }
|
||||||
|
|
||||||
|
virtual bool HasImageHostOverlays() override
|
||||||
|
{
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
return mImageHostOverlays.Count() > 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddImageHostOverlay(ImageHostOverlay* aOverlay) override
|
||||||
|
{
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
mImageHostOverlays.PutEntry(aOverlay);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RemoveImageHostOverlay(ImageHostOverlay* aOverlay) override
|
||||||
|
{
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
mImageHostOverlays.RemoveEntry(aOverlay);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GLContext* gl() const { return mGLContext; }
|
GLContext* gl() const { return mGLContext; }
|
||||||
/**
|
/**
|
||||||
* Clear the program state. This must be called
|
* Clear the program state. This must be called
|
||||||
@@ -447,6 +479,11 @@ private:
|
|||||||
gfx::Rect mRenderBound;
|
gfx::Rect mRenderBound;
|
||||||
|
|
||||||
CompositorOGLVRObjects mVR;
|
CompositorOGLVRObjects mVR;
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||||
|
nsTHashtable<nsPtrHashKey<ImageHostOverlay> > mImageHostOverlays;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ HwcComposer2D::HwcComposer2D()
|
|||||||
mRBSwapSupport = mHal->Query(HwcHALBase::QueryType::RB_SWAP);
|
mRBSwapSupport = mHal->Query(HwcHALBase::QueryType::RB_SWAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
HwcComposer2D::~HwcComposer2D() {
|
HwcComposer2D::~HwcComposer2D()
|
||||||
|
{
|
||||||
free(mList);
|
free(mList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +271,8 @@ HwcComposer2D::ReallocLayerList()
|
|||||||
bool
|
bool
|
||||||
HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||||
const nsIntRect& aClip,
|
const nsIntRect& aClip,
|
||||||
const Matrix& aParentTransform)
|
const Matrix& aParentTransform,
|
||||||
|
bool aFindSidebandStreams)
|
||||||
{
|
{
|
||||||
// NB: we fall off this path whenever there are container layers
|
// NB: we fall off this path whenever there are container layers
|
||||||
// that require intermediate surfaces. That means all the
|
// that require intermediate surfaces. That means all the
|
||||||
@@ -289,12 +291,12 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mHal->SupportTransparency() && opacity < 0xFF) {
|
if (!mHal->SupportTransparency() && opacity < 0xFF && !aFindSidebandStreams) {
|
||||||
LOGD("%s Layer has planar semitransparency which is unsupported by hwcomposer", aLayer->Name());
|
LOGD("%s Layer has planar semitransparency which is unsupported by hwcomposer", aLayer->Name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aLayer->GetMaskLayer()) {
|
if (aLayer->GetMaskLayer() && !aFindSidebandStreams) {
|
||||||
LOGD("%s Layer has MaskLayer which is unsupported by hwcomposer", aLayer->Name());
|
LOGD("%s Layer has MaskLayer which is unsupported by hwcomposer", aLayer->Name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -335,7 +337,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ContainerLayer* container = aLayer->AsContainerLayer()) {
|
if (ContainerLayer* container = aLayer->AsContainerLayer()) {
|
||||||
if (container->UseIntermediateSurface()) {
|
if (container->UseIntermediateSurface() && !aFindSidebandStreams) {
|
||||||
LOGD("Container layer needs intermediate surface");
|
LOGD("Container layer needs intermediate surface");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -343,7 +345,8 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||||||
container->SortChildrenBy3DZOrder(children);
|
container->SortChildrenBy3DZOrder(children);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < children.Length(); i++) {
|
for (uint32_t i = 0; i < children.Length(); i++) {
|
||||||
if (!PrepareLayerList(children[i], clip, layerTransform)) {
|
if (!PrepareLayerList(children[i], clip, layerTransform, aFindSidebandStreams) &&
|
||||||
|
!aFindSidebandStreams) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -645,6 +648,12 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||||||
hwcLayer.transform = colorLayer->GetColor().ToABGR();
|
hwcLayer.transform = colorLayer->GetColor().ToABGR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID_VERSION >= 21
|
||||||
|
if (aFindSidebandStreams && hwcLayer.compositionType == HWC_SIDEBAND) {
|
||||||
|
mCachedSidebandLayers.AppendElement(hwcLayer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mHwcLayerMap.AppendElement(static_cast<LayerComposite*>(aLayer->ImplData()));
|
mHwcLayerMap.AppendElement(static_cast<LayerComposite*>(aLayer->ImplData()));
|
||||||
mList->numHwLayers++;
|
mList->numHwLayers++;
|
||||||
return true;
|
return true;
|
||||||
@@ -702,6 +711,9 @@ HwcComposer2D::TryHwComposition(nsScreenGonk* aScreen)
|
|||||||
case HWC_BLIT:
|
case HWC_BLIT:
|
||||||
blitComposite = true;
|
blitComposite = true;
|
||||||
break;
|
break;
|
||||||
|
#if ANDROID_VERSION >= 21
|
||||||
|
case HWC_SIDEBAND:
|
||||||
|
#endif
|
||||||
case HWC_OVERLAY: {
|
case HWC_OVERLAY: {
|
||||||
// HWC will compose HWC_OVERLAY layers in partial
|
// HWC will compose HWC_OVERLAY layers in partial
|
||||||
// Overlay Composition, set layer composition flag
|
// Overlay Composition, set layer composition flag
|
||||||
@@ -780,6 +792,15 @@ HwcComposer2D::Render(nsIWidget* aWidget)
|
|||||||
mList->hwLayers[0].acquireFenceFd = -1;
|
mList->hwLayers[0].acquireFenceFd = -1;
|
||||||
mList->hwLayers[0].releaseFenceFd = -1;
|
mList->hwLayers[0].releaseFenceFd = -1;
|
||||||
mList->hwLayers[0].displayFrame = {0, 0, mScreenRect.width, mScreenRect.height};
|
mList->hwLayers[0].displayFrame = {0, 0, mScreenRect.width, mScreenRect.height};
|
||||||
|
|
||||||
|
#if ANDROID_VERSION >= 21
|
||||||
|
// Prepare layers for sideband streams
|
||||||
|
const uint32_t len = mCachedSidebandLayers.Length();
|
||||||
|
for (uint32_t i = 0; i < len; ++i) {
|
||||||
|
++mList->numHwLayers;
|
||||||
|
mList->hwLayers[i+1] = mCachedSidebandLayers[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Prepare(dispSurface->lastHandle, dispSurface->GetPrevDispAcquireFd(), screen);
|
Prepare(dispSurface->lastHandle, dispSurface->GetPrevDispAcquireFd(), screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,7 +889,8 @@ HwcComposer2D::Render(nsIWidget* aWidget)
|
|||||||
bool
|
bool
|
||||||
HwcComposer2D::TryRenderWithHwc(Layer* aRoot,
|
HwcComposer2D::TryRenderWithHwc(Layer* aRoot,
|
||||||
nsIWidget* aWidget,
|
nsIWidget* aWidget,
|
||||||
bool aGeometryChanged)
|
bool aGeometryChanged,
|
||||||
|
bool aHasImageHostOverlays)
|
||||||
{
|
{
|
||||||
if (!mHal->HasHwc()) {
|
if (!mHal->HasHwc()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -893,12 +915,28 @@ HwcComposer2D::TryRenderWithHwc(Layer* aRoot,
|
|||||||
|
|
||||||
mScreenRect = screen->GetNaturalBounds().ToUnknownRect();
|
mScreenRect = screen->GetNaturalBounds().ToUnknownRect();
|
||||||
MOZ_ASSERT(mHwcLayerMap.IsEmpty());
|
MOZ_ASSERT(mHwcLayerMap.IsEmpty());
|
||||||
|
mCachedSidebandLayers.Clear();
|
||||||
if (!PrepareLayerList(aRoot,
|
if (!PrepareLayerList(aRoot,
|
||||||
mScreenRect,
|
mScreenRect,
|
||||||
gfx::Matrix()))
|
gfx::Matrix(),
|
||||||
|
/* aFindSidebandStreams */ false))
|
||||||
{
|
{
|
||||||
mHwcLayerMap.Clear();
|
mHwcLayerMap.Clear();
|
||||||
LOGD("Render aborted. Nothing was drawn to the screen");
|
LOGD("Render aborted. Fallback to GPU Composition");
|
||||||
|
if (aHasImageHostOverlays) {
|
||||||
|
LOGD("Prepare layers of SidebandStreams");
|
||||||
|
// Failed to create a layer list for hwc. But we need the list
|
||||||
|
// only for handling sideband streams. Traverse layer tree without
|
||||||
|
// some early returns to make sure we can find all the layers.
|
||||||
|
// It is the best wrong thing that we can do.
|
||||||
|
PrepareLayerList(aRoot,
|
||||||
|
mScreenRect,
|
||||||
|
gfx::Matrix(),
|
||||||
|
/* aFindSidebandStreams */ true);
|
||||||
|
// Reset mPrepared to false, since we already fell back to
|
||||||
|
// gpu composition.
|
||||||
|
mPrepared = false;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ public:
|
|||||||
// by this composer so nothing was rendered at all
|
// by this composer so nothing was rendered at all
|
||||||
virtual bool TryRenderWithHwc(layers::Layer* aRoot,
|
virtual bool TryRenderWithHwc(layers::Layer* aRoot,
|
||||||
nsIWidget* aWidget,
|
nsIWidget* aWidget,
|
||||||
bool aGeometryChanged) override;
|
bool aGeometryChanged,
|
||||||
|
bool aHasImageHostOverlays) override;
|
||||||
|
|
||||||
virtual bool Render(nsIWidget* aWidget) override;
|
virtual bool Render(nsIWidget* aWidget) override;
|
||||||
|
|
||||||
@@ -94,7 +95,8 @@ private:
|
|||||||
bool TryHwComposition(nsScreenGonk* aScreen);
|
bool TryHwComposition(nsScreenGonk* aScreen);
|
||||||
bool ReallocLayerList();
|
bool ReallocLayerList();
|
||||||
bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip,
|
bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip,
|
||||||
const gfx::Matrix& aParentTransform);
|
const gfx::Matrix& aParentTransform,
|
||||||
|
bool aFindSidebandStreams);
|
||||||
void SendtoLayerScope();
|
void SendtoLayerScope();
|
||||||
|
|
||||||
UniquePtr<HwcHALBase> mHal;
|
UniquePtr<HwcHALBase> mHal;
|
||||||
@@ -108,6 +110,7 @@ private:
|
|||||||
std::list<HwcUtils::RectVector> mVisibleRegions;
|
std::list<HwcUtils::RectVector> mVisibleRegions;
|
||||||
layers::FenceHandle mPrevRetireFence;
|
layers::FenceHandle mPrevRetireFence;
|
||||||
layers::FenceHandle mPrevDisplayFence;
|
layers::FenceHandle mPrevDisplayFence;
|
||||||
|
nsTArray<HwcLayer> mCachedSidebandLayers;
|
||||||
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
||||||
bool mPrepared;
|
bool mPrepared;
|
||||||
bool mHasHWVsync;
|
bool mHasHWVsync;
|
||||||
|
|||||||
Reference in New Issue
Block a user