Bug 1444537 - Part 4. Add gtests for AnimatedFrameBuffer for redecode errors. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 24 Apr 2018 13:51:38 -0400
changeset 471477 96a90528f1cd14f1a863ab0cbcaf9107b30e7a51
parent 471476 1173dccd114e1c86047a6f01e341cf1c4ea8fe9c
child 471478 3802f86e1bd10c3e8d5d810c18675aa999bdefa7
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1444537
milestone61.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 1444537 - Part 4. Add gtests for AnimatedFrameBuffer for redecode errors. r=tnikkel
image/test/gtest/TestAnimationFrameBuffer.cpp
--- a/image/test/gtest/TestAnimationFrameBuffer.cpp
+++ b/image/test/gtest/TestAnimationFrameBuffer.cpp
@@ -138,16 +138,17 @@ TEST_F(ImageAnimationFrameBuffer, Finish
     EXPECT_FALSE(buffer.SizeKnown());
 
     if (i == 4) {
       EXPECT_EQ(size_t(15), buffer.PendingDecode());
       keepDecoding = buffer.MarkComplete();
       EXPECT_FALSE(keepDecoding);
       EXPECT_TRUE(buffer.SizeKnown());
       EXPECT_EQ(size_t(0), buffer.PendingDecode());
+      EXPECT_FALSE(buffer.HasRedecodeError());
     }
 
     EXPECT_FALSE(buffer.MayDiscard());
 
     DrawableFrameRef gotFrame = buffer.Get(i);
     EXPECT_EQ(frame.get(), gotFrame.get());
     ASSERT_EQ(i + 1, frames.Length());
     EXPECT_EQ(frame.get(), frames[i].get());
@@ -215,16 +216,17 @@ TEST_F(ImageAnimationFrameBuffer, Finish
   // Add the last frame.
   keepDecoding = buffer.Insert(CreateEmptyFrame());
   EXPECT_TRUE(keepDecoding);
   keepDecoding = buffer.MarkComplete();
   EXPECT_FALSE(keepDecoding);
   EXPECT_TRUE(buffer.SizeKnown());
   EXPECT_EQ(size_t(0), buffer.PendingDecode());
   EXPECT_EQ(size_t(5), frames.Length());
+  EXPECT_FALSE(buffer.HasRedecodeError());
 
   // Finish progressing through the animation.
   for ( ; i < frames.Length(); ++i) {
     DrawableFrameRef gotFrame = buffer.Get(i);
     EXPECT_TRUE(gotFrame);
     restartDecoder = buffer.AdvanceTo(i);
     EXPECT_FALSE(restartDecoder);
   }
@@ -325,16 +327,17 @@ TEST_F(ImageAnimationFrameBuffer, MayDis
   // frame will restart at the beginning.
   keepDecoding = buffer.Insert(CreateEmptyFrame());
   EXPECT_TRUE(keepDecoding);
   keepDecoding = buffer.MarkComplete();
   EXPECT_TRUE(keepDecoding);
   EXPECT_TRUE(buffer.SizeKnown());
   EXPECT_EQ(size_t(2), buffer.PendingDecode());
   EXPECT_EQ(size_t(10), frames.Length());
+  EXPECT_FALSE(buffer.HasRedecodeError());
 
   // Use remaining pending room. It shouldn't add new frames, only replace.
   do {
     keepDecoding = buffer.Insert(CreateEmptyFrame());
   } while (keepDecoding);
 
   EXPECT_EQ(size_t(0), buffer.PendingDecode());
   EXPECT_EQ(size_t(10), frames.Length());
@@ -508,8 +511,164 @@ TEST_F(ImageAnimationFrameBuffer, StartA
   // in the real scenario, the decoder thread is still running and it is easier
   // to let it insert its last frame than to coordinate quitting earlier.
   buffer.Reset();
   EXPECT_EQ(size_t(0), buffer.Displayed());
   EXPECT_EQ(size_t(1), buffer.PendingDecode());
   EXPECT_EQ(size_t(0), buffer.PendingAdvance());
 }
 
+TEST_F(ImageAnimationFrameBuffer, RedecodeMoreFrames)
+{
+  const size_t kThreshold = 5;
+  const size_t kBatch = 2;
+  AnimationFrameBuffer buffer;
+  buffer.Initialize(kThreshold, kBatch, 0);
+  const auto& frames = buffer.Frames();
+
+  // Add frames until we exceed the threshold.
+  bool keepDecoding;
+  bool restartDecoder;
+  size_t i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    EXPECT_TRUE(keepDecoding);
+    if (i > 0) {
+      restartDecoder = buffer.AdvanceTo(i);
+      EXPECT_FALSE(restartDecoder);
+    }
+    ++i;
+  } while (!buffer.MayDiscard());
+
+  // Should have threshold + 1 frames, and still not complete.
+  EXPECT_EQ(size_t(6), frames.Length());
+  EXPECT_FALSE(buffer.SizeKnown());
+
+  // Now we lock in at 6 frames.
+  keepDecoding = buffer.MarkComplete();
+  EXPECT_TRUE(keepDecoding);
+  EXPECT_TRUE(buffer.SizeKnown());
+  EXPECT_FALSE(buffer.HasRedecodeError());
+
+  // Reinsert 6 frames first.
+  i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    EXPECT_TRUE(keepDecoding);
+    restartDecoder = buffer.AdvanceTo(i);
+    EXPECT_FALSE(restartDecoder);
+    ++i;
+  } while (i < 6);
+
+  // We should now encounter an error and shutdown further decodes.
+  keepDecoding = buffer.Insert(CreateEmptyFrame());
+  EXPECT_FALSE(keepDecoding);
+  EXPECT_EQ(size_t(0), buffer.PendingDecode());
+  EXPECT_TRUE(buffer.HasRedecodeError());
+}
+
+TEST_F(ImageAnimationFrameBuffer, RedecodeFewerFrames)
+{
+  const size_t kThreshold = 5;
+  const size_t kBatch = 2;
+  AnimationFrameBuffer buffer;
+  buffer.Initialize(kThreshold, kBatch, 0);
+  const auto& frames = buffer.Frames();
+
+  // Add frames until we exceed the threshold.
+  bool keepDecoding;
+  bool restartDecoder;
+  size_t i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    EXPECT_TRUE(keepDecoding);
+    if (i > 0) {
+      restartDecoder = buffer.AdvanceTo(i);
+      EXPECT_FALSE(restartDecoder);
+    }
+    ++i;
+  } while (!buffer.MayDiscard());
+
+  // Should have threshold + 1 frames, and still not complete.
+  EXPECT_EQ(size_t(6), frames.Length());
+  EXPECT_FALSE(buffer.SizeKnown());
+
+  // Now we lock in at 6 frames.
+  keepDecoding = buffer.MarkComplete();
+  EXPECT_TRUE(keepDecoding);
+  EXPECT_TRUE(buffer.SizeKnown());
+  EXPECT_FALSE(buffer.HasRedecodeError());
+
+  // Reinsert 5 frames before marking complete.
+  i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    EXPECT_TRUE(keepDecoding);
+    restartDecoder = buffer.AdvanceTo(i);
+    EXPECT_FALSE(restartDecoder);
+    ++i;
+  } while (i < 5);
+
+  // We should now encounter an error and shutdown further decodes.
+  keepDecoding = buffer.MarkComplete();
+  EXPECT_FALSE(keepDecoding);
+  EXPECT_EQ(size_t(0), buffer.PendingDecode());
+  EXPECT_TRUE(buffer.HasRedecodeError());
+}
+
+TEST_F(ImageAnimationFrameBuffer, RedecodeFewerFramesAndBehindAdvancing)
+{
+  const size_t kThreshold = 5;
+  const size_t kBatch = 2;
+  AnimationFrameBuffer buffer;
+  buffer.Initialize(kThreshold, kBatch, 0);
+  const auto& frames = buffer.Frames();
+
+  // Add frames until we exceed the threshold.
+  bool keepDecoding;
+  bool restartDecoder;
+  size_t i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    EXPECT_TRUE(keepDecoding);
+    if (i > 0) {
+      restartDecoder = buffer.AdvanceTo(i);
+      EXPECT_FALSE(restartDecoder);
+    }
+    ++i;
+  } while (!buffer.MayDiscard());
+
+  // Should have threshold + 1 frames, and still not complete.
+  EXPECT_EQ(size_t(6), frames.Length());
+  EXPECT_FALSE(buffer.SizeKnown());
+
+  // Now we lock in at 6 frames.
+  keepDecoding = buffer.MarkComplete();
+  EXPECT_TRUE(keepDecoding);
+  EXPECT_TRUE(buffer.SizeKnown());
+  EXPECT_FALSE(buffer.HasRedecodeError());
+
+  // Reinsert frames without advancing until we exhaust our pending space. This
+  // should be less than the current buffer length by definition.
+  i = 0;
+  do {
+    keepDecoding = buffer.Insert(CreateEmptyFrame());
+    ++i;
+  } while (keepDecoding);
+
+  EXPECT_EQ(size_t(2), i);
+
+  // We should now encounter an error and shutdown further decodes.
+  keepDecoding = buffer.MarkComplete();
+  EXPECT_FALSE(keepDecoding);
+  EXPECT_EQ(size_t(0), buffer.PendingDecode());
+  EXPECT_TRUE(buffer.HasRedecodeError());
+
+  // We should however be able to continue advancing to the last decoded frame
+  // without it requesting the decoder to restart.
+  i = 0;
+  do {
+    restartDecoder = buffer.AdvanceTo(i);
+    EXPECT_FALSE(restartDecoder);
+    ++i;
+  } while (i < 2);
+}
+