Bug 1465590 - Clean up code for copying between an old tile buffer and a new one. r?nical
Another cleanup patch.
MozReview-Commit-ID: Ak0TTcbFePt
--- a/gfx/layers/client/SingleTiledContentClient.cpp
+++ b/gfx/layers/client/SingleTiledContentClient.cpp
@@ -192,78 +192,31 @@ ClientSingleTiledLayerBuffer::PaintThebe
// If the old frontbuffer was discarded then attempt to copy what we
// can from it to the new backbuffer.
if (discardedFrontBuffer) {
nsIntRegion copyableRegion;
copyableRegion.And(aNewValidRegion, discardedValidRegion);
copyableRegion.SubOut(aDirtyRegion);
- if (!copyableRegion.IsEmpty()) {
- OpenMode asyncFlags = asyncPaint ? OpenMode::OPEN_ASYNC
- : OpenMode::OPEN_NONE;
-
- TextureClientAutoLock frontLock(discardedFrontBuffer,
- OpenMode::OPEN_READ | asyncFlags);
- Maybe<TextureClientAutoLock> frontOnWhiteLock;
- if (discardedFrontBufferOnWhite && backBufferOnWhite) {
- frontOnWhiteLock.emplace(discardedFrontBufferOnWhite, OpenMode::OPEN_READ | asyncFlags);
- }
-
- // Copy to both backBuffer and backBufferOnWhite if required, or copy to neither.
- if (frontLock.Succeeded() && (!frontOnWhiteLock || frontOnWhiteLock->Succeeded())) {
- RefPtr<gfx::DrawTarget> frontBuffer = discardedFrontBuffer->BorrowDrawTarget();
-
- if (frontBuffer) {
- for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
- const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
- const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
-
- auto copy = CapturedTiledPaintState::Copy{
- frontBuffer, dt, rect, dest
- };
- if (asyncPaint) {
- paintCopies.push_back(copy);
- } else {
- copy.CopyBuffer();
- }
- }
+ if (!mTile.CopyFromBuffer(discardedFrontBuffer,
+ discardedFrontBufferOnWhite,
+ discardedValidRegion.GetBounds().TopLeft(),
+ mTilingOrigin,
+ copyableRegion,
+ aFlags,
+ &paintCopies)) {
+ gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
+ } else {
+ TILING_LOG("TILING %p: Region copied from discarded frontbuffer %s\n", &mPaintedLayer, Stringify(copyableRegion).c_str());
- if (frontOnWhiteLock) {
- RefPtr<gfx::DrawTarget> frontBufferOnWhite = discardedFrontBufferOnWhite->BorrowDrawTarget();
-
- if (frontBufferOnWhite) {
- for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
- const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
- const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
-
- auto copy = CapturedTiledPaintState::Copy{
- frontBufferOnWhite, dtOnWhite, rect, dest
- };
- if (asyncPaint) {
- paintCopies.push_back(copy);
- } else {
- copy.CopyBuffer();
- }
- }
- } else {
- gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
- }
- }
- } else {
- gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
- }
-
- TILING_LOG("TILING %p: Region copied from discarded frontbuffer %s\n", &mPaintedLayer, Stringify(copyableRegion).c_str());
-
- // We don't need to repaint valid content that was just copied.
- paintRegion.SubOut(copyableRegion);
- copyableRegion.MoveBy(-mTilingOrigin);
- tileDirtyRegion.SubOut(copyableRegion);
- }
+ // We don't need to repaint valid content that was just copied.
+ paintRegion.SubOut(copyableRegion);
+ copyableRegion.MoveBy(-mTilingOrigin);
+ tileDirtyRegion.SubOut(copyableRegion);
}
}
if (mode != SurfaceMode::SURFACE_OPAQUE) {
auto clear = CapturedTiledPaintState::Clear{
dt,
dtOnWhite,
tileDirtyRegion,
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -579,16 +579,69 @@ TileClient::DiscardBackBuffer()
if (mBackBuffer) {
DiscardTexture(mBackBuffer, mAllocator);
mBackBuffer.Set(this, nullptr);
DiscardTexture(mBackBufferOnWhite, mAllocator);
mBackBufferOnWhite = nullptr;
}
}
+bool
+TileClient::CopyFromBuffer(RefPtr<TextureClient> aBuffer,
+ RefPtr<TextureClient> aBufferOnWhite,
+ nsIntPoint aBufferOrigin,
+ nsIntPoint aTileOrigin,
+ const nsIntRegion& aRegion,
+ TilePaintFlags aFlags,
+ std::vector<CapturedTiledPaintState::Copy>* aCopies)
+{
+ if (aRegion.IsEmpty()) {
+ return true;
+ }
+
+ bool asyncPaint = !!(aFlags & TilePaintFlags::Async);
+ auto CopyBuffer = [&aRegion, asyncPaint, &aCopies] (auto aSrc, auto aSrcOrigin, auto aDest, auto aDestOrigin) {
+ MOZ_ASSERT(aDest->IsLocked());
+
+ OpenMode asyncFlags = asyncPaint ? OpenMode::OPEN_ASYNC
+ : OpenMode::OPEN_NONE;
+ TextureClientAutoLock lock(aSrc, OpenMode::OPEN_READ | asyncFlags);
+ if (!lock.Succeeded()) {
+ return false;
+ }
+
+ RefPtr<gfx::DrawTarget> srcTarget = aSrc->BorrowDrawTarget();
+ RefPtr<gfx::DrawTarget> destTarget = aDest->BorrowDrawTarget();
+ if (!srcTarget || !destTarget) {
+ return false;
+ }
+
+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
+ const gfx::IntRect src = iter.Get() - aSrcOrigin;
+ const gfx::IntPoint dest = iter.Get().TopLeft() - aDestOrigin;
+
+ auto copy = CapturedTiledPaintState::Copy{
+ srcTarget, destTarget, src, dest
+ };
+
+ if (asyncPaint) {
+ aCopies->push_back(copy);
+ } else {
+ copy.CopyBuffer();
+ }
+ }
+ return true;
+ };
+
+ return CopyBuffer(aBuffer, aBufferOrigin, mBackBuffer, aTileOrigin) &&
+ (!aBufferOnWhite ||
+ !mBackBufferOnWhite ||
+ CopyBuffer(aBufferOnWhite, aBufferOrigin, mBackBufferOnWhite, aTileOrigin));
+}
+
static already_AddRefed<TextureClient>
CreateBackBufferTexture(TextureClient* aCurrentTexture,
CompositableClient& aCompositable,
TextureClientAllocator* aAllocator)
{
if (aCurrentTexture) {
// Our current back-buffer is still locked by the compositor. This can occur
// when the client is producing faster than the compositor can consume. In
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -135,16 +135,28 @@ struct TileClient
RefPtr<TextureClient>* aTextureClientOnWhite,
std::vector<CapturedTiledPaintState::Copy>* aCopies,
std::vector<RefPtr<TextureClient>>* aClients);
void DiscardFrontBuffer();
void DiscardBackBuffer();
+ /*
+ * Copy aRegion from aBuffer and aBufferOnWhite positioned at aBufferOrigin
+ * into ourselves assuming we are positioned at aTileOrigin.
+ */
+ bool CopyFromBuffer(RefPtr<TextureClient> aBuffer,
+ RefPtr<TextureClient> aBufferOnWhite,
+ nsIntPoint aBufferOrigin,
+ nsIntPoint aTileOrigin,
+ const nsIntRegion& aRegion,
+ TilePaintFlags aFlags,
+ std::vector<CapturedTiledPaintState::Copy>* aCopies);
+
/* We wrap the back buffer in a class that disallows assignment
* so that we can track when ever it changes so that we can update
* the expiry tracker for expiring the back buffers */
class PrivateProtector {
public:
void Set(TileClient * container, RefPtr<TextureClient>);
void Set(TileClient * container, TextureClient*);
// Implicitly convert to TextureClient* because we can't chain
@@ -163,18 +175,20 @@ struct TileClient
bool mWasPlaceholder;
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
TimeStamp mLastUpdate;
#endif
nsIntRegion mInvalidFront;
nsIntRegion mInvalidBack;
nsExpirationState mExpirationState;
private:
- // Copies dirty pixels from the front buffer into the back buffer,
- // and records the copied region in aAddPaintedRegion.
+ /*
+ * Copies dirty pixels from the front buffer into the back buffer,
+ * and records the copied region in aAddPaintedRegion.
+ */
void ValidateBackBufferFromFront(const nsIntRegion &aDirtyRegion,
const nsIntRegion& aVisibleRegion,
nsIntRegion& aAddPaintedRegion,
TilePaintFlags aFlags,
std::vector<CapturedTiledPaintState::Copy>* aCopies,
std::vector<RefPtr<TextureClient>>* aClients);
};