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 id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs633164
milestone2.0b12pre
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