From 948f5853f154e121eff2b52cc894fb35c805c899 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 18 Dec 2014 13:32:45 -0500 Subject: [PATCH] Bug 1112476 - Support dumping texture data on the ClientLayerManager. r=mstange --HG-- extra : rebase_source : 5d5cf3372993ca4af78e12236fc64836a56eff4b --- gfx/layers/TiledLayerBuffer.h | 34 ++++++++++++++++ gfx/layers/client/ClientPaintedLayer.cpp | 11 +++++ gfx/layers/client/ClientPaintedLayer.h | 4 +- gfx/layers/client/ClientTiledPaintedLayer.cpp | 12 ++++++ gfx/layers/client/ClientTiledPaintedLayer.h | 2 + gfx/layers/client/CompositableClient.cpp | 14 +++++++ gfx/layers/client/CompositableClient.h | 1 + gfx/layers/client/ContentClient.cpp | 23 +++++++++++ gfx/layers/client/ContentClient.h | 9 +++++ gfx/layers/client/TextureClient.cpp | 40 +++++++++++++++++++ gfx/layers/client/TextureClient.h | 6 +++ gfx/layers/client/TiledContentClient.cpp | 22 ++++++++++ gfx/layers/client/TiledContentClient.h | 11 +++++ gfx/layers/composite/TiledContentHost.cpp | 33 +-------------- gfx/layers/composite/TiledContentHost.h | 5 +++ .../opengl/MacIOSurfaceTextureClientOGL.cpp | 6 +++ .../opengl/MacIOSurfaceTextureClientOGL.h | 2 + 17 files changed, 202 insertions(+), 33 deletions(-) diff --git a/gfx/layers/TiledLayerBuffer.h b/gfx/layers/TiledLayerBuffer.h index 7bf1f918cba..9b1a42e9c4c 100644 --- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -176,6 +176,8 @@ public: Iterator TilesBegin() { return mRetainedTiles.Elements(); } Iterator TilesEnd() { return mRetainedTiles.Elements() + mRetainedTiles.Length(); } + void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml); + protected: // The implementor should call Update() to change // the new valid region. This implementation will call @@ -307,6 +309,38 @@ TiledLayerBuffer::RemoveTile(int x, int y, Tile& aRemovedTile) return false; } +template void +TiledLayerBuffer::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + nsIntRect visibleRect = GetValidRegion().GetBounds(); + gfx::IntSize scaledTileSize = GetScaledTileSize(); + for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { + int32_t tileStartX = GetTileStart(x, scaledTileSize.width); + int32_t w = scaledTileSize.width - tileStartX; + + for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { + int32_t tileStartY = GetTileStart(y, scaledTileSize.height); + 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 != AsDerived().GetPlaceholderTile()) { + tileTexture.DumpTexture(aStream); + } else { + aStream << "empty tile"; + } + y += h; + } + x += w; + } +} + template void TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion) diff --git a/gfx/layers/client/ClientPaintedLayer.cpp b/gfx/layers/client/ClientPaintedLayer.cpp index f9c980eee53..7096f5f3be2 100644 --- a/gfx/layers/client/ClientPaintedLayer.cpp +++ b/gfx/layers/client/ClientPaintedLayer.cpp @@ -176,6 +176,17 @@ ClientLayerManager::CreatePaintedLayerWithHint(PaintedLayerCreationHint aHint) } } +void +ClientPaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + PaintedLayer::PrintInfo(aStream, aPrefix); + if (mContentClient) { + aStream << "\n"; + nsAutoCString pfx(aPrefix); + pfx += " "; + mContentClient->PrintInfo(aStream, pfx.get()); + } +} } } diff --git a/gfx/layers/client/ClientPaintedLayer.h b/gfx/layers/client/ClientPaintedLayer.h index 449ee3dfbcc..288c33740e2 100644 --- a/gfx/layers/client/ClientPaintedLayer.h +++ b/gfx/layers/client/ClientPaintedLayer.h @@ -108,7 +108,9 @@ public: protected: void PaintThebes(); - + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE; + void DestroyBackBuffer() { mContentClient = nullptr; diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index c71b769f227..5452d8e8139 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -470,5 +470,17 @@ ClientTiledPaintedLayer::RenderLayer() EndPaint(); } +void +ClientTiledPaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + PaintedLayer::PrintInfo(aStream, aPrefix); + if (mContentClient) { + aStream << "\n"; + nsAutoCString pfx(aPrefix); + pfx += " "; + mContentClient->PrintInfo(aStream, pfx.get()); + } +} + } // mozilla } // layers diff --git a/gfx/layers/client/ClientTiledPaintedLayer.h b/gfx/layers/client/ClientTiledPaintedLayer.h index 6648a5e4fbe..37b3674305e 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.h +++ b/gfx/layers/client/ClientTiledPaintedLayer.h @@ -47,6 +47,8 @@ public: protected: ~ClientTiledPaintedLayer(); + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE; + public: // Override name to distinguish it from ClientPaintedLayer in layer dumps virtual const char* Name() const { return "TiledPaintedLayer"; } diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 94ee01bd0ff..66fef80f0e8 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -16,6 +16,7 @@ #include "mozilla/layers/TextureD3D11.h" #include "mozilla/layers/TextureD3D9.h" #endif +#include "gfxUtils.h" namespace mozilla { namespace layers { @@ -258,5 +259,18 @@ CompositableClient::GetTextureClientRecycler() return mTextureClientRecycler; } +void +CompositableClient::DumpTextureClient(std::stringstream& aStream, TextureClient* aTexture) +{ + if (!aTexture) { + return; + } + RefPtr dSurf = aTexture->GetAsSurface(); + if (!dSurf) { + return; + } + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 0c51e3f726b..63c8f457f47 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -232,6 +232,7 @@ public: TextureClientRecycleAllocator* GetTextureClientRecycler(); + static void DumpTextureClient(std::stringstream& aStream, TextureClient* aTexture); protected: CompositableChild* mCompositableChild; CompositableForwarder* mForwarder; diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 0c7c9f94126..62298d81ffe 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -118,6 +118,20 @@ ContentClient::EndPaint(nsTArray* aReadbackUpdates) OnTransaction(); } +void +ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("ContentClient (0x%p)", this).get(); + + if (profiler_feature_active("displaylistdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + Dump(aStream, pfx.get(), false); + } +} + // We pass a null pointer for the ContentClient Forwarder argument, which means // this client will not have a ContentHost on the other side. ContentClientBasic::ContentClientBasic() @@ -401,6 +415,15 @@ ContentClientRemoteBuffer::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) mFrontAndBackBufferDiffer = true; } +void +ContentClientRemoteBuffer::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableClient::DumpTextureClient(aStream, mTextureClient); +} + void ContentClientDoubleBuffered::DestroyFrontBuffer() { diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index bd597e6843c..dec05a882d1 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -89,6 +89,11 @@ public: virtual ~ContentClient() {} + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false) {}; virtual void Clear() = 0; virtual RotatedContentBuffer::PaintState BeginPaintBuffer(PaintedLayer* aLayer, @@ -208,6 +213,10 @@ public: mTextureClientOnWhite = nullptr; } + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false) MOZ_OVERRIDE; + virtual PaintState BeginPaintBuffer(PaintedLayer* aLayer, uint32_t aFlags) MOZ_OVERRIDE { diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index fdb22befca6..793ef351411 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -22,6 +22,10 @@ #include "mozilla/layers/PTextureChild.h" #include "SharedSurface.h" #include "GLContext.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning +#include "nsPrintfCString.h" // for nsPrintfCString +#include "LayersLogging.h" // for AppendToString +#include "gfxUtils.h" // for gfxUtils::GetAsLZ4Base64Str #ifdef XP_WIN #include "mozilla/layers/TextureD3D9.h" @@ -572,6 +576,28 @@ TextureClient::ShouldDeallocateInDestructor() const return !IsSharedWithCompositor() || (GetFlags() & TextureFlags::DEALLOCATE_CLIENT); } +void +TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("TextureClient (0x%p)", this).get(); + AppendToString(aStream, GetSize(), " [size=", "]"); + AppendToString(aStream, GetFormat(), " [format=", "]"); + AppendToString(aStream, mFlags, " [flags=", "]"); + +#ifdef MOZ_DUMP_PAINTING + if (gfxPrefs::LayersDumpTexture() || profiler_feature_active("layersdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + aStream << "\n" << pfx.get() << "Surface: "; + RefPtr dSurf = GetAsSurface(); + if (dSurf) { + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); + } + } +#endif +} bool ShmemTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) { @@ -866,6 +892,20 @@ BufferTextureClient::GetLockedData() const return serializer.GetData(); } +TemporaryRef +BufferTextureClient::GetAsSurface() +{ + ImageDataSerializer serializer(GetBuffer(), GetBufferSize()); + MOZ_ASSERT(serializer.IsValid()); + + RefPtr wrappingSurf = + gfx::Factory::CreateWrappingDataSourceSurface(serializer.GetData(), + serializer.GetStride(), + serializer.GetSize(), + serializer.GetFormat()); + return gfx::CreateDataSourceSurfaceByCloning(wrappingSurf); +} + //////////////////////////////////////////////////////////////////////// // SharedSurfaceTextureClient diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 4ac737d53ec..bb520c8c217 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -281,6 +281,10 @@ public: return gfx::SurfaceFormat::UNKNOWN; } + virtual TemporaryRef GetAsSurface() { return nullptr; } + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + /** * Copies a rectangle from this texture client to a position in aTarget. * It is assumed that the necessary locks are in place; so this should at @@ -584,6 +588,8 @@ public: gfx::IntSize aCbCrSize, StereoMode aStereoMode) MOZ_OVERRIDE; + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } // XXX - Bug 908196 - Make Allocate(uint32_t) and GetBufferSize() protected. diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 3af08478489..2795f2d7a5d 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1598,5 +1598,27 @@ ClientTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion, return isBufferChanged; } +void +TiledContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("TiledContentClient (0x%p)", this).get(); + + if (profiler_feature_active("displaylistdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + Dump(aStream, pfx.get(), false); + } +} + +void +TiledContentClient::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml); +} + } } diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index 4a68dd973ce..303fca780f3 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -218,6 +218,11 @@ struct TileClient */ void Flip(); + void DumpTexture(std::stringstream& aStream) { + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableClient::DumpTextureClient(aStream, mFrontBuffer); + } + /** * Returns an unlocked TextureClient that can be used for writing new * data to the tile. This may flip the front-buffer to the back-buffer if @@ -527,6 +532,12 @@ protected: mLowPrecisionTiledBuffer.Release(); } + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false); + public: virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE { diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 9b53ef21b57..164a61284b0 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -642,38 +642,7 @@ TiledContentHost::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml) { - nsIntRect visibleRect = mTiledBuffer.GetValidRegion().GetBounds(); - gfx::IntSize scaledTileSize = mTiledBuffer.GetScaledTileSize(); - for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { - int32_t tileStartX = mTiledBuffer.GetTileStart(x, scaledTileSize.width); - int32_t w = scaledTileSize.width - tileStartX; - if (x + w > visibleRect.x + visibleRect.width) { - w = visibleRect.x + visibleRect.width - x; - } - - for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { - int32_t tileStartY = mTiledBuffer.GetTileStart(y, scaledTileSize.height); - TileHost tileTexture = mTiledBuffer. - GetTile(nsIntPoint(mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width), - mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); - int32_t h = scaledTileSize.height - tileStartY; - if (y + h > visibleRect.y + visibleRect.height) { - h = visibleRect.y + visibleRect.height - y; - } - - aStream << "\n" << aPrefix << "Tile (x=" << - mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" << - mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height) << "): "; - if (tileTexture != mTiledBuffer.GetPlaceholderTile()) { - DumpTextureHost(aStream, tileTexture.mTextureHost); - // TODO We should combine the OnWhite/OnBlack here an just output a single image. - } else { - aStream << "empty tile"; - } - y += h; - } - x += w; - } + mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml); } } // namespace diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index 229d07e355f..c7f0d495cf5 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -106,6 +106,11 @@ public: } } + void DumpTexture(std::stringstream& aStream) { + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableHost::DumpTextureHost(aStream, mTextureHost); + } + RefPtr mSharedLock; CompositableTextureHostRef mTextureHost; CompositableTextureHostRef mTextureHostOnWhite; diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp index 1b784f44d76..cdf9601f1bd 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp @@ -65,5 +65,11 @@ MacIOSurfaceTextureClientOGL::GetSize() const return gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight()); } +TemporaryRef +MacIOSurfaceTextureClientOGL::GetAsSurface() +{ + RefPtr surf = mSurface->GetAsSurface(); + return surf->GetDataSurface(); +} } } diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h index b7353464337..e423ffc9599 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h @@ -36,6 +36,8 @@ public: virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; } + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; + // This TextureClient should not be used in a context where we use CreateSimilar // (ex. component alpha) because the underlying texture data is always created by // an external producer.