Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: sky/engine/platform/graphics/gpu/DrawingBufferTest.cpp

Issue 1229113003: Remove some unneeded DEPS from //sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
32 #include "sky/engine/platform/graphics/gpu/DrawingBuffer.h"
33
34 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
35 #include "sky/engine/platform/graphics/ImageBuffer.h"
36 #include "sky/engine/platform/graphics/UnacceleratedImageBufferSurface.h"
37 #include "sky/engine/platform/graphics/gpu/Extensions3DUtil.h"
38 #include "sky/engine/platform/graphics/test/MockWebGraphicsContext3D.h"
39 #include "sky/engine/public/platform/Platform.h"
40 #include "sky/engine/public/platform/WebExternalTextureMailbox.h"
41 #include "sky/engine/wtf/RefPtr.h"
42
43 #include <gmock/gmock.h>
44 #include <gtest/gtest.h>
45
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 , m_mostRecentlyWaitedSyncPoint(0)
65 , m_currentImageId(1) { }
66
67 virtual void bindTexture(WGC3Denum target, WebGLId texture)
68 {
69 if (target == GL_TEXTURE_2D) {
70 m_boundTexture = texture;
71 }
72 }
73
74 virtual void texImage2D(WGC3Denum target, WGC3Dint level, WGC3Denum internal format, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format, WGC3Denum type, const void* pixels)
75 {
76 if (target == GL_TEXTURE_2D && !level) {
77 m_textureSizes.set(m_boundTexture, IntSize(width, height));
78 }
79 }
80
81 virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox)
82 {
83 ++m_currentMailboxByte;
84 WebExternalTextureMailbox temp;
85 memset(mailbox, m_currentMailboxByte, sizeof(temp.name));
86 }
87
88 virtual void produceTextureDirectCHROMIUM(WebGLId texture, WGC3Denum target, const WGC3Dbyte* mailbox)
89 {
90 ASSERT_EQ(target, static_cast<WGC3Denum>(GL_TEXTURE_2D));
91 ASSERT_TRUE(m_textureSizes.contains(texture));
92 m_mostRecentlyProducedSize = m_textureSizes.get(texture);
93 }
94
95 IntSize mostRecentlyProducedSize()
96 {
97 return m_mostRecentlyProducedSize;
98 }
99
100 virtual unsigned insertSyncPoint()
101 {
102 static unsigned syncPointGenerator = 0;
103 return ++syncPointGenerator;
104 }
105
106 virtual void waitSyncPoint(unsigned syncPoint)
107 {
108 m_mostRecentlyWaitedSyncPoint = syncPoint;
109 }
110
111 virtual WGC3Duint createImageCHROMIUM(WGC3Dsizei width, WGC3Dsizei height, W GC3Denum internalformat, WGC3Denum usage)
112 {
113 m_imageSizes.set(m_currentImageId, IntSize(width, height));
114 return m_currentImageId++;
115 }
116
117 MOCK_METHOD1(destroyImageMock, void(WGC3Duint imageId));
118 void destroyImageCHROMIUM(WGC3Duint imageId)
119 {
120 m_imageSizes.remove(imageId);
121 // No textures should be bound to this.
122 ASSERT(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end());
123 m_imageSizes.remove(imageId);
124 destroyImageMock(imageId);
125 }
126
127 MOCK_METHOD1(bindTexImage2DMock, void(WGC3Dint imageId));
128 void bindTexImage2DCHROMIUM(WGC3Denum target, WGC3Dint imageId)
129 {
130 if (target == GL_TEXTURE_2D) {
131 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value );
132 m_imageToTextureMap.set(imageId, m_boundTexture);
133 bindTexImage2DMock(imageId);
134 }
135 }
136
137 MOCK_METHOD1(releaseTexImage2DMock, void(WGC3Dint imageId));
138 void releaseTexImage2DCHROMIUM(WGC3Denum target, WGC3Dint imageId)
139 {
140 if (target == GL_TEXTURE_2D) {
141 m_imageSizes.set(m_currentImageId, IntSize());
142 m_imageToTextureMap.remove(imageId);
143 releaseTexImage2DMock(imageId);
144 }
145 }
146
147 unsigned mostRecentlyWaitedSyncPoint()
148 {
149 return m_mostRecentlyWaitedSyncPoint;
150 }
151
152 WGC3Duint nextImageIdToBeCreated()
153 {
154 return m_currentImageId;
155 }
156
157 private:
158 WebGLId m_boundTexture;
159 HashMap<WebGLId, IntSize> m_textureSizes;
160 WGC3Dbyte m_currentMailboxByte;
161 IntSize m_mostRecentlyProducedSize;
162 unsigned m_mostRecentlyWaitedSyncPoint;
163 WGC3Duint m_currentImageId;
164 HashMap<WGC3Duint, IntSize> m_imageSizes;
165 HashMap<WGC3Duint, WebGLId> m_imageToTextureMap;
166 };
167
168 static const int initialWidth = 100;
169 static const int initialHeight = 100;
170 static const int alternateHeight = 50;
171
172 class DrawingBufferForTests : public DrawingBuffer {
173 public:
174 static PassRefPtr<DrawingBufferForTests> create(PassOwnPtr<WebGraphicsContex t3D> context,
175 const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextE victionManager> contextEvictionManager)
176 {
177 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(conte xt.get());
178 RefPtr<DrawingBufferForTests> drawingBuffer =
179 adoptRef(new DrawingBufferForTests(context, extensionsUtil.release() , preserve, contextEvictionManager));
180 if (!drawingBuffer->initialize(size)) {
181 drawingBuffer->beginDestruction();
182 return PassRefPtr<DrawingBufferForTests>();
183 }
184 return drawingBuffer.release();
185 }
186
187 DrawingBufferForTests(PassOwnPtr<WebGraphicsContext3D> context,
188 PassOwnPtr<Extensions3DUtil> extensionsUtil,
189 PreserveDrawingBuffer preserve,
190 PassRefPtr<ContextEvictionManager> contextEvictionManager)
191 : DrawingBuffer(context, extensionsUtil, false /* multisampleExtensionSu pported */,
192 false /* packedDepthStencilExtensionSupported */, preserve, WebGraph icsContext3D::Attributes(), contextEvictionManager)
193 , m_live(0)
194 { }
195
196 virtual ~DrawingBufferForTests()
197 {
198 if (m_live)
199 *m_live = false;
200 }
201
202 bool* m_live;
203 };
204
205 class DrawingBufferTest : public Test {
206 protected:
207 void SetUp() override
208 {
209 RefPtr<FakeContextEvictionManager> contextEvictionManager = adoptRef(new FakeContextEvictionManager());
210 OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsC ontext3DForTests);
211 m_context = context.get();
212 m_drawingBuffer = DrawingBufferForTests::create(context.release(),
213 IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve, conte xtEvictionManager.release());
214 }
215
216 WebGraphicsContext3DForTests* webContext()
217 {
218 return m_context;
219 }
220
221 WebGraphicsContext3DForTests* m_context;
222 RefPtr<DrawingBufferForTests> m_drawingBuffer;
223 };
224
225 TEST_F(DrawingBufferTest, testPaintRenderingResultsToCanvas)
226 {
227 OwnPtr<ImageBufferSurface> imageBufferSurface = adoptPtr(new UnacceleratedIm ageBufferSurface(IntSize(initialWidth, initialHeight)));
228 EXPECT_FALSE(!imageBufferSurface);
229 EXPECT_TRUE(imageBufferSurface->isValid());
230 OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageBufferSurface.rel ease());
231 EXPECT_FALSE(!imageBuffer);
232 EXPECT_FALSE(imageBuffer->isAccelerated());
233 EXPECT_FALSE(imageBuffer->bitmap().isNull());
234 m_drawingBuffer->paintRenderingResultsToCanvas(imageBuffer.get());
235 EXPECT_FALSE(imageBuffer->isAccelerated());
236 EXPECT_FALSE(imageBuffer->bitmap().isNull());
237 m_drawingBuffer->beginDestruction();
238 }
239
240 TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes)
241 {
242 WebExternalTextureMailbox mailbox;
243
244 IntSize initialSize(initialWidth, initialHeight);
245 IntSize alternateSize(initialWidth, alternateHeight);
246
247 // Produce one mailbox at size 100x100.
248 m_drawingBuffer->markContentsChanged();
249 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
250 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
251
252 // Resize to 100x50.
253 m_drawingBuffer->reset(IntSize(initialWidth, alternateHeight));
254 m_drawingBuffer->mailboxReleased(mailbox, false);
255
256 // Produce a mailbox at this size.
257 m_drawingBuffer->markContentsChanged();
258 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
259 EXPECT_EQ(alternateSize, webContext()->mostRecentlyProducedSize());
260
261 // Reset to initial size.
262 m_drawingBuffer->reset(IntSize(initialWidth, initialHeight));
263 m_drawingBuffer->mailboxReleased(mailbox, false);
264
265 // Prepare another mailbox and verify that it's the correct size.
266 m_drawingBuffer->markContentsChanged();
267 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
268 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
269
270 // Prepare one final mailbox and verify that it's the correct size.
271 m_drawingBuffer->mailboxReleased(mailbox, false);
272 m_drawingBuffer->markContentsChanged();
273 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
274 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
275 m_drawingBuffer->beginDestruction();
276 }
277
278 TEST_F(DrawingBufferTest, verifyDestructionCompleteAfterAllMailboxesReleased)
279 {
280 bool live = true;
281 m_drawingBuffer->m_live = &live;
282
283 WebExternalTextureMailbox mailbox1;
284 WebExternalTextureMailbox mailbox2;
285 WebExternalTextureMailbox mailbox3;
286
287 IntSize initialSize(initialWidth, initialHeight);
288
289 // Produce mailboxes.
290 m_drawingBuffer->markContentsChanged();
291 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox1, 0));
292 m_drawingBuffer->markContentsChanged();
293 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox2, 0));
294 m_drawingBuffer->markContentsChanged();
295 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox3, 0));
296
297 m_drawingBuffer->markContentsChanged();
298 m_drawingBuffer->mailboxReleased(mailbox1, false);
299
300 m_drawingBuffer->beginDestruction();
301 EXPECT_EQ(live, true);
302
303 DrawingBufferForTests* weakPointer = m_drawingBuffer.get();
304 m_drawingBuffer.clear();
305 EXPECT_EQ(live, true);
306
307 weakPointer->markContentsChanged();
308 weakPointer->mailboxReleased(mailbox2, false);
309 EXPECT_EQ(live, true);
310
311 weakPointer->markContentsChanged();
312 weakPointer->mailboxReleased(mailbox3, false);
313 EXPECT_EQ(live, false);
314 }
315
316 TEST_F(DrawingBufferTest, verifyDrawingBufferStaysAliveIfResourcesAreLost)
317 {
318 bool live = true;
319 m_drawingBuffer->m_live = &live;
320 WebExternalTextureMailbox mailbox1;
321 WebExternalTextureMailbox mailbox2;
322 WebExternalTextureMailbox mailbox3;
323
324 m_drawingBuffer->markContentsChanged();
325 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox1, 0));
326 m_drawingBuffer->markContentsChanged();
327 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox2, 0));
328 m_drawingBuffer->markContentsChanged();
329 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox3, 0));
330
331 m_drawingBuffer->markContentsChanged();
332 m_drawingBuffer->mailboxReleased(mailbox1, true);
333 EXPECT_EQ(live, true);
334
335 m_drawingBuffer->beginDestruction();
336 EXPECT_EQ(live, true);
337
338 m_drawingBuffer->markContentsChanged();
339 m_drawingBuffer->mailboxReleased(mailbox2, false);
340 EXPECT_EQ(live, true);
341
342 DrawingBufferForTests* weakPtr = m_drawingBuffer.get();
343 m_drawingBuffer.clear();
344 EXPECT_EQ(live, true);
345
346 weakPtr->markContentsChanged();
347 weakPtr->mailboxReleased(mailbox3, true);
348 EXPECT_EQ(live, false);
349 }
350
351 class TextureMailboxWrapper {
352 public:
353 explicit TextureMailboxWrapper(const WebExternalTextureMailbox& mailbox)
354 : m_mailbox(mailbox)
355 { }
356
357 bool operator==(const TextureMailboxWrapper& other) const
358 {
359 return !memcmp(m_mailbox.name, other.m_mailbox.name, sizeof(m_mailbox.na me));
360 }
361
362 bool operator!=(const TextureMailboxWrapper& other) const
363 {
364 return !(*this == other);
365 }
366
367 private:
368 WebExternalTextureMailbox m_mailbox;
369 };
370
371 TEST_F(DrawingBufferTest, verifyOnlyOneRecycledMailboxMustBeKept)
372 {
373 WebExternalTextureMailbox mailbox1;
374 WebExternalTextureMailbox mailbox2;
375 WebExternalTextureMailbox mailbox3;
376
377 // Produce mailboxes.
378 m_drawingBuffer->markContentsChanged();
379 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox1, 0));
380 m_drawingBuffer->markContentsChanged();
381 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox2, 0));
382 m_drawingBuffer->markContentsChanged();
383 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox3, 0));
384
385 // Release mailboxes by specific order; 1, 3, 2.
386 m_drawingBuffer->markContentsChanged();
387 m_drawingBuffer->mailboxReleased(mailbox1, false);
388 m_drawingBuffer->markContentsChanged();
389 m_drawingBuffer->mailboxReleased(mailbox3, false);
390 m_drawingBuffer->markContentsChanged();
391 m_drawingBuffer->mailboxReleased(mailbox2, false);
392
393 // The first recycled mailbox must be 2. 1 and 3 were deleted by FIFO order because
394 // DrawingBuffer never keeps more than one mailbox.
395 WebExternalTextureMailbox recycledMailbox1;
396 m_drawingBuffer->markContentsChanged();
397 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&recycledMailbox1, 0));
398 EXPECT_EQ(TextureMailboxWrapper(mailbox2), TextureMailboxWrapper(recycledMai lbox1));
399
400 // The second recycled mailbox must be a new mailbox.
401 WebExternalTextureMailbox recycledMailbox2;
402 m_drawingBuffer->markContentsChanged();
403 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&recycledMailbox2, 0));
404 EXPECT_NE(TextureMailboxWrapper(mailbox1), TextureMailboxWrapper(recycledMai lbox2));
405 EXPECT_NE(TextureMailboxWrapper(mailbox2), TextureMailboxWrapper(recycledMai lbox2));
406 EXPECT_NE(TextureMailboxWrapper(mailbox3), TextureMailboxWrapper(recycledMai lbox2));
407
408 m_drawingBuffer->mailboxReleased(recycledMailbox1, false);
409 m_drawingBuffer->mailboxReleased(recycledMailbox2, false);
410 m_drawingBuffer->beginDestruction();
411 }
412
413 TEST_F(DrawingBufferTest, verifyInsertAndWaitSyncPointCorrectly)
414 {
415 WebExternalTextureMailbox mailbox;
416
417 // Produce mailboxes.
418 m_drawingBuffer->markContentsChanged();
419 EXPECT_EQ(0u, webContext()->mostRecentlyWaitedSyncPoint());
420 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
421 // prepareMailbox() does not wait for any sync point.
422 EXPECT_EQ(0u, webContext()->mostRecentlyWaitedSyncPoint());
423
424 unsigned waitSyncPoint = webContext()->insertSyncPoint();
425 mailbox.syncPoint = waitSyncPoint;
426 m_drawingBuffer->mailboxReleased(mailbox, false);
427 // m_drawingBuffer will wait for the sync point when recycling.
428 EXPECT_EQ(0u, webContext()->mostRecentlyWaitedSyncPoint());
429
430 m_drawingBuffer->markContentsChanged();
431 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
432 // m_drawingBuffer waits for the sync point when recycling in prepareMailbox ().
433 EXPECT_EQ(waitSyncPoint, webContext()->mostRecentlyWaitedSyncPoint());
434
435 m_drawingBuffer->beginDestruction();
436 waitSyncPoint = webContext()->insertSyncPoint();
437 mailbox.syncPoint = waitSyncPoint;
438 m_drawingBuffer->mailboxReleased(mailbox, false);
439 // m_drawingBuffer waits for the sync point because the destruction is in pr ogress.
440 EXPECT_EQ(waitSyncPoint, webContext()->mostRecentlyWaitedSyncPoint());
441 }
442
443 class DrawingBufferImageChromiumTest : public DrawingBufferTest {
444 protected:
445 void SetUp() override
446 {
447 RefPtr<FakeContextEvictionManager> contextEvictionManager = adoptRef(new FakeContextEvictionManager());
448 OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsC ontext3DForTests);
449 m_context = context.get();
450 RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(true);
451 m_imageId0 = webContext()->nextImageIdToBeCreated();
452 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId0)).Times(1);
453 m_drawingBuffer = DrawingBufferForTests::create(context.release(),
454 IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve, conte xtEvictionManager.release());
455 testing::Mock::VerifyAndClearExpectations(webContext());
456 }
457
458 void TearDown() override
459 {
460 RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(false);
461 }
462 WGC3Duint m_imageId0;
463 };
464
465 TEST_F(DrawingBufferImageChromiumTest, verifyResizingReallocatesImages)
466 {
467 WebExternalTextureMailbox mailbox;
468
469 IntSize initialSize(initialWidth, initialHeight);
470 IntSize alternateSize(initialWidth, alternateHeight);
471
472 WGC3Duint m_imageId1 = webContext()->nextImageIdToBeCreated();
473 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId1)).Times(1);
474 // Produce one mailbox at size 100x100.
475 m_drawingBuffer->markContentsChanged();
476 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
477 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
478 EXPECT_TRUE(mailbox.allowOverlay);
479 testing::Mock::VerifyAndClearExpectations(webContext());
480
481 WGC3Duint m_imageId2 = webContext()->nextImageIdToBeCreated();
482 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId2)).Times(1);
483 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId0)).Times(1);
484 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId0)).Times(1);
485 // Resize to 100x50.
486 m_drawingBuffer->reset(IntSize(initialWidth, alternateHeight));
487 m_drawingBuffer->mailboxReleased(mailbox, false);
488 testing::Mock::VerifyAndClearExpectations(webContext());
489
490 WGC3Duint m_imageId3 = webContext()->nextImageIdToBeCreated();
491 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId3)).Times(1);
492 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId1)).Times(1);
493 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId1)).Times(1);
494 // Produce a mailbox at this size.
495 m_drawingBuffer->markContentsChanged();
496 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
497 EXPECT_EQ(alternateSize, webContext()->mostRecentlyProducedSize());
498 EXPECT_TRUE(mailbox.allowOverlay);
499 testing::Mock::VerifyAndClearExpectations(webContext());
500
501 WGC3Duint m_imageId4 = webContext()->nextImageIdToBeCreated();
502 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId4)).Times(1);
503 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId2)).Times(1);
504 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId2)).Times(1);
505 // Reset to initial size.
506 m_drawingBuffer->reset(IntSize(initialWidth, initialHeight));
507 m_drawingBuffer->mailboxReleased(mailbox, false);
508 testing::Mock::VerifyAndClearExpectations(webContext());
509
510 WGC3Duint m_imageId5 = webContext()->nextImageIdToBeCreated();
511 EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId5)).Times(1);
512 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId3)).Times(1);
513 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId3)).Times(1);
514 // Prepare another mailbox and verify that it's the correct size.
515 m_drawingBuffer->markContentsChanged();
516 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
517 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
518 EXPECT_TRUE(mailbox.allowOverlay);
519 testing::Mock::VerifyAndClearExpectations(webContext());
520
521 // Prepare one final mailbox and verify that it's the correct size.
522 m_drawingBuffer->mailboxReleased(mailbox, false);
523 m_drawingBuffer->markContentsChanged();
524 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
525 EXPECT_EQ(initialSize, webContext()->mostRecentlyProducedSize());
526 EXPECT_TRUE(mailbox.allowOverlay);
527 m_drawingBuffer->mailboxReleased(mailbox, false);
528
529 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId5)).Times(1);
530 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId5)).Times(1);
531 EXPECT_CALL(*webContext(), destroyImageMock(m_imageId4)).Times(1);
532 EXPECT_CALL(*webContext(), releaseTexImage2DMock(m_imageId4)).Times(1);
533 m_drawingBuffer->beginDestruction();
534 testing::Mock::VerifyAndClearExpectations(webContext());
535 }
536
537 class DepthStencilTrackingContext : public MockWebGraphicsContext3D {
538 public:
539 DepthStencilTrackingContext()
540 : m_nextRenderBufferId(1)
541 , m_stencilAttachment(0)
542 , m_depthAttachment(0) { }
543 virtual ~DepthStencilTrackingContext() { }
544
545 int numAllocatedRenderBuffer() const { return m_nextRenderBufferId - 1; }
546 WebGLId stencilAttachment() const { return m_stencilAttachment; }
547 WebGLId depthAttachment() const { return m_depthAttachment; }
548
549 virtual WebString getString(WGC3Denum type) override
550 {
551 if (type == GL_EXTENSIONS) {
552 return WebString::fromUTF8("GL_OES_packed_depth_stencil");
553 }
554 return WebString();
555 }
556
557 virtual WebGLId createRenderbuffer() override
558 {
559 return ++m_nextRenderBufferId;
560 }
561
562 virtual void framebufferRenderbuffer(WGC3Denum target, WGC3Denum attachment, WGC3Denum renderbuffertarget, WebGLId renderbuffer) override
563 {
564 if (attachment == GL_STENCIL_ATTACHMENT) {
565 m_stencilAttachment = renderbuffer;
566 } else {
567 m_depthAttachment = renderbuffer;
568 }
569 }
570
571 virtual void getIntegerv(WGC3Denum ptype, WGC3Dint* value) override
572 {
573 switch (ptype) {
574 case GL_DEPTH_BITS:
575 *value = m_depthAttachment ? 24 : 0;
576 return;
577 case GL_STENCIL_BITS:
578 *value = m_stencilAttachment ? 8 : 0;
579 return;
580 }
581 MockWebGraphicsContext3D::getIntegerv(ptype, value);
582 }
583
584 private:
585 WebGLId m_nextRenderBufferId;
586 WebGLId m_stencilAttachment;
587 WebGLId m_depthAttachment;
588 };
589
590 struct DepthStencilTestCase {
591 DepthStencilTestCase(bool requestStencil, bool requestDepth, int expectedRen derBuffers, bool expectDepthStencil, const char* const testCaseName)
592 : requestStencil(requestStencil)
593 , requestDepth(requestDepth)
594 , expectDepthStencil(expectDepthStencil)
595 , expectedRenderBuffers(expectedRenderBuffers)
596 , testCaseName(testCaseName) { }
597
598 bool requestStencil;
599 bool requestDepth;
600 bool expectDepthStencil;
601 int expectedRenderBuffers;
602 const char* const testCaseName;
603 };
604
605 // This tests that when the packed depth+stencil extension is supported DrawingB uffer always allocates
606 // a single packed renderbuffer if either is requested and properly computes the actual context attributes
607 // as defined by WebGL. We always allocate a packed buffer in this case since ma ny desktop OpenGL drivers
608 // that support this extension do not consider a framebuffer with only a depth o r a stencil buffer attached
609 // to be complete.
610 TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported)
611 {
612 DepthStencilTestCase cases[] = {
613 DepthStencilTestCase(false, false, false, 0, "neither"),
614 DepthStencilTestCase(true, false, true, 1, "stencil only"),
615 DepthStencilTestCase(false, true, true, 1, "depth only"),
616 DepthStencilTestCase(true, true, true, 1, "both"),
617 };
618
619 for (size_t i = 0; i < arraysize(cases); i++) {
620 SCOPED_TRACE(cases[i].testCaseName);
621 OwnPtr<DepthStencilTrackingContext> context = adoptPtr(new DepthStencilT rackingContext);
622 DepthStencilTrackingContext* trackingContext = context.get();
623 DrawingBuffer::PreserveDrawingBuffer preserve = DrawingBuffer::Preserve;
624 RefPtr<ContextEvictionManager> contextEvictionManager = adoptRef(new Fak eContextEvictionManager);
625
626 WebGraphicsContext3D::Attributes requestedAttributes;
627 requestedAttributes.stencil = cases[i].requestStencil;
628 requestedAttributes.depth = cases[i].requestDepth;
629 RefPtr<DrawingBuffer> drawingBuffer = DrawingBuffer::create(context.rele ase(), IntSize(10, 10), preserve, requestedAttributes, contextEvictionManager);
630
631 EXPECT_EQ(cases[i].requestDepth, drawingBuffer->getActualAttributes().de pth);
632 EXPECT_EQ(cases[i].requestStencil, drawingBuffer->getActualAttributes(). stencil);
633 EXPECT_EQ(cases[i].expectedRenderBuffers, trackingContext->numAllocatedR enderBuffer());
634 if (cases[i].expectDepthStencil) {
635 EXPECT_EQ(trackingContext->stencilAttachment(), trackingContext->dep thAttachment());
636 } else if (cases[i].requestStencil || cases[i].requestDepth) {
637 EXPECT_NE(trackingContext->stencilAttachment(), trackingContext->dep thAttachment());
638 } else {
639 EXPECT_EQ(0u, trackingContext->stencilAttachment());
640 EXPECT_EQ(0u, trackingContext->depthAttachment());
641 }
642
643 drawingBuffer->reset(IntSize(10, 20));
644 EXPECT_EQ(cases[i].requestDepth, drawingBuffer->getActualAttributes().de pth);
645 EXPECT_EQ(cases[i].requestStencil, drawingBuffer->getActualAttributes(). stencil);
646 EXPECT_EQ(cases[i].expectedRenderBuffers, trackingContext->numAllocatedR enderBuffer());
647 if (cases[i].expectDepthStencil) {
648 EXPECT_EQ(trackingContext->stencilAttachment(), trackingContext->dep thAttachment());
649 } else if (cases[i].requestStencil || cases[i].requestDepth) {
650 EXPECT_NE(trackingContext->stencilAttachment(), trackingContext->dep thAttachment());
651 } else {
652 EXPECT_EQ(0u, trackingContext->stencilAttachment());
653 EXPECT_EQ(0u, trackingContext->depthAttachment());
654 }
655
656 drawingBuffer->beginDestruction();
657 }
658 }
659
660 TEST_F(DrawingBufferTest, verifySetIsHiddenProperlyAffectsMailboxes)
661 {
662 blink::WebExternalTextureMailbox mailbox;
663
664 // Produce mailboxes.
665 m_drawingBuffer->markContentsChanged();
666 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
667
668 unsigned waitSyncPoint = webContext()->insertSyncPoint();
669 mailbox.syncPoint = waitSyncPoint;
670 m_drawingBuffer->setIsHidden(true);
671 m_drawingBuffer->mailboxReleased(mailbox);
672 // m_drawingBuffer deletes mailbox immediately when hidden.
673 EXPECT_EQ(waitSyncPoint, webContext()->mostRecentlyWaitedSyncPoint());
674
675 m_drawingBuffer->beginDestruction();
676 }
677
678 } // namespace
OLDNEW
« no previous file with comments | « sky/engine/platform/graphics/gpu/DrawingBuffer.cpp ('k') | sky/engine/platform/graphics/gpu/Extensions3DUtil.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698