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 516419 Details for
Bug 580531
[patch]
Patch: add paint stats to ImagesContainer
580531-gfx-paint-time.patch (text/plain), 10.42 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:
10.42 KB
patch
obsolete
># HG changeset patch ># User Chris Pearce <chris@pearce.org.nz> ># Parent 76ae47618819550ce83a1b81e378d79f0380838d >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 >@@ -39,16 +39,17 @@ > #define GFX_IMAGELAYER_H > > #include "Layers.h" > > #include "gfxPattern.h" > #include "nsThreadUtils.h" > #include "nsCoreAnimationSupport.h" > #include "mozilla/Monitor.h" >+#include "mozilla/TimeStamp.h" > > namespace mozilla { > namespace layers { > > enum StereoMode { > STEREO_MODE_MONO, > STEREO_MODE_LEFT_RIGHT, > STEREO_MODE_RIGHT_LEFT, >@@ -127,32 +128,40 @@ 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() : mMonitor("ImageContainer") {} >+ >+ ImageContainer() : >+ mMonitor("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() while holding mMonitor. >+ * > * 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 > * where the current image is destroyed before the caller can add >@@ -207,22 +216,90 @@ 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. Can be called from any thread. >+ */ >+ TimeStamp GetPaintTime() { >+ MonitorAutoEnter mon(mMonitor); >+ return mPaintTime; >+ } >+ >+ /** >+ * Returns the number of images which have been contained in this container >+ * and painted at least once. Can be called from any thread. >+ */ >+ PRUint32 GetPaintCount() { >+ MonitorAutoEnter mon(mMonitor); >+ return mPaintCount; >+ } >+ >+ /** >+ * Increments mPaintCount if this is the first time aPainted has been >+ * painted, and sets mPaintTime if the painted image is the current image. >+ * current image. Can be called from any thread. >+ */ >+ void NotifyPaintedImage(Image* aPainted) { >+ MonitorAutoEnter mon(mMonitor); >+ nsRefPtr<Image> current = GetCurrentImage(); >+ if (aPainted == current) { >+ 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; >+ } >+ } >+ > protected: > typedef mozilla::Monitor Monitor; > LayerManager* mManager; > Monitor mMonitor; > >- ImageContainer(LayerManager* aManager) : mManager(aManager), mMonitor("ImageContainer") {} >+ ImageContainer(LayerManager* aManager) : >+ mManager(aManager), >+ mMonitor("ImageContainer"), >+ mPaintCount(0), >+ mPreviousImagePainted(PR_FALSE) >+ {} >+ >+ // Performs necessary housekeeping to ensure the painted frame statistics >+ // are accurate. Must be called by SetCurrentImage() implementations with >+ // mMonitor held. >+ void CurrentImageChanged() { >+ mMonitor.AssertCurrentThreadIn(); >+ 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. >+ PRPackedBool 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 >@@ -344,16 +344,17 @@ BasicImageContainer::CreateImage(const I > return image.forget(); > } > > 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 >@@ -119,16 +119,17 @@ ImageContainerD3D10::CreateImage(const I > } > > void > ImageContainerD3D10::SetCurrentImage(Image *aImage) > { > MonitorAutoEnter mon(mMonitor); > > mActiveImage = aImage; >+ CurrentImageChanged(); > } > > already_AddRefed<Image> > ImageContainerD3D10::GetCurrentImage() > { > MonitorAutoEnter mon(mMonitor); > > nsRefPtr<Image> retval = mActiveImage; >@@ -346,16 +347,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/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp >--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp >+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp >@@ -154,16 +154,17 @@ ImageContainerD3D9::CreateImage(const Im > } > > void > ImageContainerD3D9::SetCurrentImage(Image *aImage) > { > MonitorAutoEnter mon(mMonitor); > > mActiveImage = aImage; >+ CurrentImageChanged(); > } > > already_AddRefed<Image> > ImageContainerD3D9::GetCurrentImage() > { > MonitorAutoEnter mon(mMonitor); > > nsRefPtr<Image> retval = mActiveImage; >@@ -367,16 +368,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/opengl/ImageLayerOGL.cpp b/gfx/layers/opengl/ImageLayerOGL.cpp >--- a/gfx/layers/opengl/ImageLayerOGL.cpp >+++ b/gfx/layers/opengl/ImageLayerOGL.cpp >@@ -230,16 +230,17 @@ ImageContainerOGL::SetCurrentImage(Image > { > nsRefPtr<Image> oldImage; > > { > MonitorAutoEnter mon(mMonitor); > > 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() >@@ -493,16 +494,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);
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