| 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
|
|
|