Bug 590252 - part 3 - Only flush invalidations when we need to.r=joe,a=blocker
authorBobby Holley <bobbyholley@gmail.com>
Wed, 25 Aug 2010 16:11:09 -0400
changeset 51593 9cf06ffbf06e2cad0a00f5af33efbd805a1c68d3
parent 51592 5875f7dbf9c66bb6e2574624d3a743acd7d52ac4
child 51594 17d4c9bde22258595953e14008dca0d1f76180b5
push idunknown
push userunknown
push dateunknown
reviewersjoe, blocker
bugs590252
milestone2.0b5pre
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 590252 - part 3 - Only flush invalidations when we need to.r=joe,a=blocker
modules/libpr0n/src/Decoder.cpp
modules/libpr0n/src/Decoder.h
modules/libpr0n/src/RasterImage.cpp
--- a/modules/libpr0n/src/Decoder.cpp
+++ b/modules/libpr0n/src/Decoder.cpp
@@ -169,28 +169,28 @@ void
 Decoder::PostFrameStop()
 {
   // We should be mid-frame
   NS_ABORT_IF_FALSE(mInFrame, "Stopping frame when we didn't start one!");
 
   // Update our state
   mInFrame = false;
 
+  // Flush any invalidations before we finish the frame
+  FlushInvalidations();
+
   // Fire notification
   if (mObserver)
     mObserver->OnStopFrame(nsnull, mFrameCount - 1); // frame # is zero-indexed
 }
 
 void
 Decoder::PostInvalidation(nsIntRect& aRect)
 {
   // We should be mid-frame
   NS_ABORT_IF_FALSE(mInFrame, "Can't invalidate when not mid-frame!");
 
   // Account for the new region
   mInvalidRect.UnionRect(mInvalidRect, aRect);
-
-  // For now, just flush invalidations immediately. We'll stop doing this soon.
-  FlushInvalidations();
 }
 
 } // namespace imagelib
 } // namespace mozilla
--- a/modules/libpr0n/src/Decoder.h
+++ b/modules/libpr0n/src/Decoder.h
@@ -82,17 +82,22 @@ public:
   /**
    * Informs the decoder that all the data has been written.
    *
    * Notifications Sent: TODO
    */
   nsresult Finish();
 
   /**
-   * Tells the decoder to flush any pending invalidations.
+   * Tells the decoder to flush any pending invalidations. This informs the image
+   * frame of its decoded region, and sends the appropriate OnDataAvailable call
+   * to consumers.
+   *
+   * This can be called any time when we're midway through decoding a frame,
+   * and must be called after finishing a frame (before starting a new one).
    */
   void FlushInvalidations();
 
   // We're not COM-y, so we don't get refcounts by default
   NS_INLINE_DECL_REFCOUNTING(Decoder)
 
   /*
    * State.
--- a/modules/libpr0n/src/RasterImage.cpp
+++ b/modules/libpr0n/src/RasterImage.cpp
@@ -1238,16 +1238,23 @@ RasterImage::AddSourceData(const char *a
 
   // This call should come straight from necko - no reentrancy allowed
   NS_ABORT_IF_FALSE(!mInDecoder, "Re-entrant call to AddSourceData!");
 
   // If we're not storing source data, write it directly to the decoder
   if (!StoringSourceData()) {
     rv = WriteToDecoder(aBuffer, aCount);
     CONTAINER_ENSURE_SUCCESS(rv);
+
+    // We're not storing source data, so this data is probably coming straight
+    // from the network. In this case, we want to display data as soon as we
+    // get it, so we want to flush invalidations after every write.
+    mInDecoder = PR_TRUE;
+    mDecoder->FlushInvalidations();
+    mInDecoder = PR_FALSE;
   }
 
   // Otherwise, we're storing data in the source buffer
   else {
 
     // Store the data
     char *newElem = mSourceData.AppendElements(aBuffer, aCount);
     if (!newElem)
@@ -2371,16 +2378,24 @@ RasterImage::SyncDecode()
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // Write everything we have
   rv = WriteToDecoder(mSourceData.Elements() + mBytesDecoded,
                       mSourceData.Length() - mBytesDecoded);
   CONTAINER_ENSURE_SUCCESS(rv);
 
+  // When we're doing a sync decode, we want to get as much information from the
+  // image as possible. We've send the decoder all of our data, so now's a good
+  // time  to flush any invalidations (in case we don't have all the data and what
+  // we got left us mid-frame).
+  mInDecoder = PR_TRUE;
+  mDecoder->FlushInvalidations();
+  mInDecoder = PR_FALSE;
+
   // If we finished the decode, shutdown the decoder
   if (IsDecodeFinished()) {
     rv = ShutdownDecoder(eShutdownIntent_Done);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // All good!
   return NS_OK;
@@ -2625,16 +2640,21 @@ imgDecodeWorker::Run()
       return rv;
     }
 
     // Figure out if we still have more data
     haveMoreData =
       image->mSourceData.Length() > image->mBytesDecoded;
   }
 
+  // Flush invalidations _after_ we've written everything we're going to.
+  image->mInDecoder = PR_TRUE;
+  image->mDecoder->FlushInvalidations();
+  image->mInDecoder = PR_FALSE;
+
   // If the decode finished, shutdown the decoder
   if (image->IsDecodeFinished()) {
     rv = image->ShutdownDecoder(RasterImage::eShutdownIntent_Done);
     if (NS_FAILED(rv)) {
       image->DoError();
       return rv;
     }
   }