Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / tests / DrawingBufferTest.cpp
1 /*
2  * Copyright (C) 2013 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #include "platform/graphics/gpu/DrawingBuffer.h"
34
35 #include "platform/graphics/ImageBuffer.h"
36 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
37 #include "public/platform/Platform.h"
38 #include "public/platform/WebExternalTextureMailbox.h"
39 #include "web/tests/MockWebGraphicsContext3D.h"
40 #include "wtf/RefPtr.h"
41
42 #include <gmock/gmock.h>
43 #include <gtest/gtest.h>
44
45 using namespace WebCore;
46 using namespace blink;
47 using testing::Test;
48 using testing::_;
49
50 namespace {
51
52 class FakeContextEvictionManager : public ContextEvictionManager {
53 public:
54     void forciblyLoseOldestContext(const String& reason) { }
55     IntSize oldestContextSize() { return IntSize(); }
56 };
57
58 class WebGraphicsContext3DForTests : public MockWebGraphicsContext3D {
59 public:
60     WebGraphicsContext3DForTests()
61         : MockWebGraphicsContext3D()
62         , m_boundTexture(0)
63         , m_currentMailboxByte(0) { }
64
65     virtual void bindTexture(WGC3Denum target, WebGLId texture)
66     {
67         if (target == GL_TEXTURE_2D) {
68             m_boundTexture = texture;
69         }
70     }
71
72     virtual void texImage2D(WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format, WGC3Denum type, const void* pixels)
73     {
74         if (target == GL_TEXTURE_2D && !level) {
75             m_textureSizes.set(m_boundTexture, IntSize(width, height));
76         }
77     }
78
79     virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox)
80     {
81         ++m_currentMailboxByte;
82         WebExternalTextureMailbox temp;
83         memset(mailbox, m_currentMailboxByte, sizeof(temp.name));
84     }
85
86     virtual void produceTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailbox)
87     {
88         ASSERT_EQ(target, static_cast<WGC3Denum>(GL_TEXTURE_2D));
89         m_mostRecentlyProducedSize = m_textureSizes.get(m_boundTexture);
90     }
91
92     IntSize mostRecentlyProducedSize()
93     {
94         return m_mostRecentlyProducedSize;
95     }
96
97 private:
98     WebGLId m_boundTexture;
99     HashMap<WebGLId, IntSize> m_textureSizes;
100     WGC3Dbyte m_currentMailboxByte;
101     IntSize m_mostRecentlyProducedSize;
102 };
103
104 static const int initialWidth = 100;
105 static const int initialHeight = 100;
106 static const int alternateHeight = 50;
107
108 } // namespace
109
110 class DrawingBufferTest : public Test {
111 protected:
112     virtual void SetUp()
113     {
114         RefPtr<FakeContextEvictionManager> contextEvictionManager = adoptRef(new FakeContextEvictionManager());
115         m_context = adoptPtr(new WebGraphicsContext3DForTests);
116         m_drawingBuffer = DrawingBuffer::create(m_context.get(), IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve, contextEvictionManager.release());
117     }
118
119     WebGraphicsContext3DForTests* webContext()
120     {
121         return m_context.get();
122     }
123
124     OwnPtr<WebGraphicsContext3DForTests> m_context;
125     RefPtr<DrawingBuffer> m_drawingBuffer;
126 };
127
128 namespace {
129
130 TEST_F(DrawingBufferTest, testPaintRenderingResultsToCanvas)
131 {
132     OwnPtr<ImageBufferSurface> imageBufferSurface = adoptPtr(new UnacceleratedImageBufferSurface(IntSize(initialWidth, initialHeight)));
133     EXPECT_FALSE(!imageBufferSurface);
134     EXPECT_TRUE(imageBufferSurface->isValid());
135     OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageBufferSurface.release());
136     EXPECT_FALSE(!imageBuffer);
137     EXPECT_FALSE(imageBuffer->isAccelerated());
138     EXPECT_FALSE(imageBuffer->bitmap().isNull());
139     m_drawingBuffer->paintRenderingResultsToCanvas(imageBuffer.get());
140     EXPECT_FALSE(imageBuffer->isAccelerated());
141     EXPECT_FALSE(imageBuffer->bitmap().isNull());
142 }
143
144 TEST_F(DrawingBufferTest, verifyNoNewBuffersAfterContextLostWithMailboxes)
145 {
146     // Tell the buffer its contents changed and context was lost.
147     m_drawingBuffer->markContentsChanged();
148     m_drawingBuffer->releaseResources();
149
150     blink::WebExternalTextureMailbox mailbox;
151     EXPECT_FALSE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
152 }
153
154 TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes)
155 {
156     blink::WebExternalTextureMailbox mailbox;
157
158     IntSize initialSize(initialWidth, initialHeight);
159     IntSize alternateSize(initialWidth, alternateHeight);
160
161     // Produce one mailbox at size 100x100.
162     m_drawingBuffer->markContentsChanged();
163     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
164     EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
165
166     // Resize to 100x50.
167     m_drawingBuffer->reset(IntSize(initialWidth, alternateHeight));
168     m_drawingBuffer->mailboxReleased(mailbox);
169
170     // Produce a mailbox at this size.
171     m_drawingBuffer->markContentsChanged();
172     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
173     EXPECT_EQ(alternateSize, webContext()->mostRecentlyProducedSize());
174
175     // Reset to initial size.
176     m_drawingBuffer->reset(IntSize(initialWidth, initialHeight));
177     m_drawingBuffer->mailboxReleased(mailbox);
178
179     // Prepare another mailbox and verify that it's the correct size.
180     m_drawingBuffer->markContentsChanged();
181     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
182     EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
183
184     // Prepare one final mailbox and verify that it's the correct size.
185     m_drawingBuffer->mailboxReleased(mailbox);
186     m_drawingBuffer->markContentsChanged();
187     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
188     EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
189 }
190
191 class TextureMailboxWrapper {
192 public:
193     explicit TextureMailboxWrapper(const blink::WebExternalTextureMailbox& mailbox)
194         : m_mailbox(mailbox)
195     { }
196
197     bool operator==(const TextureMailboxWrapper& other) const
198     {
199         return !memcmp(m_mailbox.name, other.m_mailbox.name, sizeof(m_mailbox.name));
200     }
201
202 private:
203     blink::WebExternalTextureMailbox m_mailbox;
204 };
205
206 TEST_F(DrawingBufferTest, verifyRecyclingMailboxesByFIFO)
207 {
208     blink::WebExternalTextureMailbox mailbox1;
209     blink::WebExternalTextureMailbox mailbox2;
210     blink::WebExternalTextureMailbox mailbox3;
211
212     IntSize initialSize(initialWidth, initialHeight);
213
214     // Produce mailboxes.
215     m_drawingBuffer->markContentsChanged();
216     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox1, 0));
217     m_drawingBuffer->markContentsChanged();
218     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox2, 0));
219     m_drawingBuffer->markContentsChanged();
220     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox3, 0));
221
222     // Release mailboxes by specific order; 2, 3, 1.
223     m_drawingBuffer->markContentsChanged();
224     m_drawingBuffer->mailboxReleased(mailbox2);
225     m_drawingBuffer->markContentsChanged();
226     m_drawingBuffer->mailboxReleased(mailbox3);
227     m_drawingBuffer->markContentsChanged();
228     m_drawingBuffer->mailboxReleased(mailbox1);
229
230     // The first recycled mailbox must be 2.
231     blink::WebExternalTextureMailbox recycledMailbox;
232     m_drawingBuffer->markContentsChanged();
233     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&recycledMailbox, 0));
234     EXPECT_EQ(TextureMailboxWrapper(mailbox2), TextureMailboxWrapper(recycledMailbox));
235
236     // The second recycled mailbox must be 3.
237     m_drawingBuffer->markContentsChanged();
238     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&recycledMailbox, 0));
239     EXPECT_EQ(TextureMailboxWrapper(mailbox3), TextureMailboxWrapper(recycledMailbox));
240
241     // The third recycled mailbox must be 1.
242     m_drawingBuffer->markContentsChanged();
243     EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&recycledMailbox, 0));
244     EXPECT_EQ(TextureMailboxWrapper(mailbox1), TextureMailboxWrapper(recycledMailbox));
245 }
246
247 } // namespace