gecko-dev/image/test/gtest/TestContainers.cpp
Andrew Osmond 29af4ed6a2 Bug 1446309 - Part 3. Properly handle ImgDrawResult for WebRender display list generation. r=tnikkel
When generating display lists for WebRender, we were not caching the
draw result via nsDisplayItemGenericImageGeometry::UpdateDrawResult (or
similar) after completing CreateWebRenderCommands. This is important
because reftests use this to force sync decoding for images; it may be a
reason for image-related intermittent failures on *-qr builds.

Additionally, we may have been requesting fallback in cases where fallback
could not do anything more than WebRender could. For example, if we can't
get an image container yet, there is no point in requesting fallback
because it might just be we haven't started decoding yet. We should just
return the actual draw result in such cases.
2018-09-13 19:48:27 -04:00

114 lines
4.4 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "BasicLayers.h"
#include "Common.h"
#include "imgIContainer.h"
#include "imgITools.h"
#include "ImageFactory.h"
#include "ImageContainer.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsIInputStream.h"
#include "nsString.h"
#include "ProgressTracker.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
class ImageContainers : public ::testing::Test
{
protected:
AutoInitializeImageLib mInit;
};
TEST_F(ImageContainers, RasterImageContainer)
{
ImageTestCase testCase = GreenPNGTestCase();
// Create an image.
RefPtr<Image> image =
ImageFactory::CreateAnonymousImage(nsDependentCString(testCase.mMimeType));
ASSERT_TRUE(!image->HasError());
nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
ASSERT_TRUE(inputStream);
// Figure out how much data we have.
uint64_t length;
nsresult rv = inputStream->Available(&length);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Write the data into the image.
rv = image->OnImageDataAvailable(nullptr, nullptr, inputStream, 0,
static_cast<uint32_t>(length));
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Let the image know we've sent all the data.
rv = image->OnImageDataComplete(nullptr, nullptr, NS_OK, true);
ASSERT_TRUE(NS_SUCCEEDED(rv));
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
RefPtr<layers::LayerManager> layerManager =
new layers::BasicLayerManager(layers::BasicLayerManager::BLM_OFFSCREEN);
// Get at native size.
RefPtr<layers::ImageContainer> nativeContainer =
image->GetImageContainer(layerManager,
imgIContainer::FLAG_SYNC_DECODE);
ASSERT_TRUE(nativeContainer != nullptr);
IntSize containerSize = nativeContainer->GetCurrentSize();
EXPECT_EQ(testCase.mSize.width, containerSize.width);
EXPECT_EQ(testCase.mSize.height, containerSize.height);
// Upscaling should give the native size.
ImgDrawResult drawResult;
IntSize requestedSize = testCase.mSize;
requestedSize.Scale(2, 2);
RefPtr<layers::ImageContainer> upscaleContainer;
drawResult = image->GetImageContainerAtSize(layerManager,
requestedSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING,
getter_AddRefs(upscaleContainer));
EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
ASSERT_TRUE(upscaleContainer != nullptr);
containerSize = upscaleContainer->GetCurrentSize();
EXPECT_EQ(testCase.mSize.width, containerSize.width);
EXPECT_EQ(testCase.mSize.height, containerSize.height);
// Downscaling should give the downscaled size.
requestedSize = testCase.mSize;
requestedSize.width /= 2;
requestedSize.height /= 2;
RefPtr<layers::ImageContainer> downscaleContainer;
drawResult = image->GetImageContainerAtSize(layerManager,
requestedSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING,
getter_AddRefs(downscaleContainer));
EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
ASSERT_TRUE(downscaleContainer != nullptr);
containerSize = downscaleContainer->GetCurrentSize();
EXPECT_EQ(requestedSize.width, containerSize.width);
EXPECT_EQ(requestedSize.height, containerSize.height);
// Get at native size again. Should give same container.
RefPtr<layers::ImageContainer> againContainer;
drawResult = image->GetImageContainerAtSize(layerManager,
testCase.mSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(againContainer));
EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
ASSERT_EQ(nativeContainer.get(), againContainer.get());
}