Bug 1444537 - Part 4. Add gtests for AnimatedFrameBuffer for redecode errors. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 13 Apr 2018 10:58:54 -0400
changeset 466777 0d23d74448c8493ac96828ee757f0211c47a7b44
parent 466776 07f5d48b90cb5f65e55ded783254ad5fa6fe2beb
child 466778 f7fb95c9979452fe25e42873f54cf56a80a0a0d8
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [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);
+}
+