| 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 |