| 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 d556600eee076ab2162cc61a77e3210d83ea6f9b..0b34859663144a5450d66ec483b86d6a726c227c 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/WebTaskRunner.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 "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,40 @@ 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,
 | 
| +    WeakPtr<WebGraphicsContext3DProviderWrapper> contextProvider,
 | 
| +    IntSize mailboxSize) {
 | 
| +  return adoptRef(new AcceleratedStaticBitmapImage(
 | 
| +      mailbox, syncToken, textureId, contextProvider, mailboxSize));
 | 
|  }
 | 
|  
 | 
| -AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image)
 | 
| -    : StaticBitmapImage(std::move(image)),
 | 
| -      m_sharedContextId(SharedGpuContext::contextId()) {
 | 
| +AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
 | 
| +    sk_sp<SkImage> image) {
 | 
| +  m_textureHolder = wrapUnique(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,
 | 
| +    WeakPtr<WebGraphicsContext3DProviderWrapper> contextProvider,
 | 
| +    IntSize mailboxSize) {
 | 
| +  m_textureHolder = wrapUnique(new MailboxTextureHolder(
 | 
| +      mailbox, syncToken, textureId, contextProvider, 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() {}
 | 
| +
 | 
| +IntSize AcceleratedStaticBitmapImage::size() const {
 | 
| +  return m_textureHolder->size();
 | 
|  }
 | 
|  
 | 
| -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();
 | 
| +void AcceleratedStaticBitmapImage::updateSyncToken(gpu::SyncToken syncToken) {
 | 
| +  m_textureHolder->updateSyncToken(syncToken);
 | 
|  }
 | 
|  
 | 
|  void AcceleratedStaticBitmapImage::copyToTexture(
 | 
| @@ -83,9 +79,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_textureHolder->syncToken().GetData());
 | 
| +  GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM(
 | 
| +      GL_TEXTURE_2D, m_textureHolder->mailbox().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,116 +94,77 @@ sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() {
 | 
|    if (!isValid())
 | 
|      return nullptr;
 | 
|    createImageFromMailboxIfNeeded();
 | 
| -  return m_image;
 | 
| +  return m_textureHolder->skImage();
 | 
|  }
 | 
|  
 | 
| -void AcceleratedStaticBitmapImage::draw(
 | 
| -    SkCanvas* canvas,
 | 
| -    const SkPaint& paint,
 | 
| -    const FloatRect& dstRect,
 | 
| -    const FloatRect& srcRect,
 | 
| -    RespectImageOrientationEnum respectImageOrientation,
 | 
| -    ImageClampingMode imageClampingMode) {
 | 
| +void AcceleratedStaticBitmapImage::draw(SkCanvas* canvas,
 | 
| +                                        const SkPaint& paint,
 | 
| +                                        const FloatRect& dstRect,
 | 
| +                                        const FloatRect& srcRect,
 | 
| +                                        RespectImageOrientationEnum,
 | 
| +                                        ImageClampingMode imageClampingMode) {
 | 
|    checkThread();
 | 
|    if (!isValid())
 | 
|      return;
 | 
|    createImageFromMailboxIfNeeded();
 | 
| -  StaticBitmapImage::draw(canvas, paint, dstRect, srcRect,
 | 
| -                          respectImageOrientation, imageClampingMode);
 | 
| +  sk_sp<SkImage> image = m_textureHolder->skImage();
 | 
| +  StaticBitmapImage::drawHelper(canvas, paint, dstRect, srcRect,
 | 
| +                                imageClampingMode, image);
 | 
|  }
 | 
|  
 | 
|  bool AcceleratedStaticBitmapImage::isValid() {
 | 
| -  if (!m_image)
 | 
| +  if (!m_textureHolder)
 | 
|      return false;
 | 
|    if (!SharedGpuContext::isValid())
 | 
|      return false;  // Gpu context was lost
 | 
| -  if (imageBelongsToSharedContext() &&
 | 
| -      m_sharedContextId != SharedGpuContext::contextId()) {
 | 
| +  unsigned sharedContextId = m_textureHolder->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_textureHolder->sharedContextId() != SharedGpuContext::kNoSharedContext)
 | 
| +    return;
 | 
| +  if (m_textureHolder->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_textureHolder =
 | 
| +      wrapUnique(new SkiaTextureHolder(std::move(m_textureHolder)));
 | 
|  }
 | 
|  
 | 
|  void AcceleratedStaticBitmapImage::ensureMailbox() {
 | 
| -  if (m_hasMailbox)
 | 
| +  if (m_textureHolder->isMailboxTextureHolder())
 | 
|      return;
 | 
|  
 | 
| -  DCHECK(m_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_textureHolder =
 | 
| +      wrapUnique(new MailboxTextureHolder(std::move(m_textureHolder)));
 | 
|  }
 | 
|  
 | 
|  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();
 | 
| +  // If |m_textureThreadTaskRunner| in TextureHolder is set, it means that
 | 
| +  // the |m_texture| in this class 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_imageThreadTaskRunner|, so we ensure that
 | 
| +  // releaseImage() or releaseTexture() is called on the right thread.
 | 
| +  if (!m_textureHolder->wasTransferred()) {
 | 
| +    WebThread* currentThread = Platform::current()->currentThread();
 | 
| +    m_textureHolder->setWasTransferred(true);
 | 
| +    m_textureHolder->setTextureThreadTaskRunner(
 | 
| +        currentThread->getWebTaskRunner()->clone());
 | 
| +  }
 | 
|    m_detachThreadAtNextCheck = true;
 | 
|  }
 | 
|  
 | 
| +bool AcceleratedStaticBitmapImage::currentFrameKnownToBeOpaque(
 | 
| +    MetadataMode metadataMode) {
 | 
| +  return m_textureHolder->currentFrameKnownToBeOpaque(metadataMode);
 | 
| +}
 | 
| +
 | 
|  void AcceleratedStaticBitmapImage::checkThread() {
 | 
|    if (m_detachThreadAtNextCheck) {
 | 
|      m_threadChecker.DetachFromThread();
 | 
| @@ -216,31 +173,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
 | 
| 
 |