blob: 4d0379811621c8f9435ff680181d6dc29142bf87 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/graphics/paint/PaintChunker.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::ElementsAre;
namespace blink {
namespace {
static PaintChunkProperties rootPaintChunkProperties() { return PaintChunkProperties(); }
class PaintChunkerTest : public testing::Test {
protected:
void SetUp() override
{
RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(true);
}
void TearDown() override
{
m_featuresBackup.restore();
}
private:
RuntimeEnabledFeatures::Backup m_featuresBackup;
};
TEST_F(PaintChunkerTest, Empty)
{
Vector<PaintChunk> chunks = PaintChunker().releasePaintChunks();
ASSERT_TRUE(chunks.isEmpty());
}
TEST_F(PaintChunkerTest, SingleNonEmptyRange)
{
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 2, rootPaintChunkProperties())));
}
TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk)
{
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 3, rootPaintChunkProperties())));
}
TEST_F(PaintChunkerTest, CanRewindDisplayItemIndex)
{
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.decrementDisplayItemIndex();
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 2, rootPaintChunkProperties())));
}
TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging)
{
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(simpleTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties anotherTransform;
anotherTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(anotherTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 2, rootPaintChunkProperties()),
PaintChunk(2, 3, simpleTransform),
PaintChunk(3, 4, anotherTransform)));
}
TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges)
{
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(simpleTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties simpleTransformAndEffect;
simpleTransformAndEffect.transform = simpleTransform.transform;
simpleTransformAndEffect.effect = EffectPaintPropertyNode::create(0.5f);
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffect);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties simpleTransformAndEffectWithUpdatedTransform;
simpleTransformAndEffectWithUpdatedTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(1, 1, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
simpleTransformAndEffectWithUpdatedTransform.effect = EffectPaintPropertyNode::create(simpleTransformAndEffect.effect->opacity());
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffectWithUpdatedTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
// Test that going back to a previous chunk property still creates a new chunk.
chunker.updateCurrentPaintChunkProperties(simpleTransformAndEffect);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 1, rootPaintChunkProperties()),
PaintChunk(1, 3, simpleTransform),
PaintChunk(3, 5, simpleTransformAndEffect),
PaintChunk(5, 7, simpleTransformAndEffectWithUpdatedTransform),
PaintChunk(7, 9, simpleTransformAndEffect)));
}
TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms)
{
// Test that "nested" transforms linearize using the following
// sequence of transforms and display items:
// <root xform>, <paint>, <a xform>, <paint>, <paint>, </a xform>, <paint>, </root xform>
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(simpleTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 1, rootPaintChunkProperties()),
PaintChunk(1, 3, simpleTransform),
PaintChunk(3, 4, rootPaintChunkProperties())));
}
TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems)
{
// Test that properties can change without display items being generated.
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
PaintChunkProperties firstTransform;
firstTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(firstTransform);
PaintChunkProperties secondTransform;
secondTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1));
chunker.updateCurrentPaintChunkProperties(secondTransform);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 1, rootPaintChunkProperties()),
PaintChunk(1, 2, secondTransform)));
}
TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested)
{
// Tests that the chunker creates a separate chunks for display items which
// require it.
PaintChunker chunker;
chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties());
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
chunker.decrementDisplayItemIndex();
chunker.decrementDisplayItemIndex();
chunker.decrementDisplayItemIndex();
chunker.incrementDisplayItemIndex(PaintChunker::DefaultBehavior);
chunker.incrementDisplayItemIndex(PaintChunker::RequiresSeparateChunk);
Vector<PaintChunk> chunks = chunker.releasePaintChunks();
EXPECT_THAT(chunks, ElementsAre(
PaintChunk(0, 1, rootPaintChunkProperties()),
PaintChunk(1, 2, rootPaintChunkProperties()),
PaintChunk(2, 3, rootPaintChunkProperties()),
PaintChunk(3, 4, rootPaintChunkProperties()),
PaintChunk(4, 6, rootPaintChunkProperties()),
PaintChunk(6, 7, rootPaintChunkProperties())));
}
} // namespace
} // namespace blink