mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 893301. Content hosts. r=nical
This commit is contained in:
parent
0c1a756507
commit
c6c0992ff8
@ -297,6 +297,17 @@ public:
|
||||
void AddTextureHost(TextureHost* aTexture);
|
||||
virtual void UseTextureHost(TextureHost* aTexture) {}
|
||||
virtual void RemoveTextureHost(uint64_t aTextureID);
|
||||
// If a texture host is flagged for deferred removal, the compositable will
|
||||
// get an option to run any cleanup code early, that is when it would have
|
||||
// been run if the texture host was not marked deferred. That is, this method
|
||||
// is called _before_ RemoveTextureHost for deferred removal texture hosts.
|
||||
// If the compositable does not cleanup the texture host now, it is the
|
||||
// compositable's responsibility to cleanup the texture host before the
|
||||
// texture host dies.
|
||||
virtual void RemoveTextureHostDeferred(TextureHost* aTexture)
|
||||
{
|
||||
MOZ_CRASH("Compositable was not expecting to handle deferred removal of texture hosts");
|
||||
}
|
||||
TextureHost* GetTextureHost(uint64_t aTextureID);
|
||||
|
||||
protected:
|
||||
|
@ -26,6 +26,314 @@ using namespace gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
ContentHostBaseNew::ContentHostBaseNew(const TextureInfo& aTextureInfo)
|
||||
: ContentHost(aTextureInfo)
|
||||
, mPaintWillResample(false)
|
||||
, mInitialised(false)
|
||||
{}
|
||||
|
||||
ContentHostBaseNew::~ContentHostBaseNew()
|
||||
{
|
||||
DestroyTextureHost();
|
||||
DestroyTextureHostOnWhite();
|
||||
}
|
||||
|
||||
TextureHost*
|
||||
ContentHostBaseNew::GetAsTextureHost()
|
||||
{
|
||||
return mTextureHost;
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBaseNew::DestroyTextureHost()
|
||||
{
|
||||
// The third clause in the if statement checks that we are in fact done with
|
||||
// this texture. We don't want to prematurely deallocate a texture we might
|
||||
// use again or double deallocate. Deallocation will happen in
|
||||
// RemoveTextureHostDeferred.
|
||||
// Note that GetTextureHost is linear in the number of texture hosts, but as
|
||||
// long as that number is small (I expect a maximum of 6 for now) then it
|
||||
// should be ok.
|
||||
if (mTextureHost &&
|
||||
mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED &&
|
||||
!GetTextureHost(mTextureHost->GetID())) {
|
||||
MOZ_ASSERT(!(mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
|
||||
mTextureHost->DeallocateSharedData();
|
||||
}
|
||||
mTextureHost = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBaseNew::DestroyTextureHostOnWhite()
|
||||
{
|
||||
if (mTextureHostOnWhite &&
|
||||
mTextureHostOnWhite->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED &&
|
||||
!GetTextureHost(mTextureHostOnWhite->GetID())) {
|
||||
MOZ_ASSERT(!(mTextureHostOnWhite->GetFlags() & TEXTURE_DEALLOCATE_CLIENT));
|
||||
mTextureHostOnWhite->DeallocateSharedData();
|
||||
}
|
||||
mTextureHostOnWhite = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBaseNew::RemoveTextureHostDeferred(TextureHost* aTexture)
|
||||
{
|
||||
if (!(mTextureHost && mTextureHost == aTexture) &&
|
||||
!(mTextureHostOnWhite && mTextureHostOnWhite == aTexture)) {
|
||||
MOZ_ASSERT(aTexture->GetFlags() & TEXTURE_DEALLOCATE_DEFERRED);
|
||||
aTexture->DeallocateSharedData();
|
||||
}
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoLockTextureHost
|
||||
{
|
||||
public:
|
||||
AutoLockTextureHost(TextureHost* aHost)
|
||||
: mHost(aHost)
|
||||
{
|
||||
mLockSuccess = mHost ? mHost->Lock() : true;
|
||||
}
|
||||
|
||||
~AutoLockTextureHost()
|
||||
{
|
||||
if (mHost) {
|
||||
mHost->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
return mLockSuccess;
|
||||
}
|
||||
|
||||
private:
|
||||
TextureHost* mHost;
|
||||
bool mLockSuccess;
|
||||
};
|
||||
|
||||
void
|
||||
ContentHostBaseNew::Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const Filter& aFilter,
|
||||
const Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion,
|
||||
TiledLayerProperties* aLayerProperties)
|
||||
{
|
||||
NS_ASSERTION(aVisibleRegion, "Requires a visible region");
|
||||
|
||||
AutoLockTextureHost lock(mTextureHost);
|
||||
AutoLockTextureHost lockOnWhite(mTextureHostOnWhite);
|
||||
|
||||
if (!mTextureHost ||
|
||||
!lock.IsValid() ||
|
||||
!lockOnWhite.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<NewTextureSource> source = mTextureHost->GetTextureSources();
|
||||
RefPtr<NewTextureSource> sourceOnWhite = mTextureHostOnWhite
|
||||
? mTextureHostOnWhite->GetTextureSources()
|
||||
: nullptr;
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
RefPtr<TexturedEffect> effect =
|
||||
CreateTexturedEffect(source, sourceOnWhite, aFilter);
|
||||
|
||||
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 = source->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);
|
||||
}
|
||||
|
||||
TileIterator* tileIter = source->AsTileIterator();
|
||||
TileIterator* iterOnWhite = nullptr;
|
||||
if (tileIter) {
|
||||
tileIter->BeginTileIteration();
|
||||
}
|
||||
|
||||
if (mTextureHostOnWhite) {
|
||||
iterOnWhite = sourceOnWhite->AsTileIterator();
|
||||
MOZ_ASSERT(!tileIter || tileIter->GetTileCount() == iterOnWhite->GetTileCount(),
|
||||
"Tile count mismatch on component alpha texture");
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->BeginTileIteration();
|
||||
}
|
||||
}
|
||||
|
||||
bool usingTiles = (tileIter && tileIter->GetTileCount() > 1);
|
||||
do {
|
||||
if (iterOnWhite) {
|
||||
MOZ_ASSERT(iterOnWhite->GetTileRect() == tileIter->GetTileRect(),
|
||||
"component alpha textures should be the same size.");
|
||||
}
|
||||
|
||||
nsIntRect texRect = tileIter ? tileIter->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) {
|
||||
DiagnosticTypes diagnostics = DIAGNOSTIC_CONTENT | DIAGNOSTIC_BIGIMAGE;
|
||||
diagnostics |= iterOnWhite ? DIAGNOSTIC_COMPONENT_ALPHA : 0;
|
||||
GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect,
|
||||
aTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->NextTile();
|
||||
}
|
||||
} while (usingTiles && tileIter->NextTile());
|
||||
|
||||
if (tileIter) {
|
||||
tileIter->EndTileIteration();
|
||||
}
|
||||
if (iterOnWhite) {
|
||||
iterOnWhite->EndTileIteration();
|
||||
}
|
||||
|
||||
DiagnosticTypes diagnostics = DIAGNOSTIC_CONTENT;
|
||||
diagnostics |= iterOnWhite ? DIAGNOSTIC_COMPONENT_ALPHA : 0;
|
||||
GetCompositor()->DrawDiagnostics(diagnostics, *aVisibleRegion, aClipRect, aTransform);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContentHostBaseNew::UseTextureHost(TextureHost* aTexture)
|
||||
{
|
||||
if (aTexture->GetFlags() & TEXTURE_ON_WHITE) {
|
||||
DestroyTextureHost();
|
||||
mTextureHostOnWhite = aTexture;
|
||||
} else {
|
||||
DestroyTextureHostOnWhite();
|
||||
mTextureHost = aTexture;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBaseNew::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositableHost::SetCompositor(aCompositor);
|
||||
if (mTextureHost) {
|
||||
mTextureHost->SetCompositor(aCompositor);
|
||||
}
|
||||
if (mTextureHostOnWhite) {
|
||||
mTextureHostOnWhite->SetCompositor(aCompositor);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
void
|
||||
ContentHostBaseNew::Dump(FILE* aFile,
|
||||
const char* aPrefix,
|
||||
bool aDumpHtml)
|
||||
{
|
||||
if (!aDumpHtml) {
|
||||
return;
|
||||
}
|
||||
if (!aFile) {
|
||||
aFile = stderr;
|
||||
}
|
||||
fprintf(aFile, "<ul>");
|
||||
if (mTextureHost) {
|
||||
fprintf(aFile, "%s", aPrefix);
|
||||
fprintf(aFile, "<li> <a href=");
|
||||
DumpTextureHost(aFile, mTextureHost);
|
||||
fprintf(aFile, "> Front buffer </a></li> ");
|
||||
}
|
||||
if (mTextureHostOnWhite) {
|
||||
fprintf(aFile, "%s", aPrefix);
|
||||
fprintf(aFile, "<li> <a href=");
|
||||
DumpTextureHost(aFile, mTextureHostOnWhite);
|
||||
fprintf(aFile, "> Front buffer on white </a> </li> ");
|
||||
}
|
||||
fprintf(aFile, "</ul>");
|
||||
}
|
||||
#endif
|
||||
|
||||
ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo)
|
||||
: ContentHost(aTextureInfo)
|
||||
, mPaintWillResample(false)
|
||||
@ -278,6 +586,48 @@ ContentHostBase::Dump(FILE* aFile,
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
ContentHostSingleBufferedNew::UpdateThebes(const ThebesBufferData& aData,
|
||||
const nsIntRegion& aUpdated,
|
||||
const nsIntRegion& aOldValidRegionBack,
|
||||
nsIntRegion* aUpdatedRegionBack)
|
||||
{
|
||||
aUpdatedRegionBack->SetEmpty();
|
||||
|
||||
if (!mTextureHost) {
|
||||
mInitialised = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// updated is in screen coordinates. Convert it to buffer coordinates.
|
||||
nsIntRegion destRegion(aUpdated);
|
||||
destRegion.MoveBy(-aData.rect().TopLeft());
|
||||
|
||||
// Correct for rotation
|
||||
destRegion.MoveBy(aData.rotation());
|
||||
|
||||
gfxIntSize size = aData.rect().Size();
|
||||
nsIntRect destBounds = destRegion.GetBounds();
|
||||
destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0,
|
||||
(destBounds.y >= size.height) ? -size.height : 0);
|
||||
|
||||
// There's code to make sure that updated regions don't cross rotation
|
||||
// boundaries, so assert here that this is the case
|
||||
MOZ_ASSERT((destBounds.x % size.width) + destBounds.width <= size.width,
|
||||
"updated region lies across rotation boundaries!");
|
||||
MOZ_ASSERT((destBounds.y % size.height) + destBounds.height <= size.height,
|
||||
"updated region lies across rotation boundaries!");
|
||||
|
||||
mTextureHost->Updated(&destRegion);
|
||||
if (mTextureHostOnWhite) {
|
||||
mTextureHostOnWhite->Updated(&destRegion);
|
||||
}
|
||||
mInitialised = true;
|
||||
|
||||
mBufferRect = aData.rect();
|
||||
mBufferRotation = aData.rotation();
|
||||
}
|
||||
|
||||
ContentHostSingleBuffered::~ContentHostSingleBuffered()
|
||||
{
|
||||
DestroyTextures();
|
||||
@ -375,6 +725,43 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
||||
mBufferRotation = aData.rotation();
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostDoubleBufferedNew::UpdateThebes(const ThebesBufferData& aData,
|
||||
const nsIntRegion& aUpdated,
|
||||
const nsIntRegion& aOldValidRegionBack,
|
||||
nsIntRegion* aUpdatedRegionBack)
|
||||
{
|
||||
if (!mTextureHost) {
|
||||
mInitialised = false;
|
||||
|
||||
*aUpdatedRegionBack = aUpdated;
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't need to calculate an update region because we assume that if we
|
||||
// are using double buffering then we have render-to-texture and thus no
|
||||
// upload to do.
|
||||
mTextureHost->Updated();
|
||||
if (mTextureHostOnWhite) {
|
||||
mTextureHostOnWhite->Updated();
|
||||
}
|
||||
mInitialised = true;
|
||||
|
||||
mBufferRect = aData.rect();
|
||||
mBufferRotation = aData.rotation();
|
||||
|
||||
*aUpdatedRegionBack = aUpdated;
|
||||
|
||||
// Save the current valid region of our front buffer, because if
|
||||
// we're double buffering, it's going to be the valid region for the
|
||||
// next back buffer sent back to the renderer.
|
||||
//
|
||||
// NB: we rely here on the fact that mValidRegion is initialized to
|
||||
// empty, and that the first time Swap() is called we don't have a
|
||||
// valid front buffer that we're going to return to content.
|
||||
mValidRegionForNextBackBuffer = aOldValidRegionBack;
|
||||
}
|
||||
|
||||
ContentHostDoubleBuffered::~ContentHostDoubleBuffered()
|
||||
{
|
||||
DestroyTextures();
|
||||
@ -756,6 +1143,27 @@ ContentHostIncremental::TextureUpdateRequest::Execute(ContentHostIncremental* aH
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostBaseNew::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
aTo += aPrefix;
|
||||
aTo += nsPrintfCString("ContentHostSingleBuffered (0x%p)", this);
|
||||
|
||||
AppendToString(aTo, mBufferRect, " [buffer-rect=", "]");
|
||||
AppendToString(aTo, mBufferRotation, " [buffer-rotation=", "]");
|
||||
if (PaintWillResample()) {
|
||||
aTo += " [paint-will-resample]";
|
||||
}
|
||||
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
|
||||
if (mTextureHost) {
|
||||
aTo += "\n";
|
||||
mTextureHost->PrintInfo(aTo, pfx.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentHostSingleBuffered::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
@ -833,6 +1241,22 @@ ContentHostDoubleBuffered::Dump(FILE* aFile,
|
||||
}
|
||||
#endif
|
||||
|
||||
LayerRenderState
|
||||
ContentHostBaseNew::GetRenderState()
|
||||
{
|
||||
if (!mTextureHost) {
|
||||
return LayerRenderState();
|
||||
}
|
||||
|
||||
LayerRenderState result = mTextureHost->GetRenderState();
|
||||
|
||||
if (mBufferRotation != nsIntPoint()) {
|
||||
result.mFlags |= LAYER_RENDER_STATE_BUFFER_ROTATION;
|
||||
}
|
||||
result.SetOffset(GetOriginOffset());
|
||||
return result;
|
||||
}
|
||||
|
||||
LayerRenderState
|
||||
ContentHostBase::GetRenderState()
|
||||
{
|
||||
@ -846,6 +1270,16 @@ ContentHostBase::GetRenderState()
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
already_AddRefed<gfxImageSurface>
|
||||
ContentHostBaseNew::GetAsSurface()
|
||||
{
|
||||
if (!mTextureHost) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mTextureHost->GetAsSurface();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxImageSurface>
|
||||
ContentHostBase::GetAsSurface()
|
||||
{
|
||||
|
@ -84,6 +84,65 @@ protected:
|
||||
* It is the responsibility of the ContentHost to destroy its resources when
|
||||
* they are recreated or the ContentHost dies.
|
||||
*/
|
||||
class ContentHostBaseNew : public ContentHost
|
||||
{
|
||||
public:
|
||||
typedef RotatedContentBuffer::ContentType ContentType;
|
||||
typedef RotatedContentBuffer::PaintState PaintState;
|
||||
|
||||
ContentHostBaseNew(const TextureInfo& aTextureInfo);
|
||||
virtual ~ContentHostBaseNew();
|
||||
|
||||
virtual void Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform,
|
||||
const gfx::Filter& aFilter,
|
||||
const gfx::Rect& aClipRect,
|
||||
const nsIntRegion* aVisibleRegion = nullptr,
|
||||
TiledLayerProperties* aLayerProperties = nullptr);
|
||||
|
||||
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
|
||||
|
||||
virtual void Dump(FILE* aFile=nullptr,
|
||||
const char* aPrefix="",
|
||||
bool aDumpHtml=false) MOZ_OVERRIDE;
|
||||
#endif
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
|
||||
|
||||
virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RemoveTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
|
||||
|
||||
protected:
|
||||
virtual nsIntPoint GetOriginOffset()
|
||||
{
|
||||
return mBufferRect.TopLeft() - mBufferRotation;
|
||||
}
|
||||
|
||||
bool PaintWillResample() { return mPaintWillResample; }
|
||||
|
||||
// These must be called before forgetting mTextureHost or mTextureHostOnWhite
|
||||
void DestroyTextureHost();
|
||||
void DestroyTextureHostOnWhite();
|
||||
|
||||
nsIntRect mBufferRect;
|
||||
nsIntPoint mBufferRotation;
|
||||
RefPtr<TextureHost> mTextureHost;
|
||||
RefPtr<TextureHost> mTextureHostOnWhite;
|
||||
bool mPaintWillResample;
|
||||
bool mInitialised;
|
||||
};
|
||||
class ContentHostBase : public ContentHost
|
||||
{
|
||||
public:
|
||||
@ -155,8 +214,30 @@ protected:
|
||||
};
|
||||
|
||||
/**
|
||||
* Double buffering is implemented by swapping the front and back DeprecatedTextureHosts.
|
||||
* Double buffering is implemented by swapping the front and back TextureHosts.
|
||||
* We assume that whenever we use double buffering, then we have
|
||||
* render-to-texture and thus no texture upload to do.
|
||||
*/
|
||||
class ContentHostDoubleBufferedNew : public ContentHostBaseNew
|
||||
{
|
||||
public:
|
||||
ContentHostDoubleBufferedNew(const TextureInfo& aTextureInfo)
|
||||
: ContentHostBaseNew(aTextureInfo)
|
||||
{}
|
||||
|
||||
virtual ~ContentHostDoubleBufferedNew() {}
|
||||
|
||||
virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_DOUBLE; }
|
||||
|
||||
virtual void UpdateThebes(const ThebesBufferData& aData,
|
||||
const nsIntRegion& aUpdated,
|
||||
const nsIntRegion& aOldValidRegionBack,
|
||||
nsIntRegion* aUpdatedRegionBack);
|
||||
|
||||
protected:
|
||||
nsIntRegion mValidRegionForNextBackBuffer;
|
||||
};
|
||||
|
||||
class ContentHostDoubleBuffered : public ContentHostBase
|
||||
{
|
||||
public:
|
||||
@ -201,6 +282,22 @@ protected:
|
||||
* Single buffered, therefore we must synchronously upload the image from the
|
||||
* DeprecatedTextureHost in the layers transaction (i.e., in UpdateThebes).
|
||||
*/
|
||||
class ContentHostSingleBufferedNew : public ContentHostBaseNew
|
||||
{
|
||||
public:
|
||||
ContentHostSingleBufferedNew(const TextureInfo& aTextureInfo)
|
||||
: ContentHostBaseNew(aTextureInfo)
|
||||
{}
|
||||
virtual ~ContentHostSingleBufferedNew() {}
|
||||
|
||||
virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_SINGLE; }
|
||||
|
||||
virtual void UpdateThebes(const ThebesBufferData& aData,
|
||||
const nsIntRegion& aUpdated,
|
||||
const nsIntRegion& aOldValidRegionBack,
|
||||
nsIntRegion* aUpdatedRegionBack);
|
||||
};
|
||||
|
||||
class ContentHostSingleBuffered : public ContentHostBase
|
||||
{
|
||||
public:
|
||||
|
@ -271,7 +271,11 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
|
||||
TextureFlags flags = texture->GetFlags();
|
||||
|
||||
if (!(flags & TEXTURE_DEALLOCATE_CLIENT)) {
|
||||
if (flags & TEXTURE_DEALLOCATE_DEFERRED) {
|
||||
MOZ_ASSERT(!(flags & TEXTURE_DEALLOCATE_CLIENT),
|
||||
"textures should not be marked for deferred removal and client-side removal");
|
||||
compositable->RemoveTextureHostDeferred(texture);
|
||||
} else if (!(flags & TEXTURE_DEALLOCATE_CLIENT)) {
|
||||
texture->DeallocateSharedData();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user