// Copyright 2011 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 "cc/layer_tree_host.h"

#include "base/synchronization/lock.h"
#include "cc/content_layer.h"
#include "cc/content_layer_client.h"
#include "cc/layer_impl.h"
#include "cc/layer_tree_host_impl.h"
#include "cc/layer_tree_impl.h"
#include "cc/output_surface.h"
#include "cc/single_thread_proxy.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_proxy.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_test_common.h"
#include "cc/test/occlusion_tracker_test_common.h"
#include "cc/resource_update_queue.h"
#include "cc/timing_function.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/vector2d_conversions.h"
#include <public/WebLayerScrollClient.h>
#include <public/WebSize.h>

namespace cc {
namespace {

class LayerTreeHostTest : public ThreadedTest { };

// Shortlived layerTreeHosts shouldn't die.
class LayerTreeHostTestShortlived1 : public LayerTreeHostTest {
public:
    LayerTreeHostTestShortlived1() { }

    virtual void beginTest() OVERRIDE
    {
        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

// Shortlived layerTreeHosts shouldn't die with a commit in flight.
class LayerTreeHostTestShortlived2 : public LayerTreeHostTest {
public:
    LayerTreeHostTestShortlived2() { }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();

        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived2)

// Shortlived layerTreeHosts shouldn't die with a redraw in flight.
class LayerTreeHostTestShortlived3 : public LayerTreeHostTest {
public:
    LayerTreeHostTestShortlived3() { }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsRedrawToMainThread();

        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived3)

// Test interleaving of redraws and commits
class LayerTreeHostTestCommitingWithContinuousRedraw : public LayerTreeHostTest {
public:
    LayerTreeHostTestCommitingWithContinuousRedraw()
        : m_numCompleteCommits(0)
        , m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        m_numCompleteCommits++;
        if (m_numCompleteCommits == 2)
            endTest();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        if (m_numDraws == 1)
          postSetNeedsCommitToMainThread();
        m_numDraws++;
        postSetNeedsRedrawToMainThread();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCompleteCommits;
    int m_numDraws;
};

TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw, runMultiThread)
{
    runTest(true);
}

// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
// draw with frame 0.
class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetNeedsCommit1()
        : m_numCommits(0)
        , m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_numDraws++;
        if (!impl->activeTree()->source_frame_number())
            endTest();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        m_numCommits++;
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_GE(1, m_numCommits);
        EXPECT_GE(1, m_numDraws);
    }

private:
    int m_numCommits;
    int m_numDraws;
};

TEST_F(LayerTreeHostTestSetNeedsCommit1, DISABLED_runMultiThread)
{
    runTest(true);
}

// A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
// first committed frame draws should lead to another commit.
class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetNeedsCommit2()
        : m_numCommits(0)
        , m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        if (impl->activeTree()->source_frame_number() == 0)
            postSetNeedsCommitToMainThread();
        else if (impl->activeTree()->source_frame_number() == 1)
            endTest();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        m_numCommits++;
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(2, m_numCommits);
        EXPECT_GE(2, m_numDraws);
    }

private:
    int m_numCommits;
    int m_numDraws;
};

TEST_F(LayerTreeHostTestSetNeedsCommit2, runMultiThread)
{
    runTest(true);
}

// 1 setNeedsRedraw after the first commit has completed should lead to 1
// additional draw.
class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetNeedsRedraw()
        : m_numCommits(0)
        , m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        EXPECT_EQ(0, impl->activeTree()->source_frame_number());
        if (!m_numDraws)
            postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
        else
            endTest();
        m_numDraws++;
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        EXPECT_EQ(0, m_numDraws);
        m_numCommits++;
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_GE(2, m_numDraws);
        EXPECT_EQ(1, m_numCommits);
    }

private:
    int m_numCommits;
    int m_numDraws;
};

TEST_F(LayerTreeHostTestSetNeedsRedraw, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
public:
    LayerTreeHostTestNoExtraCommitFromInvalidate()
        : m_rootLayer(ContentLayer::create(&m_client))
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_rootLayer->setAutomaticallyComputeRasterScale(false);
        m_rootLayer->setIsDrawable(true);
        m_rootLayer->setBounds(gfx::Size(1, 1));
        m_layerTreeHost->setRootLayer(m_rootLayer);
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommit() OVERRIDE
    {
        switch (m_layerTreeHost->commitNumber()) {
        case 1:
            // Changing the content bounds will cause a single commit!
            m_rootLayer->setRasterScale(4.0f);
            break;
        default:
            // No extra commits.
            EXPECT_EQ(2, m_layerTreeHost->commitNumber());
            endTest();
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<ContentLayer> m_rootLayer;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate)

class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
public:
    LayerTreeHostTestCompositeAndReadback()
        : m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommit() OVERRIDE
    {
        m_numCommits++;
        if (m_numCommits == 1) {
            char pixels[4];
            m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
        } else if (m_numCommits == 2) {
            // This is inside the readback. We should get another commit after it.
        } else if (m_numCommits == 3) {
            endTest();
        } else {
          NOTREACHED();
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
};

TEST_F(LayerTreeHostTestCompositeAndReadback, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws : public LayerTreeHostTest {
public:
    LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
        : m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommit() OVERRIDE
    {
        m_numCommits++;
        if (m_numCommits == 1) {
            m_layerTreeHost->setNeedsCommit();
        } else if (m_numCommits == 2) {
            char pixels[4];
            m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
        } else if (m_numCommits == 3) {
            // This is inside the readback. We should get another commit after it.
        } else if (m_numCommits == 4) {
            endTest();
        } else {
          NOTREACHED();
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
};

TEST_F(LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws, runMultiThread)
{
    runTest(true);
}

// If the layerTreeHost says it can't draw, then we should not try to draw.
class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
public:
    LayerTreeHostTestCanDrawBlocksDrawing()
        : m_numCommits(0)
        , m_done(false)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        if (m_done)
            return;
        // Only the initial draw should bring us here.
        EXPECT_TRUE(impl->canDraw());
        EXPECT_EQ(0, impl->activeTree()->source_frame_number());
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        if (m_done)
            return;
        if (m_numCommits >= 1) {
            // After the first commit, we should not be able to draw.
            EXPECT_FALSE(impl->canDraw());
        }
    }

    virtual void didCommit() OVERRIDE
    {
        m_numCommits++;
        if (m_numCommits == 1) {
            // Make the viewport empty so the host says it can't draw.
            m_layerTreeHost->setViewportSize(gfx::Size(0, 0), gfx::Size(0, 0));
        } else if (m_numCommits == 2) {
            char pixels[4];
            m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
        } else if (m_numCommits == 3) {
            // Let it draw so we go idle and end the test.
            m_layerTreeHost->setViewportSize(gfx::Size(1, 1), gfx::Size(1, 1));
            m_done = true;
            endTest();
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
    bool m_done;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing)

// beginLayerWrite should prevent draws from executing until a commit occurs
class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
public:
    LayerTreeHostTestWriteLayersRedraw()
        : m_numCommits(0)
        , m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAcquireLayerTextures();
        postSetNeedsRedrawToMainThread(); // should be inhibited without blocking
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_numDraws++;
        EXPECT_EQ(m_numDraws, m_numCommits);
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        m_numCommits++;
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(1, m_numCommits);
    }

private:
    int m_numCommits;
    int m_numDraws;
};

TEST_F(LayerTreeHostTestWriteLayersRedraw, runMultiThread)
{
    runTest(true);
}

// Verify that when resuming visibility, requesting layer write permission
// will not deadlock the main thread even though there are not yet any
// scheduled redraws. This behavior is critical for reliably surviving tab
// switching. There are no failure conditions to this test, it just passes
// by not timing out.
class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
public:
    LayerTreeHostTestWriteLayersAfterVisible()
        : m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        m_numCommits++;
        if (m_numCommits == 2)
            endTest();
        else if (m_numCommits < 2) {
            postSetVisibleToMainThread(false);
            postSetVisibleToMainThread(true);
            postAcquireLayerTextures();
            postSetNeedsCommitToMainThread();
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
};

TEST_F(LayerTreeHostTestWriteLayersAfterVisible, runMultiThread)
{
    runTest(true);
}

// A compositeAndReadback while invisible should force a normal commit without assertion.
class LayerTreeHostTestCompositeAndReadbackWhileInvisible : public LayerTreeHostTest {
public:
    LayerTreeHostTestCompositeAndReadbackWhileInvisible()
        : m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        m_numCommits++;
        if (m_numCommits == 1) {
            m_layerTreeHost->setVisible(false);
            m_layerTreeHost->setNeedsCommit();
            m_layerTreeHost->setNeedsCommit();
            char pixels[4];
            m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
        } else
            endTest();

    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
};

TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
public:
    LayerTreeHostTestAbortFrameWhenInvisible()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        // Request a commit (from the main thread), which will trigger the commit flow from the impl side.
        m_layerTreeHost->setNeedsCommit();
        // Then mark ourselves as not visible before processing any more messages on the main thread.
        m_layerTreeHost->setVisible(false);
        // If we make it without kicking a frame, we pass!
        endTestAfterDelay(1);
    }

    virtual void layout() OVERRIDE
    {
        ASSERT_FALSE(true);
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
};

TEST_F(LayerTreeHostTestAbortFrameWhenInvisible, runMultiThread)
{
    runTest(true);
}

// Makes sure that setNedsAnimate does not cause the commitRequested() state to be set.
class LayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested()
        : m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void animate(base::TimeTicks monotonicTime) OVERRIDE
    {
        // We skip the first commit becasue its the commit that populates the
        // impl thread with a tree. After the second commit, the test is done.
        if (m_numCommits != 1)
            return;

        m_layerTreeHost->setNeedsAnimate();
        // Right now, commitRequested is going to be true, because during
        // beginFrame, we force commitRequested to true to prevent requests from
        // hitting the impl thread. But, when the next didCommit happens, we should
        // verify that commitRequested has gone back to false.
    }

    virtual void didCommit() OVERRIDE
    {
        if (!m_numCommits) {
            EXPECT_FALSE(m_layerTreeHost->commitRequested());
            m_layerTreeHost->setNeedsAnimate();
            EXPECT_FALSE(m_layerTreeHost->commitRequested());
        }

        // Verifies that the setNeedsAnimate we made in ::animate did not
        // trigger commitRequested.
        EXPECT_FALSE(m_layerTreeHost->commitRequested());
        endTest();
        m_numCommits++;
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numCommits;
};

TEST_F(LayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested, runMultiThread)
{
    runTest(true);
}



// Trigger a frame with setNeedsCommit. Then, inside the resulting animate
// callback, requet another frame using setNeedsAnimate. End the test when
// animate gets called yet-again, indicating that the proxy is correctly
// handling the case where setNeedsAnimate() is called inside the begin frame
// flow.
class LayerTreeHostTestSetNeedsAnimateInsideAnimationCallback : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetNeedsAnimateInsideAnimationCallback()
        : m_numAnimates(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsAnimateToMainThread();
    }

    virtual void animate(base::TimeTicks) OVERRIDE
    {
        if (!m_numAnimates) {
            m_layerTreeHost->setNeedsAnimate();
            m_numAnimates++;
            return;
        }
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numAnimates;
};

TEST_F(LayerTreeHostTestSetNeedsAnimateInsideAnimationCallback, runMultiThread)
{
    runTest(true);
}

// Add a layer animation and confirm that LayerTreeHostImpl::animateLayers does get
// called and continues to get called.
class LayerTreeHostTestAddAnimation : public LayerTreeHostTest {
public:
    LayerTreeHostTestAddAnimation()
        : m_numAnimates(0)
        , m_receivedAnimationStartedNotification(false)
        , m_startTime(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddInstantAnimationToMainThread();
    }

    virtual void animateLayers(LayerTreeHostImpl* layerTreeHostImpl, base::TimeTicks monotonicTime) OVERRIDE
    {
        if (!m_numAnimates) {
            // The animation had zero duration so layerTreeHostImpl should no
            // longer need to animate its layers.
            EXPECT_FALSE(layerTreeHostImpl->needsAnimateLayers());
            m_numAnimates++;
            m_firstMonotonicTime = monotonicTime;
            return;
        }
        EXPECT_LT(0, m_startTime);
        EXPECT_TRUE(m_receivedAnimationStartedNotification);
        endTest();
    }

    virtual void notifyAnimationStarted(double wallClockTime) OVERRIDE
    {
        m_receivedAnimationStartedNotification = true;
        m_startTime = wallClockTime;
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numAnimates;
    bool m_receivedAnimationStartedNotification;
    double m_startTime;
    base::TimeTicks m_firstMonotonicTime;
};

TEST_F(LayerTreeHostTestAddAnimation, runMultiThread)
{
    runTest(true);
}

// Add a layer animation to a layer, but continually fail to draw. Confirm that after
// a while, we do eventually force a draw.
class LayerTreeHostTestCheckerboardDoesNotStarveDraws : public LayerTreeHostTest {
public:
    LayerTreeHostTestCheckerboardDoesNotStarveDraws()
        : m_startedAnimating(false)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
    }

    virtual void afterTest() OVERRIDE
    {
    }

    virtual void animateLayers(LayerTreeHostImpl* layerTreeHostImpl, base::TimeTicks monotonicTime) OVERRIDE
    {
        m_startedAnimating = true;
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        if (m_startedAnimating)
            endTest();
    }

    virtual bool prepareToDrawOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        return false;
    }

private:
    bool m_startedAnimating;
};

// Starvation can only be an issue with the MT compositor.
TEST_F(LayerTreeHostTestCheckerboardDoesNotStarveDraws, runMultiThread)
{
    runTest(true);
}

// Ensures that animations continue to be ticked when we are backgrounded.
class LayerTreeHostTestTickAnimationWhileBackgrounded : public LayerTreeHostTest {
public:
    LayerTreeHostTestTickAnimationWhileBackgrounded()
        : m_numAnimates(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
    }

    // Use willAnimateLayers to set visible false before the animation runs and
    // causes a commit, so we block the second visible animate in single-thread
    // mode.
    virtual void willAnimateLayers(LayerTreeHostImpl* layerTreeHostImpl, base::TimeTicks monotonicTime) OVERRIDE
    {
        if (m_numAnimates < 2) {
            if (!m_numAnimates) {
                // We have a long animation running. It should continue to tick even if we are not visible.
                postSetVisibleToMainThread(false);
            }
            m_numAnimates++;
            return;
        }
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_numAnimates;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTickAnimationWhileBackgrounded)

// Ensures that animations continue to be ticked when we are backgrounded.
class LayerTreeHostTestAddAnimationWithTimingFunction : public LayerTreeHostTest {
public:
    LayerTreeHostTestAddAnimationWithTimingFunction()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
    }

    virtual void animateLayers(LayerTreeHostImpl* layerTreeHostImpl, base::TimeTicks monotonicTime) OVERRIDE
    {
        const ActiveAnimation* animation = m_layerTreeHost->rootLayer()->layerAnimationController()->getActiveAnimation(0, ActiveAnimation::Opacity);
        if (!animation)
            return;
        const FloatAnimationCurve* curve = animation->curve()->toFloatAnimationCurve();
        float startOpacity = curve->getValue(0);
        float endOpacity = curve->getValue(curve->duration());
        float linearlyInterpolatedOpacity = 0.25 * endOpacity + 0.75 * startOpacity;
        double time = curve->duration() * 0.25;
        // If the linear timing function associated with this animation was not picked up,
        // then the linearly interpolated opacity would be different because of the
        // default ease timing function.
        EXPECT_FLOAT_EQ(linearlyInterpolatedOpacity, curve->getValue(time));

        const ActiveAnimation* animationImpl = layerTreeHostImpl->rootLayer()->layerAnimationController()->getActiveAnimation(0, ActiveAnimation::Opacity);

        m_layerTreeHost->rootLayer()->layerAnimationController()->removeAnimation(animation->id());
        layerTreeHostImpl->rootLayer()->layerAnimationController()->removeAnimation(animationImpl->id());
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAddAnimationWithTimingFunction)

// Ensures that main thread animations have their start times synchronized with impl thread animations.
class LayerTreeHostTestSynchronizeAnimationStartTimes : public LayerTreeHostTest {
public:
    LayerTreeHostTestSynchronizeAnimationStartTimes()
        : m_mainStartTime(-1)
        , m_implStartTime(-1)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
    }

    virtual void notifyAnimationStarted(double time) OVERRIDE
    {
        LayerAnimationController* controller = m_layerTreeHost->rootLayer()->layerAnimationController();
        ActiveAnimation* animation = controller->getActiveAnimation(0, ActiveAnimation::Opacity);
        m_mainStartTime = animation->startTime();
        controller->removeAnimation(animation->id());

        if (m_implStartTime > 0)
            endTest();
    }

    virtual void animateLayers(LayerTreeHostImpl* impl, base::TimeTicks monotonicTime)
    {
        LayerAnimationController* controller = impl->rootLayer()->layerAnimationController();
        ActiveAnimation* animation = controller->getActiveAnimation(0, ActiveAnimation::Opacity);
        if (!animation)
            return;

        m_implStartTime = animation->startTime();
        controller->removeAnimation(animation->id());

        if (m_mainStartTime > 0)
            endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_FLOAT_EQ(m_implStartTime, m_mainStartTime);
    }

private:
    double m_mainStartTime;
    double m_implStartTime;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSynchronizeAnimationStartTimes)

// Ensures that main thread animations have their start times synchronized with impl thread animations.
class LayerTreeHostTestAnimationFinishedEvents : public LayerTreeHostTest {
public:
    LayerTreeHostTestAnimationFinishedEvents()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postAddInstantAnimationToMainThread();
    }

    virtual void notifyAnimationFinished(double time) OVERRIDE
    {
        const ActiveAnimation* animation = m_layerTreeHost->rootLayer()->layerAnimationController()->getActiveAnimation(0, ActiveAnimation::Opacity);
        m_layerTreeHost->rootLayer()->layerAnimationController()->removeAnimation(animation->id());
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAnimationFinishedEvents)

class LayerTreeHostTestScrollSimple : public LayerTreeHostTest {
public:
    LayerTreeHostTestScrollSimple()
        : m_initialScroll(10, 20)
        , m_secondScroll(40, 5)
        , m_scrollAmount(2, -1)
        , m_scrolls(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->rootLayer()->setScrollable(true);
        m_layerTreeHost->rootLayer()->setScrollOffset(m_initialScroll);
        postSetNeedsCommitToMainThread();
    }

    virtual void layout() OVERRIDE
    {
        Layer* root = m_layerTreeHost->rootLayer();
        if (!m_layerTreeHost->commitNumber())
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll);
        else {
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount);

            // Pretend like Javascript updated the scroll position itself.
            root->setScrollOffset(m_secondScroll);
        }
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        LayerImpl* root = impl->rootLayer();
        EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d());

        root->setScrollable(true);
        root->setMaxScrollOffset(gfx::Vector2d(100, 100));
        root->scrollBy(m_scrollAmount);

        if (!impl->activeTree()->source_frame_number()) {
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll);
            EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount);
            postSetNeedsCommitToMainThread();
        } else if (impl->activeTree()->source_frame_number() == 1) {
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_secondScroll);
            EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount);
            endTest();
        }
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset();
        m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta);
        m_scrolls++;
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(1, m_scrolls);
    }
private:
    gfx::Vector2d m_initialScroll;
    gfx::Vector2d m_secondScroll;
    gfx::Vector2d m_scrollAmount;
    int m_scrolls;
};

TEST_F(LayerTreeHostTestScrollSimple, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestScrollMultipleRedraw : public LayerTreeHostTest {
public:
    LayerTreeHostTestScrollMultipleRedraw()
        : m_initialScroll(40, 10)
        , m_scrollAmount(-3, 17)
        , m_scrolls(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->rootLayer()->setScrollable(true);
        m_layerTreeHost->rootLayer()->setScrollOffset(m_initialScroll);
        postSetNeedsCommitToMainThread();
    }

    virtual void beginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        Layer* root = m_layerTreeHost->rootLayer();
        if (!m_layerTreeHost->commitNumber())
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll);
        else if (m_layerTreeHost->commitNumber() == 1)
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount);
        else if (m_layerTreeHost->commitNumber() == 2)
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount);
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        LayerImpl* root = impl->rootLayer();
        root->setScrollable(true);
        root->setMaxScrollOffset(gfx::Vector2d(100, 100));

        if (!impl->activeTree()->source_frame_number() && impl->sourceAnimationFrameNumber() == 1) {
            // First draw after first commit.
            EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d());
            root->scrollBy(m_scrollAmount);
            EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount);

            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll);
            postSetNeedsRedrawToMainThread();
        } else if (!impl->activeTree()->source_frame_number() && impl->sourceAnimationFrameNumber() == 2) {
            // Second draw after first commit.
            EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
            root->scrollBy(m_scrollAmount);
            EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount + m_scrollAmount);

            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll);
            postSetNeedsCommitToMainThread();
        } else if (impl->activeTree()->source_frame_number() == 1) {
            // Third or later draw after second commit.
            EXPECT_GE(impl->sourceAnimationFrameNumber(), 3);
            EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d());
            EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount);
            endTest();
        }
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset();
        m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta);
        m_scrolls++;
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(1, m_scrolls);
    }
private:
    gfx::Vector2d m_initialScroll;
    gfx::Vector2d m_scrollAmount;
    int m_scrolls;
};

TEST_F(LayerTreeHostTestScrollMultipleRedraw, runMultiThread)
{
    runTest(true);
}

// This test verifies that properties on the layer tree host are commited to the impl side.
class LayerTreeHostTestCommit : public LayerTreeHostTest {
public:

    LayerTreeHostTestCommit() { }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(20, 20), gfx::Size(20, 20));
        m_layerTreeHost->setBackgroundColor(SK_ColorGRAY);
        m_layerTreeHost->setPageScaleFactorAndLimits(5, 5, 5);

        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        EXPECT_EQ(gfx::Size(20, 20), impl->layoutViewportSize());
        EXPECT_EQ(SK_ColorGRAY, impl->backgroundColor());
        EXPECT_EQ(5, impl->pageScaleFactor());

        endTest();
    }

    virtual void afterTest() OVERRIDE { }
};

TEST_F(LayerTreeHostTestCommit, runTest)
{
    runTest(true);
}

// Verifies that startPageScaleAnimation events propagate correctly from LayerTreeHost to
// LayerTreeHostImpl in the MT compositor.
class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
public:

    LayerTreeHostTestStartPageScaleAnimation()
        : m_animationRequested(false)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->rootLayer()->setScrollable(true);
        m_layerTreeHost->rootLayer()->setScrollOffset(gfx::Vector2d());
        postSetNeedsCommitToMainThread();
        postSetNeedsRedrawToMainThread();
    }

    void requestStartPageScaleAnimation()
    {
        layerTreeHost()->startPageScaleAnimation(gfx::Vector2d(), false, 1.25, base::TimeDelta());
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        impl->rootLayer()->setScrollable(true);
        impl->rootLayer()->setScrollOffset(gfx::Vector2d());
        impl->setPageScaleFactorAndLimits(impl->pageScaleFactor(), 0.5, 2);

        // We request animation only once.
        if (!m_animationRequested) {
            m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&LayerTreeHostTestStartPageScaleAnimation::requestStartPageScaleAnimation, base::Unretained(this)));
            m_animationRequested = true;
        }
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset();
        m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta);
        m_layerTreeHost->setPageScaleFactorAndLimits(scale, 0.5, 2);
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        impl->processScrollDeltas();
        // We get one commit before the first draw, and the animation doesn't happen until the second draw.
        if (impl->activeTree()->source_frame_number() == 1) {
            EXPECT_EQ(1.25, impl->pageScaleFactor());
            endTest();
        } else
            postSetNeedsRedrawToMainThread();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    bool m_animationRequested;
};

TEST_F(LayerTreeHostTestStartPageScaleAnimation, runTest)
{
    runTest(true);
}

class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
public:

    LayerTreeHostTestSetVisible()
        : m_numDraws(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
        postSetVisibleToMainThread(false);
        postSetNeedsRedrawToMainThread(); // This is suppressed while we're invisible.
        postSetVisibleToMainThread(true); // Triggers the redraw.
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        EXPECT_TRUE(impl->visible());
        ++m_numDraws;
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(1, m_numDraws);
    }

private:
    int m_numDraws;
};

TEST_F(LayerTreeHostTestSetVisible, runMultiThread)
{
    runTest(true);
}

class TestOpacityChangeLayerDelegate : public ContentLayerClient {
public:
    TestOpacityChangeLayerDelegate()
        : m_testLayer(0)
    {
    }

    void setTestLayer(Layer* testLayer)
    {
        m_testLayer = testLayer;
    }

    virtual void paintContents(SkCanvas*, const gfx::Rect&, gfx::RectF&) OVERRIDE
    {
        // Set layer opacity to 0.
        if (m_testLayer)
            m_testLayer->setOpacity(0);
    }

private:
    Layer* m_testLayer;
};

class ContentLayerWithUpdateTracking : public ContentLayer {
public:
    static scoped_refptr<ContentLayerWithUpdateTracking> create(ContentLayerClient* client) { return make_scoped_refptr(new ContentLayerWithUpdateTracking(client)); }

    int paintContentsCount() { return m_paintContentsCount; }
    void resetPaintContentsCount() { m_paintContentsCount = 0; }

    virtual void update(ResourceUpdateQueue& queue, const OcclusionTracker* occlusion, RenderingStats& stats) OVERRIDE
    {
        ContentLayer::update(queue, occlusion, stats);
        m_paintContentsCount++;
    }

private:
    explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
        : ContentLayer(client)
        , m_paintContentsCount(0)
    {
        setAnchorPoint(gfx::PointF(0, 0));
        setBounds(gfx::Size(10, 10));
        setIsDrawable(true);
    }
    virtual ~ContentLayerWithUpdateTracking()
    {
    }

    int m_paintContentsCount;
};

// Layer opacity change during paint should not prevent compositor resources from being updated during commit.
class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
public:
    LayerTreeHostTestOpacityChange()
        : m_testOpacityChangeDelegate()
        , m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_testOpacityChangeDelegate))
    {
        m_testOpacityChangeDelegate.setTestLayer(m_updateCheckLayer.get());
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
        m_layerTreeHost->rootLayer()->addChild(m_updateCheckLayer);

        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        // update() should have been called once.
        EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount());

        // clear m_updateCheckLayer so LayerTreeHost dies.
        m_updateCheckLayer = NULL;
    }

private:
    TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate;
    scoped_refptr<ContentLayerWithUpdateTracking> m_updateCheckLayer;
};

TEST_F(LayerTreeHostTestOpacityChange, runMultiThread)
{
    runTest(true);
}

class NoScaleContentLayer : public ContentLayer {
public:
    static scoped_refptr<NoScaleContentLayer> create(ContentLayerClient* client) { return make_scoped_refptr(new NoScaleContentLayer(client)); }

    virtual void calculateContentsScale(
        float idealContentsScale,
        float* contentsScaleX,
        float* contentsScaleY,
        gfx::Size* contentBounds) OVERRIDE
    {
        Layer::calculateContentsScale(
             idealContentsScale,
             contentsScaleX,
             contentsScaleY,
             contentBounds);
    }

private:
    explicit NoScaleContentLayer(ContentLayerClient* client)
        : ContentLayer(client) { }
    virtual ~NoScaleContentLayer() { }
};

// Ensures that when opacity is being animated, this value does not cause the subtree to be skipped.
class LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public LayerTreeHostTest {
public:
    LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity()
        : m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_client))
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
        m_layerTreeHost->rootLayer()->addChild(m_updateCheckLayer);
        m_updateCheckLayer->setOpacity(0);
        m_updateCheckLayer->drawProperties().opacity = 0;
        postAddAnimationToMainThread(m_updateCheckLayer.get());
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        // update() should have been called once, proving that the layer was not skipped.
        EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount());

        // clear m_updateCheckLayer so LayerTreeHost dies.
        m_updateCheckLayer = NULL;
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<ContentLayerWithUpdateTracking> m_updateCheckLayer;
};

TEST_F(LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread)
{
    runTest(true);
}


class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public LayerTreeHostTest {
public:

    LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
        : m_rootLayer(NoScaleContentLayer::create(&m_client))
        , m_childLayer(ContentLayer::create(&m_client))
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(40, 40), gfx::Size(60, 60));
        m_layerTreeHost->setDeviceScaleFactor(1.5);
        EXPECT_EQ(gfx::Size(40, 40), m_layerTreeHost->layoutViewportSize());
        EXPECT_EQ(gfx::Size(60, 60), m_layerTreeHost->deviceViewportSize());

        m_rootLayer->addChild(m_childLayer);

        m_rootLayer->setIsDrawable(true);
        m_rootLayer->setBounds(gfx::Size(30, 30));
        m_rootLayer->setAnchorPoint(gfx::PointF(0, 0));

        m_childLayer->setIsDrawable(true);
        m_childLayer->setPosition(gfx::Point(2, 2));
        m_childLayer->setBounds(gfx::Size(10, 10));
        m_childLayer->setAnchorPoint(gfx::PointF(0, 0));

        m_layerTreeHost->setRootLayer(m_rootLayer);

        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        // Get access to protected methods.
        MockLayerTreeHostImpl* mockImpl = static_cast<MockLayerTreeHostImpl*>(impl);

        // Should only do one commit.
        EXPECT_EQ(0, impl->activeTree()->source_frame_number());
        // Device scale factor should come over to impl.
        EXPECT_NEAR(impl->deviceScaleFactor(), 1.5, 0.00001);

        // Both layers are on impl.
        ASSERT_EQ(1u, impl->rootLayer()->children().size());

        // Device viewport is scaled.
        EXPECT_EQ(gfx::Size(40, 40), impl->layoutViewportSize());
        EXPECT_EQ(gfx::Size(60, 60), impl->deviceViewportSize());

        LayerImpl* root = impl->rootLayer();
        LayerImpl* child = impl->rootLayer()->children()[0];

        // Positions remain in layout pixels.
        EXPECT_EQ(gfx::Point(0, 0), root->position());
        EXPECT_EQ(gfx::Point(2, 2), child->position());

        // Compute all the layer transforms for the frame.
        MockLayerTreeHostImpl::LayerList renderSurfaceLayerList;
        mockImpl->calculateRenderSurfaceLayerList(renderSurfaceLayerList);

        // Both layers should be drawing into the root render surface.
        ASSERT_EQ(1u, renderSurfaceLayerList.size());
        ASSERT_EQ(root->renderSurface(), renderSurfaceLayerList[0]->renderSurface());
        ASSERT_EQ(2u, root->renderSurface()->layerList().size());

        // The root render surface is the size of the viewport.
        EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60), root->renderSurface()->contentRect());

        // The content bounds of the child should be scaled.
        gfx::Size childBoundsScaled = gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
        EXPECT_EQ(childBoundsScaled, child->contentBounds());

        gfx::Transform scaleTransform;
        scaleTransform.Scale(impl->deviceScaleFactor(), impl->deviceScaleFactor());

        // The root layer is scaled by 2x.
        gfx::Transform rootScreenSpaceTransform = scaleTransform;
        gfx::Transform rootDrawTransform = scaleTransform;

        EXPECT_EQ(rootDrawTransform, root->drawTransform());
        EXPECT_EQ(rootScreenSpaceTransform, root->screenSpaceTransform());

        // The child is at position 2,2, which is transformed to 3,3 after the scale
        gfx::Transform childScreenSpaceTransform;
        childScreenSpaceTransform.Translate(3, 3);
        gfx::Transform childDrawTransform = childScreenSpaceTransform;

        EXPECT_TRANSFORMATION_MATRIX_EQ(childDrawTransform, child->drawTransform());
        EXPECT_TRANSFORMATION_MATRIX_EQ(childScreenSpaceTransform, child->screenSpaceTransform());

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        m_rootLayer = NULL;
        m_childLayer = NULL;
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<NoScaleContentLayer> m_rootLayer;
    scoped_refptr<ContentLayer> m_childLayer;
};

TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers, runMultiThread)
{
    runTest(true);
}

// Verify atomicity of commits and reuse of textures.
class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
public:
    LayerTreeHostTestAtomicCommit()
        : m_layer(ContentLayerWithUpdateTracking::create(&m_client))
    {
        // Make sure partial texture updates are turned off.
        m_settings.maxPartialTextureUpdates = 0;
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setRootLayer(m_layer);
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));

        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->outputSurface()->Context3D());

        switch (impl->activeTree()->source_frame_number()) {
        case 0:
            // Number of textures should be one.
            ASSERT_EQ(1, context->numTextures());
            // Number of textures used for commit should be one.
            EXPECT_EQ(1, context->numUsedTextures());
            // Verify that used texture is correct.
            EXPECT_TRUE(context->usedTexture(context->texture(0)));

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 1:
            // Number of textures should be two as the first texture
            // is used by impl thread and cannot by used for update.
            ASSERT_EQ(2, context->numTextures());
            // Number of textures used for commit should still be one.
            EXPECT_EQ(1, context->numUsedTextures());
            // First texture should not have been used.
            EXPECT_FALSE(context->usedTexture(context->texture(0)));
            // New texture should have been used.
            EXPECT_TRUE(context->usedTexture(context->texture(1)));

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 2:
            endTest();
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->outputSurface()->Context3D());

        // Number of textures used for draw should always be one.
        EXPECT_EQ(1, context->numUsedTextures());
        context->resetUsedTextures();
    }

    virtual void layout() OVERRIDE
    {
        m_layer->setNeedsDisplay();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<ContentLayerWithUpdateTracking> m_layer;
};

TEST_F(LayerTreeHostTestAtomicCommit, runMultiThread)
{
    runTest(true);
}

static void setLayerPropertiesForTesting(Layer* layer, Layer* parent, const gfx::Transform& transform, const gfx::PointF& anchor, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
{
    layer->removeAllChildren();
    if (parent)
        parent->addChild(layer);
    layer->setTransform(transform);
    layer->setAnchorPoint(anchor);
    layer->setPosition(position);
    layer->setBounds(bounds);
    layer->setContentsOpaque(opaque);
}

class LayerTreeHostTestAtomicCommitWithPartialUpdate : public LayerTreeHostTest {
public:
    LayerTreeHostTestAtomicCommitWithPartialUpdate()
        : m_parent(ContentLayerWithUpdateTracking::create(&m_client))
        , m_child(ContentLayerWithUpdateTracking::create(&m_client))
        , m_numCommits(0)
    {
        // Allow one partial texture update.
        m_settings.maxPartialTextureUpdates = 1;
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setRootLayer(m_parent);
        m_layerTreeHost->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));

        gfx::Transform identityMatrix;
        setLayerPropertiesForTesting(m_parent.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(10, 20), true);
        setLayerPropertiesForTesting(m_child.get(), m_parent.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 10), gfx::Size(10, 10), false);

        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->outputSurface()->Context3D());

        switch (impl->activeTree()->source_frame_number()) {
        case 0:
            // Number of textures should be two.
            ASSERT_EQ(2, context->numTextures());
            // Number of textures used for commit should be two.
            EXPECT_EQ(2, context->numUsedTextures());
            // Verify that used textures are correct.
            EXPECT_TRUE(context->usedTexture(context->texture(0)));
            EXPECT_TRUE(context->usedTexture(context->texture(1)));

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 1:
            // Number of textures used for commit should still be two.
            EXPECT_EQ(2, context->numUsedTextures());
            // First two textures should not have been used.
            EXPECT_FALSE(context->usedTexture(context->texture(0)));
            EXPECT_FALSE(context->usedTexture(context->texture(1)));
            // New textures should have been used.
            EXPECT_TRUE(context->usedTexture(context->texture(2)));
            EXPECT_TRUE(context->usedTexture(context->texture(3)));

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 2:
            // Number of textures used for commit should still be two.
            EXPECT_EQ(2, context->numUsedTextures());

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 3:
            // No textures should be used for commit.
            EXPECT_EQ(0, context->numUsedTextures());

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 4:
            // Number of textures used for commit should be one.
            EXPECT_EQ(1, context->numUsedTextures());

            context->resetUsedTextures();
            postSetNeedsCommitToMainThread();
            break;
        case 5:
            endTest();
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->outputSurface()->Context3D());

        // Number of textures used for drawing should two except for frame 4
        // where the viewport only contains one layer.
        if (impl->activeTree()->source_frame_number() == 3)
            EXPECT_EQ(1, context->numUsedTextures());
        else
            EXPECT_EQ(2, context->numUsedTextures());

        context->resetUsedTextures();
    }

    virtual void layout() OVERRIDE
    {
        switch (m_numCommits++) {
        case 0:
        case 1:
            m_parent->setNeedsDisplay();
            m_child->setNeedsDisplay();
            break;
        case 2:
            // Damage part of layers.
            m_parent->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
            m_child->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
            break;
        case 3:
            m_child->setNeedsDisplay();
            m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
            break;
        case 4:
            m_layerTreeHost->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
            break;
        case 5:
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<ContentLayerWithUpdateTracking> m_parent;
    scoped_refptr<ContentLayerWithUpdateTracking> m_child;
    int m_numCommits;
};

TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate, runMultiThread)
{
    runTest(true);
}

class TestLayer : public Layer {
public:
    static scoped_refptr<TestLayer> create() { return make_scoped_refptr(new TestLayer()); }

    virtual void update(ResourceUpdateQueue&, const OcclusionTracker* occlusion, RenderingStats&) OVERRIDE
    {
        // Gain access to internals of the OcclusionTracker.
        const TestOcclusionTracker* testOcclusion = static_cast<const TestOcclusionTracker*>(occlusion);
        if (!testOcclusion) {
            m_occlusion.Clear();
            return;
        }
        m_occlusion = UnionRegions(testOcclusion->occlusionFromInsideTarget(), testOcclusion->occlusionFromOutsideTarget());
    }

    virtual bool drawsContent() const OVERRIDE { return true; }

    const Region& occlusion() const { return m_occlusion; }
    void clearOcclusion() { m_occlusion.Clear(); }

private:
    TestLayer() : Layer() { }
    virtual ~TestLayer() { }

    Region m_occlusion;
};

static void setTestLayerPropertiesForTesting(TestLayer* layer, Layer* parent, const gfx::Transform& transform, const gfx::PointF& anchor, const gfx::PointF& position, const gfx::Size& bounds, bool opaque)
{
    setLayerPropertiesForTesting(layer, parent, transform, anchor, position, bounds, opaque);
    layer->clearOcclusion();
}

class LayerTreeHostTestLayerOcclusion : public LayerTreeHostTest {
public:
    LayerTreeHostTestLayerOcclusion() { }

    virtual void beginTest() OVERRIDE
    {
        scoped_refptr<TestLayer> rootLayer = TestLayer::create();
        scoped_refptr<TestLayer> child = TestLayer::create();
        scoped_refptr<TestLayer> child2 = TestLayer::create();
        scoped_refptr<TestLayer> grandChild = TestLayer::create();
        scoped_refptr<TestLayer> mask = TestLayer::create();

        gfx::Transform identityMatrix;

        child->setMasksToBounds(true);
        child->setForceRenderSurface(true);

        // See LayerTreeHostCommonTest.layerAddsSelfToOccludedRegionWithRotatedSurface for a nice visual of these layers and how they end up
        // positioned on the screen.

        // The child layer is a surface and the grandChild is opaque, but clipped to the child and rootLayer
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), false);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 10, 10, 190).ToString(), rootLayer->occlusion().ToString());

        // If the child layer is opaque, then it adds to the occlusion seen by the rootLayer.
        setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 10, 190, 190).ToString(), rootLayer->occlusion().ToString());

        // Add a second child to the root layer and the regions should merge
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), false);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);
        setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true);

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 10, 20, 190).ToString(), rootLayer->occlusion().ToString());

        // If the child layer has a mask on it, then it shouldn't contribute to occlusion on stuff below it
        setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 20), gfx::Size(500, 500), true);
        setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(500, 500), true);

        child->setMaskLayer(mask.get());

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 180, 180).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 10, 190, 190).ToString(), rootLayer->occlusion().ToString());

        // If the child layer with a mask is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer
        setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);
        setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true);

        child->setMaskLayer(mask.get());

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(20, 10, 10, 190), rootLayer->occlusion());

        // If the child layer has a non-opaque drawOpacity, then it shouldn't contribute to occlusion on stuff below it
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);

        child->setMaskLayer(0);
        child->setOpacity(0.5);

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(20, 10, 10, 190).ToString(), rootLayer->occlusion().ToString());

        // If the child layer with non-opaque drawOpacity is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true);
        setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true);

        child->setMaskLayer(0);
        child->setOpacity(0.5);

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(20, 10, 10, 190).ToString(), rootLayer->occlusion().ToString());

        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLayerOcclusion)

class LayerTreeHostTestLayerOcclusionWithFilters : public LayerTreeHostTest {
public:
    LayerTreeHostTestLayerOcclusionWithFilters() { }

    virtual void beginTest() OVERRIDE
    {
        scoped_refptr<TestLayer> rootLayer = TestLayer::create();
        scoped_refptr<TestLayer> child = TestLayer::create();
        scoped_refptr<TestLayer> child2 = TestLayer::create();
        scoped_refptr<TestLayer> grandChild = TestLayer::create();
        scoped_refptr<TestLayer> mask = TestLayer::create();

        gfx::Transform identityMatrix;
        gfx::Transform childTransform;
        childTransform.Translate(250, 250);
        childTransform.Rotate(90);
        childTransform.Translate(-250, -250);

        child->setMasksToBounds(true);

        // If the child layer has a filter that changes alpha values, and is below child2, then child2 should contribute to occlusion on everything,
        // and child shouldn't contribute to the rootLayer
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true);

        {
            WebKit::WebFilterOperations filters;
            filters.append(WebKit::WebFilterOperation::createOpacityFilter(0.5));
            child->setFilters(filters);
        }

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(40, 330, 130, 190).ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(UnionRegions(gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20)).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occlusion().ToString());

        // If the child layer has a filter that moves pixels/changes alpha, and is below child2, then child should not inherit occlusion from outside its subtree,
        // and should not contribute to the rootLayer
        setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
        setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true);
        setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true);

        {
            WebKit::WebFilterOperations filters;
            filters.append(WebKit::WebFilterOperation::createBlurFilter(10));
            child->setFilters(filters);
        }

        m_layerTreeHost->setRootLayer(rootLayer);
        m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString());
        EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 330, 160, 170).ToString(), child->occlusion().ToString());
        EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occlusion().ToString());

        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        LayerTreeHost::setNeedsFilterContext(false);
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLayerOcclusionWithFilters)

class LayerTreeHostTestManySurfaces : public LayerTreeHostTest {
public:
    LayerTreeHostTestManySurfaces() { }

    virtual void beginTest() OVERRIDE
    {
        // We create enough RenderSurfaces that it will trigger Vector reallocation while computing occlusion.
        Region occluded;
        const gfx::Transform identityMatrix;
        std::vector<scoped_refptr<TestLayer> > layers;
        std::vector<scoped_refptr<TestLayer> > children;
        int numSurfaces = 20;
        scoped_refptr<TestLayer> replica = TestLayer::create();

        for (int i = 0; i < numSurfaces; ++i) {
            layers.push_back(TestLayer::create());
            if (!i) {
                setTestLayerPropertiesForTesting(layers.back().get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true);
                layers.back()->createRenderSurface();
            } else {
                setTestLayerPropertiesForTesting(layers.back().get(), layers[layers.size()-2].get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(1, 1), gfx::Size(200-i, 200-i), true);
                layers.back()->setMasksToBounds(true);
                layers.back()->setReplicaLayer(replica.get()); // Make it have a RenderSurfaceImpl
            }
        }

        for (int i = 1; i < numSurfaces; ++i) {
            children.push_back(TestLayer::create());
            setTestLayerPropertiesForTesting(children.back().get(), layers[i].get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(500, 500), false);
        }

        m_layerTreeHost->setRootLayer(layers[0].get());
        m_layerTreeHost->setViewportSize(layers[0]->bounds(), layers[0]->bounds());
        ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded());
        ResourceUpdateQueue queue;
        m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
        m_layerTreeHost->commitComplete();

        for (int i = 0; i < numSurfaces-1; ++i) {
            gfx::Rect expectedOcclusion(1, 1, 200-i-1, 200-i-1);
            EXPECT_EQ(expectedOcclusion.ToString(), layers[i]->occlusion().ToString());
        }

        // Kill the layerTreeHost immediately.
        m_layerTreeHost->setRootLayer(0);
        m_layerTreeHost.reset();

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestManySurfaces)

// A loseOutputSurface(1) should lead to a didRecreateOutputSurface(true)
class LayerTreeHostTestSetSingleLostContext : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetSingleLostContext()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        m_layerTreeHost->loseOutputSurface(1);
    }

    virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE
    {
        EXPECT_TRUE(succeeded);
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

TEST_F(LayerTreeHostTestSetSingleLostContext, runMultiThread)
{
    runTest(true);
}

// A loseOutputSurface(10) should lead to a didRecreateOutputSurface(false), and
// a finishAllRendering() should not hang.
class LayerTreeHostTestSetRepeatedLostContext : public LayerTreeHostTest {
public:
    LayerTreeHostTestSetRepeatedLostContext()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        m_layerTreeHost->loseOutputSurface(10);
    }

    virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE
    {
        EXPECT_FALSE(succeeded);
        m_layerTreeHost->finishAllRendering();
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

TEST_F(LayerTreeHostTestSetRepeatedLostContext, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestFractionalScroll : public LayerTreeHostTest {
public:
    LayerTreeHostTestFractionalScroll()
        : m_scrollAmount(1.75, 0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->rootLayer()->setScrollable(true);
        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        LayerImpl* root = impl->rootLayer();
        root->setMaxScrollOffset(gfx::Vector2d(100, 100));

        // Check that a fractional scroll delta is correctly accumulated over multiple commits.
        if (!impl->activeTree()->source_frame_number()) {
            EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::Vector2d(0, 0));
            EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d(0, 0));
            postSetNeedsCommitToMainThread();
        } else if (impl->activeTree()->source_frame_number() == 1) {
            EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::ToFlooredVector2d(m_scrollAmount));
            EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2dF(fmod(m_scrollAmount.x(), 1), 0));
            postSetNeedsCommitToMainThread();
        } else if (impl->activeTree()->source_frame_number() == 2) {
            EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::ToFlooredVector2d(m_scrollAmount + m_scrollAmount));
            EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2dF(fmod(2 * m_scrollAmount.x(), 1), 0));
            endTest();
        }
        root->scrollBy(m_scrollAmount);
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset();
        m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta);
    }

    virtual void afterTest() OVERRIDE
    {
    }
private:
    gfx::Vector2dF m_scrollAmount;
};

TEST_F(LayerTreeHostTestFractionalScroll, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
public:
    LayerTreeHostTestFinishAllRendering()
        : m_once(false)
        , m_drawCount(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setNeedsRedraw();
        postSetNeedsCommitToMainThread();
    }

    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        if (m_once)
            return;
        m_once = true;
        m_layerTreeHost->setNeedsRedraw();
        m_layerTreeHost->acquireLayerTextures();
        {
            base::AutoLock lock(m_lock);
            m_drawCount = 0;
        }
        m_layerTreeHost->finishAllRendering();
        {
            base::AutoLock lock(m_lock);
            EXPECT_EQ(0, m_drawCount);
        }
        endTest();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        base::AutoLock lock(m_lock);
        ++m_drawCount;
    }

    virtual void afterTest() OVERRIDE
    {
    }
private:

    bool m_once;
    base::Lock m_lock;
    int m_drawCount;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering)

// Layers added to tree with existing active animations should have the animation
// correctly recognized.
class LayerTreeHostTestLayerAddedWithAnimation : public LayerTreeHostTest {
public:
    LayerTreeHostTestLayerAddedWithAnimation()
        : m_addedAnimation(false)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        EXPECT_FALSE(m_addedAnimation);

        scoped_refptr<Layer> layer = Layer::create();
        layer->setLayerAnimationDelegate(this);

        // Any valid AnimationCurve will do here.
        scoped_ptr<AnimationCurve> curve(EaseTimingFunction::create());
        scoped_ptr<ActiveAnimation> animation(ActiveAnimation::create(curve.Pass(), 1, 1, ActiveAnimation::Opacity));
        layer->layerAnimationController()->addAnimation(animation.Pass());

        // We add the animation *before* attaching the layer to the tree.
        m_layerTreeHost->rootLayer()->addChild(layer);
        EXPECT_TRUE(m_addedAnimation);

        endTest();
    }

    virtual void didAddAnimation() OVERRIDE
    {
        m_addedAnimation = true;
    }

    virtual void afterTest() OVERRIDE { }

private:
    bool m_addedAnimation;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLayerAddedWithAnimation)

class LayerTreeHostTestScrollChildLayer : public LayerTreeHostTest, public WebKit::WebLayerScrollClient {
public:
    LayerTreeHostTestScrollChildLayer(float deviceScaleFactor)
        : m_deviceScaleFactor(deviceScaleFactor)
        , m_initialScroll(10, 20)
        , m_secondScroll(40, 5)
        , m_scrollAmount(2, -1)
        , m_rootScrolls(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        gfx::Size viewportSize(10, 10);
        gfx::Size deviceViewportSize = gfx::ToCeiledSize(gfx::ScaleSize(viewportSize, m_deviceScaleFactor));
        m_layerTreeHost->setViewportSize(viewportSize, deviceViewportSize);

        m_layerTreeHost->setDeviceScaleFactor(m_deviceScaleFactor);

        m_rootScrollLayer = ContentLayer::create(&m_fakeDelegate);
        m_rootScrollLayer->setBounds(gfx::Size(110, 110));

        m_rootScrollLayer->setPosition(gfx::PointF(0, 0));
        m_rootScrollLayer->setAnchorPoint(gfx::PointF(0, 0));

        m_rootScrollLayer->setIsDrawable(true);
        m_rootScrollLayer->setScrollable(true);
        m_rootScrollLayer->setMaxScrollOffset(gfx::Vector2d(100, 100));
        m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer);

        m_childLayer = ContentLayer::create(&m_fakeDelegate);
        m_childLayer->setLayerScrollClient(this);
        m_childLayer->setBounds(gfx::Size(110, 110));

        // The scrolls will happen at 5, 5. If they are treated like device pixels, then
        // they will be at 2.5, 2.5 in logical pixels, and will miss this layer.
        m_childLayer->setPosition(gfx::PointF(5, 5));
        m_childLayer->setAnchorPoint(gfx::PointF(0, 0));

        m_childLayer->setIsDrawable(true);
        m_childLayer->setScrollable(true);
        m_childLayer->setMaxScrollOffset(gfx::Vector2d(100, 100));
        m_rootScrollLayer->addChild(m_childLayer);

        m_childLayer->setScrollOffset(m_initialScroll);

        postSetNeedsCommitToMainThread();
    }

    virtual void didScroll() OVERRIDE
    {
        m_finalScrollOffset = m_childLayer->scrollOffset();
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_rootScrollLayer->scrollOffset();
        m_rootScrollLayer->setScrollOffset(offset + scrollDelta);
        m_rootScrolls++;
    }

    virtual void layout() OVERRIDE
    {
        EXPECT_VECTOR_EQ(gfx::Vector2d(), m_rootScrollLayer->scrollOffset());

        switch (m_layerTreeHost->commitNumber()) {
        case 0:
            EXPECT_VECTOR_EQ(m_initialScroll, m_childLayer->scrollOffset());
            break;
        case 1:
            EXPECT_VECTOR_EQ(m_initialScroll + m_scrollAmount, m_childLayer->scrollOffset());

            // Pretend like Javascript updated the scroll position itself.
            m_childLayer->setScrollOffset(m_secondScroll);
            break;
        case 2:
            EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_childLayer->scrollOffset());
            break;
        }
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        LayerImpl* root = impl->rootLayer();
        LayerImpl* rootScrollLayer = root->children()[0];
        LayerImpl* childLayer = rootScrollLayer->children()[0];

        EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d());
        EXPECT_VECTOR_EQ(rootScrollLayer->scrollDelta(), gfx::Vector2d());
        EXPECT_EQ(rootScrollLayer->bounds().width() * m_deviceScaleFactor, rootScrollLayer->contentBounds().width());
        EXPECT_EQ(rootScrollLayer->bounds().height() * m_deviceScaleFactor, rootScrollLayer->contentBounds().height());
        EXPECT_EQ(childLayer->bounds().width() * m_deviceScaleFactor, childLayer->contentBounds().width());
        EXPECT_EQ(childLayer->bounds().height() * m_deviceScaleFactor, childLayer->contentBounds().height());

        switch (impl->activeTree()->source_frame_number()) {
        case 0:
            // Gesture scroll on impl thread.
            EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Gesture), InputHandlerClient::ScrollStarted);
            impl->scrollBy(gfx::Point(), m_scrollAmount);
            impl->scrollEnd();

            EXPECT_VECTOR_EQ(m_initialScroll, childLayer->scrollOffset());
            EXPECT_VECTOR_EQ(m_scrollAmount, childLayer->scrollDelta());
            break;
        case 1:
            // Wheel scroll on impl thread.
            EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Wheel), InputHandlerClient::ScrollStarted);
            impl->scrollBy(gfx::Point(), m_scrollAmount);
            impl->scrollEnd();

            EXPECT_VECTOR_EQ(m_secondScroll, childLayer->scrollOffset());
            EXPECT_VECTOR_EQ(m_scrollAmount, childLayer->scrollDelta());
            break;
        case 2:
            EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, childLayer->scrollOffset());
            EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), childLayer->scrollDelta());

            endTest();
        }
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(0, m_rootScrolls);
        EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_finalScrollOffset);
    }

private:
    float m_deviceScaleFactor;
    gfx::Vector2d m_initialScroll;
    gfx::Vector2d m_secondScroll;
    gfx::Vector2d m_scrollAmount;
    int m_rootScrolls;
    gfx::Vector2d m_finalScrollOffset;

    FakeContentLayerClient m_fakeDelegate;
    scoped_refptr<Layer> m_rootScrollLayer;
    scoped_refptr<Layer> m_childLayer;
};

class LayerTreeHostTestScrollChildLayerNormalDpi : public LayerTreeHostTestScrollChildLayer {
public:
    LayerTreeHostTestScrollChildLayerNormalDpi() : LayerTreeHostTestScrollChildLayer(1) { }
};

TEST_F(LayerTreeHostTestScrollChildLayerNormalDpi, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestScrollChildLayerHighDpi : public LayerTreeHostTestScrollChildLayer {
public:
    LayerTreeHostTestScrollChildLayerHighDpi() : LayerTreeHostTestScrollChildLayer(2) { }
};

TEST_F(LayerTreeHostTestScrollChildLayerHighDpi, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestScrollRootScrollLayer : public LayerTreeHostTest {
public:
    LayerTreeHostTestScrollRootScrollLayer(float deviceScaleFactor)
        : m_deviceScaleFactor(deviceScaleFactor)
        , m_initialScroll(10, 20)
        , m_secondScroll(40, 5)
        , m_scrollAmount(2, -1)
        , m_rootScrolls(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        gfx::Size viewportSize(10, 10);
        gfx::Size deviceViewportSize = gfx::ToCeiledSize(gfx::ScaleSize(viewportSize, m_deviceScaleFactor));
        m_layerTreeHost->setViewportSize(viewportSize, deviceViewportSize);

        m_layerTreeHost->setDeviceScaleFactor(m_deviceScaleFactor);

        m_rootScrollLayer = ContentLayer::create(&m_fakeDelegate);
        m_rootScrollLayer->setBounds(gfx::Size(110, 110));

        m_rootScrollLayer->setPosition(gfx::PointF(0, 0));
        m_rootScrollLayer->setAnchorPoint(gfx::PointF(0, 0));

        m_rootScrollLayer->setIsDrawable(true);
        m_rootScrollLayer->setScrollable(true);
        m_rootScrollLayer->setMaxScrollOffset(gfx::Vector2d(100, 100));
        m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer);

        m_rootScrollLayer->setScrollOffset(m_initialScroll);

        postSetNeedsCommitToMainThread();
    }

    virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE
    {
        gfx::Vector2d offset = m_rootScrollLayer->scrollOffset();
        m_rootScrollLayer->setScrollOffset(offset + scrollDelta);
        m_rootScrolls++;
    }

    virtual void layout() OVERRIDE
    {
        switch (m_layerTreeHost->commitNumber()) {
        case 0:
            EXPECT_VECTOR_EQ(m_initialScroll, m_rootScrollLayer->scrollOffset());
            break;
        case 1:
            EXPECT_VECTOR_EQ(m_initialScroll + m_scrollAmount, m_rootScrollLayer->scrollOffset());

            // Pretend like Javascript updated the scroll position itself.
            m_rootScrollLayer->setScrollOffset(m_secondScroll);
            break;
        case 2:
            EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_rootScrollLayer->scrollOffset());
            break;
        }
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        LayerImpl* root = impl->rootLayer();
        LayerImpl* rootScrollLayer = root->children()[0];

        EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d());
        EXPECT_EQ(rootScrollLayer->bounds().width() * m_deviceScaleFactor, rootScrollLayer->contentBounds().width());
        EXPECT_EQ(rootScrollLayer->bounds().height() * m_deviceScaleFactor, rootScrollLayer->contentBounds().height());

        switch (impl->activeTree()->source_frame_number()) {
        case 0:
            // Gesture scroll on impl thread.
            EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Gesture), InputHandlerClient::ScrollStarted);
            impl->scrollBy(gfx::Point(), m_scrollAmount);
            impl->scrollEnd();

            EXPECT_VECTOR_EQ(m_initialScroll, rootScrollLayer->scrollOffset());
            EXPECT_VECTOR_EQ(m_scrollAmount, rootScrollLayer->scrollDelta());
            break;
        case 1:
            // Wheel scroll on impl thread.
            EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Wheel), InputHandlerClient::ScrollStarted);
            impl->scrollBy(gfx::Point(), m_scrollAmount);
            impl->scrollEnd();

            EXPECT_VECTOR_EQ(m_secondScroll, rootScrollLayer->scrollOffset());
            EXPECT_VECTOR_EQ(m_scrollAmount, rootScrollLayer->scrollDelta());
            break;
        case 2:
            EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, rootScrollLayer->scrollOffset());
            EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), rootScrollLayer->scrollDelta());

            endTest();
        }
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(2, m_rootScrolls);
    }

private:
    float m_deviceScaleFactor;
    gfx::Vector2d m_initialScroll;
    gfx::Vector2d m_secondScroll;
    gfx::Vector2d m_scrollAmount;
    int m_rootScrolls;

    FakeContentLayerClient m_fakeDelegate;
    scoped_refptr<Layer> m_rootScrollLayer;
};

class LayerTreeHostTestScrollRootScrollLayerNormalDpi : public LayerTreeHostTestScrollRootScrollLayer {
public:
    LayerTreeHostTestScrollRootScrollLayerNormalDpi() : LayerTreeHostTestScrollRootScrollLayer(1) { }
};

TEST_F(LayerTreeHostTestScrollRootScrollLayerNormalDpi, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestScrollRootScrollLayerHighDpi : public LayerTreeHostTestScrollRootScrollLayer {
public:
    LayerTreeHostTestScrollRootScrollLayerHighDpi() : LayerTreeHostTestScrollRootScrollLayer(2) { }
};

TEST_F(LayerTreeHostTestScrollRootScrollLayerHighDpi, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
public:
    LayerTreeHostTestCompositeAndReadbackCleanup() { }

    virtual void beginTest() OVERRIDE
    {
        Layer* rootLayer = m_layerTreeHost->rootLayer();

        char pixels[4];
        m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
        EXPECT_FALSE(rootLayer->renderSurface());

        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup)

class LayerTreeHostTestCompositeAndReadbackAnimateCount : public LayerTreeHostTest {
public:
    LayerTreeHostTestCompositeAndReadbackAnimateCount()
        : m_layoutCount(0)
    {
    }

    virtual void animate(base::TimeTicks) OVERRIDE
    {
        // We shouldn't animate on the compositeAndReadback-forced commit, but we should
        // for the setNeedsCommit-triggered commit.
        EXPECT_EQ(1, m_layoutCount);
    }

    virtual void layout() OVERRIDE
    {
        m_layoutCount++;
        if (m_layoutCount == 2)
            endTest();
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setNeedsCommit();

        char pixels[4];
        m_layerTreeHost->compositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    int m_layoutCount;
};

TEST_F(LayerTreeHostTestCompositeAndReadbackAnimateCount, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public LayerTreeHostTest {
public:
    LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
        : m_rootLayer(ContentLayerWithUpdateTracking::create(&m_fakeDelegate))
        , m_surfaceLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate))
        , m_replicaLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate))
        , m_surfaceLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate))
        , m_replicaLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate))
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(100, 100), gfx::Size(100, 100));

        m_rootLayer->setBounds(gfx::Size(100, 100));
        m_surfaceLayer1->setBounds(gfx::Size(100, 100));
        m_surfaceLayer1->setForceRenderSurface(true);
        m_surfaceLayer1->setOpacity(0.5);
        m_surfaceLayer2->setBounds(gfx::Size(100, 100));
        m_surfaceLayer2->setForceRenderSurface(true);
        m_surfaceLayer2->setOpacity(0.5);

        m_surfaceLayer1->setReplicaLayer(m_replicaLayer1.get());
        m_surfaceLayer2->setReplicaLayer(m_replicaLayer2.get());

        m_rootLayer->addChild(m_surfaceLayer1);
        m_surfaceLayer1->addChild(m_surfaceLayer2);
        m_layerTreeHost->setRootLayer(m_rootLayer);

        postSetNeedsCommitToMainThread();
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* hostImpl) OVERRIDE
    {
        Renderer* renderer = hostImpl->renderer();
        RenderPass::Id surface1RenderPassId = hostImpl->rootLayer()->children()[0]->renderSurface()->renderPassId();
        RenderPass::Id surface2RenderPassId = hostImpl->rootLayer()->children()[0]->children()[0]->renderSurface()->renderPassId();

        switch (hostImpl->activeTree()->source_frame_number()) {
        case 0:
            EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId));
            EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId));

            // Reduce the memory limit to only fit the root layer and one render surface. This
            // prevents any contents drawing into surfaces from being allocated.
            hostImpl->setManagedMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
            break;
        case 1:
            EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId));
            EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId));

            endTest();
            break;
        }
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(2, m_rootLayer->paintContentsCount());
        EXPECT_EQ(2, m_surfaceLayer1->paintContentsCount());
        EXPECT_EQ(2, m_surfaceLayer2->paintContentsCount());

        // Clear layer references so LayerTreeHost dies.
        m_rootLayer = NULL;
        m_surfaceLayer1 = NULL;
        m_replicaLayer1 = NULL;
        m_surfaceLayer2 = NULL;
        m_replicaLayer2 = NULL;
    }

private:
    FakeContentLayerClient m_fakeDelegate;
    scoped_refptr<ContentLayerWithUpdateTracking> m_rootLayer;
    scoped_refptr<ContentLayerWithUpdateTracking> m_surfaceLayer1;
    scoped_refptr<ContentLayerWithUpdateTracking> m_replicaLayer1;
    scoped_refptr<ContentLayerWithUpdateTracking> m_surfaceLayer2;
    scoped_refptr<ContentLayerWithUpdateTracking> m_replicaLayer2;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit)

class EvictionTestLayer : public Layer {
public:
    static scoped_refptr<EvictionTestLayer> create() { return make_scoped_refptr(new EvictionTestLayer()); }

    virtual void update(ResourceUpdateQueue&, const OcclusionTracker*, RenderingStats&) OVERRIDE;
    virtual bool drawsContent() const OVERRIDE { return true; }

    virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE;
    virtual void pushPropertiesTo(LayerImpl*) OVERRIDE;
    virtual void setTexturePriorities(const PriorityCalculator&) OVERRIDE;

    bool haveBackingTexture() const { return m_texture.get() ? m_texture->haveBackingTexture() : false; }

private:
    EvictionTestLayer() : Layer() { }
    virtual ~EvictionTestLayer() { }

    void createTextureIfNeeded()
    {
        if (m_texture.get())
            return;
        m_texture = PrioritizedResource::create(layerTreeHost()->contentsTextureManager());
        m_texture->setDimensions(gfx::Size(10, 10), GL_RGBA);
        m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
    }

    scoped_ptr<PrioritizedResource> m_texture;
    SkBitmap m_bitmap;
};

class EvictionTestLayerImpl : public LayerImpl {
public:
    static scoped_ptr<EvictionTestLayerImpl> create(LayerTreeImpl* treeImpl, int id)
    {
        return make_scoped_ptr(new EvictionTestLayerImpl(treeImpl, id));
    }
    virtual ~EvictionTestLayerImpl() { }

    virtual void appendQuads(QuadSink& quadSink, AppendQuadsData&) OVERRIDE
    {
        ASSERT_TRUE(m_hasTexture);
        ASSERT_NE(0u, layerTreeImpl()->resource_provider()->numResources());
    }

    void setHasTexture(bool hasTexture) { m_hasTexture = hasTexture; }

private:
    EvictionTestLayerImpl(LayerTreeImpl* treeImpl, int id)
        : LayerImpl(treeImpl, id)
        , m_hasTexture(false) { }

    bool m_hasTexture;
};

void EvictionTestLayer::setTexturePriorities(const PriorityCalculator&)
{
    createTextureIfNeeded();
    if (!m_texture.get())
        return;
    m_texture->setRequestPriority(PriorityCalculator::uiPriority(true));
}

void EvictionTestLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker*, RenderingStats&)
{
    createTextureIfNeeded();
    if (!m_texture.get())
        return;

    gfx::Rect fullRect(0, 0, 10, 10);
    ResourceUpdate upload = ResourceUpdate::Create(
        m_texture.get(), &m_bitmap, fullRect, fullRect, gfx::Vector2d());
    queue.appendFullUpload(upload);
}

scoped_ptr<LayerImpl> EvictionTestLayer::createLayerImpl(LayerTreeImpl* treeImpl)
{
    return EvictionTestLayerImpl::create(treeImpl, m_layerId).PassAs<LayerImpl>();
}

void EvictionTestLayer::pushPropertiesTo(LayerImpl* layerImpl)
{
    Layer::pushPropertiesTo(layerImpl);

    EvictionTestLayerImpl* testLayerImpl = static_cast<EvictionTestLayerImpl*>(layerImpl);
    testLayerImpl->setHasTexture(m_texture->haveBackingTexture());
}

class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
public:
    LayerTreeHostTestEvictTextures()
        : m_layer(EvictionTestLayer::create())
        , m_implForEvictTextures(0)
        , m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setRootLayer(m_layer);
        m_layerTreeHost->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));

        gfx::Transform identityMatrix;
        setLayerPropertiesForTesting(m_layer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(10, 20), true);

        postSetNeedsCommitToMainThread();
    }

    void postEvictTextures()
    {
        DCHECK(implThread());
        implThread()->postTask(base::Bind(&LayerTreeHostTestEvictTextures::evictTexturesOnImplThread,
                               base::Unretained(this)));
    }

    void evictTexturesOnImplThread()
    {
        DCHECK(m_implForEvictTextures);
        m_implForEvictTextures->enforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
    }

    // Commit 1: Just commit and draw normally, then post an eviction at the end
    // that will trigger a commit.
    // Commit 2: Triggered by the eviction, let it go through and then set
    // needsCommit.
    // Commit 3: Triggered by the setNeedsCommit. In layout(), post an eviction
    // task, which will be handled before the commit. Don't set needsCommit, it
    // should have been posted. A frame should not be drawn (note,
    // didCommitAndDrawFrame may be called anyway).
    // Commit 4: Triggered by the eviction, let it go through and then set
    // needsCommit.
    // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
    // layout(), a frame should not be drawn but a commit will be posted.
    // Commit 6: Triggered by the eviction, post an eviction task in
    // layout(), which will be a noop, letting the commit (which recreates the
    // textures) go through and draw a frame, then end the test.
    //
    // Commits 1+2 test the eviction recovery path where eviction happens outside
    // of the beginFrame/commit pair.
    // Commits 3+4 test the eviction recovery path where eviction happens inside
    // the beginFrame/commit pair.
    // Commits 5+6 test the path where an eviction happens during the eviction
    // recovery path.
    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        switch (m_numCommits) {
        case 1:
            EXPECT_TRUE(m_layer->haveBackingTexture());
            postEvictTextures();
            break;
        case 2:
            EXPECT_TRUE(m_layer->haveBackingTexture());
            m_layerTreeHost->setNeedsCommit();
            break;
        case 3:
            break;
        case 4:
            EXPECT_TRUE(m_layer->haveBackingTexture());
            m_layerTreeHost->setNeedsCommit();
            break;
        case 5:
            break;
        case 6:
            EXPECT_TRUE(m_layer->haveBackingTexture());
            endTest();
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_implForEvictTextures = impl;
    }

    virtual void layout() OVERRIDE
    {
        ++m_numCommits;
        switch (m_numCommits) {
        case 1:
        case 2:
            break;
        case 3:
            postEvictTextures();
            break;
        case 4:
            // We couldn't check in didCommitAndDrawFrame on commit 3, so check here.
            EXPECT_FALSE(m_layer->haveBackingTexture());
            break;
        case 5:
            postEvictTextures();
            break;
        case 6:
            // We couldn't check in didCommitAndDrawFrame on commit 5, so check here.
            EXPECT_FALSE(m_layer->haveBackingTexture());
            postEvictTextures();
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<EvictionTestLayer> m_layer;
    LayerTreeHostImpl* m_implForEvictTextures;
    int m_numCommits;
};

TEST_F(LayerTreeHostTestEvictTextures, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestLostContextAfterEvictTextures : public LayerTreeHostTest {
public:
    LayerTreeHostTestLostContextAfterEvictTextures()
        : m_layer(EvictionTestLayer::create())
        , m_implForEvictTextures(0)
        , m_numCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setRootLayer(m_layer);
        m_layerTreeHost->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));

        gfx::Transform identityMatrix;
        setLayerPropertiesForTesting(m_layer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(10, 20), true);

        postSetNeedsCommitToMainThread();
    }

    void postEvictTextures()
    {
        if (implThread()) {
            implThread()->postTask(base::Bind(&LayerTreeHostTestLostContextAfterEvictTextures::evictTexturesOnImplThread,
                                              base::Unretained(this)));
        } else {
            DebugScopedSetImplThread impl(proxy());
            evictTexturesOnImplThread();
        }
    }

    void evictTexturesOnImplThread()
    {
        DCHECK(m_implForEvictTextures);
        m_implForEvictTextures->enforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
    }

    // Commit 1: Just commit and draw normally, then at the end, set ourselves
    // invisible (to prevent a commit that would recreate textures after
    // eviction, before the context recovery), and post a task that will evict
    // textures, then cause the context to be lost, and then set ourselves
    // visible again (to allow commits, since that's what causes context
    // recovery in single thread).
    virtual void didCommitAndDrawFrame() OVERRIDE
    {
        ++m_numCommits;
        switch (m_numCommits) {
        case 1:
            EXPECT_TRUE(m_layer->haveBackingTexture());
            m_layerTreeHost->setVisible(false);
            postEvictTextures();
            m_layerTreeHost->loseOutputSurface(1);
            m_layerTreeHost->setVisible(true);
            break;
        default:
            break;
        }
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_implForEvictTextures = impl;
    }

    virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE
    {
        EXPECT_TRUE(succeeded);
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<EvictionTestLayer> m_layer;
    LayerTreeHostImpl* m_implForEvictTextures;
    int m_numCommits;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLostContextAfterEvictTextures)

class CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext : public CompositorFakeWebGraphicsContext3D {
public:
    static scoped_ptr<CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext> create(Attributes attrs)
    {
        return make_scoped_ptr(new CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext(attrs));
    }

    virtual void setContextLostCallback(WebGraphicsContextLostCallback* callback) { m_contextLostCallback = callback; }
    virtual bool isContextLost() { return m_isContextLost; }

    virtual void beginQueryEXT(WebKit::WGC3Denum, WebKit::WebGLId) { }
    virtual void endQueryEXT(WebKit::WGC3Denum)
    {
        // Lose context.
        if (!m_isContextLost) {
            m_contextLostCallback->onContextLost();
            m_isContextLost = true;
        }
    }
    virtual void getQueryObjectuivEXT(WebKit::WebGLId, WebKit::WGC3Denum pname, WebKit::WGC3Duint* params)
    {
        // Context is lost. We need to behave as if result is available.
        if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
            *params = 1;
    }

private:
    explicit CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext(Attributes attrs)
        : CompositorFakeWebGraphicsContext3D(attrs)
        , m_contextLostCallback(0)
        , m_isContextLost(false) { }

    WebGraphicsContextLostCallback* m_contextLostCallback;
    bool m_isContextLost;
};

class LayerTreeHostTestLostContextWhileUpdatingResources : public LayerTreeHostTest {
public:
    LayerTreeHostTestLostContextWhileUpdatingResources()
        : m_parent(ContentLayerWithUpdateTracking::create(&m_client))
        , m_numChildren(50)
    {
        for (int i = 0; i < m_numChildren; i++)
            m_children.push_back(ContentLayerWithUpdateTracking::create(&m_client));
    }

    virtual void beginTest()
    {
        m_layerTreeHost->setRootLayer(m_parent);
        m_layerTreeHost->setViewportSize(gfx::Size(m_numChildren, 1), gfx::Size(m_numChildren, 1));

        gfx::Transform identityMatrix;
        setLayerPropertiesForTesting(m_parent.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(m_numChildren, 1), true);
        for (int i = 0; i < m_numChildren; i++)
            setLayerPropertiesForTesting(m_children[i].get(), m_parent.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(i, 0), gfx::Size(1, 1), false);

        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl)
    {
        endTest();
    }

    virtual void layout()
    {
        m_parent->setNeedsDisplay();
        for (int i = 0; i < m_numChildren; i++)
            m_children[i]->setNeedsDisplay();
    }

    virtual void afterTest()
    {
    }

private:
    FakeContentLayerClient m_client;
    scoped_refptr<ContentLayerWithUpdateTracking> m_parent;
    int m_numChildren;
    std::vector<scoped_refptr<ContentLayerWithUpdateTracking> > m_children;
};

TEST_F(LayerTreeHostTestLostContextWhileUpdatingResources, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
public:
    LayerTreeHostTestContinuousCommit()
        : m_numCommitComplete(0)
        , m_numDrawLayers(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
        m_layerTreeHost->rootLayer()->setBounds(gfx::Size(10, 10));

        postSetNeedsCommitToMainThread();
    }

    virtual void didCommit() OVERRIDE
    {
        if (m_numDrawLayers == 2)
            return;
        postSetNeedsCommitToMainThread();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        if (m_numDrawLayers == 1)
            m_numCommitComplete++;
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_numDrawLayers++;
        if (m_numDrawLayers == 2)
            endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        // Check that we didn't commit twice between first and second draw.
        EXPECT_EQ(1, m_numCommitComplete);
    }

private:
    int m_numCommitComplete;
    int m_numDrawLayers;
};

TEST_F(LayerTreeHostTestContinuousCommit, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
public:
    LayerTreeHostTestContinuousInvalidate()
        : m_numCommitComplete(0)
        , m_numDrawLayers(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
        m_layerTreeHost->rootLayer()->setBounds(gfx::Size(10, 10));

        m_contentLayer = ContentLayer::create(&m_fakeDelegate);
        m_contentLayer->setBounds(gfx::Size(10, 10));
        m_contentLayer->setPosition(gfx::PointF(0, 0));
        m_contentLayer->setAnchorPoint(gfx::PointF(0, 0));
        m_contentLayer->setIsDrawable(true);
        m_layerTreeHost->rootLayer()->addChild(m_contentLayer);

        postSetNeedsCommitToMainThread();
    }

    virtual void didCommit() OVERRIDE
    {
        if (m_numDrawLayers == 2)
            return;
        m_contentLayer->setNeedsDisplay();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        if (m_numDrawLayers == 1)
            m_numCommitComplete++;
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_numDrawLayers++;
        if (m_numDrawLayers == 2)
            endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        // Check that we didn't commit twice between first and second draw.
        EXPECT_EQ(1, m_numCommitComplete);

        // Clear layer references so LayerTreeHost dies.
        m_contentLayer = NULL;
    }

private:
    FakeContentLayerClient m_fakeDelegate;
    scoped_refptr<Layer> m_contentLayer;
    int m_numCommitComplete;
    int m_numDrawLayers;
};

TEST_F(LayerTreeHostTestContinuousInvalidate, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestAdjustPointForZoom : public LayerTreeHostTest {
public:
    LayerTreeHostTestAdjustPointForZoom()
    {
    }

    virtual void beginTest() OVERRIDE
    {
        gfx::Transform m;
        m.Translate(250, 360);
        m.Scale(2, 2);

        gfx::Point point(400, 550);
        gfx::Point transformedPoint;

        // Unit transform, no change expected.
        m_layerTreeHost->setImplTransform(gfx::Transform());
        transformedPoint = gfx::ToRoundedPoint(m_layerTreeHost->adjustEventPointForPinchZoom(point));
        EXPECT_EQ(point.x(), transformedPoint.x());
        EXPECT_EQ(point.y(), transformedPoint.y());

        m_layerTreeHost->setImplTransform(m);

        // Apply m^(-1): 75 = (400 - 250) / 2; 95 = (550 - 360) / 2.
        transformedPoint = gfx::ToRoundedPoint(m_layerTreeHost->adjustEventPointForPinchZoom(point));
        EXPECT_EQ(75, transformedPoint.x());
        EXPECT_EQ(95, transformedPoint.y());
        endTest();
    }

    virtual void afterTest() OVERRIDE
    {
    }
};

TEST_F(LayerTreeHostTestAdjustPointForZoom, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestContinuousAnimate : public LayerTreeHostTest {
public:
    LayerTreeHostTestContinuousAnimate()
        : m_numCommitComplete(0)
        , m_numDrawLayers(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
        m_layerTreeHost->rootLayer()->setBounds(gfx::Size(10, 10));

        postSetNeedsCommitToMainThread();
    }

    virtual void animate(base::TimeTicks) OVERRIDE
    {
        if (m_numDrawLayers == 2)
            return;
        m_layerTreeHost->setNeedsAnimate();
    }

    virtual void layout() OVERRIDE
    {
        m_layerTreeHost->rootLayer()->setNeedsDisplay();
    }

    virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
    {
        if (m_numDrawLayers == 1)
            m_numCommitComplete++;
    }

    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
    {
        m_numDrawLayers++;
        if (m_numDrawLayers == 2)
            endTest();
    }

    virtual void afterTest() OVERRIDE
    {
        // Check that we didn't commit twice between first and second draw.
        EXPECT_EQ(1, m_numCommitComplete);
    }

private:
    int m_numCommitComplete;
    int m_numDrawLayers;
};

TEST_F(LayerTreeHostTestContinuousAnimate, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
public:
    LayerTreeHostTestDeferCommits()
        : m_numCommitsDeferred(0)
        , m_numCompleteCommits(0)
    {
    }

    virtual void beginTest() OVERRIDE
    {
        postSetNeedsCommitToMainThread();
    }

    virtual void didDeferCommit() OVERRIDE
    {
        m_numCommitsDeferred++;
        m_layerTreeHost->setDeferCommits(false);
    }

    virtual void didCommit() OVERRIDE
    {
        m_numCompleteCommits++;
        switch (m_numCompleteCommits) {
        case 1:
            EXPECT_EQ(0, m_numCommitsDeferred);
            m_layerTreeHost->setDeferCommits(true);
            postSetNeedsCommitToMainThread();
            break;
        case 2:
            endTest();
            break;
        default:
            NOTREACHED();
            break;
        }
    }

    virtual void afterTest() OVERRIDE
    {
        EXPECT_EQ(1, m_numCommitsDeferred);
        EXPECT_EQ(2, m_numCompleteCommits);
    }

private:
    int m_numCommitsDeferred;
    int m_numCompleteCommits;
};

TEST_F(LayerTreeHostTestDeferCommits, runMultiThread)
{
    runTest(true);
}

class LayerTreeHostWithProxy : public LayerTreeHost {
public:
    LayerTreeHostWithProxy(FakeLayerImplTreeHostClient* client, const LayerTreeSettings& settings, scoped_ptr<Proxy> proxy)
            : LayerTreeHost(client, settings)
    {
        EXPECT_TRUE(initializeForTesting(proxy.Pass()));
    }

private:
    FakeLayerImplTreeHostClient m_client;
};

TEST(LayerTreeHostTest, LimitPartialUpdates)
{
    // When partial updates are not allowed, max updates should be 0.
    {
        FakeLayerImplTreeHostClient client;

        scoped_ptr<FakeProxy> proxy = make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
        proxy->rendererCapabilities().allowPartialTextureUpdates = false;
        proxy->setMaxPartialTextureUpdates(5);

        LayerTreeSettings settings;
        settings.maxPartialTextureUpdates = 10;

        LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>());
        EXPECT_TRUE(host.initializeRendererIfNeeded());

        EXPECT_EQ(0u, host.settings().maxPartialTextureUpdates);
    }

    // When partial updates are allowed, max updates should be limited by the proxy.
    {
        FakeLayerImplTreeHostClient client;

        scoped_ptr<FakeProxy> proxy = make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
        proxy->rendererCapabilities().allowPartialTextureUpdates = true;
        proxy->setMaxPartialTextureUpdates(5);

        LayerTreeSettings settings;
        settings.maxPartialTextureUpdates = 10;

        LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>());
        EXPECT_TRUE(host.initializeRendererIfNeeded());

        EXPECT_EQ(5u, host.settings().maxPartialTextureUpdates);
    }

    // When partial updates are allowed, max updates should also be limited by the settings.
    {
        FakeLayerImplTreeHostClient client;

        scoped_ptr<FakeProxy> proxy = make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
        proxy->rendererCapabilities().allowPartialTextureUpdates = true;
        proxy->setMaxPartialTextureUpdates(20);

        LayerTreeSettings settings;
        settings.maxPartialTextureUpdates = 10;

        LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>());
        EXPECT_TRUE(host.initializeRendererIfNeeded());

        EXPECT_EQ(10u, host.settings().maxPartialTextureUpdates);
    }
}

TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer)
{
    bool useSoftwareRendering = false;
    bool useDelegatingRenderer = false;
    FakeLayerImplTreeHostClient client(useSoftwareRendering, useDelegatingRenderer);

    LayerTreeSettings settings;
    settings.maxPartialTextureUpdates = 4;

    scoped_ptr<LayerTreeHost> host = LayerTreeHost::create(&client, settings, scoped_ptr<Thread>());
    EXPECT_TRUE(host->initializeRendererIfNeeded());
    EXPECT_EQ(4u, host->settings().maxPartialTextureUpdates);
}

TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer)
{
    bool useSoftwareRendering = true;
    bool useDelegatingRenderer = false;
    FakeLayerImplTreeHostClient client(useSoftwareRendering, useDelegatingRenderer);

    LayerTreeSettings settings;
    settings.maxPartialTextureUpdates = 4;

    scoped_ptr<LayerTreeHost> host = LayerTreeHost::create(&client, settings, scoped_ptr<Thread>());
    EXPECT_TRUE(host->initializeRendererIfNeeded());
    EXPECT_EQ(4u, host->settings().maxPartialTextureUpdates);
}

TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent)
{
    bool useSoftwareRendering = false;
    bool useDelegatingRenderer = true;
    FakeLayerImplTreeHostClient client(useSoftwareRendering, useDelegatingRenderer);

    LayerTreeSettings settings;
    settings.maxPartialTextureUpdates = 4;

    scoped_ptr<LayerTreeHost> host = LayerTreeHost::create(&client, settings, scoped_ptr<Thread>());
    EXPECT_TRUE(host->initializeRendererIfNeeded());
    EXPECT_EQ(0u, host->settings().maxPartialTextureUpdates);
}

TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndSoftwareContent)
{
    bool useSoftwareRendering = true;
    bool useDelegatingRenderer = true;
    FakeLayerImplTreeHostClient client(useSoftwareRendering, useDelegatingRenderer);

    LayerTreeSettings settings;
    settings.maxPartialTextureUpdates = 4;

    scoped_ptr<LayerTreeHost> host = LayerTreeHost::create(&client, settings, scoped_ptr<Thread>());
    EXPECT_TRUE(host->initializeRendererIfNeeded());
    EXPECT_EQ(0u, host->settings().maxPartialTextureUpdates);
}

}  // namespace
}  // namespace cc
