Chromium Code Reviews| 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 |