Bug 919936 - Add gtests for YCbCr memory textures. r=BenWa
authorNicolas Silva <nical@mozilla.com>
Tue, 15 Oct 2013 17:42:03 -0700
changeset 150852 048984fc3cd11817b17d7da6b4ce9702248cf25b
parent 150851 e7d649603075c8142770527b383bd2ede5541491
child 150853 32bb598c8a821eafa85cf27e91812dc54e8bd2fc
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersBenWa
bugs919936
milestone27.0a1
Bug 919936 - Add gtests for YCbCr memory textures. r=BenWa
gfx/tests/gtest/TestTextures.cpp
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -6,18 +6,19 @@
 #include "gtest/gtest.h"
 #include "gmock/gmock.h"
 
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "gfx2DGlue.h"
 #include "gfxImageSurface.h"
 #include "gfxTypes.h"
+#include "ImageContainer.h"
+#include "mozilla/layers/YCbCrImageDataSerializer.h"
 
-using namespace gfx;
 using namespace mozilla;
 using namespace mozilla::layers;
 
 /*
  * This test performs the following actions:
  * - creates a surface
  * - initialize a texture client with it
  * - serilaizes the texture client
@@ -68,16 +69,41 @@ void AssertSurfacesEqual(gfxImageSurface
       for (int b = 0; b < bpp; ++b) {
         ASSERT_EQ(data1[y*stride1 + x*bpp + b],
                   data2[y*stride2 + x*bpp + b]);
       }
     }
   }
 }
 
+// Same as above, for YCbCr surfaces
+void AssertYCbCrSurfacesEqual(PlanarYCbCrData* surface1,
+                              PlanarYCbCrData* surface2)
+{
+  ASSERT_EQ(surface1->mYSize, surface2->mYSize);
+  ASSERT_EQ(surface1->mCbCrSize, surface2->mCbCrSize);
+  ASSERT_EQ(surface1->mStereoMode, surface2->mStereoMode);
+  ASSERT_EQ(surface1->mPicSize, surface2->mPicSize);
+
+  for (int y = 0; y < surface1->mYSize.height; ++y) {
+    for (int x = 0; x < surface1->mYSize.width; ++x) {
+      ASSERT_EQ(surface1->mYChannel[y*surface1->mYStride + x*(1+surface1->mYSkip)],
+                surface2->mYChannel[y*surface2->mYStride + x*(1+surface2->mYSkip)]);
+    }
+  }
+  for (int y = 0; y < surface1->mCbCrSize.height; ++y) {
+    for (int x = 0; x < surface1->mCbCrSize.width; ++x) {
+      ASSERT_EQ(surface1->mCbChannel[y*surface1->mCbCrStride + x*(1+surface1->mCbSkip)],
+                surface2->mCbChannel[y*surface2->mCbCrStride + x*(1+surface2->mCbSkip)]);
+      ASSERT_EQ(surface1->mCrChannel[y*surface1->mCbCrStride + x*(1+surface1->mCrSkip)],
+                surface2->mCrChannel[y*surface2->mCbCrStride + x*(1+surface2->mCrSkip)]);
+    }
+  }
+}
+
 // Run the test for a texture client and a surface
 void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) {
 
   // client allocation
   ASSERT_TRUE(texture->AsTextureClientSurface() != nullptr);
   TextureClientSurface* client = texture->AsTextureClientSurface();
   client->AllocateForSurface(ToIntSize(surface->GetSize()));
   ASSERT_TRUE(texture->IsAllocated());
@@ -114,16 +140,84 @@ void TestTextureClientSurface(TextureCli
   host->Unlock();
 
   AssertSurfacesEqual(surface, hostSurface.get());
 
   // host deallocation
   host->DeallocateSharedData();
 }
 
+// Same as above, for YCbCr surfaces
+void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
+
+  // client allocation
+  ASSERT_TRUE(client->AsTextureClientYCbCr() != nullptr);
+  TextureClientYCbCr* texture = client->AsTextureClientYCbCr();
+  texture->AllocateForYCbCr(ToIntSize(ycbcrData.mYSize),
+                            ToIntSize(ycbcrData.mCbCrSize),
+                            ycbcrData.mStereoMode);
+  ASSERT_TRUE(client->IsAllocated());
+
+  // client painting
+  texture->UpdateYCbCr(ycbcrData);
+
+  ASSERT_TRUE(client->Lock(OPEN_READ_ONLY));
+  client->Unlock();
+
+  // client serialization
+  client->SetID(1);
+  SurfaceDescriptor descriptor;
+  ASSERT_TRUE(client->ToSurfaceDescriptor(descriptor));
+
+  ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
+
+  // host deserialization
+  RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(client->GetID(),
+                                                                        descriptor, nullptr,
+                                                                        client->GetFlags());
+
+  RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());
+
+  ASSERT_TRUE(host.get() != nullptr);
+  ASSERT_EQ(host->GetFlags(), client->GetFlags());
+  ASSERT_EQ(host->GetID(), client->GetID());
+
+  // This will work iff the compositor is not BasicCompositor
+  ASSERT_EQ(host->GetFormat(), mozilla::gfx::FORMAT_YUV);
+
+  // host read
+  ASSERT_TRUE(host->Lock());
+
+  ASSERT_TRUE(host->GetFormat() == mozilla::gfx::FORMAT_YUV);
+
+  YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer());
+  ASSERT_TRUE(yuvDeserializer.IsValid());
+  PlanarYCbCrData data;
+  data.mYChannel = yuvDeserializer.GetYData();
+  data.mCbChannel = yuvDeserializer.GetCbData();
+  data.mCrChannel = yuvDeserializer.GetCrData();
+  data.mYStride = yuvDeserializer.GetYStride();
+  data.mCbCrStride = yuvDeserializer.GetCbCrStride();
+  data.mStereoMode = yuvDeserializer.GetStereoMode();
+  data.mYSize = yuvDeserializer.GetYSize();
+  data.mCbCrSize = yuvDeserializer.GetCbCrSize();
+  data.mYSkip = 0;
+  data.mCbSkip = 0;
+  data.mCrSkip = 0;
+  data.mPicSize = data.mYSize;
+  data.mPicX = 0;
+  data.mPicY = 0;
+
+  AssertYCbCrSurfacesEqual(&ycbcrData, &data);
+  host->Unlock();
+
+  // host deallocation
+  host->DeallocateSharedData();
+}
+
 TEST(Layers, TextureSerialization) {
   // the test is run on all the following image formats
   gfxImageFormat formats[3] = {
     gfxImageFormatARGB32,
     gfxImageFormatRGB24,
     gfxImageFormatA8,
   };
 
@@ -137,8 +231,43 @@ TEST(Layers, TextureSerialization) {
                                 mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
                                 TEXTURE_FLAGS_DEFAULT);
 
     TestTextureClientSurface(client, surface);
 
     // XXX - Test more texture client types.
   }
 }
+
+TEST(Layers, TextureYCbCrSerialization) {
+  RefPtr<gfxImageSurface> ySurface = new gfxImageSurface(gfxIntSize(400,300), gfxImageFormatA8);
+  RefPtr<gfxImageSurface> cbSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormatA8);
+  RefPtr<gfxImageSurface> crSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormatA8);
+  SetupSurface(ySurface.get());
+  SetupSurface(cbSurface.get());
+  SetupSurface(crSurface.get());
+
+  PlanarYCbCrData clientData;
+  clientData.mYChannel = ySurface->Data();
+  clientData.mCbChannel = cbSurface->Data();
+  clientData.mCrChannel = crSurface->Data();
+  clientData.mYSize = ySurface->GetSize();
+  clientData.mPicSize = ySurface->GetSize();
+  clientData.mCbCrSize = cbSurface->GetSize();
+  clientData.mYStride = ySurface->Stride();
+  clientData.mCbCrStride = cbSurface->Stride();
+  clientData.mStereoMode = STEREO_MODE_MONO;
+  clientData.mYSkip = 0;
+  clientData.mCbSkip = 0;
+  clientData.mCrSkip = 0;
+  clientData.mCrSkip = 0;
+  clientData.mPicX = 0;
+  clientData.mPicX = 0;
+
+  RefPtr<TextureClient> client
+    = new MemoryTextureClient(nullptr,
+                              mozilla::gfx::FORMAT_YUV,
+                              TEXTURE_FLAGS_DEFAULT);
+
+  TestTextureClientYCbCr(client, clientData);
+
+  // XXX - Test more texture client types.
+}