1c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// found in the LICENSE file.
4c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
5c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "config.h"
6c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
7c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/graphics/RecordingImageBufferSurface.h"
8c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
9c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h"
10c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h"
11c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/graphics/ImageBufferClient.h"
12c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "public/platform/Platform.h"
13c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "public/platform/WebThread.h"
14c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h"
15c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "third_party/skia/include/core/SkPictureRecorder.h"
16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/OwnPtr.h"
17c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/PassOwnPtr.h"
18c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/RefPtr.h"
19c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
20c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include <gmock/gmock.h>
21c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include <gtest/gtest.h>
22c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
23c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
24c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using testing::Test;
25c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
26c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace {
27c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
28c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class FakeImageBufferClient : public ImageBufferClient, public WebThread::TaskObserver {
29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
30c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    FakeImageBufferClient(ImageBuffer* imageBuffer)
31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : m_isDirty(false)
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_imageBuffer(imageBuffer)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_frameCount(0)
34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    { }
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual ~FakeImageBufferClient() { }
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // ImageBufferClient implementation
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void notifySurfaceInvalid() { }
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool isDirty() { return m_isDirty; };
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void didFinalizeFrame()
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (m_isDirty) {
44e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            Platform::current()->currentThread()->removeTaskObserver(this);
45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            m_isDirty = false;
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ++m_frameCount;
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // TaskObserver implementation
51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void willProcessTask() OVERRIDE { ASSERT_NOT_REACHED(); }
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void didProcessTask() OVERRIDE
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT_TRUE(m_isDirty);
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        FloatRect dirtyRect(0, 0, 1, 1);
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_imageBuffer->finalizeFrame(dirtyRect);
57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT_FALSE(m_isDirty);
58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void fakeDraw()
61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (m_isDirty)
63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return;
64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_isDirty = true;
65e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::current()->currentThread()->addTaskObserver(this);
66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int frameCount() { return m_frameCount; }
69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool m_isDirty;
72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ImageBuffer* m_imageBuffer;
73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int m_frameCount;
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // unnamed namespace
77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class RecordingImageBufferSurfaceTest : public Test {
79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)protected:
80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RecordingImageBufferSurfaceTest()
81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        OwnPtr<RecordingImageBufferSurface> testSurface = adoptPtr(new RecordingImageBufferSurface(IntSize(10, 10)));
83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface = testSurface.get();
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // We create an ImageBuffer in order for the testSurface to be
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // properly initialized with a GraphicsContext
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_imageBuffer = ImageBuffer::create(testSurface.release());
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        EXPECT_FALSE(!m_imageBuffer);
88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient = adoptPtr(new FakeImageBufferClient(m_imageBuffer.get()));
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_imageBuffer->setClient(m_fakeImageBufferClient.get());
90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
93c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testEmptyPicture()
94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        RefPtr<SkPicture> picture = m_testSurface->getPicture();
97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_TRUE((bool)picture.get());
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
100c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testNoFallbackWithClear()
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->didClearCanvas();
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testNonAnimatedCanvasUpdate()
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // acquire picture twice to simulate a static canvas: nothing drawn between updates
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testAnimatedWithoutClear()
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
126c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true); // first frame has an implicit clear
129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(false);
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testFrameFinalizedByTaskObserver1()
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
142c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
144c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
145c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
147c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
148c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
150c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // Display list will be disabled only after exiting the runLoop
152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
153c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testFrameFinalizedByTaskObserver2()
154c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
155c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(false);
157c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
158c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(4, m_fakeImageBufferClient->frameCount());
159c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(false);
160c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(4, m_fakeImageBufferClient->frameCount());
162c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(false);
163c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
164c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
165c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testAnimatedWithClear()
166c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
167c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
168c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->didClearCanvas();
170c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
172c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // clear after use
176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->didClearCanvas();
178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
179c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
181c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
182c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
183c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void testClearRect()
185c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->initializeCurrentFrame();
187c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_imageBuffer->context()->clearRect(FloatRect(FloatPoint(0, 0), FloatSize(m_testSurface->size())));
189c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_fakeImageBufferClient->fakeDraw();
190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_testSurface->getPicture();
192c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        expectDisplayListEnabled(true);
194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
195c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void expectDisplayListEnabled(bool displayListEnabled)
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get());
199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(!displayListEnabled, (bool)m_testSurface->m_rasterCanvas.get());
200c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
201c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
202c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
203c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RecordingImageBufferSurface* m_testSurface;
204c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    OwnPtr<FakeImageBufferClient> m_fakeImageBufferClient;
205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    OwnPtr<ImageBuffer> m_imageBuffer;
206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
207c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace {
209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// The following test helper class installs a mock platform that provides a mock WebThread
211c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// for the current thread. The Mock thread is capable of queuing a single non-delayed task
212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// and registering a single task observer. The run loop exits immediately after running
213c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// the single task.
214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class AutoInstallCurrentThreadPlatformMock {
215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AutoInstallCurrentThreadPlatformMock()
217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
218e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        m_oldPlatform = Platform::current();
219e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::initialize(&m_mockPlatform);
220c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
221c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
222c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ~AutoInstallCurrentThreadPlatformMock()
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
224e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::initialize(m_oldPlatform);
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    class CurrentThreadMock : public WebThread {
229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    public:
230c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        CurrentThreadMock() : m_taskObserver(0), m_task(0) { }
231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual ~CurrentThreadMock()
233c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
234c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            EXPECT_EQ((Task*)0, m_task);
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
236c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
237c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void postTask(Task* task)
238c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
239c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            EXPECT_EQ((Task*)0, m_task);
240c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            m_task = task;
241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
242c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
243c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void postDelayedTask(Task*, long long delayMs) OVERRIDE { ASSERT_NOT_REACHED(); };
244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
245c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual bool isCurrentThread() const OVERRIDE { return true; }
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        virtual PlatformThreadId threadId() const OVERRIDE
2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        {
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ASSERT_NOT_REACHED();
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
251c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
252c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void addTaskObserver(TaskObserver* taskObserver) OVERRIDE
253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
254c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            EXPECT_EQ((TaskObserver*)0, m_taskObserver);
255c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            m_taskObserver = taskObserver;
256c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
258c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void removeTaskObserver(TaskObserver* taskObserver) OVERRIDE
259c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            EXPECT_EQ(m_taskObserver, taskObserver);
261c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            m_taskObserver = 0;
262c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
263c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void enterRunLoop() OVERRIDE
265c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
266c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (m_taskObserver)
267c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_taskObserver->willProcessTask();
268c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (m_task) {
269c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_task->run();
270c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                delete m_task;
271c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_task = 0;
272c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            }
273c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (m_taskObserver)
274c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_taskObserver->didProcessTask();
275c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
276c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
277c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void exitRunLoop() OVERRIDE { ASSERT_NOT_REACHED(); }
278c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
279c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    private:
280c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TaskObserver* m_taskObserver;
281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Task* m_task;
282c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    };
283c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
284e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    class CurrentThreadPlatformMock : public Platform {
285c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    public:
286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        CurrentThreadPlatformMock() { }
287c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void cryptographicallyRandomValues(unsigned char* buffer, size_t length) { ASSERT_NOT_REACHED(); }
288c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual WebThread* currentThread() OVERRIDE { return &m_currentThread; }
289c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    private:
290c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        CurrentThreadMock m_currentThread;
291c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    };
292c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
293c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CurrentThreadPlatformMock m_mockPlatform;
294e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    Platform* m_oldPlatform;
295c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
296c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
297c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
298c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define DEFINE_TEST_TASK_WRAPPER_CLASS(TEST_METHOD)                                               \
299e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)class TestWrapperTask_ ## TEST_METHOD : public WebThread::Task {                           \
300c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    public:                                                                                       \
301c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TestWrapperTask_ ## TEST_METHOD(RecordingImageBufferSurfaceTest* test) : m_test(test) { } \
302c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        virtual void run() OVERRIDE { m_test->TEST_METHOD(); }                                    \
303c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    private:                                                                                      \
304c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        RecordingImageBufferSurfaceTest* m_test;                                                  \
305c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
306c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
307c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define CALL_TEST_TASK_WRAPPER(TEST_METHOD)                                                               \
308c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {                                                                                                     \
309c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        AutoInstallCurrentThreadPlatformMock ctpm;                                                        \
310e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::current()->currentThread()->postTask(new TestWrapperTask_ ## TEST_METHOD(this)); \
311e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::current()->currentThread()->enterRunLoop();                                      \
312c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
313c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
314c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testEmptyPicture)
315c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
316c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    testEmptyPicture();
317c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
318c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
319c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear)
320c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
321c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    testNoFallbackWithClear();
322c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
323c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
324c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testNonAnimatedCanvasUpdate)
325c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate)
326c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
327c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testNonAnimatedCanvasUpdate)
328c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(true);
329c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
330c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
331c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithoutClear)
332c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear)
333c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
334c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testAnimatedWithoutClear)
335c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(false);
336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
337c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
338c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver1)
339c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver2)
340c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testFrameFinalizedByTaskObserver)
341c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
342c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver1)
343c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(false);
344c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver2)
345c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(false);
346c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
347c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
348c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithClear)
349c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear)
350c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
351c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testAnimatedWithClear)
352c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(true);
353c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
354c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
355c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)DEFINE_TEST_TASK_WRAPPER_CLASS(testClearRect)
356c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(RecordingImageBufferSurfaceTest, testClearRect)
357c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
358c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CALL_TEST_TASK_WRAPPER(testClearRect);
359c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    expectDisplayListEnabled(true);
360c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
361c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace
363