// fills the surface with values betwee 0 and 100. staticvoid SetupSurface(gfxImageSurface* surface) { int bpp = gfxASurface::BytePerPixelFromFormat(surface->Format()); int stride = surface->Stride();
uint8_t val = 0;
uint8_t* data = surface->Data(); for (int y = 0; y < surface->Height(); ++y) { for (int x = 0; x < surface->Height(); ++x) { for (int b = 0; b < bpp; ++b) {
data[y * stride + x * bpp + b] = val; if (val == 100) {
val = 0;
} else {
++val;
}
}
}
}
}
// return true if two surfaces contain the same data staticvoid AssertSurfacesEqual(gfxImageSurface* surface1,
gfxImageSurface* surface2) {
ASSERT_EQ(surface1->GetSize(), surface2->GetSize());
ASSERT_EQ(surface1->Format(), surface2->Format());
uint8_t* data1 = surface1->Data();
uint8_t* data2 = surface2->Data(); int stride1 = surface1->Stride(); int stride2 = surface2->Stride(); int bpp = gfxASurface::BytePerPixelFromFormat(surface1->Format());
for (int y = 0; y < surface1->Height(); ++y) { for (int x = 0; x < surface1->Width(); ++x) { for (int b = 0; b < bpp; ++b) {
ASSERT_EQ(data1[y * stride1 + x * bpp + b],
data2[y * stride2 + x * bpp + b]);
}
}
}
}
RefPtr<DataSourceSurface> dataSurface1 = surface1->GetDataSurface();
RefPtr<DataSourceSurface> dataSurface2 = surface2->GetDataSurface();
DataSourceSurface::MappedSurface map1;
DataSourceSurface::MappedSurface map2; if (!dataSurface1->Map(DataSourceSurface::READ, &map1)) { return;
} if (!dataSurface2->Map(DataSourceSurface::READ, &map2)) {
dataSurface1->Unmap(); return;
}
uint8_t* data1 = map1.mData;
uint8_t* data2 = map2.mData; int stride1 = map1.mStride; int stride2 = map2.mStride; int bpp = BytesPerPixel(surface1->GetFormat()); int width = surface1->GetSize().width; int height = surface1->GetSize().height;
for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { for (int b = 0; b < bpp; ++b) {
ASSERT_EQ(data1[y * stride1 + x * bpp + b],
data2[y * stride2 + x * bpp + b]);
}
}
}
dataSurface1->Unmap();
dataSurface2->Unmap();
}
// Run the test for a texture client and a surface void TestTextureClientSurface(TextureClient* texture,
gfxImageSurface* surface) { // client allocation
ASSERT_TRUE(texture->CanExposeDrawTarget());
// Helper: creates a YCbCr texture with the given transfer function and // optional HDR metadata, then verifies they are correctly written into the // YCbCrDescriptor by CreateForYCbCr. void TestYCbCrDescriptorTransferFunction(
TransferFunction aTF, Maybe<gfx::HDRMetadata> aHDRMetadata,
RefPtr<ImageBridgeChild> aImageBridge) {
RefPtr<gfxImageSurface> ySurface = new gfxImageSurface(IntSize(400, 300), SurfaceFormat::A8);
RefPtr<gfxImageSurface> cbSurface = new gfxImageSurface(IntSize(200, 150), SurfaceFormat::A8);
RefPtr<gfxImageSurface> crSurface = new gfxImageSurface(IntSize(200, 150), SurfaceFormat::A8);
SetupSurface(ySurface.get());
SetupSurface(cbSurface.get());
SetupSurface(crSurface.get());
TEST(Layers, TextureSerialization)
{ // the test is run on all the following image formats
gfxImageFormat formats[3] = {
SurfaceFormat::A8R8G8B8_UINT32,
SurfaceFormat::X8R8G8B8_UINT32,
SurfaceFormat::A8,
};
for (int f = 0; f < 3; ++f) {
RefPtr<gfxImageSurface> surface = new gfxImageSurface(IntSize(400, 300), formats[f]);
SetupSurface(surface.get());
AssertSurfacesEqual(surface, surface);
RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton(); staticint retry = 5; while (!imageBridge->IPCOpen() && retry) { // IPDL connection takes time especially in slow testing environment, like // VM machines. Here we added retry mechanism to wait for IPDL connnection. #ifdef XP_WIN
Sleep(1); #else
sleep(1); #endif
retry--;
}
// Skip this testing if IPDL connection is not ready if (!retry && !imageBridge->IPCOpen()) { return;
}
TEST(Layers, TextureYCbCrRejectsDisplayRectExceedingYSize)
{ // The gtest harness sets XPCOM_DEBUG_BREAK=stack-and-abort, so the // NS_ERROR in the rejection path of CreateBackendIndependentTextureHost // becomes a MOZ_CRASH_UNSAFE in DEBUG builds. We split the verification: // DEBUG builds observe the death; opt builds (where NS_ERROR is a no-op) // check that the function returns nullptr directly. auto shmemBuilder = ipc::Shmem::Builder(128);
ASSERT_TRUE(shmemBuilder); auto [msg, shmem] = shmemBuilder.Build(100, false, 0);
ASSERT_TRUE(shmem.IsWritable());
// [[maybe_unused]]: on Darwin, EXPECT_DEATH_WRAP is a no-op (death tests // are too slow there), so in DEBUG-on-Darwin builds runRejection is // defined but never called. Suppress the resulting -Wunused-variable // -Werror without an #ifdef.
[[maybe_unused]] auto runRejection = [&]() -> RefPtr<TextureHost> { // display (8x8) exceeds ySize (4x4). // Offsets: yOffset=0, cbOffset=16, crOffset=20
YCbCrDescriptor ycbcrDesc(
IntRect(0, 0, 8, 8), IntSize(4, 4), 4u, IntSize(2, 2), 2u, 0u, 16u, 20u,
StereoMode::MONO, ColorDepth::COLOR_8, YUVColorSpace::BT601,
ColorRange::LIMITED, TransferFunction::BT709,
ChromaSubsampling::HALF_WIDTH_AND_HEIGHT, mozilla::Nothing());
#ifdef DEBUG
SAVE_GDB_SLEEP_LOCAL();
EXPECT_DEATH_WRAP({ (void)runRejection(); }, "");
RESTORE_GDB_SLEEP_LOCAL(); #else
RefPtr<TextureHost> host = runRejection();
EXPECT_EQ(host.get(), nullptr)
<< "Must reject YCbCr descriptors where display rect exceeds Y plane " "dimensions (display=8x8 vs ySize=4x4)."; #endif
}
TEST(Layers, TextureYCbCrRejectsCbCrSizeInconsistentWithDisplay)
{ auto shmemBuilder = ipc::Shmem::Builder(128);
ASSERT_TRUE(shmemBuilder); auto [msg, shmem] = shmemBuilder.Build(101, false, 0);
ASSERT_TRUE(shmem.IsWritable());
// [[maybe_unused]]: on Darwin, EXPECT_DEATH_WRAP is a no-op (death tests // are too slow there), so in DEBUG-on-Darwin builds runRejection is // defined but never called. Suppress the resulting -Wunused-variable // -Werror without an #ifdef.
[[maybe_unused]] auto runRejection = [&]() -> RefPtr<TextureHost> { // display (8x8) fits within ySize (8x8), but cbCrSize (1x1) is too // small for the chroma dimensions derived from display. // Offsets: yOffset=0, cbOffset=64, crOffset=68
YCbCrDescriptor ycbcrDesc(
IntRect(0, 0, 8, 8), IntSize(8, 8), 8u, IntSize(1, 1), 1u, 0u, 64u, 68u,
StereoMode::MONO, ColorDepth::COLOR_8, YUVColorSpace::BT601,
ColorRange::LIMITED, TransferFunction::BT709,
ChromaSubsampling::HALF_WIDTH_AND_HEIGHT, mozilla::Nothing());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.