mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 2 changesets (bug 1150549) for OSX asserts.
Backed out changeset ef2faa9a0845 (bug 1150549) Backed out changeset b35c88257a9c (bug 1150549) CLOSED TREE
This commit is contained in:
parent
5dbf351278
commit
106bfc1dbf
@ -94,9 +94,7 @@ class TiledLayerBuffer
|
||||
{
|
||||
public:
|
||||
TiledLayerBuffer()
|
||||
: mFirstTileX(0)
|
||||
, mFirstTileY(0)
|
||||
, mRetainedWidth(0)
|
||||
: mRetainedWidth(0)
|
||||
, mRetainedHeight(0)
|
||||
, mResolution(1)
|
||||
, mTileSize(gfxPlatform::GetPlatform()->GetTileWidth(), gfxPlatform::GetPlatform()->GetTileHeight())
|
||||
@ -110,21 +108,13 @@ public:
|
||||
// (aTileOrigin.x, aTileOrigin.y,
|
||||
// GetScaledTileSize().width, GetScaledTileSize().height)
|
||||
// and GetValidRegion() to get the area of the tile that is valid.
|
||||
Tile& GetTile(const gfx::IntPoint& aTileOrigin);
|
||||
Tile GetTile(const nsIntPoint& aTileOrigin) const;
|
||||
|
||||
// Given a tile x, y relative to the top left of the layer, this function
|
||||
// will return the tile for
|
||||
// (x*GetScaledTileSize().width, y*GetScaledTileSize().height,
|
||||
// GetScaledTileSize().width, GetScaledTileSize().height)
|
||||
Tile& GetTile(int x, int y);
|
||||
|
||||
int TileIndex(const gfx::IntPoint& aTileOrigin) const;
|
||||
int TileIndex(int x, int y) const { return x * mRetainedHeight + y; }
|
||||
|
||||
bool HasTile(int index) const { return index >= 0 && index < (int)mRetainedTiles.Length(); }
|
||||
bool HasTile(const gfx::IntPoint& aTileOrigin) const;
|
||||
bool HasTile(int x, int y) const {
|
||||
return x >= 0 && x < mRetainedWidth && y >= 0 && y < mRetainedHeight;
|
||||
}
|
||||
Tile GetTile(int x, int y) const;
|
||||
|
||||
const gfx::IntSize& GetTileSize() const { return mTileSize; }
|
||||
|
||||
@ -165,6 +155,14 @@ public:
|
||||
// individual tile's rect in relation to the valid region.
|
||||
// Setting the resolution will invalidate the buffer.
|
||||
float GetResolution() const { return mResolution; }
|
||||
void SetResolution(float aResolution) {
|
||||
if (mResolution == aResolution) {
|
||||
return;
|
||||
}
|
||||
|
||||
Update(nsIntRegion(), nsIntRegion());
|
||||
mResolution = aResolution;
|
||||
}
|
||||
bool IsLowPrecision() const { return mResolution < 1; }
|
||||
|
||||
typedef Tile* Iterator;
|
||||
@ -180,10 +178,6 @@ protected:
|
||||
// to the implementor.
|
||||
void Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion);
|
||||
|
||||
// Return a reference to this tile in GetTile when the requested tile offset
|
||||
// does not exist.
|
||||
Tile mPlaceHolderTile;
|
||||
|
||||
nsIntRegion mValidRegion;
|
||||
nsIntRegion mPaintedRegion;
|
||||
|
||||
@ -196,8 +190,6 @@ protected:
|
||||
* tiles is scaled by mResolution.
|
||||
*/
|
||||
nsTArray<Tile> mRetainedTiles;
|
||||
int mFirstTileX;
|
||||
int mFirstTileY;
|
||||
int mRetainedWidth; // in tiles
|
||||
int mRetainedHeight; // in tiles
|
||||
float mResolution;
|
||||
@ -257,39 +249,24 @@ static inline int floor_div(int a, int b)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> bool
|
||||
TiledLayerBuffer<Derived, Tile>::HasTile(const gfx::IntPoint& aTileOrigin) const {
|
||||
gfx::IntSize scaledTileSize = GetScaledTileSize();
|
||||
return HasTile(floor_div(aTileOrigin.x, scaledTileSize.width) - mFirstTileX,
|
||||
floor_div(aTileOrigin.y, scaledTileSize.height) - mFirstTileY);
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> Tile&
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(const nsIntPoint& aTileOrigin)
|
||||
{
|
||||
if (HasTile(aTileOrigin)) {
|
||||
return mRetainedTiles[TileIndex(aTileOrigin)];
|
||||
}
|
||||
return mPlaceHolderTile;
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> int
|
||||
TiledLayerBuffer<Derived, Tile>::TileIndex(const gfx::IntPoint& aTileOrigin) const
|
||||
template<typename Derived, typename Tile> Tile
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(const nsIntPoint& aTileOrigin) const
|
||||
{
|
||||
// TODO Cache firstTileOriginX/firstTileOriginY
|
||||
// Find the tile x/y of the first tile and the target tile relative to the (0, 0)
|
||||
// origin, the difference is the tile x/y relative to the start of the tile buffer.
|
||||
gfx::IntSize scaledTileSize = GetScaledTileSize();
|
||||
return TileIndex(floor_div(aTileOrigin.x, scaledTileSize.width) - mFirstTileX,
|
||||
floor_div(aTileOrigin.y, scaledTileSize.height) - mFirstTileY);
|
||||
int firstTileX = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width);
|
||||
int firstTileY = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height);
|
||||
return GetTile(floor_div(aTileOrigin.x, scaledTileSize.width) - firstTileX,
|
||||
floor_div(aTileOrigin.y, scaledTileSize.height) - firstTileY);
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> Tile&
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(int x, int y)
|
||||
template<typename Derived, typename Tile> Tile
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(int x, int y) const
|
||||
{
|
||||
if (HasTile(x, y)) {
|
||||
return mRetainedTiles[TileIndex(x, y)];
|
||||
}
|
||||
return mPlaceHolderTile;
|
||||
int index = x * mRetainedHeight + y;
|
||||
return mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile());
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> void
|
||||
@ -305,15 +282,15 @@ TiledLayerBuffer<Derived, Tile>::Dump(std::stringstream& aStream,
|
||||
|
||||
for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) {
|
||||
int32_t tileStartY = GetTileStart(y, scaledTileSize.height);
|
||||
nsIntPoint tileOrigin = nsIntPoint(RoundDownToTileEdge(x, scaledTileSize.width),
|
||||
RoundDownToTileEdge(y, scaledTileSize.height));
|
||||
Tile& tileTexture = GetTile(tileOrigin);
|
||||
Tile tileTexture =
|
||||
GetTile(nsIntPoint(RoundDownToTileEdge(x, scaledTileSize.width),
|
||||
RoundDownToTileEdge(y, scaledTileSize.height)));
|
||||
int32_t h = scaledTileSize.height - tileStartY;
|
||||
|
||||
aStream << "\n" << aPrefix << "Tile (x=" <<
|
||||
RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" <<
|
||||
RoundDownToTileEdge(y, scaledTileSize.height) << "): ";
|
||||
if (!tileTexture.IsPlaceholderTile()) {
|
||||
if (tileTexture != AsDerived().GetPlaceholderTile()) {
|
||||
tileTexture.DumpTexture(aStream);
|
||||
} else {
|
||||
aStream << "empty tile";
|
||||
@ -620,10 +597,6 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& newValidRegion,
|
||||
|
||||
mRetainedTiles = newRetainedTiles;
|
||||
mValidRegion = newValidRegion;
|
||||
|
||||
mFirstTileX = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width);
|
||||
mFirstTileY = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height);
|
||||
|
||||
mPaintedRegion.Or(mPaintedRegion, aPaintRegion);
|
||||
}
|
||||
|
||||
|
@ -374,7 +374,7 @@ int32_t
|
||||
gfxMemorySharedReadLock::ReadUnlock()
|
||||
{
|
||||
int32_t readCount = PR_ATOMIC_DECREMENT(&mReadCount);
|
||||
MOZ_ASSERT(readCount >= 0);
|
||||
NS_ASSERTION(readCount >= 0, "ReadUnlock called without ReadLock.");
|
||||
|
||||
return readCount;
|
||||
}
|
||||
@ -424,7 +424,7 @@ gfxShmSharedReadLock::ReadUnlock() {
|
||||
}
|
||||
ShmReadLockInfo* info = GetShmReadLockInfoPtr();
|
||||
int32_t readCount = PR_ATOMIC_DECREMENT(&info->readCount);
|
||||
MOZ_ASSERT(readCount >= 0);
|
||||
NS_ASSERTION(readCount >= 0, "ReadUnlock called without a ReadLock.");
|
||||
if (readCount <= 0) {
|
||||
mAllocator->FreeShmemSection(mShmemSection);
|
||||
}
|
||||
@ -520,7 +520,6 @@ TileClient::TileClient(const TileClient& o)
|
||||
mBackLock = o.mBackLock;
|
||||
mFrontLock = o.mFrontLock;
|
||||
mCompositableClient = o.mCompositableClient;
|
||||
mUpdateRect = o.mUpdateRect;
|
||||
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
|
||||
mLastUpdate = o.mLastUpdate;
|
||||
#endif
|
||||
@ -540,7 +539,6 @@ TileClient::operator=(const TileClient& o)
|
||||
mBackLock = o.mBackLock;
|
||||
mFrontLock = o.mFrontLock;
|
||||
mCompositableClient = o.mCompositableClient;
|
||||
mUpdateRect = o.mUpdateRect;
|
||||
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
|
||||
mLastUpdate = o.mLastUpdate;
|
||||
#endif
|
||||
@ -611,8 +609,6 @@ CopyFrontToBack(TextureClient* aFront,
|
||||
|
||||
gfx::IntPoint rectToCopyTopLeft = aRectToCopy.TopLeft();
|
||||
aFront->CopyToTextureClient(aBack, &aRectToCopy, &rectToCopyTopLeft);
|
||||
|
||||
aFront->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -709,9 +705,9 @@ TileClient::DiscardBackBuffer()
|
||||
mManager->ReportClientLost(*mBackBufferOnWhite);
|
||||
}
|
||||
} else {
|
||||
mManager->ReturnTextureClientDeferred(*mBackBuffer);
|
||||
mManager->ReturnTextureClient(*mBackBuffer);
|
||||
if (mBackBufferOnWhite) {
|
||||
mManager->ReturnTextureClientDeferred(*mBackBufferOnWhite);
|
||||
mManager->ReturnTextureClient(*mBackBufferOnWhite);
|
||||
}
|
||||
}
|
||||
mBackLock->ReadUnlock();
|
||||
@ -820,17 +816,23 @@ TileClient::GetTileDescriptor()
|
||||
if (mFrontLock->GetType() == gfxSharedReadLock::TYPE_MEMORY) {
|
||||
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
|
||||
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
|
||||
mUpdateRect,
|
||||
TileLock(uintptr_t(mFrontLock.get())));
|
||||
} else {
|
||||
gfxShmSharedReadLock *lock = static_cast<gfxShmSharedReadLock*>(mFrontLock.get());
|
||||
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
|
||||
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
|
||||
mUpdateRect,
|
||||
TileLock(lock->GetShmemSection()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientTiledLayerBuffer::ReadUnlock() {
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
if (mRetainedTiles[i].IsPlaceholderTile()) continue;
|
||||
mRetainedTiles[i].ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientTiledLayerBuffer::ReadLock() {
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
@ -871,12 +873,9 @@ ClientTiledLayerBuffer::GetSurfaceDescriptorTiles()
|
||||
tileDesc = mRetainedTiles[i].GetTileDescriptor();
|
||||
}
|
||||
tiles.AppendElement(tileDesc);
|
||||
mRetainedTiles[i].mUpdateRect = IntRect();
|
||||
}
|
||||
return SurfaceDescriptorTiles(mValidRegion, mPaintedRegion,
|
||||
tiles,
|
||||
mFirstTileX, mFirstTileY,
|
||||
mRetainedWidth, mRetainedHeight,
|
||||
tiles, mRetainedWidth, mRetainedHeight,
|
||||
mResolution, mFrameResolution.xScale,
|
||||
mFrameResolution.yScale);
|
||||
}
|
||||
@ -1137,9 +1136,6 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
|
||||
&createdTextureClient, extraPainted,
|
||||
&backBufferOnWhite);
|
||||
|
||||
aTile.mUpdateRect = offsetScaledDirtyRegion.GetBounds();
|
||||
aTile.mUpdateRect = aTile.mUpdateRect.Union(extraPainted.GetBounds());
|
||||
|
||||
extraPainted.MoveBy(aTileOrigin);
|
||||
extraPainted.And(extraPainted, mNewValidRegion);
|
||||
mPaintedRegion.Or(mPaintedRegion, extraPainted);
|
||||
|
@ -270,7 +270,6 @@ struct TileClient
|
||||
RefPtr<gfxSharedReadLock> mBackLock;
|
||||
RefPtr<gfxSharedReadLock> mFrontLock;
|
||||
RefPtr<ClientLayerManager> mManager;
|
||||
gfx::IntRect mUpdateRect;
|
||||
CompositableClient* mCompositableClient;
|
||||
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
|
||||
TimeStamp mLastUpdate;
|
||||
@ -419,6 +418,8 @@ public:
|
||||
LayerManager::DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
void ReadUnlock();
|
||||
|
||||
void ReadLock();
|
||||
|
||||
void Release();
|
||||
@ -444,15 +445,6 @@ public:
|
||||
|
||||
SurfaceDescriptorTiles GetSurfaceDescriptorTiles();
|
||||
|
||||
void SetResolution(float aResolution) {
|
||||
if (mResolution == aResolution) {
|
||||
return;
|
||||
}
|
||||
|
||||
Update(nsIntRegion(), nsIntRegion());
|
||||
mResolution = aResolution;
|
||||
}
|
||||
|
||||
protected:
|
||||
TileClient ValidateTile(TileClient aTile,
|
||||
const nsIntPoint& aTileRect,
|
||||
|
@ -326,7 +326,6 @@ protected:
|
||||
virtual ~TextureHost();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Factory method.
|
||||
*/
|
||||
|
@ -29,28 +29,198 @@ class Layer;
|
||||
|
||||
TiledLayerBufferComposite::TiledLayerBufferComposite()
|
||||
: mFrameResolution()
|
||||
, mHasDoubleBufferedTiles(false)
|
||||
, mIsValid(false)
|
||||
{}
|
||||
|
||||
TiledLayerBufferComposite::~TiledLayerBufferComposite()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
TiledLayerBufferComposite::RecycleCallback(TextureHost* textureHost, void* aClosure)
|
||||
{
|
||||
textureHost->CompositorRecycle();
|
||||
}
|
||||
|
||||
TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator,
|
||||
const SurfaceDescriptorTiles& aDescriptor,
|
||||
const nsIntRegion& aOldPaintedRegion,
|
||||
Compositor* aCompositor)
|
||||
{
|
||||
mIsValid = true;
|
||||
mHasDoubleBufferedTiles = false;
|
||||
mValidRegion = aDescriptor.validRegion();
|
||||
mPaintedRegion = aDescriptor.paintedRegion();
|
||||
mRetainedWidth = aDescriptor.retainedWidth();
|
||||
mRetainedHeight = aDescriptor.retainedHeight();
|
||||
mResolution = aDescriptor.resolution();
|
||||
mFrameResolution = CSSToParentLayerScale2D(aDescriptor.frameXResolution(),
|
||||
aDescriptor.frameYResolution());
|
||||
if (mResolution == 0 || IsNaN(mResolution)) {
|
||||
// There are divisions by mResolution so this protects the compositor process
|
||||
// against malicious content processes and fuzzing.
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Combine any valid content that wasn't already uploaded
|
||||
nsIntRegion oldPaintedRegion(aOldPaintedRegion);
|
||||
oldPaintedRegion.And(oldPaintedRegion, mValidRegion);
|
||||
mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion);
|
||||
|
||||
bool isSameProcess = aAllocator->IsSameProcess();
|
||||
|
||||
const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles();
|
||||
for(size_t i = 0; i < tiles.Length(); i++) {
|
||||
CompositableTextureHostRef texture;
|
||||
CompositableTextureHostRef textureOnWhite;
|
||||
const TileDescriptor& tileDesc = tiles[i];
|
||||
switch (tileDesc.type()) {
|
||||
case TileDescriptor::TTexturedTileDescriptor : {
|
||||
texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent());
|
||||
MaybeTexture onWhite = tileDesc.get_TexturedTileDescriptor().textureOnWhite();
|
||||
if (onWhite.type() == MaybeTexture::TPTextureParent) {
|
||||
textureOnWhite = TextureHost::AsTextureHost(onWhite.get_PTextureParent());
|
||||
}
|
||||
const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock();
|
||||
nsRefPtr<gfxSharedReadLock> sharedLock;
|
||||
if (ipcLock.type() == TileLock::TShmemSection) {
|
||||
sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection());
|
||||
} else {
|
||||
if (!isSameProcess) {
|
||||
// Trying to use a memory based lock instead of a shmem based one in
|
||||
// the cross-process case is a bad security violation.
|
||||
NS_ERROR("A client process may be trying to peek at the host's address space!");
|
||||
// This tells the TiledContentHost that deserialization failed so that
|
||||
// it can propagate the error.
|
||||
mIsValid = false;
|
||||
|
||||
mRetainedTiles.Clear();
|
||||
return;
|
||||
}
|
||||
sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t());
|
||||
if (sharedLock) {
|
||||
// The corresponding AddRef is in TiledClient::GetTileDescriptor
|
||||
sharedLock.get()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
CompositableTextureSourceRef textureSource;
|
||||
CompositableTextureSourceRef textureSourceOnWhite;
|
||||
if (texture) {
|
||||
texture->SetCompositor(aCompositor);
|
||||
texture->PrepareTextureSource(textureSource);
|
||||
}
|
||||
if (textureOnWhite) {
|
||||
textureOnWhite->SetCompositor(aCompositor);
|
||||
textureOnWhite->PrepareTextureSource(textureSourceOnWhite);
|
||||
}
|
||||
mRetainedTiles.AppendElement(TileHost(sharedLock,
|
||||
texture.get(),
|
||||
textureOnWhite.get(),
|
||||
textureSource.get(),
|
||||
textureSourceOnWhite.get()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_WARNING("Unrecognised tile descriptor type");
|
||||
// Fall through
|
||||
case TileDescriptor::TPlaceholderTileDescriptor :
|
||||
mRetainedTiles.AppendElement(GetPlaceholderTile());
|
||||
break;
|
||||
}
|
||||
if (texture && !texture->HasInternalBuffer()) {
|
||||
mHasDoubleBufferedTiles = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::ReadUnlock()
|
||||
{
|
||||
if (!IsValid()) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
mRetainedTiles[i].ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::ReleaseTextureHosts()
|
||||
{
|
||||
if (!IsValid()) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
mRetainedTiles[i].mTextureHost = nullptr;
|
||||
mRetainedTiles[i].mTextureHostOnWhite = nullptr;
|
||||
mRetainedTiles[i].mTextureSource = nullptr;
|
||||
mRetainedTiles[i].mTextureSourceOnWhite = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::Upload()
|
||||
{
|
||||
if(!IsValid()) {
|
||||
return;
|
||||
}
|
||||
// The TextureClients were created with the TextureFlags::IMMEDIATE_UPLOAD flag,
|
||||
// so calling Update on all the texture hosts will perform the texture upload.
|
||||
Update(mValidRegion, mPaintedRegion);
|
||||
ClearPaintedRegion();
|
||||
}
|
||||
|
||||
TileHost
|
||||
TiledLayerBufferComposite::ValidateTile(TileHost aTile,
|
||||
const IntPoint& aTileOrigin,
|
||||
const nsIntRegion& aDirtyRect)
|
||||
{
|
||||
if (aTile.IsPlaceholderTile()) {
|
||||
NS_WARNING("Placeholder tile encountered in painted region");
|
||||
return aTile;
|
||||
}
|
||||
|
||||
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
|
||||
printf_stderr("Upload tile %i, %i\n", aTileOrigin.x, aTileOrigin.y);
|
||||
long start = PR_IntervalNow();
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(aTile.mTextureHost->GetFlags() & TextureFlags::IMMEDIATE_UPLOAD);
|
||||
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
MOZ_ASSERT(!aTile.mTextureHostOnWhite);
|
||||
// We possibly upload the entire texture contents here. This is a purposeful
|
||||
// decision, as sub-image upload can often be slow and/or unreliable, but
|
||||
// we may want to reevaluate this in the future.
|
||||
// For !HasInternalBuffer() textures, this is likely a no-op.
|
||||
aTile.mTextureHost->Updated(nullptr);
|
||||
#else
|
||||
nsIntRegion tileUpdated = aDirtyRect.MovedBy(-aTileOrigin);
|
||||
aTile.mTextureHost->Updated(&tileUpdated);
|
||||
if (aTile.mTextureHostOnWhite) {
|
||||
aTile.mTextureHostOnWhite->Updated(&tileUpdated);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
|
||||
if (PR_IntervalNow() - start > 1) {
|
||||
printf_stderr("Tile Time to upload %i\n", PR_IntervalNow() - start);
|
||||
}
|
||||
#endif
|
||||
return aTile;
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor);
|
||||
for (TileHost& tile : mRetainedTiles) {
|
||||
if (tile.IsPlaceholderTile()) continue;
|
||||
tile.mTextureHost->SetCompositor(aCompositor);
|
||||
if (tile.mTextureHostOnWhite) {
|
||||
tile.mTextureHostOnWhite->SetCompositor(aCompositor);
|
||||
if (!IsValid()) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
if (mRetainedTiles[i].IsPlaceholderTile()) continue;
|
||||
mRetainedTiles[i].mTextureHost->SetCompositor(aCompositor);
|
||||
if (mRetainedTiles[i].mTextureHostOnWhite) {
|
||||
mRetainedTiles[i].mTextureHostOnWhite->SetCompositor(aCompositor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,6 +229,10 @@ TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
|
||||
: ContentHost(aTextureInfo)
|
||||
, mTiledBuffer(TiledLayerBufferComposite())
|
||||
, mLowPrecisionTiledBuffer(TiledLayerBufferComposite())
|
||||
, mOldTiledBuffer(TiledLayerBufferComposite())
|
||||
, mOldLowPrecisionTiledBuffer(TiledLayerBufferComposite())
|
||||
, mPendingUpload(false)
|
||||
, mPendingLowPrecisionUpload(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TiledContentHost);
|
||||
}
|
||||
@ -66,6 +240,28 @@ TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
|
||||
TiledContentHost::~TiledContentHost()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TiledContentHost);
|
||||
|
||||
// Unlock any buffers that may still be locked. If we have a pending upload,
|
||||
// we will need to unlock the buffer that was about to be uploaded.
|
||||
// If a buffer that was being composited had double-buffered tiles, we will
|
||||
// need to unlock that buffer too.
|
||||
if (mPendingUpload) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
if (mOldTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldTiledBuffer.ReadUnlock();
|
||||
}
|
||||
} else if (mTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
}
|
||||
|
||||
if (mPendingLowPrecisionUpload) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
if (mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldLowPrecisionTiledBuffer.ReadUnlock();
|
||||
}
|
||||
} else if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -81,10 +277,33 @@ TiledContentHost::Detach(Layer* aLayer,
|
||||
AttachFlags aFlags /* = NO_FLAGS */)
|
||||
{
|
||||
if (!mKeepAttached || aLayer == mLayer || aFlags & FORCE_DETACH) {
|
||||
// Clear the TiledLayerBuffers, which will take care of releasing the
|
||||
// copy-on-write locks.
|
||||
mTiledBuffer.Clear();
|
||||
mLowPrecisionTiledBuffer.Clear();
|
||||
|
||||
// Unlock any buffers that may still be locked. If we have a pending upload,
|
||||
// we will need to unlock the buffer that was about to be uploaded.
|
||||
// If a buffer that was being composited had double-buffered tiles, we will
|
||||
// need to unlock that buffer too.
|
||||
if (mPendingUpload) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
if (mOldTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldTiledBuffer.ReadUnlock();
|
||||
}
|
||||
} else if (mTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
}
|
||||
|
||||
if (mPendingLowPrecisionUpload) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
if (mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldLowPrecisionTiledBuffer.ReadUnlock();
|
||||
}
|
||||
} else if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
}
|
||||
|
||||
mTiledBuffer = TiledLayerBufferComposite();
|
||||
mLowPrecisionTiledBuffer = TiledLayerBufferComposite();
|
||||
mOldTiledBuffer = TiledLayerBufferComposite();
|
||||
mOldLowPrecisionTiledBuffer = TiledLayerBufferComposite();
|
||||
}
|
||||
CompositableHost::Detach(aLayer,aFlags);
|
||||
}
|
||||
@ -94,268 +313,60 @@ TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator,
|
||||
const SurfaceDescriptorTiles& aTiledDescriptor)
|
||||
{
|
||||
if (aTiledDescriptor.resolution() < 1) {
|
||||
if (!mLowPrecisionTiledBuffer.UseTiles(aTiledDescriptor, mCompositor, aAllocator)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!mTiledBuffer.UseTiles(aTiledDescriptor, mCompositor, aAllocator)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
UseTileTexture(CompositableTextureHostRef& aTexture,
|
||||
CompositableTextureSourceRef& aTextureSource,
|
||||
const IntRect& aUpdateRect,
|
||||
TextureHost* aNewTexture,
|
||||
Compositor* aCompositor)
|
||||
{
|
||||
aTexture = aNewTexture;
|
||||
if (aTexture) {
|
||||
if (aCompositor) {
|
||||
aTexture->SetCompositor(aCompositor);
|
||||
}
|
||||
|
||||
if (!aUpdateRect.IsEmpty()) {
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
aTexture->Updated(nullptr);
|
||||
#else
|
||||
// We possibly upload the entire texture contents here. This is a purposeful
|
||||
// decision, as sub-image upload can often be slow and/or unreliable, but
|
||||
// we may want to reevaluate this in the future.
|
||||
// For !HasInternalBuffer() textures, this is likely a no-op.
|
||||
nsIntRegion region = aUpdateRect;
|
||||
aTexture->Updated(®ion);
|
||||
#endif
|
||||
}
|
||||
aTexture->PrepareTextureSource(aTextureSource);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GetCopyOnWriteLock(const TileLock& ipcLock, TileHost& aTile, ISurfaceAllocator* aAllocator) {
|
||||
MOZ_ASSERT(aAllocator);
|
||||
|
||||
nsRefPtr<gfxSharedReadLock> sharedLock;
|
||||
if (ipcLock.type() == TileLock::TShmemSection) {
|
||||
sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection());
|
||||
} else {
|
||||
if (!aAllocator->IsSameProcess()) {
|
||||
// Trying to use a memory based lock instead of a shmem based one in
|
||||
// the cross-process case is a bad security violation.
|
||||
NS_ERROR("A client process may be trying to peek at the host's address space!");
|
||||
return false;
|
||||
}
|
||||
sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t());
|
||||
if (sharedLock) {
|
||||
// The corresponding AddRef is in TiledClient::GetTileDescriptor
|
||||
sharedLock.get()->Release();
|
||||
}
|
||||
}
|
||||
aTile.mSharedLock = sharedLock;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
||||
Compositor* aCompositor,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
if (mResolution != aTiles.resolution()) {
|
||||
Clear();
|
||||
}
|
||||
MOZ_ASSERT(aAllocator);
|
||||
MOZ_ASSERT(aCompositor);
|
||||
if (!aAllocator || !aCompositor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aTiles.resolution() == 0 || IsNaN(aTiles.resolution())) {
|
||||
// There are divisions by mResolution so this protects the compositor process
|
||||
// against malicious content processes and fuzzing.
|
||||
return false;
|
||||
}
|
||||
|
||||
int newFirstTileX = aTiles.firstTileX();
|
||||
int newFirstTileY = aTiles.firstTileY();
|
||||
int oldFirstTileX = mFirstTileX;
|
||||
int oldFirstTileY = mFirstTileY;
|
||||
int newRetainedWidth = aTiles.retainedWidth();
|
||||
int newRetainedHeight = aTiles.retainedHeight();
|
||||
int oldRetainedWidth = mRetainedWidth;
|
||||
int oldRetainedHeight = mRetainedHeight;
|
||||
|
||||
const InfallibleTArray<TileDescriptor>& tileDescriptors = aTiles.tiles();
|
||||
|
||||
nsTArray<TileHost> oldTiles;
|
||||
mRetainedTiles.SwapElements(oldTiles);
|
||||
mRetainedTiles.SetLength(tileDescriptors.Length());
|
||||
|
||||
// Step 1, we need to unlock tiles that don't have an internal buffer after the
|
||||
// next frame where they are replaced.
|
||||
// Since we are about to replace the tiles' textures, we need to keep their locks
|
||||
// somewhere (in mPreviousSharedLock) until we composite the layer.
|
||||
for (size_t i = 0; i < oldTiles.Length(); ++i) {
|
||||
TileHost& tile = oldTiles[i];
|
||||
// It can happen that we still have a previous lock at this point,
|
||||
// if we changed a tile's front buffer (causing mSharedLock to
|
||||
// go into mPreviousSharedLock, and then did not composite that tile until
|
||||
// the next transaction, either because the tile is offscreen or because the
|
||||
// two transactions happened with no composition in between (over-production).
|
||||
tile.ReadUnlockPrevious();
|
||||
|
||||
if (tile.mTextureHost && !tile.mTextureHost->HasInternalBuffer()) {
|
||||
MOZ_ASSERT(tile.mSharedLock);
|
||||
int tileX = i % oldRetainedWidth + oldFirstTileX;
|
||||
int tileY = i / oldRetainedWidth + oldFirstTileY;
|
||||
|
||||
if (tileX >= newFirstTileX && tileY >= newFirstTileY &&
|
||||
tileX < (newFirstTileX + newRetainedWidth) &&
|
||||
tileY < (newFirstTileY + newRetainedHeight)) {
|
||||
// This tile still exist in the new buffer
|
||||
tile.mPreviousSharedLock = tile.mSharedLock;
|
||||
tile.mSharedLock = nullptr;
|
||||
} else {
|
||||
// This tile does not exist anymore in the new buffer because the size
|
||||
// changed.
|
||||
tile.ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
// By now we should not have anything in mSharedLock.
|
||||
MOZ_ASSERT(!tile.mSharedLock);
|
||||
}
|
||||
|
||||
// Step 2, move the tiles in mRetainedTiles at places that correspond to where
|
||||
// they should be with the new retained with and height rather than the
|
||||
// old one.
|
||||
for (size_t i = 0; i < tileDescriptors.Length(); i++) {
|
||||
int tileX = i % newRetainedWidth + newFirstTileX;
|
||||
int tileY = i / newRetainedWidth + newFirstTileY;
|
||||
|
||||
// First, get the already existing tiles to the right place in the array,
|
||||
// and use placeholders where there was no tiles.
|
||||
if (tileX < oldFirstTileX || tileY < oldFirstTileY ||
|
||||
tileX >= (oldFirstTileX + oldRetainedWidth) ||
|
||||
tileY >= (oldFirstTileY + oldRetainedHeight)) {
|
||||
mRetainedTiles[i] = GetPlaceholderTile();
|
||||
if (mPendingLowPrecisionUpload) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
} else {
|
||||
mRetainedTiles[i] = oldTiles[(tileY - oldFirstTileY) * oldRetainedWidth +
|
||||
(tileX - oldFirstTileX)];
|
||||
// If we hit this assertion it means we probably mixed something up in the
|
||||
// logic that tries to reuse tiles on the compositor side. It is most likely
|
||||
// benign, but we are missing some fast paths so let's try to make it not happen.
|
||||
MOZ_ASSERT(tileX == mRetainedTiles[i].x && tileY == mRetainedTiles[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
// It is important to remove the duplicated reference to tiles before calling
|
||||
// TextureHost::PrepareTextureSource, etc. because depending on the textures
|
||||
// ref counts we may or may not get some of the fast paths.
|
||||
oldTiles.Clear();
|
||||
|
||||
// Step 3, handle the texture updates and release the copy-on-write locks.
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
const TileDescriptor& tileDesc = tileDescriptors[i];
|
||||
|
||||
TileHost& tile = mRetainedTiles[i];
|
||||
|
||||
switch (tileDesc.type()) {
|
||||
case TileDescriptor::TTexturedTileDescriptor: {
|
||||
const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
|
||||
|
||||
const TileLock& ipcLock = texturedDesc.sharedLock();
|
||||
if (!GetCopyOnWriteLock(ipcLock, tile, aAllocator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<TextureHost> textureHost = TextureHost::AsTextureHost(
|
||||
texturedDesc.textureParent()
|
||||
);
|
||||
|
||||
UseTileTexture(tile.mTextureHost,
|
||||
tile.mTextureSource,
|
||||
texturedDesc.updateRect(),
|
||||
textureHost,
|
||||
aCompositor);
|
||||
|
||||
MaybeTexture onWhite = texturedDesc.textureOnWhite();
|
||||
if (onWhite.type() == MaybeTexture::TPTextureParent) {
|
||||
RefPtr<TextureHost> textureOnWhite = TextureHost::AsTextureHost(
|
||||
onWhite.get_PTextureParent()
|
||||
);
|
||||
UseTileTexture(tile.mTextureHostOnWhite,
|
||||
tile.mTextureSourceOnWhite,
|
||||
texturedDesc.updateRect(),
|
||||
textureOnWhite,
|
||||
aCompositor);
|
||||
}
|
||||
|
||||
if (textureHost->HasInternalBuffer()) {
|
||||
// Now that we did the texture upload (in UseTileTexture), we can release
|
||||
// the lock.
|
||||
tile.ReadUnlock();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_WARNING("Unrecognised tile descriptor type");
|
||||
case TileDescriptor::TPlaceholderTileDescriptor: {
|
||||
|
||||
if (tile.mTextureHost) {
|
||||
tile.mTextureHost->UnbindTextureSource();
|
||||
tile.mTextureSource = nullptr;
|
||||
}
|
||||
if (tile.mTextureHostOnWhite) {
|
||||
tile.mTextureHostOnWhite->UnbindTextureSource();
|
||||
tile.mTextureSourceOnWhite = nullptr;
|
||||
}
|
||||
// we may have a previous lock, and are about to loose our reference to it.
|
||||
// It is okay to unlock it because we just destroyed the texture source.
|
||||
tile.ReadUnlockPrevious();
|
||||
tile = GetPlaceholderTile();
|
||||
|
||||
break;
|
||||
mPendingLowPrecisionUpload = true;
|
||||
// If the old buffer has double-buffered tiles, hang onto it so we can
|
||||
// unlock it after we've composited the new buffer.
|
||||
// We only need to hang onto the locks, but not the textures.
|
||||
// Releasing the textures here can help prevent a memory spike in the
|
||||
// situation that the client starts rendering new content before we get
|
||||
// to composite the new buffer.
|
||||
if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldLowPrecisionTiledBuffer = mLowPrecisionTiledBuffer;
|
||||
mOldLowPrecisionTiledBuffer.ReleaseTextureHosts();
|
||||
}
|
||||
}
|
||||
|
||||
tile.x = i % newRetainedWidth + newFirstTileX;
|
||||
tile.y = i / newRetainedWidth + newFirstTileY;
|
||||
mLowPrecisionTiledBuffer =
|
||||
TiledLayerBufferComposite(aAllocator,
|
||||
aTiledDescriptor,
|
||||
mLowPrecisionTiledBuffer.GetPaintedRegion(),
|
||||
mCompositor);
|
||||
if (!mLowPrecisionTiledBuffer.IsValid()) {
|
||||
// Something bad happened. Stop here, return false (kills the child process),
|
||||
// and do as little work as possible on the received data as it appears
|
||||
// to be corrupted.
|
||||
mPendingLowPrecisionUpload = false;
|
||||
mPendingUpload = false;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (mPendingUpload) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
} else {
|
||||
mPendingUpload = true;
|
||||
if (mTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldTiledBuffer = mTiledBuffer;
|
||||
mOldTiledBuffer.ReleaseTextureHosts();
|
||||
}
|
||||
}
|
||||
mTiledBuffer = TiledLayerBufferComposite(aAllocator,
|
||||
aTiledDescriptor,
|
||||
mTiledBuffer.GetPaintedRegion(),
|
||||
mCompositor);
|
||||
if (!mTiledBuffer.IsValid()) {
|
||||
// Something bad happened. Stop here, return false (kills the child process),
|
||||
// and do as little work as possible on the received data as it appears
|
||||
// to be corrupted.
|
||||
mPendingLowPrecisionUpload = false;
|
||||
mPendingUpload = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mFirstTileX = newFirstTileX;
|
||||
mFirstTileY = newFirstTileY;
|
||||
mRetainedWidth = newRetainedWidth;
|
||||
mRetainedHeight = newRetainedHeight;
|
||||
mValidRegion = aTiles.validRegion();
|
||||
|
||||
mResolution = aTiles.resolution();
|
||||
mFrameResolution = CSSToParentLayerScale2D(aTiles.frameXResolution(),
|
||||
aTiles.frameYResolution());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::Clear()
|
||||
{
|
||||
for (TileHost& tile : mRetainedTiles) {
|
||||
tile.ReadUnlock();
|
||||
tile.ReadUnlockPrevious();
|
||||
}
|
||||
mRetainedTiles.Clear();
|
||||
mFirstTileX = 0;
|
||||
mFirstTileY = 0;
|
||||
mRetainedWidth = 0;
|
||||
mRetainedHeight = 0;
|
||||
mValidRegion = nsIntRegion();
|
||||
mPaintedRegion = nsIntRegion();
|
||||
mResolution = 1.0;
|
||||
}
|
||||
|
||||
void
|
||||
TiledContentHost::Composite(EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
@ -365,6 +376,25 @@ TiledContentHost::Composite(EffectChain& aEffectChain,
|
||||
const nsIntRegion* aVisibleRegion /* = nullptr */)
|
||||
{
|
||||
MOZ_ASSERT(mCompositor);
|
||||
if (mPendingUpload) {
|
||||
mTiledBuffer.SetCompositor(mCompositor);
|
||||
mTiledBuffer.Upload();
|
||||
|
||||
// For a single-buffered tiled buffer, Upload will upload the shared memory
|
||||
// surface to texture memory and we no longer need to read from them.
|
||||
if (!mTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mTiledBuffer.ReadUnlock();
|
||||
}
|
||||
}
|
||||
if (mPendingLowPrecisionUpload) {
|
||||
mLowPrecisionTiledBuffer.SetCompositor(mCompositor);
|
||||
mLowPrecisionTiledBuffer.Upload();
|
||||
|
||||
if (!mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mLowPrecisionTiledBuffer.ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce the opacity of the low-precision buffer to make it a
|
||||
// little more subtle and less jarring. In particular, text
|
||||
// rendered at low-resolution and scaled tends to look pretty
|
||||
@ -410,11 +440,24 @@ TiledContentHost::Composite(EffectChain& aEffectChain,
|
||||
aFilter, aClipRect, *renderRegion, aTransform);
|
||||
RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aFilter,
|
||||
aClipRect, *renderRegion, aTransform);
|
||||
|
||||
// Now release the old buffer if it had double-buffered tiles, as we can
|
||||
// guarantee that they're no longer on the screen (and so any locks that may
|
||||
// have been held have been released).
|
||||
if (mPendingUpload && mOldTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldTiledBuffer.ReadUnlock();
|
||||
mOldTiledBuffer = TiledLayerBufferComposite();
|
||||
}
|
||||
if (mPendingLowPrecisionUpload && mOldLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) {
|
||||
mOldLowPrecisionTiledBuffer.ReadUnlock();
|
||||
mOldLowPrecisionTiledBuffer = TiledLayerBufferComposite();
|
||||
}
|
||||
mPendingUpload = mPendingLowPrecisionUpload = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TiledContentHost::RenderTile(TileHost& aTile,
|
||||
TiledContentHost::RenderTile(const TileHost& aTile,
|
||||
const gfxRGBA* aBackgroundColor,
|
||||
EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
@ -481,7 +524,6 @@ TiledContentHost::RenderTile(TileHost& aTile,
|
||||
}
|
||||
mCompositor->DrawDiagnostics(flags,
|
||||
aScreenRegion, aClipRect, aTransform, mFlashCounter);
|
||||
aTile.ReadUnlockPrevious();
|
||||
}
|
||||
|
||||
void
|
||||
@ -549,10 +591,10 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
|
||||
h = visibleRect.y + visibleRect.height - y;
|
||||
}
|
||||
|
||||
nsIntPoint tileOrigin = nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width),
|
||||
aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height));
|
||||
TileHost& tileTexture = aLayerBuffer.GetTile(tileOrigin);
|
||||
if (!tileTexture.IsPlaceholderTile()) {
|
||||
TileHost tileTexture = aLayerBuffer.
|
||||
GetTile(IntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width),
|
||||
aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height)));
|
||||
if (tileTexture != aLayerBuffer.GetPlaceholderTile()) {
|
||||
nsIntRegion tileDrawRegion;
|
||||
tileDrawRegion.And(IntRect(x, y, w, h), aLayerBuffer.GetValidRegion());
|
||||
tileDrawRegion.And(tileDrawRegion, aVisibleRegion);
|
||||
|
@ -52,8 +52,6 @@ public:
|
||||
// essentially, this is a sentinel used to represent an invalid or blank
|
||||
// tile.
|
||||
TileHost()
|
||||
: x(-1)
|
||||
, y(-1)
|
||||
{}
|
||||
|
||||
// Constructs a TileHost from a gfxSharedReadLock and TextureHost.
|
||||
@ -67,8 +65,6 @@ public:
|
||||
, mTextureHostOnWhite(aTextureHostOnWhite)
|
||||
, mTextureSource(aSource)
|
||||
, mTextureSourceOnWhite(aSourceOnWhite)
|
||||
, x(-1)
|
||||
, y(-1)
|
||||
{}
|
||||
|
||||
TileHost(const TileHost& o) {
|
||||
@ -77,9 +73,6 @@ public:
|
||||
mTextureSource = o.mTextureSource;
|
||||
mTextureSourceOnWhite = o.mTextureSourceOnWhite;
|
||||
mSharedLock = o.mSharedLock;
|
||||
mPreviousSharedLock = o.mPreviousSharedLock;
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
}
|
||||
TileHost& operator=(const TileHost& o) {
|
||||
if (this == &o) {
|
||||
@ -90,9 +83,6 @@ public:
|
||||
mTextureSource = o.mTextureSource;
|
||||
mTextureSourceOnWhite = o.mTextureSourceOnWhite;
|
||||
mSharedLock = o.mSharedLock;
|
||||
mPreviousSharedLock = o.mPreviousSharedLock;
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -108,14 +98,6 @@ public:
|
||||
void ReadUnlock() {
|
||||
if (mSharedLock) {
|
||||
mSharedLock->ReadUnlock();
|
||||
mSharedLock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadUnlockPrevious() {
|
||||
if (mPreviousSharedLock) {
|
||||
mPreviousSharedLock->ReadUnlock();
|
||||
mPreviousSharedLock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,14 +111,10 @@ public:
|
||||
}
|
||||
|
||||
RefPtr<gfxSharedReadLock> mSharedLock;
|
||||
RefPtr<gfxSharedReadLock> mPreviousSharedLock;
|
||||
CompositableTextureHostRef mTextureHost;
|
||||
CompositableTextureHostRef mTextureHostOnWhite;
|
||||
mutable CompositableTextureSourceRef mTextureSource;
|
||||
mutable CompositableTextureSourceRef mTextureSourceOnWhite;
|
||||
// This is not strictly necessary but makes debugging whole lot easier.
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
class TiledLayerBufferComposite
|
||||
@ -145,14 +123,13 @@ class TiledLayerBufferComposite
|
||||
friend class TiledLayerBuffer<TiledLayerBufferComposite, TileHost>;
|
||||
|
||||
public:
|
||||
typedef TiledLayerBuffer<TiledLayerBufferComposite, TileHost>::Iterator Iterator;
|
||||
|
||||
TiledLayerBufferComposite();
|
||||
~TiledLayerBufferComposite();
|
||||
|
||||
bool UseTiles(const SurfaceDescriptorTiles& aTileDescriptors,
|
||||
Compositor* aCompositor,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
void Clear();
|
||||
TiledLayerBufferComposite(ISurfaceAllocator* aAllocator,
|
||||
const SurfaceDescriptorTiles& aDescriptor,
|
||||
const nsIntRegion& aOldPaintedRegion,
|
||||
Compositor* aCompositor);
|
||||
|
||||
TileHost GetPlaceholderTile() const { return TileHost(); }
|
||||
|
||||
@ -160,16 +137,43 @@ public:
|
||||
// by the sum of the resolutions of all parent layers' FrameMetrics.
|
||||
const CSSToParentLayerScale2D& GetFrameResolution() { return mFrameResolution; }
|
||||
|
||||
void ReadUnlock();
|
||||
|
||||
void ReleaseTextureHosts();
|
||||
|
||||
/**
|
||||
* This will synchronously upload any necessary texture contents, making the
|
||||
* sources immediately available for compositing. For texture hosts that
|
||||
* don't have an internal buffer, this is unlikely to actually do anything.
|
||||
*/
|
||||
void Upload();
|
||||
|
||||
void SetCompositor(Compositor* aCompositor);
|
||||
|
||||
bool HasDoubleBufferedTiles() { return mHasDoubleBufferedTiles; }
|
||||
|
||||
bool IsValid() const { return mIsValid; }
|
||||
|
||||
// Recycle callback for TextureHost.
|
||||
// Used when TiledContentClient is present in client side.
|
||||
static void RecycleCallback(TextureHost* textureHost, void* aClosure);
|
||||
|
||||
protected:
|
||||
TileHost ValidateTile(TileHost aTile,
|
||||
const gfx::IntPoint& aTileRect,
|
||||
const nsIntRegion& dirtyRect);
|
||||
|
||||
// do nothing, the desctructor in the texture host takes care of releasing resources
|
||||
void ReleaseTile(TileHost aTile) {}
|
||||
|
||||
void SwapTiles(TileHost& aTileA, TileHost& aTileB) { std::swap(aTileA, aTileB); }
|
||||
|
||||
void UnlockTile(TileHost aTile) {}
|
||||
void PostValidate(const nsIntRegion& aPaintRegion) {}
|
||||
private:
|
||||
CSSToParentLayerScale2D mFrameResolution;
|
||||
bool mHasDoubleBufferedTiles;
|
||||
bool mIsValid;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -229,10 +233,11 @@ public:
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override
|
||||
{
|
||||
MOZ_ASSERT(aCompositor);
|
||||
CompositableHost::SetCompositor(aCompositor);
|
||||
mTiledBuffer.SetCompositor(aCompositor);
|
||||
mLowPrecisionTiledBuffer.SetCompositor(aCompositor);
|
||||
mOldTiledBuffer.SetCompositor(aCompositor);
|
||||
mOldLowPrecisionTiledBuffer.SetCompositor(aCompositor);
|
||||
}
|
||||
|
||||
virtual bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator,
|
||||
@ -274,7 +279,7 @@ private:
|
||||
gfx::Matrix4x4 aTransform);
|
||||
|
||||
// Renders a single given tile.
|
||||
void RenderTile(TileHost& aTile,
|
||||
void RenderTile(const TileHost& aTile,
|
||||
const gfxRGBA* aBackgroundColor,
|
||||
EffectChain& aEffectChain,
|
||||
float aOpacity,
|
||||
@ -289,6 +294,10 @@ private:
|
||||
|
||||
TiledLayerBufferComposite mTiledBuffer;
|
||||
TiledLayerBufferComposite mLowPrecisionTiledBuffer;
|
||||
TiledLayerBufferComposite mOldTiledBuffer;
|
||||
TiledLayerBufferComposite mOldLowPrecisionTiledBuffer;
|
||||
bool mPendingUpload;
|
||||
bool mPendingLowPrecisionUpload;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -315,7 +315,6 @@ union MaybeTexture {
|
||||
struct TexturedTileDescriptor {
|
||||
PTexture texture;
|
||||
MaybeTexture textureOnWhite;
|
||||
IntRect updateRect;
|
||||
TileLock sharedLock;
|
||||
};
|
||||
|
||||
@ -331,8 +330,6 @@ struct SurfaceDescriptorTiles {
|
||||
nsIntRegion validRegion;
|
||||
nsIntRegion paintedRegion;
|
||||
TileDescriptor[] tiles;
|
||||
int firstTileX;
|
||||
int firstTileY;
|
||||
int retainedWidth;
|
||||
int retainedHeight;
|
||||
float resolution;
|
||||
|
Loading…
Reference in New Issue
Block a user