| Index: media/renderers/video_overlay_factory.cc
 | 
| diff --git a/media/renderers/video_overlay_factory.cc b/media/renderers/video_overlay_factory.cc
 | 
| index c983906279012aa015a98cdd4e017b25da65f37b..74c014ad976a106583ef08d1b8301f84970df0e8 100644
 | 
| --- a/media/renderers/video_overlay_factory.cc
 | 
| +++ b/media/renderers/video_overlay_factory.cc
 | 
| @@ -16,49 +16,56 @@ namespace media {
 | 
|  class VideoOverlayFactory::Texture {
 | 
|   public:
 | 
|    explicit Texture(GpuVideoAcceleratorFactories* gpu_factories)
 | 
| -      : gpu_factories_(gpu_factories), texture_id_(0), image_id_(0) {
 | 
| +      : gpu_factories_(gpu_factories), image_id_(0), texture_id_(0) {
 | 
|      DCHECK(gpu_factories_);
 | 
|      DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread());
 | 
|  
 | 
|      std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock(
 | 
|          gpu_factories_->GetGLContextLock());
 | 
| -    CHECK(lock);
 | 
| -    gpu::gles2::GLES2Interface* gl = lock->ContextGL();
 | 
| -
 | 
| -    gl->GenTextures(1, &texture_id_);
 | 
| -    gl->BindTexture(GL_TEXTURE_2D, texture_id_);
 | 
| -    image_id_ = gl->CreateGpuMemoryBufferImageCHROMIUM(1, 1, GL_RGBA,
 | 
| -                                                       GL_READ_WRITE_CHROMIUM);
 | 
| -    CHECK(image_id_);
 | 
| -    gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id_);
 | 
| -
 | 
| -    gl->GenMailboxCHROMIUM(mailbox_.name);
 | 
| -    gl->ProduceTextureDirectCHROMIUM(texture_id_, GL_TEXTURE_2D, mailbox_.name);
 | 
| -
 | 
| -    const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
 | 
| -    gl->ShallowFlushCHROMIUM();
 | 
| -    gl->GenSyncTokenCHROMIUM(fence_sync, sync_token_.GetData());
 | 
| +    if (lock) {
 | 
| +      gpu::gles2::GLES2Interface* gl = lock->ContextGL();
 | 
| +      image_id_ = gl->CreateGpuMemoryBufferImageCHROMIUM(
 | 
| +          1, 1, GL_RGBA, GL_READ_WRITE_CHROMIUM);
 | 
| +      if (image_id_) {
 | 
| +        gl->GenTextures(1, &texture_id_);
 | 
| +        gl->BindTexture(GL_TEXTURE_2D, texture_id_);
 | 
| +        gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id_);
 | 
| +
 | 
| +        gl->GenMailboxCHROMIUM(mailbox_.name);
 | 
| +        gl->ProduceTextureDirectCHROMIUM(texture_id_, GL_TEXTURE_2D,
 | 
| +                                         mailbox_.name);
 | 
| +
 | 
| +        const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
 | 
| +        gl->ShallowFlushCHROMIUM();
 | 
| +        gl->GenSyncTokenCHROMIUM(fence_sync, sync_token_.GetData());
 | 
| +      }
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    ~Texture() {
 | 
|      DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread());
 | 
|  
 | 
| -    std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock(
 | 
| -        gpu_factories_->GetGLContextLock());
 | 
| -    CHECK(lock);
 | 
| -    gpu::gles2::GLES2Interface* gl = lock->ContextGL();
 | 
| -    gl->BindTexture(GL_TEXTURE_2D, texture_id_);
 | 
| -    gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id_);
 | 
| -    gl->DeleteTextures(1, &texture_id_);
 | 
| -    gl->DestroyImageCHROMIUM(image_id_);
 | 
| +    if (image_id_) {
 | 
| +      std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock(
 | 
| +          gpu_factories_->GetGLContextLock());
 | 
| +      if (lock) {
 | 
| +        gpu::gles2::GLES2Interface* gl = lock->ContextGL();
 | 
| +        gl->BindTexture(GL_TEXTURE_2D, texture_id_);
 | 
| +        gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id_);
 | 
| +        gl->DeleteTextures(1, &texture_id_);
 | 
| +        gl->DestroyImageCHROMIUM(image_id_);
 | 
| +      }
 | 
| +    }
 | 
|    }
 | 
|  
 | 
| +  bool IsValid() const { return image_id_ != 0; }
 | 
| +
 | 
|   private:
 | 
|    friend class VideoOverlayFactory;
 | 
|    GpuVideoAcceleratorFactories* gpu_factories_;
 | 
|  
 | 
| -  GLuint texture_id_;
 | 
|    GLuint image_id_;
 | 
| +  GLuint texture_id_;
 | 
|    gpu::Mailbox mailbox_;
 | 
|    gpu::SyncToken sync_token_;
 | 
|  };
 | 
| @@ -74,21 +81,17 @@ scoped_refptr<VideoFrame> VideoOverlayFactory::CreateFrame(
 | 
|    // Frame size empty => video has one dimension = 0.
 | 
|    // Dimension 0 case triggers a DCHECK later on in TextureMailbox if we push
 | 
|    // through the overlay path.
 | 
| -  if (size.IsEmpty() || !gpu_factories_) {
 | 
| +  Texture* texture = size.IsEmpty() ? nullptr : GetTexture();
 | 
| +  if (!texture) {
 | 
|      DVLOG(1) << "Create black frame " << size.width() << "x" << size.height();
 | 
|      return VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
 | 
|    }
 | 
|  
 | 
| -  DCHECK(gpu_factories_);
 | 
| -  DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread());
 | 
| -
 | 
| -  // Lazily create overlay texture.
 | 
| -  if (!texture_)
 | 
| -    texture_.reset(new Texture(gpu_factories_));
 | 
| -
 | 
| -  DVLOG(1) << "Create video overlay frame: " << size.ToString();
 | 
| +  DCHECK(texture);
 | 
| +  DCHECK(texture->IsValid());
 | 
| +  DVLOG(2) << "Create video overlay frame: " << size.ToString();
 | 
|    gpu::MailboxHolder holders[VideoFrame::kMaxPlanes] = {gpu::MailboxHolder(
 | 
| -      texture_->mailbox_, texture_->sync_token_, GL_TEXTURE_2D)};
 | 
| +      texture->mailbox_, texture->sync_token_, GL_TEXTURE_2D)};
 | 
|    scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures(
 | 
|        PIXEL_FORMAT_XRGB, holders, VideoFrame::ReleaseMailboxCB(),
 | 
|        size,                // coded_size
 | 
| @@ -103,4 +106,15 @@ scoped_refptr<VideoFrame> VideoOverlayFactory::CreateFrame(
 | 
|    return frame;
 | 
|  }
 | 
|  
 | 
| +VideoOverlayFactory::Texture* VideoOverlayFactory::GetTexture() {
 | 
| +  if (!gpu_factories_)
 | 
| +    return nullptr;
 | 
| +
 | 
| +  // Lazily create overlay texture.
 | 
| +  if (!texture_)
 | 
| +    texture_.reset(new Texture(gpu_factories_));
 | 
| +
 | 
| +  return texture_->IsValid() ? texture_.get() : nullptr;
 | 
| +}
 | 
| +
 | 
|  }  // namespace media
 | 
| 
 |