diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-21 10:57:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-21 10:57:44 +0200 |
commit | 5ef7c8a6a70875d4430752d146bdcb069605d71d (patch) | |
tree | f6256640b6c46d7da221435803cae65326817ba2 /Source/WebKit/chromium/tests/CCResourceProviderTest.cpp | |
parent | decad929f578d8db641febc8740649ca6c574638 (diff) | |
download | qtwebkit-5ef7c8a6a70875d4430752d146bdcb069605d71d.tar.gz |
Imported WebKit commit 356d83016b090995d08ad568f2d2c243aa55e831 (http://svn.webkit.org/repository/webkit/trunk@126147)
New snapshot including various build fixes for newer Qt 5
Diffstat (limited to 'Source/WebKit/chromium/tests/CCResourceProviderTest.cpp')
-rw-r--r-- | Source/WebKit/chromium/tests/CCResourceProviderTest.cpp | 290 |
1 files changed, 253 insertions, 37 deletions
diff --git a/Source/WebKit/chromium/tests/CCResourceProviderTest.cpp b/Source/WebKit/chromium/tests/CCResourceProviderTest.cpp index 42277459a..9e8599c0f 100644 --- a/Source/WebKit/chromium/tests/CCResourceProviderTest.cpp +++ b/Source/WebKit/chromium/tests/CCResourceProviderTest.cpp @@ -24,13 +24,13 @@ #include "config.h" -#include "cc/CCResourceProvider.h" +#include "CCResourceProvider.h" +#include "CCGraphicsContext.h" +#include "CCSingleThreadProxy.h" // For DebugScopedSetImplThread #include "CompositorFakeWebGraphicsContext3D.h" #include "Extensions3DChromium.h" #include "FakeWebCompositorOutputSurface.h" -#include "cc/CCGraphicsContext.h" -#include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread #include <gtest/gtest.h> #include <public/WebGraphicsContext3D.h> #include <wtf/HashMap.h> @@ -42,9 +42,98 @@ using namespace WebKit; namespace { +size_t textureSize(const IntSize& size, WGC3Denum format) +{ + unsigned int componentsPerPixel = 4; + unsigned int bytesPerComponent = 1; + GraphicsContext3D::computeFormatAndTypeParameters(format, GraphicsContext3D::UNSIGNED_BYTE, &componentsPerPixel, &bytesPerComponent); + return size.width() * size.height() * componentsPerPixel * bytesPerComponent; +} + +struct Texture { + Texture(const IntSize& size, WGC3Denum format) + : size(size) + , format(format) + , data(adoptArrayPtr(new uint8_t[textureSize(size, format)])) + { + } + + IntSize size; + WGC3Denum format; + OwnArrayPtr<uint8_t> data; +}; + +// Shared data between multiple ResourceProviderContext. This contains mailbox +// contents as well as information about sync points. +class ContextSharedData { +public: + static PassOwnPtr<ContextSharedData> create() { return adoptPtr(new ContextSharedData()); } + + unsigned insertSyncPoint() { return m_nextSyncPoint++; } + + void genMailbox(WGC3Dbyte* mailbox) + { + memset(mailbox, 0, sizeof(WGC3Dbyte[64])); + memcpy(mailbox, &m_nextMailBox, sizeof(m_nextMailBox)); + ++m_nextMailBox; + } + + void produceTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint, PassOwnPtr<Texture> texture) + { + unsigned mailbox = 0; + memcpy(&mailbox, mailboxName, sizeof(mailbox)); + ASSERT(mailbox && mailbox < m_nextMailBox); + m_textures.set(mailbox, texture); + ASSERT(m_syncPointForMailbox.get(mailbox) < syncPoint); + m_syncPointForMailbox.set(mailbox, syncPoint); + } + + PassOwnPtr<Texture> consumeTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint) + { + unsigned mailbox = 0; + memcpy(&mailbox, mailboxName, sizeof(mailbox)); + ASSERT(mailbox && mailbox < m_nextMailBox); + + // If the latest sync point the context has waited on is before the sync + // point for when the mailbox was set, pretend we never saw that + // produceTexture. + if (m_syncPointForMailbox.get(mailbox) < syncPoint) + return nullptr; + return m_textures.take(mailbox); + } + +private: + ContextSharedData() + : m_nextSyncPoint(1) + , m_nextMailBox(1) + { } + + unsigned m_nextSyncPoint; + unsigned m_nextMailBox; + typedef HashMap<unsigned, OwnPtr<Texture> > TextureMap; + TextureMap m_textures; + HashMap<unsigned, unsigned> m_syncPointForMailbox; +}; + class ResourceProviderContext : public CompositorFakeWebGraphicsContext3D { public: - static PassOwnPtr<ResourceProviderContext> create() { return adoptPtr(new ResourceProviderContext(Attributes())); } + static PassOwnPtr<ResourceProviderContext> create(ContextSharedData* sharedData) { return adoptPtr(new ResourceProviderContext(Attributes(), sharedData)); } + + virtual unsigned insertSyncPoint() + { + unsigned syncPoint = m_sharedData->insertSyncPoint(); + // Commit the produceTextureCHROMIUM calls at this point, so that + // they're associated with the sync point. + for (PendingProduceTextureList::iterator it = m_pendingProduceTextures.begin(); it != m_pendingProduceTextures.end(); ++it) + m_sharedData->produceTexture((*it)->mailbox, syncPoint, (*it)->texture.release()); + m_pendingProduceTextures.clear(); + return syncPoint; + } + + virtual void waitSyncPoint(unsigned syncPoint) + { + m_lastWaitedSyncPoint = std::max(syncPoint, m_lastWaitedSyncPoint); + } virtual void bindTexture(WGC3Denum target, WebGLId texture) { @@ -113,6 +202,29 @@ public: setPixels(xoffset, yoffset, width, height, pixels); } + virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox) { return m_sharedData->genMailbox(mailbox); } + virtual void produceTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailbox) + { + ASSERT(m_currentTexture); + ASSERT(target == GraphicsContext3D::TEXTURE_2D); + + // Delay movind the texture into the mailbox until the next + // insertSyncPoint, so that it is not visible to other contexts that + // haven't waited on that sync point. + OwnPtr<PendingProduceTexture> pending(adoptPtr(new PendingProduceTexture)); + memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox)); + pending->texture = m_textures.take(m_currentTexture); + m_textures.set(m_currentTexture, nullptr); + m_pendingProduceTextures.append(pending.release()); + } + + virtual void consumeTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailbox) + { + ASSERT(m_currentTexture); + ASSERT(target == GraphicsContext3D::TEXTURE_2D); + m_textures.set(m_currentTexture, m_sharedData->consumeTexture(mailbox, m_lastWaitedSyncPoint)); + } + void getPixels(const IntSize& size, WGC3Denum format, uint8_t* pixels) { ASSERT(m_currentTexture); @@ -128,34 +240,15 @@ public: return m_textures.size(); } - static size_t textureSize(const IntSize& size, WGC3Denum format) - { - unsigned int componentsPerPixel = 4; - unsigned int bytesPerComponent = 1; - GraphicsContext3D::computeFormatAndTypeParameters(format, GraphicsContext3D::UNSIGNED_BYTE, &componentsPerPixel, &bytesPerComponent); - return size.width() * size.height() * componentsPerPixel * bytesPerComponent; - } - protected: - explicit ResourceProviderContext(const Attributes& attrs) + ResourceProviderContext(const Attributes& attrs, ContextSharedData* sharedData) : CompositorFakeWebGraphicsContext3D(attrs) + , m_sharedData(sharedData) , m_currentTexture(0) + , m_lastWaitedSyncPoint(0) { } private: - struct Texture { - Texture(const IntSize& size_, WGC3Denum format_) - : size(size_) - , format(format_) - , data(adoptArrayPtr(new uint8_t[textureSize(size, format)])) - { - } - - IntSize size; - WGC3Denum format; - OwnArrayPtr<uint8_t> data; - }; - void allocateTexture(const IntSize& size, WGC3Denum format) { ASSERT(m_currentTexture); @@ -182,14 +275,23 @@ private: } typedef HashMap<WebGLId, OwnPtr<Texture> > TextureMap; + struct PendingProduceTexture { + WGC3Dbyte mailbox[64]; + OwnPtr<Texture> texture; + }; + typedef Deque<OwnPtr<PendingProduceTexture> > PendingProduceTextureList; + ContextSharedData* m_sharedData; WebGLId m_currentTexture; TextureMap m_textures; + unsigned m_lastWaitedSyncPoint; + PendingProduceTextureList m_pendingProduceTextures; }; class CCResourceProviderTest : public testing::Test { public: CCResourceProviderTest() - : m_context(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create())) + : m_sharedData(ContextSharedData::create()) + , m_context(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create(m_sharedData.get()))) , m_resourceProvider(CCResourceProvider::create(m_context.get())) { } @@ -206,6 +308,7 @@ public: protected: DebugScopedSetImplThread implThread; + OwnPtr<ContextSharedData> m_sharedData; OwnPtr<CCGraphicsContext> m_context; OwnPtr<CCResourceProvider> m_resourceProvider; }; @@ -215,7 +318,7 @@ TEST_F(CCResourceProviderTest, Basic) IntSize size(1, 1); WGC3Denum format = GraphicsContext3D::RGBA; int pool = 1; - size_t pixelSize = ResourceProviderContext::textureSize(size, format); + size_t pixelSize = textureSize(size, format); ASSERT_EQ(4U, pixelSize); CCResourceProvider::ResourceId id = m_resourceProvider->createResource(pool, size, format, CCResourceProvider::TextureUsageAny); @@ -223,7 +326,7 @@ TEST_F(CCResourceProviderTest, Basic) uint8_t data[4] = {1, 2, 3, 4}; IntRect rect(IntPoint(), size); - m_resourceProvider->upload(id, data, rect, rect, rect); + m_resourceProvider->upload(id, data, rect, rect, IntSize()); uint8_t result[4] = {0}; getResourcePixels(id, size, format, result); @@ -256,14 +359,14 @@ TEST_F(CCResourceProviderTest, Upload) IntSize size(2, 2); WGC3Denum format = GraphicsContext3D::RGBA; int pool = 1; - size_t pixelSize = ResourceProviderContext::textureSize(size, format); + size_t pixelSize = textureSize(size, format); ASSERT_EQ(16U, pixelSize); CCResourceProvider::ResourceId id = m_resourceProvider->createResource(pool, size, format, CCResourceProvider::TextureUsageAny); uint8_t image[16] = {0}; IntRect imageRect(IntPoint(), size); - m_resourceProvider->upload(id, image, imageRect, imageRect, imageRect); + m_resourceProvider->upload(id, image, imageRect, imageRect, IntSize()); for (uint8_t i = 0 ; i < pixelSize; ++i) image[i] = i; @@ -271,8 +374,8 @@ TEST_F(CCResourceProviderTest, Upload) uint8_t result[16] = {0}; { IntRect sourceRect(0, 0, 1, 1); - IntRect destRect(0, 0, 1, 1); - m_resourceProvider->upload(id, image, imageRect, sourceRect, destRect); + IntSize destOffset(0, 0); + m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset); uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -281,8 +384,8 @@ TEST_F(CCResourceProviderTest, Upload) } { IntRect sourceRect(0, 0, 1, 1); - IntRect destRect(1, 1, 1, 1); - m_resourceProvider->upload(id, image, imageRect, sourceRect, destRect); + IntSize destOffset(1, 1); + m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset); uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; @@ -291,8 +394,8 @@ TEST_F(CCResourceProviderTest, Upload) } { IntRect sourceRect(1, 0, 1, 1); - IntRect destRect(0, 1, 1, 1); - m_resourceProvider->upload(id, image, imageRect, sourceRect, destRect); + IntSize destOffset(0, 1); + m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset); uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3}; @@ -303,4 +406,117 @@ TEST_F(CCResourceProviderTest, Upload) m_resourceProvider->deleteResource(id); } +TEST_F(CCResourceProviderTest, TransferResources) +{ + OwnPtr<CCGraphicsContext> childContext(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create(m_sharedData.get()))); + OwnPtr<CCResourceProvider> childResourceProvider(CCResourceProvider::create(childContext.get())); + + IntSize size(1, 1); + WGC3Denum format = GraphicsContext3D::RGBA; + int pool = 1; + size_t pixelSize = textureSize(size, format); + ASSERT_EQ(4U, pixelSize); + + CCResourceProvider::ResourceId id1 = childResourceProvider->createResource(pool, size, format, CCResourceProvider::TextureUsageAny); + uint8_t data1[4] = {1, 2, 3, 4}; + IntRect rect(IntPoint(), size); + childResourceProvider->upload(id1, data1, rect, rect, IntSize()); + + CCResourceProvider::ResourceId id2 = childResourceProvider->createResource(pool, size, format, CCResourceProvider::TextureUsageAny); + uint8_t data2[4] = {5, 5, 5, 5}; + childResourceProvider->upload(id2, data2, rect, rect, IntSize()); + + int childPool = 2; + int childId = m_resourceProvider->createChild(childPool); + + { + // Transfer some resources to the parent. + CCResourceProvider::ResourceIdArray resourceIdsToTransfer; + resourceIdsToTransfer.append(id1); + resourceIdsToTransfer.append(id2); + CCResourceProvider::TransferableResourceList list = childResourceProvider->prepareSendToParent(resourceIdsToTransfer); + EXPECT_NE(0u, list.syncPoint); + EXPECT_EQ(2u, list.resources.size()); + EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1)); + EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2)); + m_resourceProvider->receiveFromChild(childId, list); + } + + EXPECT_EQ(2u, m_resourceProvider->numResources()); + EXPECT_EQ(2u, m_resourceProvider->mailboxCount()); + CCResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->getChildToParentMap(childId); + CCResourceProvider::ResourceId mappedId1 = resourceMap.get(id1); + CCResourceProvider::ResourceId mappedId2 = resourceMap.get(id2); + EXPECT_NE(0u, mappedId1); + EXPECT_NE(0u, mappedId2); + EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id1)); + EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id2)); + + uint8_t result[4] = {0}; + getResourcePixels(mappedId1, size, format, result); + EXPECT_EQ(0, memcmp(data1, result, pixelSize)); + + getResourcePixels(mappedId2, size, format, result); + EXPECT_EQ(0, memcmp(data2, result, pixelSize)); + + { + // Check that transfering again the same resource from the child to the + // parent is a noop. + CCResourceProvider::ResourceIdArray resourceIdsToTransfer; + resourceIdsToTransfer.append(id1); + CCResourceProvider::TransferableResourceList list = childResourceProvider->prepareSendToParent(resourceIdsToTransfer); + EXPECT_EQ(0u, list.syncPoint); + EXPECT_EQ(0u, list.resources.size()); + } + + { + // Transfer resources back from the parent to the child. + CCResourceProvider::ResourceIdArray resourceIdsToTransfer; + resourceIdsToTransfer.append(mappedId1); + resourceIdsToTransfer.append(mappedId2); + CCResourceProvider::TransferableResourceList list = m_resourceProvider->prepareSendToChild(childId, resourceIdsToTransfer); + EXPECT_NE(0u, list.syncPoint); + EXPECT_EQ(2u, list.resources.size()); + childResourceProvider->receiveFromParent(list); + } + EXPECT_EQ(0u, m_resourceProvider->mailboxCount()); + EXPECT_EQ(2u, childResourceProvider->mailboxCount()); + EXPECT_FALSE(childResourceProvider->inUseByConsumer(id1)); + EXPECT_FALSE(childResourceProvider->inUseByConsumer(id2)); + + ResourceProviderContext* childContext3D = static_cast<ResourceProviderContext*>(childContext->context3D()); + { + CCScopedLockResourceForRead lock(childResourceProvider.get(), id1); + ASSERT_NE(0U, lock.textureId()); + childContext3D->bindTexture(GraphicsContext3D::TEXTURE_2D, lock.textureId()); + childContext3D->getPixels(size, format, result); + EXPECT_EQ(0, memcmp(data1, result, pixelSize)); + } + { + CCScopedLockResourceForRead lock(childResourceProvider.get(), id2); + ASSERT_NE(0U, lock.textureId()); + childContext3D->bindTexture(GraphicsContext3D::TEXTURE_2D, lock.textureId()); + childContext3D->getPixels(size, format, result); + EXPECT_EQ(0, memcmp(data2, result, pixelSize)); + } + + { + // Transfer resources to the parent again. + CCResourceProvider::ResourceIdArray resourceIdsToTransfer; + resourceIdsToTransfer.append(id1); + resourceIdsToTransfer.append(id2); + CCResourceProvider::TransferableResourceList list = childResourceProvider->prepareSendToParent(resourceIdsToTransfer); + EXPECT_NE(0u, list.syncPoint); + EXPECT_EQ(2u, list.resources.size()); + EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1)); + EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2)); + m_resourceProvider->receiveFromChild(childId, list); + } + + EXPECT_EQ(2u, m_resourceProvider->numResources()); + m_resourceProvider->destroyChild(childId); + EXPECT_EQ(0u, m_resourceProvider->numResources()); + EXPECT_EQ(0u, m_resourceProvider->mailboxCount()); +} + } // namespace |