diff options
author | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 00:40:40 +0000 |
---|---|---|
committer | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 00:40:40 +0000 |
commit | 7f243b1dd4c8d11d48901982c39c8745405997d7 (patch) | |
tree | f428fbcc87a35041d8cf48ed28cd0802c21cd88b | |
parent | 82750aa55739c6fdf3dbed1c086fca2d0e171453 (diff) | |
download | chromium_src-7f243b1dd4c8d11d48901982c39c8745405997d7.zip chromium_src-7f243b1dd4c8d11d48901982c39c8745405997d7.tar.gz chromium_src-7f243b1dd4c8d11d48901982c39c8745405997d7.tar.bz2 |
cc: Add asynchronous setPixel interface.
Implements asynchronous texture uploads using
CHROMIUM_async_pixel_transfers extension.
BUG=155209
TEST=cc_unittests
Review URL: https://chromiumcodereview.appspot.com/11412043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171657 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/resource_provider.cc | 80 | ||||
-rw-r--r-- | cc/resource_provider.h | 7 |
2 files changed, 87 insertions, 0 deletions
diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc index 6aaca18..956f390 100644 --- a/cc/resource_provider.cc +++ b/cc/resource_provider.cc @@ -50,6 +50,7 @@ static bool isTextureFormatSupportedForStorage(GLenum format) ResourceProvider::Resource::Resource() : glId(0) , glPixelBufferId(0) + , glUploadQueryId(0) , pixels(0) , pixelBuffer(0) , pool(0) @@ -58,6 +59,7 @@ ResourceProvider::Resource::Resource() , external(false) , exported(false) , markedForDeletion(false) + , pendingSetPixels(false) , size() , format(0) , filter(0) @@ -68,6 +70,7 @@ ResourceProvider::Resource::Resource() ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Size& size, GLenum format, GLenum filter) : glId(textureId) , glPixelBufferId(0) + , glUploadQueryId(0) , pixels(0) , pixelBuffer(0) , pool(pool) @@ -76,6 +79,7 @@ ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si , external(false) , exported(false) , markedForDeletion(false) + , pendingSetPixels(false) , size(size) , format(format) , filter(filter) @@ -86,6 +90,7 @@ ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format, GLenum filter) : glId(0) , glPixelBufferId(0) + , glUploadQueryId(0) , pixels(pixels) , pixelBuffer(0) , pool(pool) @@ -94,6 +99,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& , external(false) , exported(false) , markedForDeletion(false) + , pendingSetPixels(false) , size(size) , format(format) , filter(filter) @@ -241,6 +247,11 @@ void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it) DCHECK(context3d); GLC(context3d, context3d->deleteTexture(resource->glId)); } + if (resource->glUploadQueryId) { + WebGraphicsContext3D* context3d = m_outputSurface->context3D(); + DCHECK(context3d); + GLC(context3d, context3d->deleteQueryEXT(resource->glUploadQueryId)); + } if (resource->glPixelBufferId) { WebGraphicsContext3D* context3d = m_outputSurface->context3D(); DCHECK(context3d); @@ -868,4 +879,73 @@ void ResourceProvider::bindForSampling(ResourceProvider::ResourceId resourceId, } } +void ResourceProvider::beginSetPixels(ResourceId id) +{ + DCHECK(m_threadChecker.CalledOnValidThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); + Resource* resource = &it->second; + DCHECK(!resource->pendingSetPixels); + + lockForWrite(id); + + if (resource->glId) { + WebGraphicsContext3D* context3d = m_outputSurface->context3D(); + DCHECK(context3d); + DCHECK(resource->glPixelBufferId); + context3d->bindTexture(GL_TEXTURE_2D, resource->glId); + context3d->bindBuffer( + GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, + resource->glPixelBufferId); + if (!resource->glUploadQueryId) + resource->glUploadQueryId = context3d->createQueryEXT(); + context3d->beginQueryEXT( + GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, + resource->glUploadQueryId); + context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, + 0, /* level */ + 0, /* x */ + 0, /* y */ + resource->size.width(), + resource->size.height(), + resource->format, + GL_UNSIGNED_BYTE, + NULL); + context3d->endQueryEXT(GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM); + context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); + } + + if (resource->pixels) + setPixelsFromBuffer(id); + + resource->pendingSetPixels = true; +} + +bool ResourceProvider::didSetPixelsComplete(ResourceId id) { + DCHECK(m_threadChecker.CalledOnValidThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); + Resource* resource = &it->second; + DCHECK(resource->lockedForWrite); + DCHECK(resource->pendingSetPixels); + + if (resource->glId) { + WebGraphicsContext3D* context3d = m_outputSurface->context3D(); + DCHECK(context3d); + DCHECK(resource->glUploadQueryId); + unsigned complete = 1; + context3d->getQueryObjectuivEXT( + resource->glUploadQueryId, + GL_QUERY_RESULT_AVAILABLE_EXT, + &complete); + if (!complete) + return false; + } + + resource->pendingSetPixels = false; + unlockForWrite(id); + + return true; +} + } // namespace cc diff --git a/cc/resource_provider.h b/cc/resource_provider.h index 0bbcaf8..860c6ca 100644 --- a/cc/resource_provider.h +++ b/cc/resource_provider.h @@ -222,6 +222,10 @@ public: // Update pixels from acquired pixel buffer. void setPixelsFromBuffer(ResourceId id); + // Asynchronously update pixels from acquired pixel buffer. + void beginSetPixels(ResourceId id); + bool didSetPixelsComplete(ResourceId id); + private: struct Resource { Resource(); @@ -231,6 +235,8 @@ private: unsigned glId; // Pixel buffer used for set pixels without unnecessary copying. unsigned glPixelBufferId; + // Query used to determine when asynchronous set pixels complete. + unsigned glUploadQueryId; Mailbox mailbox; uint8_t* pixels; uint8_t* pixelBuffer; @@ -240,6 +246,7 @@ private: bool external; bool exported; bool markedForDeletion; + bool pendingSetPixels; gfx::Size size; GLenum format; // TODO(skyostil): Use a separate sampler object for filter state. |