Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp | 
| diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp | 
| index 1517d4c9b19f95dcf87f6717a625b5bf6c13955b..73384c93d193898beea534b4530041e3f4561c51 100644 | 
| --- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp | 
| +++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp | 
| @@ -6,16 +6,13 @@ | 
| #include "gpu/command_buffer/client/gles2_interface.h" | 
| #include "gpu/command_buffer/common/sync_token.h" | 
| -#include "platform/CrossThreadFunctional.h" | 
| -#include "platform/graphics/StaticBitmapImage.h" | 
| +#include "platform/graphics/MailboxTextureHolder.h" | 
| +#include "platform/graphics/SkiaTextureHolder.h" | 
| #include "platform/graphics/gpu/SharedGpuContext.h" | 
| #include "platform/graphics/skia/SkiaUtils.h" | 
| #include "public/platform/Platform.h" | 
| #include "public/platform/WebGraphicsContext3DProvider.h" | 
| -#include "public/platform/WebTaskRunner.h" | 
| -#include "skia/ext/texture_handle.h" | 
| #include "third_party/skia/include/core/SkImage.h" | 
| -#include "third_party/skia/include/gpu/GrContext.h" | 
| #include "wtf/PtrUtil.h" | 
| #include <memory> | 
| @@ -31,41 +28,50 @@ AcceleratedStaticBitmapImage::createFromSharedContextImage( | 
| PassRefPtr<AcceleratedStaticBitmapImage> | 
| AcceleratedStaticBitmapImage::createFromWebGLContextImage( | 
| - sk_sp<SkImage> image, | 
| const gpu::Mailbox& mailbox, | 
| - const gpu::SyncToken& syncToken) { | 
| - return adoptRef( | 
| - new AcceleratedStaticBitmapImage(std::move(image), mailbox, syncToken)); | 
| + const gpu::SyncToken& syncToken, | 
| + unsigned textureId, | 
| + gpu::gles2::GLES2Interface* gl, | 
| + IntSize mailboxSize) { | 
| + return adoptRef(new AcceleratedStaticBitmapImage(mailbox, syncToken, | 
| + textureId, gl, mailboxSize)); | 
| } | 
| -AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image) | 
| - : StaticBitmapImage(std::move(image)), | 
| - m_sharedContextId(SharedGpuContext::contextId()) { | 
| +AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( | 
| + sk_sp<SkImage> image) { | 
| + m_texture = new SkiaTextureHolder(std::move(image)); | 
| m_threadChecker.DetachFromThread(); | 
| } | 
| AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( | 
| - sk_sp<SkImage> image, | 
| const gpu::Mailbox& mailbox, | 
| - const gpu::SyncToken& syncToken) | 
| - : StaticBitmapImage(std::move(image)), | 
| - m_sharedContextId(SharedGpuContext::kNoSharedContext), | 
| - m_hasMailbox(true), | 
| - m_mailbox(mailbox), | 
| - m_syncToken(syncToken) { | 
| + const gpu::SyncToken& syncToken, | 
| + unsigned textureId, | 
| + gpu::gles2::GLES2Interface* gl, | 
| + IntSize mailboxSize) { | 
| + m_texture = | 
| + new MailboxTextureHolder(mailbox, syncToken, textureId, gl, mailboxSize); | 
| m_threadChecker.DetachFromThread(); | 
| - | 
| - // Note: In this case, m_image is not usable directly because it is not in the | 
| - // shared context. It is just used to hold a reference to the texture object | 
| - // in the origin context until the mailbox can be consumed. | 
| } | 
| AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() { | 
| // Avoid leaking mailboxes in cases where the texture gets recycled by skia. | 
| - if (m_hasMailbox && SharedGpuContext::isValid()) | 
| - SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, | 
| - m_mailbox.name); | 
| - releaseImageThreadSafe(); | 
| + if (!m_texture->isSkiaTextureHolder() && SharedGpuContext::isValid()) { | 
| + SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM( | 
| 
 
Justin Novosad
2016/10/28 21:58:41
This should be moved to the destructor of MailboxT
 
 | 
| + 0, GL_TEXTURE_2D, m_texture->getMailbox().name); | 
| + } | 
| + // Do release image only when it is a skiaTextureHolder | 
| + if (m_texture->isSkiaTextureHolder()) | 
| + m_texture->releaseImageThreadSafe(); | 
| 
 
Justin Novosad
2016/10/28 21:58:41
This belongs in the destructor of SkiaTextureHolde
 
 | 
| +} | 
| + | 
| +IntSize AcceleratedStaticBitmapImage::size() const { | 
| + return m_texture->size(); | 
| +} | 
| + | 
| +void AcceleratedStaticBitmapImage::updateSyncToken(gpu::SyncToken syncToken) { | 
| + if (!m_texture->isSkiaTextureHolder()) | 
| 
 
Justin Novosad
2016/10/28 21:58:41
This conditional branch is not necessary
 
 | 
| + m_texture->updateSyncToken(syncToken); | 
| } | 
| void AcceleratedStaticBitmapImage::copyToTexture( | 
| @@ -83,9 +89,9 @@ void AcceleratedStaticBitmapImage::copyToTexture( | 
| // Get a texture id that |destProvider| knows about and copy from it. | 
| gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); | 
| - destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); | 
| - GLuint sourceTextureId = | 
| - destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); | 
| + destGL->WaitSyncTokenCHROMIUM(m_texture->getSyncToken().GetData()); | 
| + GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM( | 
| + GL_TEXTURE_2D, m_texture->getMailbox().name); | 
| destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, | 
| destType, flipY, false, false); | 
| // This drops the |destGL| context's reference on our |m_mailbox|, but it's | 
| @@ -98,7 +104,7 @@ sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() { | 
| if (!isValid()) | 
| return nullptr; | 
| createImageFromMailboxIfNeeded(); | 
| - return m_image; | 
| + return m_texture->getSkImage(); | 
| } | 
| void AcceleratedStaticBitmapImage::draw( | 
| @@ -112,99 +118,48 @@ void AcceleratedStaticBitmapImage::draw( | 
| if (!isValid()) | 
| return; | 
| createImageFromMailboxIfNeeded(); | 
| + m_image = m_texture->getSkImage(); | 
| StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, | 
| respectImageOrientation, imageClampingMode); | 
| } | 
| bool AcceleratedStaticBitmapImage::isValid() { | 
| - if (!m_image) | 
| + if (!m_texture) | 
| return false; | 
| if (!SharedGpuContext::isValid()) | 
| return false; // Gpu context was lost | 
| - if (imageBelongsToSharedContext() && | 
| - m_sharedContextId != SharedGpuContext::contextId()) { | 
| + unsigned sharedContextId = m_texture->sharedContextId(); | 
| + if (sharedContextId != SharedGpuContext::kNoSharedContext && | 
| + sharedContextId != SharedGpuContext::contextId()) { | 
| // Gpu context was lost and restored since the resource was created. | 
| return false; | 
| } | 
| return true; | 
| } | 
| -bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() { | 
| - return m_sharedContextId != SharedGpuContext::kNoSharedContext; | 
| -} | 
| - | 
| void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() { | 
| - if (imageBelongsToSharedContext()) | 
| + if (m_texture->sharedContextId() != SharedGpuContext::kNoSharedContext) | 
| + return; | 
| + if (m_texture->isSkiaTextureHolder()) | 
| return; | 
| - DCHECK(m_hasMailbox); | 
| - gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); | 
| - GrContext* sharedGrContext = SharedGpuContext::gr(); | 
| - DCHECK(sharedGL && | 
| - sharedGrContext); // context isValid already checked in callers | 
| - | 
| - sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); | 
| - GLuint sharedContextTextureId = | 
| - sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); | 
| - GrGLTextureInfo textureInfo; | 
| - textureInfo.fTarget = GL_TEXTURE_2D; | 
| - textureInfo.fID = sharedContextTextureId; | 
| - GrBackendTextureDesc backendTexture; | 
| - backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin; | 
| - backendTexture.fWidth = size().width(); | 
| - backendTexture.fHeight = size().height(); | 
| - backendTexture.fConfig = kSkia8888_GrPixelConfig; | 
| - backendTexture.fTextureHandle = | 
| - skia::GrGLTextureInfoToGrBackendObject(textureInfo); | 
| - | 
| - sk_sp<SkImage> newImage = | 
| - SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture); | 
| - releaseImageThreadSafe(); | 
| - m_image = newImage; | 
| - | 
| - m_sharedContextId = SharedGpuContext::contextId(); | 
| + m_texture = | 
| + new SkiaTextureHolder(m_texture->getMailbox(), m_texture->getSyncToken(), | 
| 
 
Justin Novosad
2016/10/28 21:58:41
would be cleaner design to reduce knowledge of tex
 
 | 
| + m_texture->getMailboxSize()); | 
| } | 
| void AcceleratedStaticBitmapImage::ensureMailbox() { | 
| - if (m_hasMailbox) | 
| + if (!m_texture->isSkiaTextureHolder()) | 
| 
 
Justin Novosad
2016/10/28 21:58:41
-> if (hasMailbox())
 
 | 
| return; | 
| - DCHECK(m_image); | 
| + sk_sp<SkImage> image = m_texture->getSkImage(); | 
| + DCHECK(image); | 
| - gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); | 
| - GrContext* sharedGrContext = SharedGpuContext::gr(); | 
| - if (!sharedGrContext) { | 
| - // Can happen if the context is lost. The SkImage won't be any good now | 
| - // anyway. | 
| - return; | 
| - } | 
| - GLuint imageTextureId = | 
| - skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true)) | 
| - ->fID; | 
| - sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId); | 
| - | 
| - sharedGL->GenMailboxCHROMIUM(m_mailbox.name); | 
| - sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); | 
| - const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); | 
| - sharedGL->Flush(); | 
| - sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData()); | 
| - | 
| - sharedGL->BindTexture(GL_TEXTURE_2D, 0); | 
| - // We changed bound textures in this function, so reset the GrContext. | 
| - sharedGrContext->resetContext(kTextureBinding_GrGLBackendState); | 
| - | 
| - m_hasMailbox = true; | 
| + m_texture = new MailboxTextureHolder(std::move(image)); | 
| 
 
Justin Novosad
2016/10/28 21:58:41
I think you also need to clear m_image here.
 
 | 
| } | 
| void AcceleratedStaticBitmapImage::transfer() { | 
| checkThread(); | 
| ensureMailbox(); | 
| - m_sharedContextId = SharedGpuContext::kNoSharedContext; | 
| - // If |m_imageThread| is set, it means that the image has been consumed on the | 
| - // current thread, which may happen when we have chained transfers. When that | 
| - // is the case, we must not reset |m_imageThread|, so we ensure that | 
| - // releaseImage() is called on the right thread. | 
| - if (!m_imageThread) | 
| - m_imageThread = Platform::current()->currentThread(); | 
| m_detachThreadAtNextCheck = true; | 
| } | 
| @@ -216,31 +171,4 @@ void AcceleratedStaticBitmapImage::checkThread() { | 
| CHECK(m_threadChecker.CalledOnValidThread()); | 
| } | 
| -void releaseImage(sk_sp<SkImage>&& image, | 
| - std::unique_ptr<gpu::SyncToken>&& syncToken) { | 
| - if (SharedGpuContext::isValid() && syncToken->HasData()) | 
| - SharedGpuContext::gl()->WaitSyncTokenCHROMIUM(syncToken->GetData()); | 
| - image.reset(); | 
| -} | 
| - | 
| -void AcceleratedStaticBitmapImage::releaseImageThreadSafe() { | 
| - // If m_image belongs to a GrContext that is on another thread, it | 
| - // must be released on that thread. | 
| - if (m_imageThread && m_image && | 
| - m_imageThread != Platform::current()->currentThread() && | 
| - SharedGpuContext::isValid()) { | 
| - gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); | 
| - std::unique_ptr<gpu::SyncToken> releaseSyncToken(new gpu::SyncToken); | 
| - const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); | 
| - sharedGL->Flush(); | 
| - sharedGL->GenSyncTokenCHROMIUM(fenceSync, releaseSyncToken->GetData()); | 
| - m_imageThread->getWebTaskRunner()->postTask( | 
| - BLINK_FROM_HERE, | 
| - crossThreadBind(&releaseImage, passed(std::move(m_image)), | 
| - passed(std::move(releaseSyncToken)))); | 
| - } | 
| - m_image = nullptr; | 
| - m_imageThread = nullptr; | 
| -} | 
| - | 
| } // namespace blink |