From 6036726eb981b6c4b42047513b9d3f4ac865daac Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 24 Oct 2018 11:30:15 +0200 Subject: BASELINE: Update Chromium to 70.0.3538.78 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7 Reviewed-by: Michael BrĂ¼ning --- chromium/media/gpu/android/codec_wrapper.cc | 71 ++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 12 deletions(-) (limited to 'chromium/media/gpu/android/codec_wrapper.cc') diff --git a/chromium/media/gpu/android/codec_wrapper.cc b/chromium/media/gpu/android/codec_wrapper.cc index 7d851d1a369..77a8dc25e4c 100644 --- a/chromium/media/gpu/android/codec_wrapper.cc +++ b/chromium/media/gpu/android/codec_wrapper.cc @@ -23,8 +23,10 @@ namespace media { // CodecOutputBuffer are the only two things that hold references to it. class CodecWrapperImpl : public base::RefCountedThreadSafe { public: - CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb); + CodecWrapperImpl( + CodecSurfacePair codec_surface_pair, + CodecWrapper::OutputReleasedCB output_buffer_release_cb, + scoped_refptr release_task_runner); using DequeueStatus = CodecWrapper::DequeueStatus; using QueueStatus = CodecWrapper::QueueStatus; @@ -89,12 +91,16 @@ class CodecWrapperImpl : public base::RefCountedThreadSafe { // A callback that's called whenever an output buffer is released back to the // codec. - base::Closure output_buffer_release_cb_; + CodecWrapper::OutputReleasedCB output_buffer_release_cb_; // Do we owe the client an EOS in DequeueOutput, due to an eos that we elided // while we're already flushed? bool elided_eos_pending_ = false; + // Task runner on which we'll release codec buffers without rendering. May be + // null to always do this on the calling task runner. + scoped_refptr release_task_runner_; + DISALLOW_COPY_AND_ASSIGN(CodecWrapperImpl); }; @@ -104,20 +110,28 @@ CodecOutputBuffer::CodecOutputBuffer(scoped_refptr codec, : codec_(std::move(codec)), id_(id), size_(size) {} CodecOutputBuffer::~CodecOutputBuffer() { - codec_->ReleaseCodecOutputBuffer(id_, false); + // While it will work if we re-release the buffer, since CodecWrapper handles + // it properly, we can save a lock + (possibly) post by checking here if we + // know that it has been rendered already. + if (!was_rendered_) + codec_->ReleaseCodecOutputBuffer(id_, false); } bool CodecOutputBuffer::ReleaseToSurface() { + was_rendered_ = true; return codec_->ReleaseCodecOutputBuffer(id_, true); } -CodecWrapperImpl::CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) +CodecWrapperImpl::CodecWrapperImpl( + CodecSurfacePair codec_surface_pair, + CodecWrapper::OutputReleasedCB output_buffer_release_cb, + scoped_refptr release_task_runner) : state_(State::kFlushed), codec_(std::move(codec_surface_pair.first)), surface_bundle_(std::move(codec_surface_pair.second)), next_buffer_id_(0), - output_buffer_release_cb_(std::move(output_buffer_release_cb)) { + output_buffer_release_cb_(std::move(output_buffer_release_cb)), + release_task_runner_(std::move(release_task_runner)) { DVLOG(2) << __func__; } @@ -364,6 +378,34 @@ scoped_refptr CodecWrapperImpl::SurfaceBundle() { } bool CodecWrapperImpl::ReleaseCodecOutputBuffer(int64_t id, bool render) { + if (!render && release_task_runner_ && + !release_task_runner_->RunsTasksInCurrentSequence()) { + // Note that this can only delay releases, but that won't ultimately change + // the ordering at the codec, assuming that releases / renders originate + // from the same thread. + // + // We know that a render call that happens before a release call will still + // run before the release's posted task, since it happens before we even + // post it. + // + // Similarly, renders are kept in order with each other. + // + // It is possible that a render happens before the posted task(s) of some + // earlier release(s) (with no intervening renders, since those are + // ordered). In this case, though, the loop below will still release + // everything earlier than the rendered buffer, so the codec still sees the + // same sequence of calls -- some releases follwed by a render. + // + // Of course, if releases and renders are posted from different threads, + // then it's unclear what the ordering was anyway. + release_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + base::IgnoreResult(&CodecWrapperImpl::ReleaseCodecOutputBuffer), + this, id, render)); + return true; + } + base::AutoLock l(lock_); if (!codec_ || state_ == State::kError) return false; @@ -386,15 +428,20 @@ bool CodecWrapperImpl::ReleaseCodecOutputBuffer(int64_t id, bool render) { int index = buffer_it->second; codec_->ReleaseOutputBuffer(index, render); buffer_ids_.erase(buffer_ids_.begin(), buffer_it + 1); - if (output_buffer_release_cb_) - output_buffer_release_cb_.Run(); + if (output_buffer_release_cb_) { + output_buffer_release_cb_.Run(state_ == State::kDrained || + state_ == State::kDraining); + } return true; } -CodecWrapper::CodecWrapper(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) +CodecWrapper::CodecWrapper( + CodecSurfacePair codec_surface_pair, + OutputReleasedCB output_buffer_release_cb, + scoped_refptr release_task_runner) : impl_(new CodecWrapperImpl(std::move(codec_surface_pair), - std::move(output_buffer_release_cb))) {} + std::move(output_buffer_release_cb), + std::move(release_task_runner))) {} CodecWrapper::~CodecWrapper() { // The codec must have already been taken. -- cgit v1.2.1