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

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 software renderer support and remove unnecessary changes to PrioritizedResource class. 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
« cc/resource_provider.h ('K') | « 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..86fa9f8bb80087f910aaf8b77497fa0b32c99c89 100644
--- a/cc/resource_provider.cc
+++ b/cc/resource_provider.cc
@@ -49,7 +49,10 @@ static bool isTextureFormatSupportedForStorage(GLenum format)
ResourceProvider::Resource::Resource()
: glId(0)
+ , glPixelBufferId(0)
+ , glUploadQueryId(0)
, pixels(0)
+ , pixelBuffer(0)
, pool(0)
, lockForReadCount(0)
, lockedForWrite(false)
@@ -64,7 +67,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 +85,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)
@@ -229,8 +238,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 +681,194 @@ 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::scheduleSetPixels(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());
+ DCHECK(resource->glPixelBufferId);
+ context3d->bindTexture(GL_TEXTURE_2D, resource->glId);
danakj 2012/11/17 17:47:25 Should this be locking for write?
reveman 2012/11/18 18:15:59 Maybe but we currently don't lock for write in set
danakj 2012/11/18 18:22:49 Well my thought is that setPixels doesn't set the
reveman 2012/11/18 19:04:42 Ok, that makes sense. I added the write lock but w
+ 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;
+ DCHECK(!resource->lockedForWrite);
+ DCHECK(!resource->lockForReadCount);
+ DCHECK(!resource->external);
+ DCHECK(!resource->exported);
+
+ if (resource->glId) {
nduca 2012/11/17 17:10:30 behavior on context lost?
danakj 2012/11/17 17:47:25 +1, also consider the lock, if we write lock durin
reveman 2012/11/18 18:15:59 This returns true on context lost (same behavior a
+ WebGraphicsContext3D* context3d = m_context->context3D();
+ DCHECK(context3d);
+ DCHECK(m_textureUploader.get());
+ DCHECK(resource->glUploadQueryId);
+ unsigned complete = 1;
+ context3d->getQueryObjectuivEXT(
+ resource->glUploadQueryId,
+ GL_QUERY_RESULT_AVAILABLE_EXT,
+ &complete);
+ return complete;
+ }
+
+ return true;
+}
+
} // namespace cc
« cc/resource_provider.h ('K') | « cc/resource_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698