summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-22 11:17:40 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-22 11:17:40 +0000
commit755451eba1c47e1b169bb4e70903d073d131abea (patch)
tree8aa079f0e91902862a766a6710ebc7f63f841928 /cc
parent77a84826ef757c200e459d0d6985e796c7590014 (diff)
downloadchromium_src-755451eba1c47e1b169bb4e70903d073d131abea.zip
chromium_src-755451eba1c47e1b169bb4e70903d073d131abea.tar.gz
chromium_src-755451eba1c47e1b169bb4e70903d073d131abea.tar.bz2
cc: Make ResourceProvider correctly handle transferring mailbox-created resources
For mailbox-created resources, the texture ID is created lazily, in lockForRead. If we use a delegating renderer, we won't lock it, so at the time we transfer it to the parent and back, we don't have a texture ID, and we shouldn't be producing/consuming. We still need to correctly handle the synchronization logic. This change implements all this, and adds tests. BUG=164095 Review URL: https://chromiumcodereview.appspot.com/12315046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184089 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/resource_provider.cc17
-rw-r--r--cc/resource_provider_unittest.cc113
2 files changed, 125 insertions, 5 deletions
diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc
index 0ac1e18..5de3149 100644
--- a/cc/resource_provider.cc
+++ b/cc/resource_provider.cc
@@ -760,8 +760,12 @@ void ResourceProvider::receiveFromParent(const TransferableResourceList& resourc
DCHECK(resource->exported);
resource->exported = false;
DCHECK(resource->mailbox.Equals(it->mailbox));
- GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->glId));
- GLC(context3d, context3d->consumeTextureCHROMIUM(GL_TEXTURE_2D, it->mailbox.name));
+ if (resource->glId) {
+ GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->glId));
+ GLC(context3d, context3d->consumeTextureCHROMIUM(GL_TEXTURE_2D, it->mailbox.name));
+ } else {
+ resource->mailbox = TextureMailbox(resource->mailbox.name(), resource->mailbox.callback(), resources.sync_point);
+ }
if (resource->markedForDeletion)
deleteResourceInternal(mapIterator);
}
@@ -791,8 +795,13 @@ bool ResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceI
} else
resource->mailbox = source->mailbox.name();
- GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId));
- GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbox.name));
+ if (source->glId) {
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId));
+ GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbox.name));
+ } else if (source->mailbox.sync_point()) {
+ GLC(context3d, context3d->waitSyncPoint(source->mailbox.sync_point()));
+ source->mailbox.ResetSyncPoint();
+ }
return true;
}
diff --git a/cc/resource_provider_unittest.cc b/cc/resource_provider_unittest.cc
index 0058d11..ebca722 100644
--- a/cc/resource_provider_unittest.cc
+++ b/cc/resource_provider_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/resource_provider.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "cc/output_surface.h"
#include "cc/scoped_ptr_deque.h"
@@ -83,8 +84,10 @@ public:
// 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[mailbox] < syncPoint)
+ if (m_syncPointForMailbox[mailbox] > syncPoint) {
+ NOTREACHED();
return scoped_ptr<Texture>();
+ }
return m_textures.take(mailbox);
}
@@ -564,6 +567,114 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources)
EXPECT_EQ(0u, childResourceProvider->numResources());
}
+void ReleaseTextureMailbox(unsigned* releaseSyncPoint, unsigned syncPoint) {
+ *releaseSyncPoint = syncPoint;
+}
+
+TEST_P(ResourceProviderTest, TransferMailboxResources)
+{
+ // Resource transfer is only supported with GL textures for now.
+ if (GetParam() != ResourceProvider::GLTexture)
+ return;
+ unsigned texture = context()->createTexture();
+ context()->bindTexture(GL_TEXTURE_2D, texture);
+ uint8_t data[4] = {1, 2, 3, 4};
+ context()->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
+ Mailbox mailbox;
+ context()->genMailboxCHROMIUM(mailbox.name);
+ context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ unsigned syncPoint = context()->insertSyncPoint();
+
+ // All the logic below assumes that the sync points are all positive.
+ EXPECT_LT(0u, syncPoint);
+
+ unsigned releaseSyncPoint = 0;
+ TextureMailbox::ReleaseCallback callback = base::Bind(ReleaseTextureMailbox, &releaseSyncPoint);
+ ResourceProvider::ResourceId resource = m_resourceProvider->createResourceFromTextureMailbox(TextureMailbox(mailbox, callback, syncPoint));
+ EXPECT_EQ(1u, context()->textureCount());
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ {
+ // Transfer the resource, expect the sync points to be consistent.
+ ResourceProvider::ResourceIdArray resourceIdsToTransfer;
+ resourceIdsToTransfer.push_back(resource);
+ TransferableResourceList list;
+ m_resourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
+ EXPECT_LE(syncPoint, list.sync_point);
+ EXPECT_EQ(1u, list.resources.size());
+ EXPECT_EQ(0u, memcmp(mailbox.name, list.resources[0].mailbox.name, sizeof(mailbox.name)));
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ context()->waitSyncPoint(list.sync_point);
+ unsigned otherTexture = context()->createTexture();
+ context()->bindTexture(GL_TEXTURE_2D, otherTexture);
+ context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ uint8_t testData[4] = {0};
+ context()->getPixels(gfx::Size(1, 1), GL_RGBA, testData);
+ EXPECT_EQ(0u, memcmp(data, testData, sizeof(data)));
+ context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ context()->deleteTexture(otherTexture);
+ list.sync_point = context()->insertSyncPoint();
+ EXPECT_LT(0u, list.sync_point);
+
+ // Receive the resource, then delete it, expect the sync points to be consistent.
+ m_resourceProvider->receiveFromParent(list);
+ EXPECT_EQ(1u, context()->textureCount());
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ m_resourceProvider->deleteResource(resource);
+ EXPECT_LE(list.sync_point, releaseSyncPoint);
+ }
+
+
+ // We're going to do the same thing as above, but testing the case where we
+ // delete the resource before we receive it back.
+ syncPoint = releaseSyncPoint;
+ EXPECT_LT(0u, syncPoint);
+ releaseSyncPoint = 0;
+ resource = m_resourceProvider->createResourceFromTextureMailbox(TextureMailbox(mailbox, callback, syncPoint));
+ EXPECT_EQ(1u, context()->textureCount());
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ {
+ // Transfer the resource, expect the sync points to be consistent.
+ ResourceProvider::ResourceIdArray resourceIdsToTransfer;
+ resourceIdsToTransfer.push_back(resource);
+ TransferableResourceList list;
+ m_resourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
+ EXPECT_LE(syncPoint, list.sync_point);
+ EXPECT_EQ(1u, list.resources.size());
+ EXPECT_EQ(0u, memcmp(mailbox.name, list.resources[0].mailbox.name, sizeof(mailbox.name)));
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ context()->waitSyncPoint(list.sync_point);
+ unsigned otherTexture = context()->createTexture();
+ context()->bindTexture(GL_TEXTURE_2D, otherTexture);
+ context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ uint8_t testData[4] = {0};
+ context()->getPixels(gfx::Size(1, 1), GL_RGBA, testData);
+ EXPECT_EQ(0u, memcmp(data, testData, sizeof(data)));
+ context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ context()->deleteTexture(otherTexture);
+ list.sync_point = context()->insertSyncPoint();
+ EXPECT_LT(0u, list.sync_point);
+
+ // Delete the resource, which shouldn't do anything.
+ m_resourceProvider->deleteResource(resource);
+ EXPECT_EQ(1u, context()->textureCount());
+ EXPECT_EQ(0u, releaseSyncPoint);
+
+ // Then receive the resource which should release the mailbox, expect the sync points to be consistent.
+ m_resourceProvider->receiveFromParent(list);
+ EXPECT_LE(list.sync_point, releaseSyncPoint);
+ }
+
+ context()->waitSyncPoint(releaseSyncPoint);
+ context()->bindTexture(GL_TEXTURE_2D, texture);
+ context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+ context()->deleteTexture(texture);
+}
+
class TextureStateTrackingContext : public TestWebGraphicsContext3D {
public:
MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));