зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1077301 - Simplify the gralloc texture code. r=sotaro
This commit is contained in:
Родитель
c457a87994
Коммит
833ec9bb3d
|
@ -135,17 +135,6 @@ enum SurfaceInitMode
|
|||
INIT_MODE_CLEAR
|
||||
};
|
||||
|
||||
/**
|
||||
* A base class for a platform-dependent helper for use by TextureHost.
|
||||
*/
|
||||
class CompositorBackendSpecificData
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData)
|
||||
|
||||
protected:
|
||||
virtual ~CompositorBackendSpecificData() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Common interface for compositor backends.
|
||||
*
|
||||
|
@ -481,10 +470,6 @@ public:
|
|||
return fillRatio;
|
||||
}
|
||||
|
||||
virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScreenRotation GetScreenRotation() const {
|
||||
return mScreenRotation;
|
||||
}
|
||||
|
|
|
@ -24,14 +24,6 @@ namespace layers {
|
|||
|
||||
class Compositor;
|
||||
|
||||
CompositableBackendSpecificData::CompositableBackendSpecificData()
|
||||
: mAllowSharingTextureHost(false)
|
||||
{
|
||||
static uint64_t sNextID = 1;
|
||||
++sNextID;
|
||||
mId = sNextID;
|
||||
}
|
||||
|
||||
/**
|
||||
* IPDL actor used by CompositableHost to match with its corresponding
|
||||
* CompositableClient on the content side.
|
||||
|
@ -87,9 +79,6 @@ CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
|
|||
CompositableHost::~CompositableHost()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CompositableHost);
|
||||
if (mBackendData) {
|
||||
mBackendData->ClearData();
|
||||
}
|
||||
}
|
||||
|
||||
PCompositableParent*
|
||||
|
@ -121,7 +110,6 @@ CompositableHost::UseTextureHost(TextureHost* aTexture)
|
|||
return;
|
||||
}
|
||||
aTexture->SetCompositor(GetCompositor());
|
||||
aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -130,17 +118,12 @@ CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
|||
{
|
||||
MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite);
|
||||
aTextureOnBlack->SetCompositor(GetCompositor());
|
||||
aTextureOnBlack->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
aTextureOnWhite->SetCompositor(GetCompositor());
|
||||
aTextureOnWhite->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
|
||||
void
|
||||
CompositableHost::RemoveTextureHost(TextureHost* aTexture)
|
||||
{
|
||||
// Clear strong refrence to CompositableBackendSpecificData
|
||||
aTexture->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
{}
|
||||
|
||||
void
|
||||
CompositableHost::SetCompositor(Compositor* aCompositor)
|
||||
|
@ -153,7 +136,7 @@ CompositableHost::AddMaskEffect(EffectChain& aEffects,
|
|||
const gfx::Matrix4x4& aTransform,
|
||||
bool aIs3D)
|
||||
{
|
||||
RefPtr<TextureSource> source;
|
||||
CompositableTextureSourceRef source;
|
||||
RefPtr<TextureHost> host = GetAsTextureHost();
|
||||
|
||||
if (!host) {
|
||||
|
@ -166,14 +149,12 @@ CompositableHost::AddMaskEffect(EffectChain& aEffects,
|
|||
return false;
|
||||
}
|
||||
|
||||
source = host->GetTextureSources();
|
||||
MOZ_ASSERT(source);
|
||||
|
||||
if (!source) {
|
||||
if (!host->BindTextureSource(source)) {
|
||||
NS_WARNING("The TextureHost was successfully locked but can't provide a TextureSource");
|
||||
host->Unlock();
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(source);
|
||||
|
||||
RefPtr<EffectMask> effect = new EffectMask(source,
|
||||
source->GetSize(),
|
||||
|
@ -192,9 +173,6 @@ CompositableHost::RemoveMaskEffect()
|
|||
}
|
||||
}
|
||||
|
||||
// implemented in TextureHostOGL.cpp
|
||||
TemporaryRef<CompositableBackendSpecificData> CreateCompositableBackendSpecificDataOGL();
|
||||
|
||||
/* static */ TemporaryRef<CompositableHost>
|
||||
CompositableHost::Create(const TextureInfo& aTextureInfo)
|
||||
{
|
||||
|
@ -227,12 +205,6 @@ CompositableHost::Create(const TextureInfo& aTextureInfo)
|
|||
default:
|
||||
NS_ERROR("Unknown CompositableType");
|
||||
}
|
||||
// We know that Tiled buffers don't use the compositable backend-specific
|
||||
// data, so don't bother creating it.
|
||||
if (result && aTextureInfo.mCompositableType != CompositableType::BUFFER_TILED) {
|
||||
RefPtr<CompositableBackendSpecificData> data = CreateCompositableBackendSpecificDataOGL();
|
||||
result->SetCompositableBackendSpecificData(data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,42 +49,6 @@ class CompositableParentManager;
|
|||
class PCompositableParent;
|
||||
struct EffectChain;
|
||||
|
||||
/**
|
||||
* A base class for doing CompositableHost and platform dependent task on TextureHost.
|
||||
*/
|
||||
class CompositableBackendSpecificData
|
||||
{
|
||||
protected:
|
||||
virtual ~CompositableBackendSpecificData() {}
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData)
|
||||
|
||||
CompositableBackendSpecificData();
|
||||
|
||||
virtual void ClearData() {}
|
||||
virtual void SetCompositor(Compositor* aCompositor) {}
|
||||
|
||||
bool IsAllowingSharingTextureHost()
|
||||
{
|
||||
return mAllowSharingTextureHost;
|
||||
}
|
||||
|
||||
void SetAllowSharingTextureHost(bool aAllow)
|
||||
{
|
||||
mAllowSharingTextureHost = aAllow;
|
||||
}
|
||||
|
||||
uint64_t GetId()
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
public:
|
||||
bool mAllowSharingTextureHost;
|
||||
uint64_t mId;
|
||||
};
|
||||
|
||||
/**
|
||||
* The compositor-side counterpart to CompositableClient. Responsible for
|
||||
* updating textures and data about textures from IPC and how textures are
|
||||
|
@ -112,16 +76,6 @@ public:
|
|||
|
||||
virtual CompositableType GetType() = 0;
|
||||
|
||||
virtual CompositableBackendSpecificData* GetCompositableBackendSpecificData()
|
||||
{
|
||||
return mBackendData;
|
||||
}
|
||||
|
||||
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
{
|
||||
mBackendData = aBackendData;
|
||||
}
|
||||
|
||||
// If base class overrides, it should still call the parent implementation
|
||||
virtual void SetCompositor(Compositor* aCompositor);
|
||||
|
||||
|
@ -252,9 +206,6 @@ public:
|
|||
SetLayer(nullptr);
|
||||
mAttached = false;
|
||||
mKeepAttached = false;
|
||||
if (mBackendData) {
|
||||
mBackendData->ClearData();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IsAttached() { return mAttached; }
|
||||
|
@ -314,7 +265,6 @@ protected:
|
|||
uint64_t mCompositorID;
|
||||
RefPtr<Compositor> mCompositor;
|
||||
Layer* mLayer;
|
||||
RefPtr<CompositableBackendSpecificData> mBackendData;
|
||||
uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
|
||||
bool mAttached;
|
||||
bool mKeepAttached;
|
||||
|
|
|
@ -35,7 +35,7 @@ ContentHostBase::~ContentHostBase()
|
|||
}
|
||||
|
||||
void
|
||||
ContentHostBase::Composite(EffectChain& aEffectChain,
|
||||
ContentHostTexture::Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const Filter& aFilter,
|
||||
|
@ -49,14 +49,18 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<TextureSource> source = GetTextureSource();
|
||||
RefPtr<TextureSource> sourceOnWhite = GetTextureSourceOnWhite();
|
||||
if (!mTextureHost->BindTextureSource(mTextureSource)) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mTextureSource.get());
|
||||
|
||||
if (!source) {
|
||||
if (mTextureHostOnWhite && !mTextureHostOnWhite->BindTextureSource(mTextureSourceOnWhite)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<TexturedEffect> effect = GenEffect(aFilter);
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureSource.get(),
|
||||
mTextureSourceOnWhite.get(),
|
||||
aFilter, true);
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
|
@ -81,7 +85,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
|
|||
region.MoveBy(-origin);
|
||||
|
||||
// Figure out the intersecting draw region
|
||||
gfx::IntSize texSize = source->GetSize();
|
||||
gfx::IntSize texSize = mTextureSource->GetSize();
|
||||
nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
|
||||
textureRect.MoveBy(region.GetBounds().TopLeft());
|
||||
nsIntRegion subregion;
|
||||
|
@ -105,14 +109,14 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
|
|||
regionRects.Or(regionRects, regionRect);
|
||||
}
|
||||
|
||||
BigImageIterator* bigImgIter = source->AsBigImageIterator();
|
||||
BigImageIterator* bigImgIter = mTextureSource->AsBigImageIterator();
|
||||
BigImageIterator* iterOnWhite = nullptr;
|
||||
if (bigImgIter) {
|
||||
bigImgIter->BeginBigImageIteration();
|
||||
}
|
||||
|
||||
if (sourceOnWhite) {
|
||||
iterOnWhite = sourceOnWhite->AsBigImageIterator();
|
||||
if (mTextureSourceOnWhite) {
|
||||
iterOnWhite = mTextureSourceOnWhite->AsBigImageIterator();
|
||||
MOZ_ASSERT(!bigImgIter || bigImgIter->GetTileCount() == iterOnWhite->GetTileCount(),
|
||||
"Tile count mismatch on component alpha texture");
|
||||
if (iterOnWhite) {
|
||||
|
@ -205,32 +209,39 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
|
|||
aTransform, mFlashCounter);
|
||||
}
|
||||
|
||||
TemporaryRef<TexturedEffect>
|
||||
ContentHostBase::GenEffect(const gfx::Filter& aFilter)
|
||||
{
|
||||
RefPtr<TextureSource> source = GetTextureSource();
|
||||
RefPtr<TextureSource> sourceOnWhite = GetTextureSourceOnWhite();
|
||||
if (!source) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateTexturedEffect(source, sourceOnWhite, aFilter, true);
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostTexture::UseTextureHost(TextureHost* aTexture)
|
||||
{
|
||||
if (mTextureHost && mTextureHost != aTexture) {
|
||||
mTextureHost->UnbindTextureSource();
|
||||
}
|
||||
ContentHostBase::UseTextureHost(aTexture);
|
||||
mTextureHost = aTexture;
|
||||
mTextureHostOnWhite = nullptr;
|
||||
if (mTextureHost) {
|
||||
mTextureHost->PrepareTextureSource(mTextureSource);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostTexture::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
||||
TextureHost* aTextureOnWhite)
|
||||
{
|
||||
if (mTextureHost && mTextureHost != aTextureOnBlack) {
|
||||
mTextureHost->UnbindTextureSource();
|
||||
}
|
||||
if (mTextureHostOnWhite && mTextureHostOnWhite != aTextureOnWhite) {
|
||||
mTextureHostOnWhite->UnbindTextureSource();
|
||||
}
|
||||
ContentHostBase::UseComponentAlphaTextures(aTextureOnBlack, aTextureOnWhite);
|
||||
mTextureHost = aTextureOnBlack;
|
||||
mTextureHostOnWhite = aTextureOnWhite;
|
||||
if (mTextureHost) {
|
||||
mTextureHost->PrepareTextureSource(mTextureSource);
|
||||
}
|
||||
if (mTextureHostOnWhite) {
|
||||
mTextureHostOnWhite->PrepareTextureSource(mTextureSourceOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -417,6 +428,176 @@ ContentHostIncremental::UpdateIncremental(TextureIdentifier aTextureId,
|
|||
FlushUpdateQueue();
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostIncremental::Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const Filter& aFilter,
|
||||
const Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion)
|
||||
{
|
||||
NS_ASSERTION(aVisibleRegion, "Requires a visible region");
|
||||
|
||||
AutoLockCompositableHost lock(this);
|
||||
if (lock.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mSource.get(),
|
||||
mSourceOnWhite.get(),
|
||||
aFilter, true);
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
|
||||
aEffectChain.mPrimaryEffect = effect;
|
||||
|
||||
nsIntRegion tmpRegion;
|
||||
const nsIntRegion* renderRegion;
|
||||
if (PaintWillResample()) {
|
||||
// If we're resampling, then the texture image will contain exactly the
|
||||
// entire visible region's bounds, and we should draw it all in one quad
|
||||
// to avoid unexpected aliasing.
|
||||
tmpRegion = aVisibleRegion->GetBounds();
|
||||
renderRegion = &tmpRegion;
|
||||
} else {
|
||||
renderRegion = aVisibleRegion;
|
||||
}
|
||||
|
||||
nsIntRegion region(*renderRegion);
|
||||
nsIntPoint origin = GetOriginOffset();
|
||||
// translate into TexImage space, buffer origin might not be at texture (0,0)
|
||||
region.MoveBy(-origin);
|
||||
|
||||
// Figure out the intersecting draw region
|
||||
gfx::IntSize texSize = mSource->GetSize();
|
||||
nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
|
||||
textureRect.MoveBy(region.GetBounds().TopLeft());
|
||||
nsIntRegion subregion;
|
||||
subregion.And(region, textureRect);
|
||||
if (subregion.IsEmpty()) {
|
||||
// Region is empty, nothing to draw
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntRegion screenRects;
|
||||
nsIntRegion regionRects;
|
||||
|
||||
// Collect texture/screen coordinates for drawing
|
||||
nsIntRegionRectIterator iter(subregion);
|
||||
while (const nsIntRect* iterRect = iter.Next()) {
|
||||
nsIntRect regionRect = *iterRect;
|
||||
nsIntRect screenRect = regionRect;
|
||||
screenRect.MoveBy(origin);
|
||||
|
||||
screenRects.Or(screenRects, screenRect);
|
||||
regionRects.Or(regionRects, regionRect);
|
||||
}
|
||||
|
||||
BigImageIterator* bigImgIter = mSource->AsBigImageIterator();
|
||||
BigImageIterator* iterOnWhite = nullptr;
|
||||
if (bigImgIter) {
|
||||
bigImgIter->BeginBigImageIteration();
|
||||
}
|
||||
|
||||
if (mSourceOnWhite) {
|
||||
iterOnWhite = mSourceOnWhite->AsBigImageIterator();
|
||||
MOZ_ASSERT(!bigImgIter || bigImgIter->GetTileCount() == iterOnWhite->GetTileCount(),
|
||||
"Tile count mismatch on component alpha texture");
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->BeginBigImageIteration();
|
||||
}
|
||||
}
|
||||
|
||||
bool usingTiles = (bigImgIter && bigImgIter->GetTileCount() > 1);
|
||||
do {
|
||||
if (iterOnWhite) {
|
||||
MOZ_ASSERT(iterOnWhite->GetTileRect() == bigImgIter->GetTileRect(),
|
||||
"component alpha textures should be the same size.");
|
||||
}
|
||||
|
||||
nsIntRect texRect = bigImgIter ? bigImgIter->GetTileRect()
|
||||
: nsIntRect(0, 0,
|
||||
texSize.width,
|
||||
texSize.height);
|
||||
|
||||
// Draw texture. If we're using tiles, we do repeating manually, as texture
|
||||
// repeat would cause each individual tile to repeat instead of the
|
||||
// compound texture as a whole. This involves drawing at most 4 sections,
|
||||
// 2 for each axis that has texture repeat.
|
||||
for (int y = 0; y < (usingTiles ? 2 : 1); y++) {
|
||||
for (int x = 0; x < (usingTiles ? 2 : 1); x++) {
|
||||
nsIntRect currentTileRect(texRect);
|
||||
currentTileRect.MoveBy(x * texSize.width, y * texSize.height);
|
||||
|
||||
nsIntRegionRectIterator screenIter(screenRects);
|
||||
nsIntRegionRectIterator regionIter(regionRects);
|
||||
|
||||
const nsIntRect* screenRect;
|
||||
const nsIntRect* regionRect;
|
||||
while ((screenRect = screenIter.Next()) &&
|
||||
(regionRect = regionIter.Next())) {
|
||||
nsIntRect tileScreenRect(*screenRect);
|
||||
nsIntRect tileRegionRect(*regionRect);
|
||||
|
||||
// When we're using tiles, find the intersection between the tile
|
||||
// rect and this region rect. Tiling is then handled by the
|
||||
// outer for-loops and modifying the tile rect.
|
||||
if (usingTiles) {
|
||||
tileScreenRect.MoveBy(-origin);
|
||||
tileScreenRect = tileScreenRect.Intersect(currentTileRect);
|
||||
tileScreenRect.MoveBy(origin);
|
||||
|
||||
if (tileScreenRect.IsEmpty())
|
||||
continue;
|
||||
|
||||
tileRegionRect = regionRect->Intersect(currentTileRect);
|
||||
tileRegionRect.MoveBy(-currentTileRect.TopLeft());
|
||||
}
|
||||
gfx::Rect rect(tileScreenRect.x, tileScreenRect.y,
|
||||
tileScreenRect.width, tileScreenRect.height);
|
||||
|
||||
effect->mTextureCoords = Rect(Float(tileRegionRect.x) / texRect.width,
|
||||
Float(tileRegionRect.y) / texRect.height,
|
||||
Float(tileRegionRect.width) / texRect.width,
|
||||
Float(tileRegionRect.height) / texRect.height);
|
||||
GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform);
|
||||
if (usingTiles) {
|
||||
DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT | DiagnosticFlags::BIGIMAGE;
|
||||
if (iterOnWhite) {
|
||||
diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
|
||||
}
|
||||
GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect,
|
||||
aTransform, mFlashCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->NextTile();
|
||||
}
|
||||
} while (usingTiles && bigImgIter->NextTile());
|
||||
|
||||
if (bigImgIter) {
|
||||
bigImgIter->EndBigImageIteration();
|
||||
}
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->EndBigImageIteration();
|
||||
}
|
||||
|
||||
DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT;
|
||||
if (iterOnWhite) {
|
||||
diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
|
||||
}
|
||||
GetCompositor()->DrawDiagnostics(diagnostics, nsIntRegion(mBufferRect), aClipRect,
|
||||
aTransform, mFlashCounter);
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostIncremental::FlushUpdateQueue()
|
||||
{
|
||||
|
@ -439,20 +620,6 @@ ContentHostIncremental::ProcessTextureUpdates()
|
|||
mUpdateList.Clear();
|
||||
}
|
||||
|
||||
TextureSource*
|
||||
ContentHostIncremental::GetTextureSource()
|
||||
{
|
||||
MOZ_ASSERT(mLocked);
|
||||
return mSource;
|
||||
}
|
||||
|
||||
TextureSource*
|
||||
ContentHostIncremental::GetTextureSourceOnWhite()
|
||||
{
|
||||
MOZ_ASSERT(mLocked);
|
||||
return mSourceOnWhite;
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental* aHost)
|
||||
{
|
||||
|
@ -683,6 +850,32 @@ ContentHostTexture::GetRenderState()
|
|||
return result;
|
||||
}
|
||||
|
||||
TemporaryRef<TexturedEffect>
|
||||
ContentHostTexture::GenEffect(const gfx::Filter& aFilter)
|
||||
{
|
||||
if (!mTextureHost) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!mTextureHost->BindTextureSource(mTextureSource)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mTextureHostOnWhite && !mTextureHostOnWhite->BindTextureSource(mTextureSourceOnWhite)) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateTexturedEffect(mTextureSource.get(),
|
||||
mTextureSourceOnWhite.get(),
|
||||
aFilter, true);
|
||||
}
|
||||
|
||||
TemporaryRef<TexturedEffect>
|
||||
ContentHostIncremental::GenEffect(const gfx::Filter& aFilter)
|
||||
{
|
||||
if (!mSource) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateTexturedEffect(mSource, mSourceOnWhite, aFilter, true);
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
TemporaryRef<gfx::DataSourceSurface>
|
||||
ContentHostTexture::GetAsSurface()
|
||||
|
|
|
@ -96,18 +96,6 @@ public:
|
|||
explicit ContentHostBase(const TextureInfo& aTextureInfo);
|
||||
virtual ~ContentHostBase();
|
||||
|
||||
virtual void Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const gfx::Filter& aFilter,
|
||||
const gfx::Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion = nullptr);
|
||||
|
||||
virtual TextureSource* GetTextureSource() = 0;
|
||||
virtual TextureSource* GetTextureSourceOnWhite() = 0;
|
||||
|
||||
virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual nsIntPoint GetOriginOffset()
|
||||
{
|
||||
|
@ -132,6 +120,13 @@ public:
|
|||
, mLocked(false)
|
||||
{ }
|
||||
|
||||
virtual void Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const gfx::Filter& aFilter,
|
||||
const gfx::Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion = nullptr);
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
|
@ -173,23 +168,15 @@ public:
|
|||
mLocked = false;
|
||||
}
|
||||
|
||||
virtual TextureSource* GetTextureSource() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(mLocked);
|
||||
return mTextureHost->GetTextureSources();
|
||||
}
|
||||
virtual TextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(mLocked);
|
||||
if (mTextureHostOnWhite) {
|
||||
return mTextureHostOnWhite->GetTextureSources();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LayerRenderState GetRenderState();
|
||||
|
||||
virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
RefPtr<TextureHost> mTextureHost;
|
||||
RefPtr<TextureHost> mTextureHostOnWhite;
|
||||
CompositableTextureSourceRef mTextureSource;
|
||||
CompositableTextureSourceRef mTextureSourceOnWhite;
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
|
@ -277,6 +264,13 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual void Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const gfx::Filter& aFilter,
|
||||
const gfx::Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion = nullptr);
|
||||
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool Lock() MOZ_OVERRIDE {
|
||||
|
@ -291,8 +285,8 @@ public:
|
|||
mLocked = false;
|
||||
}
|
||||
|
||||
virtual TextureSource* GetTextureSource() MOZ_OVERRIDE;
|
||||
virtual TextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE;
|
||||
virtual TemporaryRef<TexturedEffect>
|
||||
GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -37,28 +37,21 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo)
|
|||
ImageHost::~ImageHost()
|
||||
{
|
||||
if (mFrontBuffer) {
|
||||
mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
{
|
||||
CompositableHost::SetCompositableBackendSpecificData(aBackendData);
|
||||
// ImageHost allows TextureHost sharing among ImageHosts.
|
||||
if (aBackendData) {
|
||||
aBackendData->SetAllowSharingTextureHost(true);
|
||||
mFrontBuffer->UnbindTextureSource();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageHost::UseTextureHost(TextureHost* aTexture)
|
||||
{
|
||||
CompositableHost::UseTextureHost(aTexture);
|
||||
if (mFrontBuffer) {
|
||||
mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
if (mFrontBuffer && mFrontBuffer != aTexture) {
|
||||
mFrontBuffer->UnbindTextureSource();
|
||||
}
|
||||
CompositableHost::UseTextureHost(aTexture);
|
||||
mFrontBuffer = aTexture;
|
||||
if (mFrontBuffer) {
|
||||
mFrontBuffer->PrepareTextureSource(mTextureSource);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -66,7 +59,8 @@ ImageHost::RemoveTextureHost(TextureHost* aTexture)
|
|||
{
|
||||
CompositableHost::RemoveTextureHost(aTexture);
|
||||
if (aTexture && mFrontBuffer == aTexture) {
|
||||
aTexture->SetCompositableBackendSpecificData(nullptr);
|
||||
mFrontBuffer->UnbindTextureSource();
|
||||
mTextureSource = nullptr;
|
||||
mFrontBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -97,25 +91,34 @@ ImageHost::Composite(EffectChain& aEffectChain,
|
|||
|
||||
// Make sure the front buffer has a compositor
|
||||
mFrontBuffer->SetCompositor(GetCompositor());
|
||||
mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
|
||||
|
||||
AutoLockCompositableHost autoLock(this);
|
||||
if (autoLock.Failed()) {
|
||||
NS_WARNING("failed to lock front buffer");
|
||||
return;
|
||||
}
|
||||
RefPtr<TextureSource> source = GetTextureSource();
|
||||
if (!source) {
|
||||
|
||||
if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<TexturedEffect> effect = GenEffect(aFilter);
|
||||
if (!mTextureSource) {
|
||||
// BindTextureSource above should have returned false!
|
||||
MOZ_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isAlphaPremultiplied = !(mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED);
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
|
||||
mTextureSource.get(),
|
||||
aFilter,
|
||||
isAlphaPremultiplied);
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
|
||||
aEffectChain.mPrimaryEffect = effect;
|
||||
IntSize textureSize = source->GetSize();
|
||||
IntSize textureSize = mTextureSource->GetSize();
|
||||
gfx::Rect gfxPictureRect
|
||||
= mHasPictureRect ? gfx::Rect(0, 0, mPictureRect.width, mPictureRect.height)
|
||||
: gfx::Rect(0, 0, textureSize.width, textureSize.height);
|
||||
|
@ -123,7 +126,7 @@ ImageHost::Composite(EffectChain& aEffectChain,
|
|||
gfx::Rect pictureRect(0, 0,
|
||||
mPictureRect.width,
|
||||
mPictureRect.height);
|
||||
BigImageIterator* it = source->AsBigImageIterator();
|
||||
BigImageIterator* it = mTextureSource->AsBigImageIterator();
|
||||
if (it) {
|
||||
|
||||
// This iteration does not work if we have multiple texture sources here
|
||||
|
@ -139,7 +142,7 @@ ImageHost::Composite(EffectChain& aEffectChain,
|
|||
// the corresponding source tiles from all planes, with appropriate
|
||||
// per-plane per-tile texture coords.
|
||||
// DrawQuad currently assumes that all planes use the same texture coords.
|
||||
MOZ_ASSERT(it->GetTileCount() == 1 || !source->GetNextSibling(),
|
||||
MOZ_ASSERT(it->GetTileCount() == 1 || !mTextureSource->GetNextSibling(),
|
||||
"Can't handle multi-plane BigImages");
|
||||
|
||||
it->BeginBigImageIteration();
|
||||
|
@ -170,7 +173,7 @@ ImageHost::Composite(EffectChain& aEffectChain,
|
|||
gfxPictureRect, aClipRect,
|
||||
aTransform, mFlashCounter);
|
||||
} else {
|
||||
IntSize textureSize = source->GetSize();
|
||||
IntSize textureSize = mTextureSource->GetSize();
|
||||
gfx::Rect rect;
|
||||
if (mHasPictureRect) {
|
||||
effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width,
|
||||
|
@ -273,18 +276,10 @@ ImageHost::Unlock()
|
|||
mLocked = false;
|
||||
}
|
||||
|
||||
TemporaryRef<TextureSource>
|
||||
ImageHost::GetTextureSource()
|
||||
{
|
||||
MOZ_ASSERT(mLocked);
|
||||
return mFrontBuffer->GetTextureSources();
|
||||
}
|
||||
|
||||
TemporaryRef<TexturedEffect>
|
||||
ImageHost::GenEffect(const gfx::Filter& aFilter)
|
||||
{
|
||||
RefPtr<TextureSource> source = GetTextureSource();
|
||||
if (!source) {
|
||||
if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
|
||||
return nullptr;
|
||||
}
|
||||
bool isAlphaPremultiplied = true;
|
||||
|
@ -292,7 +287,7 @@ ImageHost::GenEffect(const gfx::Filter& aFilter)
|
|||
isAlphaPremultiplied = false;
|
||||
|
||||
return CreateTexturedEffect(mFrontBuffer->GetFormat(),
|
||||
source,
|
||||
mTextureSource,
|
||||
aFilter,
|
||||
isAlphaPremultiplied);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,6 @@ public:
|
|||
|
||||
virtual CompositableType GetType() { return mTextureInfo.mCompositableType; }
|
||||
|
||||
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
|
@ -84,13 +82,12 @@ public:
|
|||
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<TextureSource> GetTextureSource();
|
||||
|
||||
virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
RefPtr<TextureHost> mFrontBuffer;
|
||||
CompositableTextureSourceRef mTextureSource;
|
||||
nsIntRect mPictureRect;
|
||||
bool mHasPictureRect;
|
||||
bool mLocked;
|
||||
|
|
|
@ -144,6 +144,13 @@ TextureHost::GetIPDLActor()
|
|||
return mActor;
|
||||
}
|
||||
|
||||
bool
|
||||
TextureHost::BindTextureSource(CompositableTextureSourceRef& texture)
|
||||
{
|
||||
texture = GetTextureSources();
|
||||
return !!texture;
|
||||
}
|
||||
|
||||
FenceHandle
|
||||
TextureHost::GetAndResetReleaseFenceHandle()
|
||||
{
|
||||
|
@ -277,18 +284,6 @@ TextureHost::CompositorRecycle()
|
|||
static_cast<TextureParent*>(mActor)->CompositorRecycle();
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
{
|
||||
mCompositableBackendData = aBackendData;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
{
|
||||
mCompositableBackendData = nullptr;
|
||||
}
|
||||
|
||||
TextureHost::TextureHost(TextureFlags aFlags)
|
||||
: mActor(nullptr)
|
||||
, mFlags(aFlags)
|
||||
|
@ -322,9 +317,11 @@ TextureHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
|||
}
|
||||
|
||||
TextureSource::TextureSource()
|
||||
: mCompositableCount(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureSource);
|
||||
}
|
||||
|
||||
TextureSource::~TextureSource()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureSource);
|
||||
|
@ -844,8 +841,9 @@ SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor
|
|||
|
||||
GLenum target = surf->ConsTextureTarget();
|
||||
GLuint tex = surf->ConsTexture(gl);
|
||||
texSource = new GLTextureSource(compositorOGL, tex, format, target,
|
||||
surf->mSize);
|
||||
texSource = new GLTextureSource(compositorOGL, tex, target,
|
||||
surf->mSize, format,
|
||||
true/*externally owned*/);
|
||||
break;
|
||||
}
|
||||
case gl::SharedSurfaceType::EGLImageShare: {
|
||||
|
@ -860,8 +858,9 @@ SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor
|
|||
GLuint tex = 0;
|
||||
surf->AcquireConsumerTexture(gl, &tex, &target);
|
||||
|
||||
texSource = new GLTextureSource(compositorOGL, tex, format, target,
|
||||
surf->mSize);
|
||||
texSource = new GLTextureSource(compositorOGL, tex, target,
|
||||
surf->mSize, format,
|
||||
true/*externally owned*/);
|
||||
break;
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace layers {
|
|||
|
||||
class Compositor;
|
||||
class CompositableHost;
|
||||
class CompositableBackendSpecificData;
|
||||
class CompositableParentManager;
|
||||
class SurfaceDescriptor;
|
||||
class SharedSurfaceDescriptor;
|
||||
|
@ -150,10 +149,69 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void AddCompositableRef() { ++mCompositableCount; }
|
||||
|
||||
void ReleaseCompositableRef() {
|
||||
--mCompositableCount;
|
||||
MOZ_ASSERT(mCompositableCount >= 0);
|
||||
}
|
||||
|
||||
int NumCompositableRefs() const { return mCompositableCount; }
|
||||
|
||||
protected:
|
||||
virtual ~TextureSource();
|
||||
|
||||
RefPtr<TextureSource> mNextSibling;
|
||||
int mCompositableCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
|
||||
* ReleaseCompositableRef in addition to the usual AddRef and Release.
|
||||
*/
|
||||
class CompositableTextureSourceRef {
|
||||
public:
|
||||
CompositableTextureSourceRef() {}
|
||||
|
||||
~CompositableTextureSourceRef()
|
||||
{
|
||||
if (mRef) {
|
||||
mRef->ReleaseCompositableRef();
|
||||
}
|
||||
}
|
||||
|
||||
CompositableTextureSourceRef& operator=(const TemporaryRef<TextureSource>& aOther)
|
||||
{
|
||||
RefPtr<TextureSource> temp = aOther;
|
||||
if (temp) {
|
||||
temp->AddCompositableRef();
|
||||
}
|
||||
if (mRef) {
|
||||
mRef->ReleaseCompositableRef();
|
||||
}
|
||||
mRef = temp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CompositableTextureSourceRef& operator=(TextureSource* aOther)
|
||||
{
|
||||
if (aOther) {
|
||||
aOther->AddCompositableRef();
|
||||
}
|
||||
if (mRef) {
|
||||
mRef->ReleaseCompositableRef();
|
||||
}
|
||||
mRef = aOther;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TextureSource* get() const { return mRef; }
|
||||
operator TextureSource*() const { return mRef; }
|
||||
TextureSource* operator->() const { return mRef; }
|
||||
TextureSource& operator*() const { return *mRef; }
|
||||
|
||||
private:
|
||||
RefPtr<TextureSource> mRef;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -302,6 +360,25 @@ public:
|
|||
*/
|
||||
virtual TextureSource* GetTextureSources() = 0;
|
||||
|
||||
/**
|
||||
* Called during the transaction. The TextureSource may or may not be composited.
|
||||
*
|
||||
* Note that this is called outside of lock/unlock.
|
||||
*/
|
||||
virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
|
||||
|
||||
/**
|
||||
* Called at composition time, just before compositing the TextureSource composited.
|
||||
*
|
||||
* Note that this is called only withing lock/unlock.
|
||||
*/
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture);
|
||||
|
||||
/**
|
||||
* Called when another TextureHost will take over.
|
||||
*/
|
||||
virtual void UnbindTextureSource() {}
|
||||
|
||||
/**
|
||||
* Is called before compositing if the shared data has changed since last
|
||||
* composition.
|
||||
|
@ -406,10 +483,6 @@ public:
|
|||
return LayerRenderState();
|
||||
}
|
||||
|
||||
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
|
||||
|
||||
virtual void UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
|
||||
|
||||
// If a texture host holds a reference to shmem, it should override this method
|
||||
// to forget about the shmem _without_ releasing it.
|
||||
virtual void OnShutdown() {}
|
||||
|
@ -435,7 +508,6 @@ public:
|
|||
protected:
|
||||
PTextureParent* mActor;
|
||||
TextureFlags mFlags;
|
||||
RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
|
||||
|
||||
friend class TextureParent;
|
||||
};
|
||||
|
|
|
@ -136,17 +136,6 @@ GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
|||
gl()->fActiveTexture(aTextureUnit);
|
||||
gl()->fBindTexture(textureTarget, tex);
|
||||
|
||||
if (mTextureBackendSpecificData) {
|
||||
// There are two paths for locking/unlocking - if mTextureBackendSpecificData is
|
||||
// set, we use the texture on there, otherwise we use
|
||||
// CompositorBackendSpecificData from the compositor and bind the EGLImage
|
||||
// only in Lock().
|
||||
if (!mEGLImage) {
|
||||
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
||||
}
|
||||
BindEGLImage();
|
||||
}
|
||||
|
||||
ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
|
@ -159,10 +148,6 @@ GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
|||
|
||||
bool GrallocTextureSourceOGL::Lock()
|
||||
{
|
||||
if (mTextureBackendSpecificData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
|
@ -188,7 +173,7 @@ bool GrallocTextureSourceOGL::Lock()
|
|||
bool
|
||||
GrallocTextureSourceOGL::IsValid() const
|
||||
{
|
||||
return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mTextureBackendSpecificData);
|
||||
return !!gl() && !!mGraphicBuffer.get() && !!mCompositor;
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
|
@ -230,62 +215,6 @@ GrallocTextureSourceOGL::GetTextureTarget() const
|
|||
return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureSourceOGL::SetTextureBackendSpecificData(TextureSharedDataGonkOGL* aBackendData)
|
||||
{
|
||||
if (!aBackendData) {
|
||||
DeallocateDeviceData();
|
||||
// Update mTextureBackendSpecificData after calling DeallocateDeviceData().
|
||||
mTextureBackendSpecificData = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTextureBackendSpecificData != aBackendData) {
|
||||
mNeedsReset = true;
|
||||
}
|
||||
|
||||
if (!gl() || !gl()->MakeCurrent()) {
|
||||
NS_WARNING("Failed to make the context current");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mNeedsReset) {
|
||||
// Update binding to the EGLImage
|
||||
GLuint tex = GetGLTexture();
|
||||
GLuint textureTarget = GetTextureTarget();
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(textureTarget, tex);
|
||||
BindEGLImage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mCompositor) {
|
||||
mTextureBackendSpecificData = aBackendData;
|
||||
return;
|
||||
}
|
||||
|
||||
// delete old EGLImage
|
||||
DeallocateDeviceData();
|
||||
|
||||
// Update mTextureBackendSpecificData after calling DeallocateDeviceData().
|
||||
mTextureBackendSpecificData = aBackendData;
|
||||
|
||||
GLuint tex = GetGLTexture();
|
||||
GLuint textureTarget = GetTextureTarget();
|
||||
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(textureTarget, tex);
|
||||
|
||||
// Setup texure parameters at the first binding.
|
||||
gl()->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_T, GetWrapMode());
|
||||
gl()->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_S, GetWrapMode());
|
||||
|
||||
// create new EGLImage
|
||||
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
||||
BindEGLImage();
|
||||
mNeedsReset = false;
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
GrallocTextureSourceOGL::GetSize() const
|
||||
{
|
||||
|
@ -304,9 +233,6 @@ GrallocTextureSourceOGL::DeallocateDeviceData()
|
|||
if (!gl() || !gl()->MakeCurrent()) {
|
||||
return;
|
||||
}
|
||||
if (mTextureBackendSpecificData) {
|
||||
mTextureBackendSpecificData->ClearBoundEGLImage(mEGLImage);
|
||||
}
|
||||
EGLImageDestroy(gl(), mEGLImage);
|
||||
mEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
|
@ -315,49 +241,48 @@ GrallocTextureSourceOGL::DeallocateDeviceData()
|
|||
GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
|
||||
const NewSurfaceDescriptorGralloc& aDescriptor)
|
||||
: TextureHost(aFlags)
|
||||
, mGrallocHandle(aDescriptor)
|
||||
, mSize(0, 0)
|
||||
, mDescriptorSize(aDescriptor.size())
|
||||
, mFormat(gfx::SurfaceFormat::UNKNOWN)
|
||||
, mEGLImage(EGL_NO_IMAGE)
|
||||
{
|
||||
gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
|
||||
mGrallocHandle = aDescriptor;
|
||||
|
||||
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
|
||||
MOZ_ASSERT(graphicBuffer);
|
||||
|
||||
mSize = aDescriptor.size();
|
||||
if (graphicBuffer) {
|
||||
format =
|
||||
mFormat =
|
||||
SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
|
||||
aFlags & TextureFlags::RB_SWAPPED);
|
||||
mTextureSource = new GrallocTextureSourceOGL(nullptr,
|
||||
this,
|
||||
graphicBuffer,
|
||||
format);
|
||||
mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight());
|
||||
} else {
|
||||
printf_stderr("gralloc buffer is nullptr");
|
||||
}
|
||||
}
|
||||
|
||||
GrallocTextureHostOGL::~GrallocTextureHostOGL()
|
||||
{
|
||||
MOZ_ASSERT(!mTextureSource || (mFlags & TextureFlags::DEALLOCATE_CLIENT),
|
||||
"Leaking our buffer");
|
||||
}
|
||||
{}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
if (mTextureSource) {
|
||||
mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
if (mTilingTextureSource) {
|
||||
mTilingTextureSource->SetCompositor(mCompositor);
|
||||
}
|
||||
if (mGLTextureSource) {
|
||||
mGLTextureSource->SetCompositor(mCompositor);
|
||||
}
|
||||
|
||||
if (mCompositor && aCompositor != mCompositor) {
|
||||
DestroyEGLImage();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureHostOGL::Lock()
|
||||
{
|
||||
if (IsValid()) {
|
||||
mTextureSource->Lock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -369,28 +294,29 @@ GrallocTextureHostOGL::Unlock()
|
|||
bool
|
||||
GrallocTextureHostOGL::IsValid() const
|
||||
{
|
||||
if (!mTextureSource) {
|
||||
return false;
|
||||
}
|
||||
return mTextureSource->IsValid();
|
||||
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
|
||||
return graphicBuffer != nullptr;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
GrallocTextureHostOGL::GetFormat() const
|
||||
{
|
||||
if (!mTextureSource) {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
return mTextureSource->GetFormat();
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::DeallocateSharedData()
|
||||
{
|
||||
if (mTextureSource) {
|
||||
mTextureSource->ForgetBuffer();
|
||||
mTextureSource = nullptr;
|
||||
if (mTilingTextureSource) {
|
||||
mTilingTextureSource->ForgetBuffer();
|
||||
mTilingTextureSource = nullptr;
|
||||
}
|
||||
if (mGLTextureSource) {
|
||||
mGLTextureSource = nullptr;
|
||||
}
|
||||
|
||||
DestroyEGLImage();
|
||||
|
||||
if (mGrallocHandle.buffer().type() != SurfaceDescriptor::Tnull_t) {
|
||||
MaybeMagicGrallocBufferHandle handle = mGrallocHandle.buffer();
|
||||
base::ProcessId owner;
|
||||
|
@ -408,24 +334,33 @@ GrallocTextureHostOGL::DeallocateSharedData()
|
|||
void
|
||||
GrallocTextureHostOGL::ForgetSharedData()
|
||||
{
|
||||
if (mTextureSource) {
|
||||
mTextureSource->ForgetBuffer();
|
||||
mTextureSource = nullptr;
|
||||
if (mTilingTextureSource) {
|
||||
mTilingTextureSource->ForgetBuffer();
|
||||
mTilingTextureSource = nullptr;
|
||||
}
|
||||
if (mGLTextureSource) {
|
||||
mGLTextureSource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::DeallocateDeviceData()
|
||||
{
|
||||
if (mTextureSource) {
|
||||
mTextureSource->DeallocateDeviceData();
|
||||
if (mTilingTextureSource) {
|
||||
mTilingTextureSource->DeallocateDeviceData();
|
||||
}
|
||||
if (mGLTextureSource) {
|
||||
mGLTextureSource = nullptr;
|
||||
}
|
||||
DestroyEGLImage();
|
||||
}
|
||||
|
||||
LayerRenderState
|
||||
GrallocTextureHostOGL::GetRenderState()
|
||||
{
|
||||
if (IsValid()) {
|
||||
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
|
||||
|
||||
if (graphicBuffer) {
|
||||
LayerRenderStateFlags flags = LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT;
|
||||
if (mFlags & TextureFlags::NEEDS_Y_FLIP) {
|
||||
flags |= LayerRenderStateFlags::Y_FLIPPED;
|
||||
|
@ -433,8 +368,8 @@ GrallocTextureHostOGL::GetRenderState()
|
|||
if (mFlags & TextureFlags::RB_SWAPPED) {
|
||||
flags |= LayerRenderStateFlags::FORMAT_RB_SWAP;
|
||||
}
|
||||
return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
|
||||
gfx::ThebesIntSize(mSize),
|
||||
return LayerRenderState(graphicBuffer,
|
||||
gfx::ThebesIntSize(mDescriptorSize),
|
||||
flags,
|
||||
this);
|
||||
}
|
||||
|
@ -444,7 +379,7 @@ GrallocTextureHostOGL::GetRenderState()
|
|||
|
||||
TemporaryRef<gfx::DataSourceSurface>
|
||||
GrallocTextureHostOGL::GetAsSurface() {
|
||||
return mTextureSource ? mTextureSource->GetAsSurface()
|
||||
return mTilingTextureSource ? mTilingTextureSource->GetAsSurface()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -473,103 +408,186 @@ GrallocTextureSourceOGL::GetAsSurface() {
|
|||
GLuint
|
||||
GrallocTextureSourceOGL::GetGLTexture()
|
||||
{
|
||||
if (mTextureBackendSpecificData) {
|
||||
mTextureBackendSpecificData->SetCompositor(mCompositor);
|
||||
return mTextureBackendSpecificData->GetTexture();
|
||||
}
|
||||
|
||||
return mTexture;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureSourceOGL::BindEGLImage()
|
||||
{
|
||||
if (mTextureBackendSpecificData) {
|
||||
mTextureBackendSpecificData->BindEGLImage(GetTextureTarget(), mEGLImage);
|
||||
} else {
|
||||
gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
|
||||
}
|
||||
|
||||
TextureSource*
|
||||
GrallocTextureHostOGL::GetTextureSources()
|
||||
{
|
||||
// This is now only used with tiled layers, and will eventually be removed.
|
||||
// Other layer types use BindTextureSource instead.
|
||||
MOZ_ASSERT(!mGLTextureSource);
|
||||
if (!mTilingTextureSource) {
|
||||
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
|
||||
MOZ_ASSERT(graphicBuffer);
|
||||
if (!graphicBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
mTilingTextureSource = new GrallocTextureSourceOGL(mCompositor, this,
|
||||
graphicBuffer, mFormat);
|
||||
}
|
||||
mTilingTextureSource->Lock();
|
||||
return mTilingTextureSource;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::UnbindTextureSource()
|
||||
{
|
||||
// Clear the reference to the TextureSource (if any), because we know that
|
||||
// another TextureHost is being bound to the TextureSource. This means that
|
||||
// we will have to re-do gl->fEGLImageTargetTexture2D next time we go through
|
||||
// BindTextureSource (otherwise we would have skipped it).
|
||||
// Note that this doesn't "unlock" the gralloc buffer or force it to be
|
||||
// detached, Although decreasing the refcount of the TextureSource may lead
|
||||
// to the gl handle being destroyed, which would unlock the gralloc buffer.
|
||||
// That said, this method is called before another TextureHost attaches to the
|
||||
// TextureSource, which has the effect of unlocking the gralloc buffer. So when
|
||||
// this is called we know we are going to be unlocked soon.
|
||||
mGLTextureSource = nullptr;
|
||||
}
|
||||
|
||||
GLenum GetTextureTarget(gl::GLContext* aGL, android::PixelFormat aFormat) {
|
||||
MOZ_ASSERT(aGL);
|
||||
if (aGL->Renderer() == gl::GLRenderer::SGX530 ||
|
||||
aGL->Renderer() == gl::GLRenderer::SGX540) {
|
||||
// SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will
|
||||
// result in black pixels when trying to draw from bound textures.
|
||||
// Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on
|
||||
// performance.
|
||||
// See Bug 950050.
|
||||
return LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
} else {
|
||||
return TextureTargetForAndroidPixelFormat(aFormat);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
GrallocTextureHostOGL::DestroyEGLImage()
|
||||
{
|
||||
if(!aBackendData) {
|
||||
return;
|
||||
// Only called when we want to get rid of the gralloc buffer, usually
|
||||
// around the end of life of the TextureHost.
|
||||
if (mEGLImage != EGL_NO_IMAGE && GetGLContext()) {
|
||||
EGLImageDestroy(GetGLContext(), mEGLImage);
|
||||
mEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
|
||||
// Update mTextureBackendSpecificData if it is not set yet.
|
||||
if (!mTextureBackendSpecificData) {
|
||||
MOZ_ASSERT(!mCompositableBackendData);
|
||||
mCompositableBackendData = aBackendData;
|
||||
CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
|
||||
mTextureBackendSpecificData = backend->GetTextureBackendSpecificData();
|
||||
}
|
||||
|
||||
// If TextureHost sharing by multiple CompositableHosts are detected,
|
||||
// enable mBackendDatas usage.
|
||||
if (!mBackendDatas &&
|
||||
mCompositableBackendData &&
|
||||
mCompositableBackendData != aBackendData &&
|
||||
mTextureBackendSpecificData->IsAllowingSharingTextureHost())
|
||||
{
|
||||
mBackendDatas = MakeUnique<std::map<uint64_t, RefPtr<CompositableBackendSpecificData> > >();
|
||||
(*mBackendDatas)[mCompositableBackendData->GetId()] = mCompositableBackendData;
|
||||
mCompositableBackendData = nullptr;
|
||||
|
||||
// Get new mTextureBackendSpecificData
|
||||
mTextureBackendSpecificData =
|
||||
mTextureBackendSpecificData->GetNewTextureBackendSpecificData(mTextureSource->GetEGLImage());
|
||||
mTextureBackendSpecificData->SetOwnedByTextureHost();
|
||||
}
|
||||
|
||||
// Update mCompositableBackendData.
|
||||
if (mBackendDatas)
|
||||
{
|
||||
// Handle a case that TextureHost has ownership of TextureSharedDataGonkOGL.
|
||||
MOZ_ASSERT(aBackendData->IsAllowingSharingTextureHost());
|
||||
(*mBackendDatas)[aBackendData->GetId()] = aBackendData;
|
||||
if (mBackendDatas->size() > 200) {
|
||||
NS_WARNING("Too many CompositableBackends");
|
||||
}
|
||||
} else {
|
||||
// Handle a case that CompositableHost has ownership of TextureSharedDataGonkOGL.
|
||||
mCompositableBackendData = aBackendData;
|
||||
CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
|
||||
mTextureBackendSpecificData = backend->GetTextureBackendSpecificData();
|
||||
}
|
||||
|
||||
if (mTextureSource) {
|
||||
mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
||||
GrallocTextureHostOGL::PrepareTextureSource(CompositableTextureSourceRef& aTextureSource)
|
||||
{
|
||||
if(!aBackendData ||
|
||||
!mTextureBackendSpecificData) {
|
||||
// This happens during the layers transaction.
|
||||
// All of the gralloc magic goes here. The only thing that happens externally
|
||||
// and that is good to keep in mind is that when the TextureSource is deleted,
|
||||
// it destroys its gl texture handle which is important for genlock.
|
||||
|
||||
// If this TextureHost's mGLTextureSource member is non-null, it means we are
|
||||
// still bound to the TextureSource, in which case we can skip the driver
|
||||
// overhead of binding the texture again (fEGLImageTargetTexture2D)
|
||||
// As a result, if the TextureHost is used with several CompositableHosts,
|
||||
// it will be bound to only one TextureSource, and we'll do the driver work
|
||||
// only once, which is great. This means that all of the compositables that
|
||||
// use this TextureHost will keep a reference to this TextureSource at least
|
||||
// for the duration of this frame.
|
||||
|
||||
// If the compositable already has a TextureSource (the aTextureSource parameter),
|
||||
// that is compatible and is not in use by several compositable, we try to
|
||||
// attach to it. This has the effect of unlocking the previous TextureHost that
|
||||
// we attached to the TextureSource (the previous frame)
|
||||
|
||||
// If the TextureSource used by the compositable is also used by other
|
||||
// compositables (see NumCompositableRefs), we have to create a new TextureSource,
|
||||
// because otherwise we would be modifying the content of every layer that uses
|
||||
// the TextureSource in question, even thoug they don't use this TextureHost.
|
||||
|
||||
MOZ_ASSERT(!mTilingTextureSource);
|
||||
|
||||
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
|
||||
|
||||
MOZ_ASSERT(graphicBuffer);
|
||||
if (!graphicBuffer) {
|
||||
mGLTextureSource = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBackendDatas)
|
||||
{
|
||||
// Handle a case that TextureHost has ownership of TextureSharedDataGonkOGL.
|
||||
mBackendDatas->erase(aBackendData->GetId());
|
||||
if (mBackendDatas->size() == 0) {
|
||||
mCompositableBackendData = nullptr;
|
||||
mTextureBackendSpecificData = nullptr;
|
||||
}
|
||||
} else {
|
||||
// Handle a case that CompositableHost has ownership of TextureSharedDataGonkOGL.
|
||||
mCompositableBackendData = nullptr;
|
||||
mTextureBackendSpecificData = nullptr;
|
||||
if (mGLTextureSource && !mGLTextureSource->IsValid()) {
|
||||
mGLTextureSource = nullptr;
|
||||
}
|
||||
|
||||
if (mTextureSource) {
|
||||
mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
|
||||
if (mGLTextureSource) {
|
||||
// We are already attached to a TextureSource, nothing to do except tell
|
||||
// the compositable to use it.
|
||||
aTextureSource = mGLTextureSource.get();
|
||||
return;
|
||||
}
|
||||
|
||||
gl::GLContext* gl = GetGLContext();
|
||||
if (!gl || !gl->MakeCurrent()) {
|
||||
mGLTextureSource = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEGLImage == EGL_NO_IMAGE) {
|
||||
// Should only happen the first time.
|
||||
mEGLImage = EGLImageCreateFromNativeBuffer(gl, graphicBuffer->getNativeBuffer());
|
||||
}
|
||||
|
||||
GLenum textureTarget = GetTextureTarget(gl, graphicBuffer->getPixelFormat());
|
||||
|
||||
GLTextureSource* glSource = aTextureSource.get() ?
|
||||
aTextureSource->AsSourceOGL()->AsGLTextureSource() : nullptr;
|
||||
|
||||
bool shouldCreateTextureSource = !glSource || !glSource->IsValid()
|
||||
|| glSource->NumCompositableRefs() > 1
|
||||
|| glSource->GetTextureTarget() != textureTarget;
|
||||
|
||||
if (shouldCreateTextureSource) {
|
||||
GLuint textureHandle;
|
||||
gl->fGenTextures(1, &textureHandle);
|
||||
gl->fBindTexture(textureTarget, textureHandle);
|
||||
gl->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
gl->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
gl->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
||||
|
||||
mGLTextureSource = new GLTextureSource(mCompositor, textureHandle, textureTarget,
|
||||
mSize, mFormat);
|
||||
aTextureSource = mGLTextureSource.get();
|
||||
} else {
|
||||
gl->fBindTexture(textureTarget, glSource->GetTextureHandle());
|
||||
|
||||
gl->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
||||
glSource->SetSize(mSize);
|
||||
glSource->SetFormat(mFormat);
|
||||
mGLTextureSource = glSource;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureHostOGL::BindTextureSource(CompositableTextureSourceRef& aTextureSource)
|
||||
{
|
||||
// This happens at composition time.
|
||||
|
||||
// If mGLTextureSource is null it means PrepareTextureSource failed.
|
||||
if (!mGLTextureSource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If Prepare didn't fail, we expect our TextureSource to be the same as aTextureSource,
|
||||
// otherwise it means something has fiddled with the TextureSource between Prepare and
|
||||
// now.
|
||||
MOZ_ASSERT(mGLTextureSource == aTextureSource);
|
||||
aTextureSource = mGLTextureSource.get();
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
// Wait until it's ready.
|
||||
WaitAcquireFenceSyncComplete();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namepsace layers
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace layers {
|
|||
|
||||
class GrallocTextureHostOGL;
|
||||
|
||||
// Progressively getting replaced by GLTextureSource
|
||||
class GrallocTextureSourceOGL : public TextureSource
|
||||
, public TextureSourceOGL
|
||||
{
|
||||
|
@ -47,8 +48,6 @@ public:
|
|||
return LOCAL_GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
virtual void SetTextureBackendSpecificData(TextureSharedDataGonkOGL* aBackendData);
|
||||
|
||||
void DeallocateDeviceData();
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
@ -75,7 +74,6 @@ public:
|
|||
bool Lock();
|
||||
|
||||
protected:
|
||||
RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
GrallocTextureHostOGL* mTextureHost;
|
||||
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
||||
|
@ -113,14 +111,17 @@ public:
|
|||
|
||||
virtual gfx::SurfaceFormat GetFormat() const;
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mDescriptorSize; }
|
||||
|
||||
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSource* GetTextureSources() MOZ_OVERRIDE
|
||||
{
|
||||
return mTextureSource;
|
||||
}
|
||||
virtual void PrepareTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
|
||||
|
||||
virtual void UnbindTextureSource() MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSource* GetTextureSources() MOZ_OVERRIDE;
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
virtual TextureHostOGL* AsHostOGL() MOZ_OVERRIDE
|
||||
|
@ -131,21 +132,27 @@ public:
|
|||
|
||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
|
||||
|
||||
virtual void UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
virtual const char* Name() MOZ_OVERRIDE { return "GrallocTextureHostOGL"; }
|
||||
|
||||
private:
|
||||
NewSurfaceDescriptorGralloc mGrallocHandle;
|
||||
RefPtr<GrallocTextureSourceOGL> mTextureSource;
|
||||
gfx::IntSize mSize; // See comment in textureClientOGL.h
|
||||
gl::GLContext* GetGLContext() const { return mCompositor ? mCompositor->gl() : nullptr; }
|
||||
|
||||
RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
|
||||
UniquePtr<std::map<uint64_t, RefPtr<CompositableBackendSpecificData> > > mBackendDatas;
|
||||
private:
|
||||
void DestroyEGLImage();
|
||||
|
||||
NewSurfaceDescriptorGralloc mGrallocHandle;
|
||||
RefPtr<GLTextureSource> mGLTextureSource;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
// only used for tiling, will be removed.
|
||||
RefPtr<GrallocTextureSourceOGL> mTilingTextureSource;
|
||||
// Size reported by the GraphicBuffer
|
||||
gfx::IntSize mSize;
|
||||
// Size reported by TextureClient, can be different in some cases (video?),
|
||||
// used by LayerRenderState.
|
||||
gfx::IntSize mDescriptorSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
EGLImage mEGLImage;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -40,16 +40,6 @@ namespace layers {
|
|||
|
||||
class Compositor;
|
||||
|
||||
TemporaryRef<CompositableBackendSpecificData>
|
||||
CreateCompositableBackendSpecificDataOGL()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
return new CompositableDataGonkOGL();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
TemporaryRef<TextureHost>
|
||||
CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
|
||||
ISurfaceAllocator* aDeallocator,
|
||||
|
@ -119,174 +109,6 @@ FlagsToGLFlags(TextureFlags aFlags)
|
|||
return static_cast<gl::TextureImage::Flags>(result);
|
||||
}
|
||||
|
||||
CompositableDataGonkOGL::CompositableDataGonkOGL()
|
||||
{
|
||||
}
|
||||
|
||||
CompositableDataGonkOGL::~CompositableDataGonkOGL()
|
||||
{
|
||||
ClearData();
|
||||
}
|
||||
|
||||
void
|
||||
CompositableDataGonkOGL::ClearData()
|
||||
{
|
||||
CompositableBackendSpecificData::ClearData();
|
||||
mTextureBackendSpecificData = nullptr;
|
||||
mCompositor = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
if (mTextureBackendSpecificData) {
|
||||
mTextureBackendSpecificData->SetCompositor(aCompositor);
|
||||
}
|
||||
}
|
||||
|
||||
TextureSharedDataGonkOGL*
|
||||
CompositableDataGonkOGL::GetTextureBackendSpecificData()
|
||||
{
|
||||
if (!mTextureBackendSpecificData) {
|
||||
mTextureBackendSpecificData = new TextureSharedDataGonkOGL();
|
||||
mTextureBackendSpecificData->SetCompositor(mCompositor);
|
||||
mTextureBackendSpecificData->SetAllowSharingTextureHost(IsAllowingSharingTextureHost());
|
||||
}
|
||||
return mTextureBackendSpecificData;
|
||||
}
|
||||
|
||||
TextureSharedDataGonkOGL::TextureSharedDataGonkOGL()
|
||||
: mOwnedByCompositableHost(true)
|
||||
, mAllowSharingTextureHost(false)
|
||||
, mTexture(0)
|
||||
, mBoundEGLImage(EGL_NO_IMAGE)
|
||||
{
|
||||
}
|
||||
|
||||
TextureSharedDataGonkOGL::TextureSharedDataGonkOGL(GLuint aTexture, EGLImage aImage, CompositorOGL* aCompositor)
|
||||
: mOwnedByCompositableHost(true)
|
||||
, mAllowSharingTextureHost(false)
|
||||
, mCompositor(aCompositor)
|
||||
, mTexture(aTexture)
|
||||
, mBoundEGLImage(aImage)
|
||||
{
|
||||
}
|
||||
|
||||
TextureSharedDataGonkOGL::~TextureSharedDataGonkOGL()
|
||||
{
|
||||
DeleteTextureIfPresent();
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
TextureSharedDataGonkOGL::gl() const
|
||||
{
|
||||
return mCompositor ? mCompositor->gl() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
TextureSharedDataGonkOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
if (gl() && mCompositor != aCompositor) {
|
||||
DeleteTextureIfPresent();
|
||||
}
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
}
|
||||
|
||||
void
|
||||
TextureSharedDataGonkOGL::ClearData()
|
||||
{
|
||||
DeleteTextureIfPresent();
|
||||
}
|
||||
|
||||
TemporaryRef<TextureSharedDataGonkOGL>
|
||||
TextureSharedDataGonkOGL::GetNewTextureBackendSpecificData(EGLImage aImage)
|
||||
{
|
||||
MOZ_ASSERT(IsAllowingSharingTextureHost());
|
||||
|
||||
if (IsEGLImageBound(aImage))
|
||||
{
|
||||
// If EGLImage is already bound to OpenGL Texture,
|
||||
// handover the OpenGL Texture to caller
|
||||
GLuint textureId = GetAndResetGLTextureOwnership();
|
||||
RefPtr<TextureSharedDataGonkOGL> data = new TextureSharedDataGonkOGL(textureId, aImage, mCompositor);
|
||||
data->SetCompositor(mCompositor);
|
||||
data->SetAllowSharingTextureHost(true);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Create brand new TextureSharedDataGonkOGL
|
||||
RefPtr<TextureSharedDataGonkOGL> data = new TextureSharedDataGonkOGL();
|
||||
data->SetCompositor(mCompositor);
|
||||
data->SetAllowSharingTextureHost(true);
|
||||
return data;
|
||||
}
|
||||
|
||||
GLuint
|
||||
TextureSharedDataGonkOGL::GetTexture()
|
||||
{
|
||||
if (!mTexture) {
|
||||
if (gl() && gl()->MakeCurrent()) {
|
||||
gl()->fGenTextures(1, &mTexture);
|
||||
}
|
||||
}
|
||||
return mTexture;
|
||||
}
|
||||
|
||||
GLuint
|
||||
TextureSharedDataGonkOGL::GetAndResetGLTextureOwnership()
|
||||
{
|
||||
GLuint texture = mTexture;
|
||||
mTexture = 0;
|
||||
mBoundEGLImage = EGL_NO_IMAGE;
|
||||
return texture;
|
||||
}
|
||||
|
||||
void
|
||||
TextureSharedDataGonkOGL::DeleteTextureIfPresent()
|
||||
{
|
||||
if (mTexture) {
|
||||
MOZ_ASSERT(mCompositor);
|
||||
if (gl() && gl()->MakeCurrent()) {
|
||||
gl()->fDeleteTextures(1, &mTexture);
|
||||
}
|
||||
mTexture = 0;
|
||||
mBoundEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureSharedDataGonkOGL::BindEGLImage(GLuint aTarget, EGLImage aImage)
|
||||
{
|
||||
if (mBoundEGLImage != aImage) {
|
||||
MOZ_ASSERT(gl());
|
||||
if (gl()) {
|
||||
gl()->fEGLImageTargetTexture2D(aTarget, aImage);
|
||||
}
|
||||
mBoundEGLImage = aImage;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureSharedDataGonkOGL::ClearBoundEGLImage(EGLImage aImage)
|
||||
{
|
||||
if (mBoundEGLImage == aImage) {
|
||||
DeleteTextureIfPresent();
|
||||
mBoundEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TextureSharedDataGonkOGL::IsEGLImageBound(EGLImage aImage)
|
||||
{
|
||||
if (mTexture != 0 &&
|
||||
aImage != EGL_NO_IMAGE &&
|
||||
aImage == mBoundEGLImage) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
bool
|
||||
TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
|
||||
|
@ -529,27 +351,56 @@ TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilt
|
|||
// GLTextureSource
|
||||
|
||||
GLTextureSource::GLTextureSource(CompositorOGL* aCompositor,
|
||||
GLuint aTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLuint aTextureHandle,
|
||||
GLenum aTarget,
|
||||
gfx::IntSize aSize)
|
||||
: mSize(aSize)
|
||||
, mCompositor(aCompositor)
|
||||
, mTex(aTex)
|
||||
, mFormat(aFormat)
|
||||
gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
bool aExternallyOwned)
|
||||
: mCompositor(aCompositor)
|
||||
, mTextureHandle(aTextureHandle)
|
||||
, mTextureTarget(aTarget)
|
||||
, mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mExternallyOwned(aExternallyOwned)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GLTextureSource);
|
||||
}
|
||||
|
||||
GLTextureSource::~GLTextureSource()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GLTextureSource);
|
||||
if (!mExternallyOwned) {
|
||||
DeleteTextureHandle();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GLTextureSource::DeallocateDeviceData()
|
||||
{
|
||||
if (!mExternallyOwned) {
|
||||
DeleteTextureHandle();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GLTextureSource::DeleteTextureHandle()
|
||||
{
|
||||
if (mTextureHandle != 0 && gl() && gl()->MakeCurrent()) {
|
||||
gl()->fDeleteTextures(1, &mTextureHandle);
|
||||
}
|
||||
mTextureHandle = 0;
|
||||
}
|
||||
|
||||
void
|
||||
GLTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
||||
{
|
||||
MOZ_ASSERT(gl());
|
||||
MOZ_ASSERT(mTextureHandle != 0);
|
||||
if (!gl()) {
|
||||
NS_WARNING("Trying to bind a texture without a GLContext");
|
||||
return;
|
||||
}
|
||||
gl()->fActiveTexture(aTextureUnit);
|
||||
gl()->fBindTexture(mTextureTarget, mTex);
|
||||
gl()->fBindTexture(mTextureTarget, mTextureHandle);
|
||||
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
|
||||
}
|
||||
|
||||
|
@ -562,7 +413,7 @@ GLTextureSource::SetCompositor(Compositor* aCompositor)
|
|||
bool
|
||||
GLTextureSource::IsValid() const
|
||||
{
|
||||
return !!gl();
|
||||
return !!gl() && mTextureHandle != 0;
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
|
@ -614,6 +465,10 @@ SurfaceTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
|||
void
|
||||
SurfaceTextureSource::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
if (mCompositor != aCompositor) {
|
||||
DeallocateDeviceData();
|
||||
}
|
||||
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,99 +58,7 @@ class Compositor;
|
|||
class CompositorOGL;
|
||||
class TextureImageTextureSourceOGL;
|
||||
class TextureSharedDataGonkOGL;
|
||||
|
||||
/**
|
||||
* CompositableBackendSpecificData implementation for the Gonk OpenGL backend.
|
||||
* Share a same texture between TextureHosts in the same CompositableHost.
|
||||
* By shareing the texture among the TextureHosts, number of texture allocations
|
||||
* can be reduced than texture allocation in every TextureHosts.
|
||||
* From Bug 912134, use only one texture among all TextureHosts degrade
|
||||
* the rendering performance.
|
||||
* CompositableDataGonkOGL chooses in a middile of them.
|
||||
*/
|
||||
class CompositableDataGonkOGL : public CompositableBackendSpecificData
|
||||
{
|
||||
protected:
|
||||
virtual ~CompositableDataGonkOGL();
|
||||
|
||||
public:
|
||||
CompositableDataGonkOGL();
|
||||
virtual void ClearData() MOZ_OVERRIDE;
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
TextureSharedDataGonkOGL* GetTextureBackendSpecificData();
|
||||
protected:
|
||||
nsRefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Manage actual shared resources of CompositableDataGonkOGL.
|
||||
* The resources are split from CompositableDataGonkOGL to handle two use cases.
|
||||
* Normally TextureHost is used from one CompositableHost at the same time.
|
||||
* In this case, performance is good if the resources are owned by CompositableDataGonkOGL.
|
||||
* But TextureHost could be shared among multiple ImageHosts.
|
||||
* If it happens, performance is good if the resource is owned by TextureHost.
|
||||
* The resources ownership is carryed over from CompositableDataGonkOGL to TextureHost.
|
||||
* See Bug 1017351.
|
||||
*/
|
||||
class TextureSharedDataGonkOGL
|
||||
{
|
||||
protected:
|
||||
virtual ~TextureSharedDataGonkOGL();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(TextureSharedDataGonkOGL)
|
||||
|
||||
TextureSharedDataGonkOGL();
|
||||
TextureSharedDataGonkOGL(GLuint aTexture, EGLImage aImage, CompositorOGL* aCompositor);
|
||||
|
||||
void SetCompositor(Compositor* aCompositor);
|
||||
void ClearData();
|
||||
|
||||
// Mark TextureSharedDataGonkOGL as owned by TextureHost.
|
||||
void SetOwnedByTextureHost()
|
||||
{
|
||||
mOwnedByCompositableHost = false;
|
||||
}
|
||||
|
||||
// Check if this is owned by CompositableHost or TextureHost.
|
||||
bool IsOwnedByCompositableHost()
|
||||
{
|
||||
return mOwnedByCompositableHost;
|
||||
}
|
||||
|
||||
bool IsAllowingSharingTextureHost()
|
||||
{
|
||||
return mAllowSharingTextureHost;
|
||||
}
|
||||
|
||||
void SetAllowSharingTextureHost(bool aAllow)
|
||||
{
|
||||
mAllowSharingTextureHost = aAllow;
|
||||
}
|
||||
|
||||
// Create new TextureSharedDataGonkOGL.
|
||||
// If aImage is already bound to OpenGL texture, the OpenGL textre is carried over
|
||||
// to a new object. It could reduce calling fEGLImageTargetTexture2D()
|
||||
// during resources ownership carry over from CompositableHost to TextureHost.
|
||||
TemporaryRef<TextureSharedDataGonkOGL> GetNewTextureBackendSpecificData(EGLImage aImage);
|
||||
|
||||
GLuint GetTexture();
|
||||
void DeleteTextureIfPresent();
|
||||
gl::GLContext* gl() const;
|
||||
void BindEGLImage(GLuint aTarget, EGLImage aImage);
|
||||
void ClearBoundEGLImage(EGLImage aImage);
|
||||
bool IsEGLImageBound(EGLImage aImage);
|
||||
protected:
|
||||
GLuint GetAndResetGLTextureOwnership();
|
||||
|
||||
bool mOwnedByCompositableHost;
|
||||
bool mAllowSharingTextureHost;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
GLuint mTexture;
|
||||
EGLImage mBoundEGLImage;
|
||||
};
|
||||
class GLTextureSource;
|
||||
|
||||
inline void ApplyFilterToBoundTexture(gl::GLContext* aGL,
|
||||
gfx::Filter aFilter,
|
||||
|
@ -205,6 +113,8 @@ public:
|
|||
|
||||
virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return nullptr; }
|
||||
|
||||
virtual GLTextureSource* AsGLTextureSource() { return nullptr; }
|
||||
|
||||
void SetFilter(gl::GLContext* aGL, gfx::Filter aFilter)
|
||||
{
|
||||
if (mHasCachedFilter &&
|
||||
|
@ -373,10 +283,15 @@ class GLTextureSource : public TextureSource
|
|||
{
|
||||
public:
|
||||
GLTextureSource(CompositorOGL* aCompositor,
|
||||
GLuint aTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLuint aTextureHandle,
|
||||
GLenum aTarget,
|
||||
gfx::IntSize aSize);
|
||||
gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
bool aExternallyOwned = false);
|
||||
|
||||
~GLTextureSource();
|
||||
|
||||
virtual GLTextureSource* AsGLTextureSource() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
|
||||
|
||||
|
@ -392,18 +307,29 @@ public:
|
|||
|
||||
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
|
||||
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
void SetSize(gfx::IntSize aSize) { mSize = aSize; }
|
||||
|
||||
void SetFormat(gfx::SurfaceFormat aFormat) { mFormat = aFormat; }
|
||||
|
||||
GLuint GetTextureHandle() const { return mTextureHandle; }
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
protected:
|
||||
const gfx::IntSize mSize;
|
||||
void DeleteTextureHandle();
|
||||
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
const GLuint mTex;
|
||||
const gfx::SurfaceFormat mFormat;
|
||||
const GLenum mTextureTarget;
|
||||
GLuint mTextureHandle;
|
||||
GLenum mTextureTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
// If the texture is externally owned, the gl handle will not be deleted
|
||||
// in the destructor.
|
||||
bool mExternallyOwned;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
Загрузка…
Ссылка в новой задаче