Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 516139 Details for
Bug 580531
[patch]
Patch: add paint stats to ImagesContainer
580531-gfx-paint-time.patch (text/plain), 15.48 KB, created by
Chris Pearce [:cpearce (Not reading bugmail)]
(
hide
)
Description:
Patch: add paint stats to ImagesContainer
Filename:
MIME Type:
Creator:
Chris Pearce [:cpearce (Not reading bugmail)]
Size:
15.48 KB
patch
obsolete
># HG changeset patch ># User Chris Pearce <chris@pearce.org.nz> ># Parent bafcbf08c5b8be075b260259005dfb04ec7fe217 >Bug 580531 - Record first paint time and number of images painted in ImageContainer. r=? > >diff --git a/gfx/layers/ImageLayers.h b/gfx/layers/ImageLayers.h >--- a/gfx/layers/ImageLayers.h >+++ b/gfx/layers/ImageLayers.h >@@ -34,16 +34,17 @@ > * the terms of any one of the MPL, the GPL or the LGPL. > * > * ***** END LICENSE BLOCK ***** */ > > #ifndef GFX_IMAGELAYER_H > #define GFX_IMAGELAYER_H > > #include "Layers.h" >+#include "mozilla/TimeStamp.h" > > #include "gfxPattern.h" > #include "nsThreadUtils.h" > #include "nsCoreAnimationSupport.h" > > namespace mozilla { > namespace layers { > >@@ -126,31 +127,33 @@ protected: > * (because layers can only be used on the main thread) and we want to > * be able to set the current Image from any thread, to facilitate > * video playback without involving the main thread, for example. > */ > class THEBES_API ImageContainer { > THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer) > > public: >- ImageContainer() {} >+ ImageContainer() : mPaintCount(0), mPreviousImagePainted(PR_FALSE) {} > virtual ~ImageContainer() {} > > /** > * Create an Image in one of the given formats. > * Picks the "best" format from the list and creates an Image of that > * format. > * Returns null if this backend does not support any of the formats. > */ > virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats, > PRUint32 aNumFormats) = 0; > > /** > * Set an Image as the current image to display. The Image must have > * been created by this ImageContainer. >+ * >+ * Implementations must call CurrentImageChanged() in a threadsafe manner. > * > * The Image data must not be modified after this method is called! > */ > virtual void SetCurrentImage(Image* aImage) = 0; > > /** > * Get the current Image. > * This has to add a reference since otherwise there are race conditions >@@ -206,20 +209,87 @@ public: > > /** > * Get the layer manager type this image container was created with, > * presumably its users might want to do something special if types do not > * match. > */ > virtual LayerManager::LayersBackend GetBackendType() = 0; > >+ /** >+ * Returns the time at which the currently contained image was first >+ * painted. This is reset every time a new image is set as the current >+ * image. Note this may return a null timestamp if the current image >+ * has not yet been painted. Threadsafe. >+ */ >+ virtual TimeStamp GetPaintTime() = 0; >+ >+ /** >+ * Returns the number of images which have been contained in this container >+ * and painted at least once. Threadsafe. >+ */ >+ virtual PRUint32 GetPaintCount() = 0; >+ >+ /** >+ * Notifies the container that aImage has been painted. Note we must pass >+ * in a pointer to the image that has been painted, as the current image >+ * can change while we're rendering, and in that case we don't want to >+ * record the paint time of the just painted image as the paint time of the >+ * current image. Threadsafe. >+ */ >+ virtual void NotifyPaintedImage(Image* aImage) = 0; >+ > protected: > LayerManager* mManager; > >- ImageContainer(LayerManager* aManager) : mManager(aManager) {} >+ ImageContainer(LayerManager* aManager) >+ : mManager(aManager), >+ mPaintCount(0), >+ mPreviousImagePainted(PR_FALSE) >+ {} >+ >+ // Increments mPaintCount if this is the first time aPainted has been >+ // painted, and sets mPaintTime if the painted image is the current image >+ // (aCurrent). It's up to the ImageContainer implementation to ensure this >+ // is called in a threadsafe manner. >+ void RecordPaintStats(Image* aPainted, Image* aCurrent) >+ { >+ if (aPainted == aCurrent) { >+ if (mPaintTime.IsNull()) { >+ mPaintTime = TimeStamp::Now(); >+ mPaintCount++; >+ } >+ } else if (!mPreviousImagePainted) { >+ // While we were painting this image, the current image changed. We >+ // still must count it as painted, but can't set mPaintTime, since we're >+ // no longer the current image. >+ mPaintCount++; >+ mPreviousImagePainted = PR_TRUE; >+ } >+ } >+ >+ // Performs necessary housekeeping to ensure the painted frame statistics >+ // are accurate. Must be called by SetCurrentImage() implementations in a >+ // thread safe manner. >+ void CurrentImageChanged() { >+ mPreviousImagePainted = !mPaintTime.IsNull(); >+ mPaintTime = TimeStamp(); >+ } >+ >+ // Number of contained images that have been painted at least once. It's up >+ // to the ImageContainer implementation to ensure accesses to this are >+ // threadsafe. >+ PRUint32 mPaintCount; >+ >+ // Time stamp at which the current image was first painted. It's up to the >+ // ImageContainer implementation to ensure accesses to this are threadsafe. >+ TimeStamp mPaintTime; >+ >+ // Denotes whether the previous image was painted. >+ PRBool mPreviousImagePainted; > }; > > /** > * A Layer which renders an Image. > */ > class THEBES_API ImageLayer : public Layer { > public: > /** >diff --git a/gfx/layers/basic/BasicImages.cpp b/gfx/layers/basic/BasicImages.cpp >--- a/gfx/layers/basic/BasicImages.cpp >+++ b/gfx/layers/basic/BasicImages.cpp >@@ -302,16 +302,20 @@ public: > virtual already_AddRefed<Image> GetCurrentImage(); > virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize); > virtual gfxIntSize GetCurrentSize(); > virtual PRBool SetLayerManager(LayerManager *aManager); > virtual void SetScaleHint(const gfxIntSize& aScaleHint); > void SetOffscreenFormat(gfxImageFormat aFormat) { mOffscreenFormat = aFormat; } > virtual LayerManager::LayersBackend GetBackendType() { return LayerManager::LAYERS_BASIC; } > >+ TimeStamp GetPaintTime(); >+ PRUint32 GetPaintCount(); >+ void NotifyPaintedImage(Image* aImage); >+ > protected: > Monitor mMonitor; > nsRefPtr<Image> mImage; > gfxIntSize mScaleHint; > gfxImageFormat mOffscreenFormat; > }; > > /** >@@ -340,21 +344,43 @@ BasicImageContainer::CreateImage(const I > } else if (FormatInList(aFormats, aNumFormats, Image::PLANAR_YCBCR)) { > MonitorAutoEnter mon(mMonitor); > image = new BasicPlanarYCbCrImage(mScaleHint); > static_cast<BasicPlanarYCbCrImage*>(image.get())->SetOffscreenFormat(mOffscreenFormat); > } > return image.forget(); > } > >+TimeStamp >+BasicImageContainer::GetPaintTime() >+{ >+ MonitorAutoEnter mon(mMonitor); >+ return mPaintTime; >+} >+ >+PRUint32 >+BasicImageContainer::GetPaintCount() >+{ >+ MonitorAutoEnter mon(mMonitor); >+ return mPaintCount; >+} >+ >+void >+BasicImageContainer::NotifyPaintedImage(Image* aImage) >+{ >+ MonitorAutoEnter mon(mMonitor); >+ RecordPaintStats(aImage, mImage); >+} >+ > void > BasicImageContainer::SetCurrentImage(Image* aImage) > { > MonitorAutoEnter mon(mMonitor); > mImage = aImage; >+ CurrentImageChanged(); > } > > already_AddRefed<Image> > BasicImageContainer::GetCurrentImage() > { > MonitorAutoEnter mon(mMonitor); > nsRefPtr<Image> image = mImage; > return image.forget(); >diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp >--- a/gfx/layers/basic/BasicLayers.cpp >+++ b/gfx/layers/basic/BasicLayers.cpp >@@ -728,16 +728,18 @@ BasicImageLayer::Paint(gfxContext* aCont > > already_AddRefed<gfxPattern> > BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext, > float aOpacity) > { > if (!mContainer) > return nsnull; > >+ nsRefPtr<Image> image = mContainer->GetCurrentImage(); >+ > nsRefPtr<gfxASurface> surface = mContainer->GetCurrentAsSurface(&mSize); > if (!surface) { > return nsnull; > } > > nsRefPtr<gfxPattern> pat = new gfxPattern(surface); > if (!pat) { > return nsnull; >@@ -747,17 +749,20 @@ BasicImageLayer::GetAndPaintCurrentImage > > // The visible region can extend outside the image. If we're not > // tiling, we don't want to draw into that area, so just draw within > // the image bounds. > const nsIntRect* tileSrcRect = GetTileSourceRect(); > PaintContext(pat, > tileSrcRect ? GetVisibleRegion() : nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)), > tileSrcRect, >- aOpacity, aContext); >+ aOpacity, aContext); >+ >+ GetContainer()->NotifyPaintedImage(image); >+ > return pat.forget(); > } > > /*static*/ void > BasicImageLayer::PaintContext(gfxPattern* aPattern, > const nsIntRegion& aVisible, > const nsIntRect* aTileSourceRect, > float aOpacity, >diff --git a/gfx/layers/d3d10/ImageLayerD3D10.cpp b/gfx/layers/d3d10/ImageLayerD3D10.cpp >--- a/gfx/layers/d3d10/ImageLayerD3D10.cpp >+++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp >@@ -120,18 +120,37 @@ ImageContainerD3D10::CreateImage(const I > } > return img.forget(); > } > > void > ImageContainerD3D10::SetCurrentImage(Image *aImage) > { > MutexAutoLock lock(mActiveImageLock); >+ >+ mActiveImage = aImage; >+ CurrentImageChanged(); >+} > >- mActiveImage = aImage; >+TimeStamp ImageContainerD3D10::GetPaintTime() { >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintTime; >+} >+ >+PRUint32 ImageContainerD3D10::GetPaintCount() { >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintCount; >+} >+ >+void ImageContainerD3D10::NotifyPaintedImage(Image* aImage) { >+ MutexAutoLock lock(mActiveImageLock); >+ >+ RecordPaintStats(aImage, mActiveImage); > } > > already_AddRefed<Image> > ImageContainerD3D10::GetCurrentImage() > { > MutexAutoLock lock(mActiveImageLock); > > nsRefPtr<Image> retval = mActiveImage; >@@ -349,16 +368,18 @@ ImageLayerD3D10::RenderLayer() > (float)0, > (float)yuvImage->mSize.width, > (float)yuvImage->mSize.height) > ); > } > > technique->GetPassByIndex(0)->Apply(0); > device()->Draw(4, 0); >+ >+ GetContainer()->NotifyPaintedImage(image); > } > > PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(ID3D10Device1 *aDevice) > : PlanarYCbCrImage(static_cast<ImageD3D10*>(this)) > , mDevice(aDevice) > , mHasData(PR_FALSE) > { > } >diff --git a/gfx/layers/d3d10/ImageLayerD3D10.h b/gfx/layers/d3d10/ImageLayerD3D10.h >--- a/gfx/layers/d3d10/ImageLayerD3D10.h >+++ b/gfx/layers/d3d10/ImageLayerD3D10.h >@@ -65,16 +65,20 @@ public: > > virtual PRBool SetLayerManager(LayerManager *aManager); > > virtual LayerManager::LayersBackend GetBackendType() { return LayerManager::LAYERS_D3D10; } > > ID3D10Device1 *device() { return mDevice; } > void SetDevice(ID3D10Device1 *aDevice) { mDevice = aDevice; } > >+ TimeStamp GetPaintTime(); >+ PRUint32 GetPaintCount(); >+ void NotifyPaintedImage(Image* aImage); >+ > private: > typedef mozilla::Mutex Mutex; > > nsRefPtr<Image> mActiveImage; > nsRefPtr<ID3D10Device1> mDevice; > > Mutex mActiveImageLock; > }; >diff --git a/gfx/layers/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp >--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp >+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp >@@ -151,22 +151,47 @@ ImageContainerD3D9::CreateImage(const Im > if (aFormats[0] == Image::PLANAR_YCBCR) { > img = new PlanarYCbCrImageD3D9(); > } else if (aFormats[0] == Image::CAIRO_SURFACE) { > img = new CairoImageD3D9(mDevice); > } > return img.forget(); > } > >+TimeStamp >+ImageContainerD3D9::GetPaintTime() >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintTime; >+} >+ >+PRUint32 >+ImageContainerD3D9::GetPaintCount() >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintCount; >+} >+ >+void >+ImageContainerD3D9::NotifyPaintedImage(Image* aImage) >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ RecordPaintStats(aImage, mActiveImage); >+} >+ > void > ImageContainerD3D9::SetCurrentImage(Image *aImage) > { > MutexAutoLock lock(mActiveImageLock); > > mActiveImage = aImage; >+ CurrentImageChanged(); > } > > already_AddRefed<Image> > ImageContainerD3D9::GetCurrentImage() > { > MutexAutoLock lock(mActiveImageLock); > > nsRefPtr<Image> retval = mActiveImage; >@@ -370,16 +395,18 @@ ImageLayerD3D9::RenderLayer() > } > device()->SetTexture(0, cairoImage->GetOrCreateTexture()); > device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); > if (mFilter == gfxPattern::FILTER_NEAREST) { > device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); > device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); > } > } >+ >+ GetContainer()->NotifyPaintedImage(image); > } > > PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9() > : PlanarYCbCrImage(static_cast<ImageD3D9*>(this)) > , mHasData(PR_FALSE) > { > } > >diff --git a/gfx/layers/d3d9/ImageLayerD3D9.h b/gfx/layers/d3d9/ImageLayerD3D9.h >--- a/gfx/layers/d3d9/ImageLayerD3D9.h >+++ b/gfx/layers/d3d9/ImageLayerD3D9.h >@@ -65,16 +65,20 @@ public: > > virtual PRBool SetLayerManager(LayerManager *aManager); > > virtual LayerManager::LayersBackend GetBackendType() { return LayerManager::LAYERS_D3D9; } > > IDirect3DDevice9 *device() { return mDevice; } > void SetDevice(IDirect3DDevice9 *aDevice) { mDevice = aDevice; } > >+ TimeStamp GetPaintTime(); >+ PRUint32 GetPaintCount(); >+ void NotifyPaintedImage(Image* aImage); >+ > private: > typedef mozilla::Mutex Mutex; > > nsRefPtr<Image> mActiveImage; > > nsRefPtr<IDirect3DDevice9> mDevice; > > Mutex mActiveImageLock; >diff --git a/gfx/layers/opengl/ImageLayerOGL.cpp b/gfx/layers/opengl/ImageLayerOGL.cpp >--- a/gfx/layers/opengl/ImageLayerOGL.cpp >+++ b/gfx/layers/opengl/ImageLayerOGL.cpp >@@ -223,26 +223,51 @@ ImageContainerOGL::CreateImage(const Ima > else if (aFormats[0] == Image::MAC_IO_SURFACE) { > img = new MacIOSurfaceImageOGL(static_cast<LayerManagerOGL*>(mManager)); > } > #endif > > return img.forget(); > } > >+TimeStamp >+ImageContainerOGL::GetPaintTime() >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintTime; >+} >+ >+PRUint32 >+ImageContainerOGL::GetPaintCount() >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ return mPaintCount; >+} >+ >+void >+ImageContainerOGL::NotifyPaintedImage(Image* aImage) >+{ >+ MutexAutoLock lock(mActiveImageLock); >+ >+ RecordPaintStats(aImage, mActiveImage); >+} >+ > void > ImageContainerOGL::SetCurrentImage(Image *aImage) > { > nsRefPtr<Image> oldImage; > > { > MutexAutoLock lock(mActiveImageLock); > > oldImage = mActiveImage.forget(); > mActiveImage = aImage; >+ CurrentImageChanged(); > } > > // Make sure oldImage is released outside the lock, so it can take our > // lock in RecycleBuffer > } > > already_AddRefed<Image> > ImageContainerOGL::GetCurrentImage() >@@ -496,16 +521,17 @@ ImageLayerOGL::RenderLayer(int, > program->SetLayerOpacity(GetEffectiveOpacity()); > program->SetRenderOffset(aOffset); > program->SetTextureUnit(0); > > mOGLManager->BindAndDrawQuad(program); > gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0); > #endif > } >+ GetContainer()->NotifyPaintedImage(image); > } > > static void > InitTexture(GLContext* aGL, GLuint aTexture, GLenum aFormat, const gfxIntSize& aSize) > { > aGL->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture); > aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR); > aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR); >diff --git a/gfx/layers/opengl/ImageLayerOGL.h b/gfx/layers/opengl/ImageLayerOGL.h >--- a/gfx/layers/opengl/ImageLayerOGL.h >+++ b/gfx/layers/opengl/ImageLayerOGL.h >@@ -153,16 +153,20 @@ public: > virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize); > > virtual gfxIntSize GetCurrentSize(); > > virtual PRBool SetLayerManager(LayerManager *aManager); > > virtual LayerManager::LayersBackend GetBackendType() { return LayerManager::LAYERS_OPENGL; } > >+ TimeStamp GetPaintTime(); >+ PRUint32 GetPaintCount(); >+ void NotifyPaintedImage(Image* aImage); >+ > private: > typedef mozilla::Mutex Mutex; > > nsRefPtr<RecycleBin> mRecycleBin; > > // This protects mActiveImage > Mutex mActiveImageLock; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
|
Review
Attachments on
bug 580531
:
458935
|
458937
|
465555
|
465556
|
468611
|
468612
|
468617
|
495942
|
496253
|
496254
|
496258
|
514667
|
515506
|
515799
|
516082
|
516083
|
516105
|
516139
|
516418
|
516419