TiledLayerChromiumTest.cpp [plain text]
#include "config.h"
#include "TiledLayerChromium.h"
#include "CCAnimationTestCommon.h"
#include "CCLayerTreeTestCommon.h"
#include "CCTiledLayerTestCommon.h"
#include "FakeCCLayerTreeHostClient.h"
#include "WebCompositor.h"
#include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
#include <gtest/gtest.h>
using namespace WebCore;
using namespace WebKitTests;
using namespace WTF;
#define EXPECT_EQ_RECT(a, b) \
EXPECT_EQ(a.x(), b.x()); \
EXPECT_EQ(a.y(), b.y()); \
EXPECT_EQ(a.width(), b.width()); \
EXPECT_EQ(a.height(), b.height());
namespace {
class TestCCOcclusionTracker : public CCOcclusionTracker {
public:
TestCCOcclusionTracker()
: CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
, m_scissorRectInScreen(IntRect(0, 0, 1000, 1000))
{
m_stack.append(StackObject());
}
void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScreen = occlusion; }
protected:
virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_scissorRectInScreen; }
private:
IntRect m_scissorRectInScreen;
};
TEST(TiledLayerChromiumTest, pushDirtyTiles)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
textureManager->unprotectAllTextures();
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, pushOccludedDirtyTiles)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setBounds(IntSize(100, 200));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
layer->setVisibleLayerRect(IntRect(0, 0, 100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), &occluded);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
textureManager->unprotectAllTextures();
layer->invalidateRect(IntRect(0, 0, 50, 50));
occluded.setOcclusion(IntRect(0, 0, 50, 50));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 2500, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, pushDeletedTiles)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
FakeTextureAllocator allocator;
layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
textureManager->evictAndDeleteAllTextures(&allocator);
textureManager->setMaxMemoryLimitBytes(4*1024*1024);
textureManager->setPreferredMemoryLimitBytes(4*1024*1024);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, pushIdlePaintTiles)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
IntSize contentBounds(500, 500);
IntRect contentRect(IntPoint::zero(), contentBounds);
IntRect visibleRect(200, 200, 100, 100);
layer->setBounds(contentBounds);
layer->setVisibleLayerRect(visibleRect);
layer->invalidateRect(contentRect);
layer->updateLayerRect(updater, visibleRect, 0);
EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(2, 2));
textureManager->unprotectAllTextures();
for (int i = 0; i < 4; i++) {
layer->updateLayerRect(updater, visibleRect, 0);
EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
layer->idleUpdateLayerRect(updater, visibleRect, 0);
layer->pushPropertiesTo(layerImpl.get());
textureManager->unprotectAllTextures();
}
EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
IntRect idlePaintTiles(1, 1, 3, 3);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (idlePaintTiles.contains(i, j))
EXPECT_TRUE(layerImpl->hasTileAt(i, j));
else
EXPECT_FALSE(layerImpl->hasTileAt(i, j));
}
}
}
TEST(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(1024*1024, 1024*1024, 1024);
DebugScopedSetImplThread implThread;
RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
OwnPtr<FakeCCTiledLayerImpl> layerImpl1(adoptPtr(new FakeCCTiledLayerImpl(0)));
RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
OwnPtr<FakeCCTiledLayerImpl> layerImpl2(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
FakeTextureAllocator allocator;
FakeTextureCopier copier;
FakeTextureUploader uploader;
IntRect layer2Rect(0, 0, 100, 300);
layer2->setBounds(layer2Rect.size());
layer2->setVisibleLayerRect(layer2Rect);
layer2->invalidateRect(layer2Rect);
IntRect layerRect(IntPoint::zero(), IntSize(100, 2400));
layer1->setBounds(layerRect.size());
layer1->setVisibleLayerRect(layerRect);
layer1->invalidateRect(layerRect);
layer1->updateLayerRect(updater, layerRect, 0);
layer2->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
EXPECT_TRUE(layer2->needsIdlePaint(layer2Rect));
updater.update(0, &allocator, &copier, &uploader, 5000);
layer1->pushPropertiesTo(layerImpl1.get());
layer2->pushPropertiesTo(layerImpl2.get());
layer2->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
layer2->idleUpdateLayerRect(updater, layer2Rect, 0);
updater.update(0, &allocator, &copier, &uploader, 5000);
layer1->pushPropertiesTo(layerImpl1.get());
layer2->pushPropertiesTo(layerImpl2.get());
EXPECT_TRUE(layerImpl1->hasTextureIdForTileAt(0, 0));
EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
EXPECT_FALSE(layerImpl2->hasTileAt(0, 1));
EXPECT_FALSE(layerImpl2->hasTileAt(0, 2));
textureManager->unprotectAllTextures();
layer2->updateLayerRect(updater, layer2Rect, 0);
layer1->updateLayerRect(updater, IntRect(), 0);
updater.update(0, &allocator, &copier, &uploader, 5000);
layer1->pushPropertiesTo(layerImpl1.get());
layer2->pushPropertiesTo(layerImpl2.get());
EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl2->hasTileAt(0, 1));
EXPECT_TRUE(layerImpl2->hasTileAt(0, 2));
EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 1));
EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 2));
}
TEST(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
occluded.setOcclusion(IntRect(0, 0, 100, 100));
layer->setBounds(IntSize(100, 100));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
layer->setVisibleLayerRect(IntRect(0, 0, 100, 100));
layer->invalidateRect(IntRect(0, 0, 100, 100));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
layer->idleUpdateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
}
TEST(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer.get());
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer1->setBounds(IntSize(100, 200));
layer1->invalidateRect(IntRect(0, 0, 100, 200));
layer2->setBounds(IntSize(100, 200));
layer2->invalidateRect(IntRect(0, 0, 100, 200));
layer1->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer1.get());
layer2->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer1->pushPropertiesTo(layer1Impl.get());
layer2->pushPropertiesTo(layer2Impl.get());
EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer1->setBounds(IntSize(100, 200));
layer1->invalidateRect(IntRect(0, 0, 100, 200));
layer2->setBounds(IntSize(100, 200));
layer2->invalidateRect(IntRect(0, 0, 100, 200));
layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer2.get());
layer1->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer2->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
layer1->pushPropertiesTo(layer1Impl.get());
layer2->pushPropertiesTo(layer2Impl.get());
EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
}
TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
{
IntSize contentBounds(300, 300);
IntRect contentRect(IntPoint::zero(), contentBounds);
IntRect visibleRect(100, 100, 100, 100);
int memoryLimit = 4 * 100 * 100;
OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer->setBounds(contentBounds);
layer->setVisibleLayerRect(visibleRect);
layer->invalidateRect(contentRect);
layer->updateLayerRect(updater, visibleRect, 0);
EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
textureManager->unprotectAllTextures();
layer->updateLayerRect(updater, visibleRect, 0);
layer->idleUpdateLayerRect(updater, visibleRect, 0);
EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
layer->pushPropertiesTo(layerImpl.get());
}
TEST(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
IntRect contentRect;
layer->setBounds(contentRect.size());
layer->setVisibleLayerRect(contentRect);
layer->invalidateRect(contentRect);
layer->updateLayerRect(updater, contentRect, 0);
EXPECT_EQ(0u, layer->numPaintedTiles());
EXPECT_FALSE(layer->needsIdlePaint(contentRect));
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
layer->idleUpdateLayerRect(updater, contentRect, 0);
EXPECT_EQ(0u, layer->numPaintedTiles());
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
}
TEST(TiledLayerChromiumTest, idlePaintZeroSizedAnimatingLayer)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer->setDrawTransformIsAnimating(true);
IntRect contentRect;
layer->setBounds(contentRect.size());
layer->setVisibleLayerRect(contentRect);
layer->invalidateRect(contentRect);
layer->updateLayerRect(updater, contentRect, 0);
EXPECT_EQ(0u, layer->numPaintedTiles());
EXPECT_FALSE(layer->needsIdlePaint(contentRect));
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
layer->idleUpdateLayerRect(updater, contentRect, 0);
EXPECT_EQ(0u, layer->numPaintedTiles());
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
}
TEST(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
{
IntSize contentBounds(100, 100);
IntRect contentRect(IntPoint::zero(), contentBounds);
OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
IntRect visibleRect;
layer->setBounds(contentBounds);
layer->setVisibleLayerRect(visibleRect);
layer->invalidateRect(contentRect);
layer->updateLayerRect(updater, visibleRect, 0);
EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
layer->idleUpdateLayerRect(updater, visibleRect, 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
}
static void idlePaintRepeat(int repeatTimes, FakeTiledLayerChromium* layer, FakeCCTiledLayerImpl* layerImpl, CCTextureUpdater& updater, const IntRect& visibleRect)
{
for (int i = 0; i < repeatTimes; ++i) {
layer->updateLayerRect(updater, visibleRect, 0);
layer->idleUpdateLayerRect(updater, visibleRect, 0);
layer->pushPropertiesTo(layerImpl);
}
}
static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have)
{
for (int i = 0; i < width; ++i) {
for (int j = 0; j < height; ++j) {
bool hasTile = i < have || j < have || i >= width - have || j >= height - have;
EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j));
}
}
}
TEST(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(8000*8000*8, 8000*8000*4, 1024);
DebugScopedSetImplThread implThread;
CCTextureUpdater updater;
int tileWidth = FakeTiledLayerChromium::tileSize().width();
int tileHeight = FakeTiledLayerChromium::tileSize().height();
int width[] = { 1, 2, 3, 4, 9, 10, 0 };
int height[] = { 1, 2, 3, 4, 9, 10, 0 };
for (int j = 0; height[j]; ++j) {
for (int i = 0; width[i]; ++i) {
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
layer->setDrawTransformIsAnimating(true);
IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight);
IntRect contentRect(IntPoint::zero(), contentBounds);
IntRect visibleRect;
layer->setBounds(contentBounds);
layer->setVisibleLayerRect(visibleRect);
layer->invalidateRect(contentRect);
bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty();
layer->updateLayerRect(updater, visibleRect, 0);
layer->pushPropertiesTo(layerImpl.get());
testHaveOuterTiles(layerImpl.get(), width[i], height[j], 0);
EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect));
idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
}
}
}
TEST(TiledLayerChromiumTest, invalidateFromPrepare)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
FakeTextureAllocator fakeAllocator;
FakeTextureCopier fakeCopier;
FakeTextureUploader fakeUploader;
RefPtr<GraphicsContext3D> context = createCompositorMockGraphicsContext3D(GraphicsContext3D::Attributes());
layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
updater.update(context.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
textureManager->unprotectAllTextures();
layer->fakeLayerTextureUpdater()->clearPrepareCount();
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
updater.update(context.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
layer->invalidateRect(IntRect(0, 0, 50, 50));
layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50), layer.get());
layer->fakeLayerTextureUpdater()->clearPrepareCount();
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
updater.update(context.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
layer->fakeLayerTextureUpdater()->clearPrepareCount();
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
updater.update(context.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
}
TEST(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
CCTextureUpdater updater;
IntRect layerBounds(0, 0, 300, 200);
IntRect contentBounds(0, 0, 200, 250);
layer->setBounds(layerBounds.size());
layer->setContentBounds(contentBounds.size());
layer->setVisibleLayerRect(contentBounds);
layer->invalidateRect(contentBounds);
layer->updateLayerRect(updater, contentBounds, 0);
EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
layer->invalidateRect(contentBounds);
layer->updateLayerRect(updater, contentBounds, 0);
EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
IntRect partialDamage(30, 100, 10, 10);
layer->invalidateRect(partialDamage);
layer->updateLayerRect(updater, contentBounds, 0);
EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
}
TEST(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
CCTextureUpdater updater;
layer->setBounds(IntSize(100, 100));
layer->setNeedsDisplay();
EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
layer->setContentsScale(2);
EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
layer->updateLayerRect(updater, IntRect(0, 0, 200, 200), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
EXPECT_TRUE(layerImpl->hasTileAt(1, 0));
EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
layer->setNeedsDisplay();
layer->updateLayerRect(updater, IntRect(1, 0, 0, 1), 0);
layer->pushPropertiesTo(layerImpl.get());
EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
}
TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
{
WebKit::WebCompositor::initialize(0);
FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, CCSettings());
IntSize contentBounds(300, 300);
IntRect contentRect(IntPoint::zero(), contentBounds);
int memoryLimit = 4 * 300 * 300; OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit, memoryLimit);
RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
rootLayer->addChild(childLayer);
rootLayer->setBounds(contentBounds);
rootLayer->setPosition(FloatPoint(150, 150));
childLayer->setBounds(contentBounds);
childLayer->setPosition(FloatPoint(150, 150));
rootLayer->invalidateRect(contentRect);
childLayer->invalidateRect(contentRect);
CCTextureUpdater updater;
ccLayerTreeHost->setRootLayer(rootLayer);
ccLayerTreeHost->setViewportSize(IntSize(300, 300));
textureManager->setMaxMemoryLimitBytes(memoryLimit);
ccLayerTreeHost->updateLayers(updater);
EXPECT_TRUE(rootLayer->skipsDraw());
EXPECT_FALSE(childLayer->skipsDraw());
ccLayerTreeHost->commitComplete();
textureManager->unprotectAllTextures();
rootLayer->removeAllChildren();
ccLayerTreeHost->updateLayers(updater);
EXPECT_FALSE(rootLayer->skipsDraw());
ccLayerTreeHost->setRootLayer(0);
ccLayerTreeHost.clear();
WebKit::WebCompositor::shutdown();
}
TEST(TiledLayerChromiumTest, resizeToSmaller)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
CCTextureUpdater updater;
layer->setBounds(IntSize(700, 700));
layer->invalidateRect(IntRect(0, 0, 700, 700));
layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
layer->setBounds(IntSize(200, 200));
layer->invalidateRect(IntRect(0, 0, 200, 200));
}
TEST(TiledLayerChromiumTest, hugeLayerUpdateCrash)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
CCTextureUpdater updater;
int size = 1 << 30;
layer->setBounds(IntSize(size, size));
layer->invalidateRect(IntRect(0, 0, size, size));
layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
}
TEST(TiledLayerChromiumTest, partialUpdates)
{
CCSettings settings;
settings.maxPartialTextureUpdates = 4;
WebKit::WebCompositor::initialize(0);
FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
IntSize contentBounds(300, 200);
IntRect contentRect(IntPoint::zero(), contentBounds);
OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
layer->setBounds(contentBounds);
layer->setPosition(FloatPoint(150, 150));
layer->invalidateRect(contentRect);
CCTextureUpdater updater;
FakeTextureAllocator allocator;
FakeTextureCopier copier;
FakeTextureUploader uploader;
ccLayerTreeHost->setRootLayer(layer);
ccLayerTreeHost->setViewportSize(IntSize(300, 200));
ccLayerTreeHost->updateLayers(updater);
{
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_TRUE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_FALSE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
layer->pushPropertiesTo(layerImpl.get());
}
ccLayerTreeHost->commitComplete();
layer->invalidateRect(IntRect(0, 0, 300, 150));
ccLayerTreeHost->updateLayers(updater);
{
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_TRUE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_FALSE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
layer->pushPropertiesTo(layerImpl.get());
}
ccLayerTreeHost->commitComplete();
layer->invalidateRect(IntRect(50, 50, 200, 100));
{
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
ccLayerTreeHost->updateLayers(updater);
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_TRUE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_FALSE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
layer->pushPropertiesTo(layerImpl.get());
}
ccLayerTreeHost->commitComplete();
layer->invalidateRect(IntRect(0, 0, 300, 200));
{
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
layer->pushPropertiesTo(layerImpl.get());
}
ccLayerTreeHost->commitComplete();
layer->invalidateRect(IntRect(50, 50, 200, 100));
{
DebugScopedSetImplThread implThread;
OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
ccLayerTreeHost->updateLayers(updater);
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_TRUE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
updater.update(0, &allocator, &copier, &uploader, 4);
EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
EXPECT_FALSE(updater.hasMoreUpdates());
layer->fakeLayerTextureUpdater()->clearUpdateCount();
layer->pushPropertiesTo(layerImpl.get());
}
ccLayerTreeHost->commitComplete();
ccLayerTreeHost->setRootLayer(0);
ccLayerTreeHost.clear();
WebKit::WebCompositor::shutdown();
}
TEST(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
CCTextureUpdater updater;
layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
}
TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setBounds(IntSize(600, 600));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(200, 200, 300, 100));
layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
occluded.setOcclusion(IntRect(250, 200, 300, 100));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
occluded.setOcclusion(IntRect(250, 250, 300, 100));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setBounds(IntSize(600, 600));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(200, 200, 300, 150));
layer->setVisibleLayerRect(IntRect(0, 0, 600, 360));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 360), &occluded);
EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
occluded.setOcclusion(IntRect(200, 200, 300, 150));
layer->setVisibleLayerRect(IntRect(0, 0, 600, 350));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 350), &occluded);
EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
occluded.setOcclusion(IntRect(200, 200, 300, 150));
layer->setVisibleLayerRect(IntRect(0, 0, 600, 340));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 340), &occluded);
EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setBounds(IntSize(600, 600));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(200, 200, 300, 100));
layer->setVisibleLayerRect(IntRect(0, 0, 600, 600));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setBounds(IntSize(600, 600));
TransformationMatrix screenTransform;
screenTransform.scale(0.5);
layer->setScreenSpaceTransform(screenTransform);
layer->setDrawTransform(screenTransform * TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(100, 100, 150, 50));
layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
layer->setContentsScale(0.5);
layer->setBounds(IntSize(600, 600));
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(200, 200, 300, 100));
layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
occluded.setOcclusion(IntRect(200, 200, 300, 200));
layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
TransformationMatrix screenTransform;
screenTransform.scale(0.5);
layer->setScreenSpaceTransform(screenTransform);
layer->setDrawTransform(screenTransform * TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
occluded.setOcclusion(IntRect(100, 100, 150, 100));
layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
layer->invalidateRect(IntRect(0, 0, 600, 600));
layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, visibleContentOpaqueRegion)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
IntRect opaquePaintRect;
Region opaqueContents;
IntRect contentBounds = IntRect(0, 0, 100, 200);
IntRect visibleBounds = IntRect(0, 0, 100, 150);
layer->setBounds(contentBounds.size());
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
layer->setVisibleLayerRect(visibleBounds);
layer->setDrawOpacity(1);
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->invalidateRect(contentBounds);
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_TRUE(opaqueContents.isEmpty());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
opaquePaintRect = IntRect(10, 10, 90, 190);
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
layer->invalidateRect(contentBounds);
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
EXPECT_EQ(1u, opaqueContents.rects().size());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
EXPECT_EQ(1u, opaqueContents.rects().size());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->invalidateRect(IntRect(0, 0, 1, 1));
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
EXPECT_EQ(1u, opaqueContents.rects().size());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->invalidateRect(IntRect(10, 10, 1, 1));
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
EXPECT_EQ(1u, opaqueContents.rects().size());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1 + 1, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->idleUpdateLayerRect(updater, contentBounds, &occluded);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1 + 1, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
}
TEST(TiledLayerChromiumTest, pixelsPaintedMetrics)
{
OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
TestCCOcclusionTracker occluded;
CCTextureUpdater updater;
IntRect opaquePaintRect;
Region opaqueContents;
IntRect contentBounds = IntRect(0, 0, 100, 300);
IntRect visibleBounds = IntRect(0, 0, 100, 300);
layer->setBounds(contentBounds.size());
layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
layer->setVisibleLayerRect(visibleBounds);
layer->setDrawOpacity(1);
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->invalidateRect(contentBounds);
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_TRUE(opaqueContents.isEmpty());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
layer->invalidateRect(IntRect(0, 0, 1, 1));
layer->invalidateRect(IntRect(50, 200, 10, 10));
layer->updateLayerRect(updater, contentBounds, &occluded);
opaqueContents = layer->visibleContentOpaqueRegion();
EXPECT_TRUE(opaqueContents.isEmpty());
EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
}
}