Bug 635405 - Zooming a windowless plugin frame can cause it to "bleed" outside its bounds. r+a=roc
authorMats Palmgren <matspal@gmail.com>
Thu, 24 Feb 2011 13:06:14 +0100
changeset 63041 cdf6300f80f5d813b680da566bd0d4acf981bce2
parent 63040 0c182eff35de43c9c87752845d28058fa8c067bd
child 63042 c3d0a9679a9464b4b6e7d4b4fd8032db33d237a9
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs635405
milestone2.0b13pre
Bug 635405 - Zooming a windowless plugin frame can cause it to "bleed" outside its bounds. r+a=roc
layout/generic/nsObjectFrame.cpp
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -3185,17 +3185,17 @@ nsPluginInstanceOwner::~nsPluginInstance
 {
   PRInt32 cnt;
 
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
          ("nsPluginInstanceOwner %p deleted\n", this));
 
   if (mWaitingForPaint) {
     // We don't care when the event is dispatched as long as it's "soon",
-    // since whoever needs it will be wwaiting for it
+    // since whoever needs it will be waiting for it.
     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, PR_TRUE);
     NS_DispatchToMainThread(event);
   }
 
 #ifdef MAC_CARBON_PLUGINS
   CancelTimer();
 #endif
 
@@ -3454,30 +3454,32 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
 {
   // If our object frame has gone away, we won't be able to determine
   // up-to-date-ness, so just fire off the event.
   if (mWaitingForPaint && (!mObjectFrame || IsUpToDate())) {
     // We don't care when the event is dispatched as long as it's "soon",
-    // since whoever needs it will be wwaiting for it
+    // since whoever needs it will be waiting for it.
     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, PR_TRUE);
     NS_DispatchToMainThread(event);
     mWaitingForPaint = false;
   }
 
   if (!mObjectFrame || !invalidRect || !mWidgetVisible)
     return NS_ERROR_FAILURE;
 
   // Each time an asynchronously-drawing plugin sends a new surface to display,
   // InvalidateRect is called. We notify reftests that painting is up to
   // date and update our ImageContainer with the new surface.
   nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer();
+  gfxIntSize oldSize;
   if (container) {
+    oldSize = container->GetCurrentSize();
     SetCurrentImage(container);
   }
 
 #ifdef MOZ_USE_IMAGE_EXPOSE
   PRBool simpleImageRender = PR_FALSE;
   mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool,
                                 &simpleImageRender);
   if (simpleImageRender) {  
@@ -3498,24 +3500,34 @@ NS_IMETHODIMP nsPluginInstanceOwner::Inv
   }
 #endif
 
   nsPresContext* presContext = mObjectFrame->PresContext();
   nsRect rect(presContext->DevPixelsToAppUnits(invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->top),
               presContext->DevPixelsToAppUnits(invalidRect->right - invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->bottom - invalidRect->top));
+ if (container) {
+   gfxIntSize newSize = container->GetCurrentSize();
+   if (newSize != oldSize) {
+     // The image size has changed - invalidate the old area too, bug 635405.
+     nsRect oldRect = nsRect(0, 0,
+                             presContext->DevPixelsToAppUnits(oldSize.width),
+                             presContext->DevPixelsToAppUnits(oldSize.height));
+     rect.UnionRect(rect, oldRect);
+   }
+ }
+ rect.MoveBy(mObjectFrame->GetUsedBorderAndPadding().TopLeft());
 #ifndef XP_MACOSX
-  mObjectFrame->InvalidateLayer(rect + mObjectFrame->GetUsedBorderAndPadding().TopLeft(), nsDisplayItem::TYPE_PLUGIN);
+  mObjectFrame->InvalidateLayer(rect, nsDisplayItem::TYPE_PLUGIN);
 #else
   if (mozilla::FrameLayerBuilder::HasDedicatedLayer(mObjectFrame, nsDisplayItem::TYPE_PLUGIN)) {
-    mObjectFrame->InvalidateWithFlags(rect + mObjectFrame->GetUsedBorderAndPadding().TopLeft(),
-                                      nsIFrame::INVALIDATE_NO_UPDATE_LAYER_TREE);
+    mObjectFrame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_UPDATE_LAYER_TREE);
   } else {
-    mObjectFrame->Invalidate(rect + mObjectFrame->GetUsedBorderAndPadding().TopLeft());
+    mObjectFrame->Invalidate(rect);
   }
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
 {
   return NS_ERROR_NOT_IMPLEMENTED;