Bug 633164 - Zoomed ogg video renders at the wrong size until I move the mouse. r+a=roc
authorMats Palmgren <matspal@gmail.com>
Thu, 17 Feb 2011 17:12:17 +0100
changeset 62745 7a9b17cca93d5969169664e220842dd7f4a2fa2b
parent 62744 3164addbc63146467523db70efbbd097388bd99a
child 62747 299667917db622522909e13718df9fb2c17157ce
push id18855
push usermpalmgren@mozilla.com
push dateThu, 17 Feb 2011 16:09:51 +0000
treeherdermozilla-central@7a9b17cca93d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs633164
milestone2.0b12pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 633164 - Zoomed ogg video renders at the wrong size until I move the mouse. r+a=roc
content/media/nsMediaDecoder.cpp
content/media/nsMediaDecoder.h
--- a/content/media/nsMediaDecoder.cpp
+++ b/content/media/nsMediaDecoder.cpp
@@ -75,16 +75,17 @@ nsMediaDecoder::nsMediaDecoder() :
   mElement(0),
   mRGBWidth(-1),
   mRGBHeight(-1),
   mVideoUpdateLock(nsnull),
   mPixelAspectRatio(1.0),
   mFrameBufferLength(0),
   mPinnedForSeek(PR_FALSE),
   mSizeChanged(PR_FALSE),
+  mImageContainerSizeChanged(PR_FALSE),
   mShuttingDown(PR_FALSE)
 {
   MOZ_COUNT_CTOR(nsMediaDecoder);
 }
 
 nsMediaDecoder::~nsMediaDecoder()
 {
   if (mVideoUpdateLock) {
@@ -133,19 +134,25 @@ static PRInt32 ConditionDimension(float 
 }
 
 void nsMediaDecoder::Invalidate()
 {
   if (!mElement)
     return;
 
   nsIFrame* frame = mElement->GetPrimaryFrame();
+  PRBool invalidateFrame = PR_FALSE;
 
   {
     nsAutoLock lock(mVideoUpdateLock);
+
+    // Get mImageContainerSizeChanged while holding the lock.
+    invalidateFrame = mImageContainerSizeChanged;
+    mImageContainerSizeChanged = PR_FALSE;
+
     if (mSizeChanged) {
       nsIntSize scaledSize(mRGBWidth, mRGBHeight);
       // Apply the aspect ratio to produce the intrinsic size we report
       // to the element.
       if (mPixelAspectRatio > 1.0) {
         // Increase the intrinsic width
         scaledSize.width =
           ConditionDimension(mPixelAspectRatio*scaledSize.width, scaledSize.width);
@@ -164,18 +171,21 @@ void nsMediaDecoder::Invalidate()
                                     nsIPresShell::eStyleChange,
                                     NS_FRAME_IS_DIRTY);
       }
     }
   }
 
   if (frame) {
     nsRect contentRect = frame->GetContentRect() - frame->GetPosition();
-    // Only the layer needs to be updated here
-    frame->InvalidateLayer(contentRect, nsDisplayItem::TYPE_VIDEO);
+    if (invalidateFrame) {
+      frame->Invalidate(contentRect);
+    } else {
+      frame->InvalidateLayer(contentRect, nsDisplayItem::TYPE_VIDEO);
+    }
   }
 
 #ifdef MOZ_SVG
   nsSVGEffects::InvalidateDirectRenderingObservers(mElement);
 #endif
 }
 
 static void ProgressCallback(nsITimer* aTimer, void* aClosure)
@@ -252,17 +262,22 @@ void nsMediaDecoder::SetVideoData(const 
   if (mRGBWidth != aSize.width || mRGBHeight != aSize.height ||
       mPixelAspectRatio != aPixelAspectRatio) {
     mRGBWidth = aSize.width;
     mRGBHeight = aSize.height;
     mPixelAspectRatio = aPixelAspectRatio;
     mSizeChanged = PR_TRUE;
   }
   if (mImageContainer && aImage) {
+    gfxIntSize oldFrameSize = mImageContainer->GetCurrentSize();
     mImageContainer->SetCurrentImage(aImage);
+    gfxIntSize newFrameSize = mImageContainer->GetCurrentSize();
+    if (oldFrameSize != newFrameSize) {
+      mImageContainerSizeChanged = PR_TRUE;
+    }
   }
 }
 
 void nsMediaDecoder::PinForSeek()
 {
   nsMediaStream* stream = GetCurrentStream();
   if (!stream || mPinnedForSeek) {
     return;
--- a/content/media/nsMediaDecoder.h
+++ b/content/media/nsMediaDecoder.h
@@ -346,19 +346,30 @@ protected:
 
   // The framebuffer size to use for audioavailable events.
   PRUint32 mFrameBufferLength;
 
   // PR_TRUE when our media stream has been pinned. We pin the stream
   // while seeking.
   PRPackedBool mPinnedForSeek;
 
-  // Has our size changed since the last repaint?
+  // Set to PR_TRUE when the video width, height or pixel aspect ratio is
+  // changed by SetVideoData().  The next call to Invalidate() will recalculate
+  // and update the intrinsic size on the element, request a frame reflow and
+  // then reset this flag.
   PRPackedBool mSizeChanged;
 
+  // Set to PR_TRUE in SetVideoData() if the new image has a different size
+  // than the current image.  The image size is also affected by transforms
+  // so this can be true even if mSizeChanged is false, for example when
+  // zooming.  The next call to Invalidate() will call nsIFrame::Invalidate
+  // when this flag is set, rather than just InvalidateLayer, and then reset
+  // this flag.
+  PRPackedBool mImageContainerSizeChanged;
+
   // True if the decoder is being shutdown. At this point all events that
   // are currently queued need to return immediately to prevent javascript
   // being run that operates on the element and decoder during shutdown.
   // Read/Write from the main thread only.
   PRPackedBool mShuttingDown;
 };
 
 #endif