[chromium] Compute occlusion during paint loop
[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 "FakeWebGraphicsContext3D.h"
31 #include "GraphicsContext3DPrivate.h"
32 #include "Region.h"
33 #include "TextureManager.h"
34 #include "cc/CCCanvasLayerImpl.h"
35 #include "cc/CCSingleThreadProxy.h"
36 #include "cc/CCTextureUpdater.h"
37
38 #include <gmock/gmock.h>
39 #include <gtest/gtest.h>
40 #include <wtf/RefPtr.h>
41
42 using namespace WebCore;
43 using namespace WebKit;
44 using namespace WebKitTests;
45 using testing::InSequence;
46 using testing::Return;
47 using testing::Test;
48
49 namespace {
50
51 class MockCanvasContext : public FakeWebGraphicsContext3D {
52 public:
53     MOCK_METHOD0(createFramebuffer, WebGLId());
54     MOCK_METHOD0(createTexture, WebGLId());
55
56     MOCK_METHOD2(bindFramebuffer, void(WGC3Denum, WebGLId));
57     MOCK_METHOD5(framebufferTexture2D, void(WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint));
58
59     MOCK_METHOD2(bindTexture, void(WGC3Denum, WebGLId));
60     MOCK_METHOD8(copyTexSubImage2D, void(WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei));
61
62     MOCK_METHOD1(deleteFramebuffer, void(WebGLId));
63     MOCK_METHOD1(deleteTexture, void(WebGLId));
64 };
65
66 class MockTextureAllocator : public TextureAllocator {
67 public:
68     MOCK_METHOD2(createTexture, unsigned(const IntSize&, GC3Denum));
69     MOCK_METHOD3(deleteTexture, void(unsigned, const IntSize&, GC3Denum));
70 };
71
72 } // namespace
73
74 namespace WebCore {
75
76 class Canvas2DLayerChromiumTest : public Test {
77 protected:
78     // This indirection is needed because individual tests aren't friends of Canvas2DLayerChromium.
79     void setTextureManager(Canvas2DLayerChromium* layer, TextureManager* manager)
80     {
81         layer->setTextureManager(manager);
82     }
83
84     void fullLifecycleTest(bool threaded)
85     {
86         GraphicsContext3D::Attributes attrs;
87
88         RefPtr<GraphicsContext3D> mainContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
89         RefPtr<GraphicsContext3D> implContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
90
91         MockCanvasContext& mainMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(mainContext.get()));
92         MockCanvasContext& implMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(implContext.get()));
93
94         MockTextureAllocator allocatorMock;
95         CCTextureUpdater updater(&allocatorMock);
96
97         const IntSize size(300, 150);
98         const size_t maxTextureSize = size.width() * size.height() * 4;
99         OwnPtr<TextureManager> textureManager = TextureManager::create(maxTextureSize, maxTextureSize, maxTextureSize);
100
101         if (threaded)
102             CCProxy::setImplThread(new FakeCCThread);
103
104         const WebGLId backTextureId = 1;
105         const WebGLId frontTextureId = 2;
106         const WebGLId fboId = 3;
107         {
108             InSequence sequence;
109
110             // Note that the canvas backing texture is doublebuffered only when using the threaded
111             // compositor.
112             if (threaded) {
113                 // Setup Canvas2DLayerChromium (on the main thread).
114                 EXPECT_CALL(mainMock, createFramebuffer())
115                     .WillOnce(Return(fboId));
116
117                 // Create texture and do the copy (on the impl thread).
118                 EXPECT_CALL(allocatorMock, createTexture(size, GraphicsContext3D::RGBA))
119                     .WillOnce(Return(frontTextureId));
120                 EXPECT_CALL(implMock, bindTexture(GraphicsContext3D::TEXTURE_2D, frontTextureId));
121                 EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fboId));
122                 EXPECT_CALL(implMock, framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, backTextureId, 0));
123                 EXPECT_CALL(implMock, copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, 300, 150));
124                 EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
125
126                 // Teardown Canvas2DLayerChromium.
127                 EXPECT_CALL(mainMock, deleteFramebuffer(fboId));
128
129                 // Teardown TextureManager.
130                 EXPECT_CALL(allocatorMock, deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA));
131             }
132         }
133
134         RefPtr<Canvas2DLayerChromium> canvas = Canvas2DLayerChromium::create(mainContext.get(), size);
135         canvas->setIsDrawable(true);
136         setTextureManager(canvas.get(), textureManager.get());
137         canvas->setBounds(IntSize(600, 300));
138         canvas->setTextureId(backTextureId);
139
140         canvas->contentChanged();
141         EXPECT_TRUE(canvas->needsDisplay());
142         Region occludedScreenSpace;
143         canvas->paintContentsIfDirty(occludedScreenSpace);
144         EXPECT_FALSE(canvas->needsDisplay());
145         {
146             DebugScopedSetImplThread scopedImplThread;
147
148             RefPtr<CCLayerImpl> layerImpl = canvas->createCCLayerImpl();
149             EXPECT_EQ(0u, static_cast<CCCanvasLayerImpl*>(layerImpl.get())->textureId());
150
151             canvas->updateCompositorResources(implContext.get(), updater);
152             canvas->pushPropertiesTo(layerImpl.get());
153
154             if (threaded)
155                 EXPECT_EQ(frontTextureId, static_cast<CCCanvasLayerImpl*>(layerImpl.get())->textureId());
156             else
157                 EXPECT_EQ(backTextureId, static_cast<CCCanvasLayerImpl*>(layerImpl.get())->textureId());
158         }
159         canvas.clear();
160         textureManager->reduceMemoryToLimit(0);
161         textureManager->deleteEvictedTextures(&allocatorMock);
162     }
163 };
164
165 TEST_F(Canvas2DLayerChromiumTest, testFullLifecycleSingleThread)
166 {
167     fullLifecycleTest(false);
168 }
169
170 TEST_F(Canvas2DLayerChromiumTest, testFullLifecycleThreaded)
171 {
172     fullLifecycleTest(true);
173 }
174
175 } // namespace webcore