[chromium] Add TextureCopier for copying texture contents
[WebKit-https.git] / Source / WebKit / chromium / tests / Canvas2DLayerChromiumTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "Canvas2DLayerChromium.h"
28
29 #include "CCSchedulerTestCommon.h"
30 #include "FakeCCLayerTreeHostClient.h"
31 #include "FakeWebGraphicsContext3D.h"
32 #include "GraphicsContext3DPrivate.h"
33 #include "Region.h"
34 #include "TextureCopier.h"
35 #include "TextureManager.h"
36 #include "WebCompositor.h"
37 #include "WebKit.h"
38 #include "cc/CCSingleThreadProxy.h"
39 #include "cc/CCTextureLayerImpl.h"
40 #include "cc/CCTextureUpdater.h"
41 #include "platform/WebKitPlatformSupport.h"
42 #include "platform/WebThread.h"
43
44 #include <gmock/gmock.h>
45 #include <gtest/gtest.h>
46 #include <wtf/RefPtr.h>
47
48 using namespace WebCore;
49 using namespace WebKit;
50 using namespace WebKitTests;
51 using testing::InSequence;
52 using testing::Return;
53 using testing::Test;
54
55 namespace {
56
57 class FakeCCLayerTreeHost : public CCLayerTreeHost {
58 public:
59     static PassRefPtr<FakeCCLayerTreeHost> create()
60     {
61         RefPtr<FakeCCLayerTreeHost> host = adoptRef(new FakeCCLayerTreeHost);
62         host->initialize();
63         return host.release();
64     }
65
66 private:
67     FakeCCLayerTreeHost()
68         : CCLayerTreeHost(&m_client, CCSettings())
69     {
70     }
71
72     FakeCCLayerTreeHostClient m_client;
73 };
74
75 class MockCanvasContext : public FakeWebGraphicsContext3D {
76 public:
77     MOCK_METHOD0(createFramebuffer, WebGLId());
78     MOCK_METHOD0(createTexture, WebGLId());
79
80     MOCK_METHOD2(bindFramebuffer, void(WGC3Denum, WebGLId));
81     MOCK_METHOD5(framebufferTexture2D, void(WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint));
82
83     MOCK_METHOD2(bindTexture, void(WGC3Denum, WebGLId));
84     MOCK_METHOD8(copyTexSubImage2D, void(WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei));
85
86     MOCK_METHOD1(deleteFramebuffer, void(WebGLId));
87     MOCK_METHOD1(deleteTexture, void(WebGLId));
88 };
89
90 class MockTextureAllocator : public TextureAllocator {
91 public:
92     MOCK_METHOD2(createTexture, unsigned(const IntSize&, GC3Denum));
93     MOCK_METHOD3(deleteTexture, void(unsigned, const IntSize&, GC3Denum));
94 };
95
96 class MockTextureCopier : public TextureCopier {
97 public:
98     MOCK_METHOD4(copyTexture, void(GraphicsContext3D*, unsigned, unsigned, const IntSize&));
99 };
100
101 class Canvas2DLayerChromiumTest : public Test {
102 protected:
103     void fullLifecycleTest(bool threaded)
104     {
105         GraphicsContext3D::Attributes attrs;
106
107         RefPtr<GraphicsContext3D> mainContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), GraphicsContext3D::RenderDirectlyToHostWindow);
108         RefPtr<GraphicsContext3D> implContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), GraphicsContext3D::RenderDirectlyToHostWindow);
109
110         MockTextureAllocator allocatorMock;
111         MockTextureCopier copierMock;
112         CCTextureUpdater updater(&allocatorMock, &copierMock);
113
114         const IntSize size(300, 150);
115
116         OwnPtr<WebThread> thread;
117         if (threaded)
118            thread = adoptPtr(webKitPlatformSupport()->createThread("Canvas2DLayerChromiumTest"));
119         WebCompositor::initialize(thread.get());
120
121         RefPtr<FakeCCLayerTreeHost> layerTreeHost = FakeCCLayerTreeHost::create();
122         // Force an update, so that we get a valid TextureManager.
123         layerTreeHost->updateLayers();
124
125         const WebGLId backTextureId = 1;
126         const WebGLId frontTextureId = 2;
127         {
128             InSequence sequence;
129
130             // Note that the canvas backing texture is doublebuffered only when using the threaded
131             // compositor.
132             if (threaded) {
133                 // Create texture and do the copy (on the impl thread).
134                 EXPECT_CALL(allocatorMock, createTexture(size, GraphicsContext3D::RGBA))
135                     .WillOnce(Return(frontTextureId));
136                 EXPECT_CALL(copierMock, copyTexture(implContext.get(), backTextureId, frontTextureId, size));
137
138                 // Teardown TextureManager.
139                 EXPECT_CALL(allocatorMock, deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA));
140             }
141         }
142
143         RefPtr<Canvas2DLayerChromium> canvas = Canvas2DLayerChromium::create(mainContext.get(), size);
144         canvas->setIsDrawable(true);
145         canvas->setLayerTreeHost(layerTreeHost.get());
146         canvas->setBounds(IntSize(600, 300));
147         canvas->setTextureId(backTextureId);
148
149         canvas->setNeedsDisplay();
150         EXPECT_TRUE(canvas->needsDisplay());
151         canvas->paintContentsIfDirty(0);
152         EXPECT_FALSE(canvas->needsDisplay());
153         {
154             DebugScopedSetImplThread scopedImplThread;
155
156             OwnPtr<CCLayerImpl> layerImpl = canvas->createCCLayerImpl();
157             EXPECT_EQ(0u, static_cast<CCTextureLayerImpl*>(layerImpl.get())->textureId());
158
159             canvas->updateCompositorResources(implContext.get(), updater);
160             canvas->pushPropertiesTo(layerImpl.get());
161
162             if (threaded)
163                 EXPECT_EQ(frontTextureId, static_cast<CCTextureLayerImpl*>(layerImpl.get())->textureId());
164             else
165                 EXPECT_EQ(backTextureId, static_cast<CCTextureLayerImpl*>(layerImpl.get())->textureId());
166         }
167         canvas.clear();
168         layerTreeHost->contentsTextureManager()->reduceMemoryToLimit(0);
169         layerTreeHost->contentsTextureManager()->deleteEvictedTextures(&allocatorMock);
170         layerTreeHost.clear();
171         WebCompositor::shutdown();
172     }
173 };
174
175 TEST_F(Canvas2DLayerChromiumTest, testFullLifecycleSingleThread)
176 {
177     fullLifecycleTest(false);
178 }
179
180 TEST_F(Canvas2DLayerChromiumTest, testFullLifecycleThreaded)
181 {
182     fullLifecycleTest(true);
183 }
184
185 } // namespace