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

Unified Diff: cc/resource_provider.cc

Issue 11412043: cc: Add asynchronous setPixel interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add abortSetPixels. Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/resource_provider.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/resource_provider.cc
diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc
index 4269b8123185b5400c66356bc9c4b9ce30697cb6..3f083ce21e3b9b64df321744da9448957574e311 100644
--- a/cc/resource_provider.cc
+++ b/cc/resource_provider.cc
@@ -47,9 +47,34 @@ static bool isTextureFormatSupportedForStorage(GLenum format)
return (format == GL_RGBA || format == GL_BGRA_EXT);
}
+static void texImage2D(WebGraphicsContext3D* context3d,
+ const gfx::Size& size,
+ GLenum format,
+ bool useTextureStorageExt)
+{
+ if (useTextureStorageExt && isTextureFormatSupportedForStorage(format)) {
+ GLenum storageFormat = textureToStorageFormat(format);
+ context3d->texStorage2DEXT(
+ GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height());
+ } else {
+ context3d->texImage2D(GL_TEXTURE_2D,
+ 0,
+ format,
+ size.width(),
+ size.height(),
+ 0,
+ format,
+ GL_UNSIGNED_BYTE,
+ 0);
+ }
+}
+
ResourceProvider::Resource::Resource()
: glId(0)
+ , glPixelBufferId(0)
+ , glUploadQueryId(0)
, pixels(0)
+ , pixelBuffer(0)
, pool(0)
, lockForReadCount(0)
, lockedForWrite(false)
@@ -64,7 +89,10 @@ ResourceProvider::Resource::Resource()
ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Size& size, GLenum format)
: glId(textureId)
+ , glPixelBufferId(0)
+ , glUploadQueryId(0)
, pixels(0)
+ , pixelBuffer(0)
, pool(pool)
, lockForReadCount(0)
, lockedForWrite(false)
@@ -79,7 +107,10 @@ ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si
ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format)
: glId(0)
+ , glPixelBufferId(0)
+ , glUploadQueryId(0)
, pixels(pixels)
+ , pixelBuffer(0)
, pool(pool)
, lockForReadCount(0)
, lockedForWrite(false)
@@ -161,11 +192,8 @@ ResourceProvider::ResourceId ResourceProvider::createGLTexture(int pool, const g
if (m_useTextureUsageHint && hint == TextureUsageFramebuffer)
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
- if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) {
- GLenum storageFormat = textureToStorageFormat(format);
- GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height()));
- } else
- GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0));
+
+ texImage2D(context3d, size, format, m_useTextureStorageExt);
ResourceId id = m_nextId++;
Resource resource(textureId, pool, size, format);
@@ -229,8 +257,20 @@ void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it)
DCHECK(context3d);
GLC(context3d, context3d->deleteTexture(resource->glId));
}
+ if (resource->glUploadQueryId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ GLC(context3d, context3d->deleteQueryEXT(resource->glUploadQueryId));
+ }
+ if (resource->glPixelBufferId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ GLC(context3d, context3d->deleteBuffer(resource->glPixelBufferId));
+ }
if (resource->pixels)
delete[] resource->pixels;
+ if (resource->pixelBuffer)
+ delete[] resource->pixelBuffer;
m_resources.erase(it);
}
@@ -660,4 +700,215 @@ bool ResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceI
return true;
}
+void ResourceProvider::acquirePixelBuffer(ResourceId id)
+{
+ DCHECK(m_threadChecker.CalledOnValidThread());
+ ResourceMap::iterator it = m_resources.find(id);
+ CHECK(it != m_resources.end());
+ Resource* resource = &it->second;
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
+ if (resource->glPixelBufferId)
+ return;
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ resource->glPixelBufferId = context3d->createBuffer();
+ context3d->bindBuffer(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->glPixelBufferId);
+ context3d->bufferData(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->size.width() * resource->size.height() * 4,
+ NULL,
+ GL_DYNAMIC_DRAW);
+ context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ }
+
+ if (resource->pixels) {
+ if (resource->pixelBuffer)
+ return;
+
+ resource->pixelBuffer = new uint8_t[
+ resource->size.width() * resource->size.height() * 4];
+ }
+}
+
+void ResourceProvider::releasePixelBuffer(ResourceId id)
+{
+ DCHECK(m_threadChecker.CalledOnValidThread());
+ ResourceMap::iterator it = m_resources.find(id);
+ CHECK(it != m_resources.end());
+ Resource* resource = &it->second;
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
+ if (!resource->glPixelBufferId)
+ return;
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ context3d->deleteBuffer(resource->glPixelBufferId);
+ resource->glPixelBufferId = 0;
+ }
+
+ if (resource->pixels) {
+ if (!resource->pixelBuffer)
+ return;
+ delete[] resource->pixelBuffer;
+ resource->pixelBuffer = 0;
+ }
+}
+
+uint8_t* ResourceProvider::mapPixelBuffer(ResourceId id)
+{
+ DCHECK(m_threadChecker.CalledOnValidThread());
+ ResourceMap::iterator it = m_resources.find(id);
+ CHECK(it != m_resources.end());
+ Resource* resource = &it->second;
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(resource->glPixelBufferId);
+ context3d->bindBuffer(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->glPixelBufferId);
+ uint8_t* image = static_cast<uint8_t*>(
+ context3d->mapBufferCHROMIUM(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
+ context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ DCHECK(image);
+ return image;
+ }
+
+ if (resource->pixels)
+ return resource->pixelBuffer;
+
+ return NULL;
+}
+
+void ResourceProvider::unmapPixelBuffer(ResourceId id)
+{
+ DCHECK(m_threadChecker.CalledOnValidThread());
+ ResourceMap::iterator it = m_resources.find(id);
+ CHECK(it != m_resources.end());
+ Resource* resource = &it->second;
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(resource->glPixelBufferId);
+ context3d->bindBuffer(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->glPixelBufferId);
+ context3d->unmapBufferCHROMIUM(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
+ context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ }
+}
+
+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->lockedForWrite);
+ DCHECK(!resource->lockForReadCount);
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(m_textureUploader.get());
+ lockForWrite(id);
+ 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_TEXTURES_UPLOADED_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_TEXTURES_UPLOADED_CHROMIUM);
+ }
+
+ if (resource->pixels) {
+ DCHECK(resource->pixelBuffer);
+ DCHECK(resource->format == GL_RGBA);
+ SkBitmap src;
+ src.setConfig(SkBitmap::kARGB_8888_Config,
+ resource->size.width(),
+ resource->size.height());
+ src.setPixels(resource->pixelBuffer);
+
+ ScopedWriteLockSoftware lock(this, id);
+ SkCanvas* dest = lock.skCanvas();
+ dest->writePixels(src, 0, 0);
+ }
+}
+
+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;
+
+ if (resource->glId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(resource->glUploadQueryId);
+ DCHECK(resource->lockedForWrite);
+ unsigned complete = 1;
+ context3d->getQueryObjectuivEXT(
+ resource->glUploadQueryId,
+ GL_QUERY_RESULT_AVAILABLE_EXT,
+ &complete);
+ if (!complete)
+ return false;
+
+ unlockForWrite(id);
+ }
+
+ return true;
+}
+
+void ResourceProvider::abortSetPixels(ResourceId id) {
+ DCHECK(m_threadChecker.CalledOnValidThread());
+ ResourceMap::iterator it = m_resources.find(id);
+ CHECK(it != m_resources.end());
+ Resource* resource = &it->second;
+
+ if (resource->glId) {
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(resource->glUploadQueryId);
+ DCHECK(resource->lockedForWrite);
+ context3d->bindTexture(GL_TEXTURE_2D, resource->glId);
+ texImage2D(context3d,
+ resource->size,
nduca 2012/11/23 22:16:42 if we land this, should we file a followup bug tha
reveman 2012/11/23 22:52:28 I don't have any intentions to land this until we
+ resource->format,
+ m_useTextureStorageExt);
+
+ unlockForWrite(id);
+ }
+}
+
} // namespace cc
« no previous file with comments | « cc/resource_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698