OLD | NEW |
| (Empty) |
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 internal
format, 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* mailb
ox) | |
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(initial
Width, 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 UnacceleratedIm
ageBufferSurface(IntSize(initialWidth, initialHeight))); | |
133 EXPECT_FALSE(!imageBufferSurface); | |
134 EXPECT_TRUE(imageBufferSurface->isValid()); | |
135 OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageBufferSurface.rel
ease()); | |
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& mailb
ox) | |
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.na
me)); | |
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(recycledMai
lbox)); | |
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(recycledMai
lbox)); | |
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(recycledMai
lbox)); | |
245 } | |
246 | |
247 } // namespace | |
OLD | NEW |