Bug 1279611 - Document and test the fact that SurfacePipe::WriteEmptyRow() overwrites the entire row. r=njn
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 17 Jun 2016 15:05:00 -0700
changeset 302040 78f55d79c3e04e9781ee58228a21c19d9a0f59f9
parent 302039 c583dc0f3f4a2fd3e0d4b478a599c1f613085d52
child 302041 35530c11c1631b62e2e02c59e071f49d877b1184
push id78553
push usermfowler@mozilla.com
push dateFri, 17 Jun 2016 22:05:44 +0000
treeherdermozilla-inbound@35530c11c163 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1279611
milestone50.0a1
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 1279611 - Document and test the fact that SurfacePipe::WriteEmptyRow() overwrites the entire row. r=njn
image/SurfacePipe.h
image/test/gtest/TestSurfaceSink.cpp
--- a/image/SurfacePipe.h
+++ b/image/SurfacePipe.h
@@ -315,17 +315,18 @@ public:
 
     AdvanceRow();
 
     return IsSurfaceFinished() ? WriteState::FINISHED
                                : WriteState::NEED_MORE_DATA;
   }
 
   /**
-   * Write an empty row to the surface.
+   * Write an empty row to the surface. If some pixels have already been written
+   * to this row, they'll be discarded.
    *
    * @return WriteState::FINISHED if the entire surface has been written to.
    *         Otherwise, returns WriteState::NEED_MORE_DATA.
    */
   WriteState WriteEmptyRow()
   {
     if (IsSurfaceFinished()) {
       return WriteState::FINISHED;  // Already done.
@@ -570,17 +571,18 @@ public:
   WriteState WriteBuffer(const PixelType* aSource,
                          const size_t aStartColumn,
                          const size_t aLength)
   {
     return mHead->WriteBuffer<PixelType>(aSource, aStartColumn, aLength);
   }
 
   /**
-   * Write an empty row to the surface.
+   * Write an empty row to the surface. If some pixels have already been written
+   * to this row, they'll be discarded.
    *
    * @see SurfaceFilter::WriteEmptyRow() for the canonical documentation.
    */
   WriteState WriteEmptyRow()
   {
     return mHead->WriteEmptyRow();
   }
 
--- a/image/test/gtest/TestSurfaceSink.cpp
+++ b/image/test/gtest/TestSurfaceSink.cpp
@@ -371,16 +371,41 @@ TEST(ImageSurfaceSink, SurfaceSinkWriteE
       CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0), [&]{
         return aSink->WriteEmptyRow();
       });
     }
 
     ResetForNextPass(aSink);
 
     {
+      // Write a partial row before we begin calling WriteEmptyRow(). We check
+      // that the generated image is entirely transparent, which is to be
+      // expected since WriteEmptyRow() overwrites the current row even if some
+      // data has already been written to it.
+      uint32_t count = 0;
+      auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+        if (count == 50) {
+          return AsVariant(WriteState::NEED_MORE_DATA);
+        }
+        ++count;
+        return AsVariant(BGRAColor::Green().AsPixel());
+      });
+
+      EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+      EXPECT_EQ(50u, count);
+      EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+      CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0), [&]{
+        return aSink->WriteEmptyRow();
+      });
+    }
+
+    ResetForNextPass(aSink);
+
+    {
       // Create a buffer the same size as one row of the surface, containing all
       // green pixels.
       uint32_t buffer[100];
       for (int i = 0; i < 100; ++i) {
         buffer[i] = BGRAColor::Green().AsPixel();
       }
 
       // Write an empty row to the middle 60 rows of the surface. The first 20
@@ -927,16 +952,41 @@ TEST(ImageSurfaceSink, PalettedSurfaceSi
       CheckPalettedIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0), [&]{
         return aSink->WriteEmptyRow();
       });
     }
 
     ResetForNextPass(aSink);
 
     {
+      // Write a partial row before we begin calling WriteEmptyRow(). We check
+      // that the generated image is entirely 0, which is to be expected since
+      // WriteEmptyRow() overwrites the current row even if some data has
+      // already been written to it.
+      uint32_t count = 0;
+      auto result = aSink->WritePixels<uint8_t>([&]() -> NextPixel<uint8_t> {
+        if (count == 50) {
+          return AsVariant(WriteState::NEED_MORE_DATA);
+        }
+        ++count;
+        return AsVariant(uint8_t(255));
+      });
+
+      EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+      EXPECT_EQ(50u, count);
+      EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+      CheckPalettedIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0), [&]{
+        return aSink->WriteEmptyRow();
+      });
+    }
+
+    ResetForNextPass(aSink);
+
+    {
       // Create a buffer the same size as one row of the surface, containing all
       // 255 pixels.
       uint8_t buffer[100];
       for (int i = 0; i < 100; ++i) {
         buffer[i] = 255;
       }
 
       // Write an empty row to the middle 60 rows of the surface. The first 20