Commit 2c238bbd authored by liberato's avatar liberato Committed by Commit bot

Add SurfaceTexture::release and call it from AVDA.

SurfaceTexture::release() discards unused buffers and tears down the
SurfaceTexture, leaving only the front buffer if it's bound to a GL
texture.  This CL plumbs that down to native.

This CL also uses it for AVDA, so that back buffers don't take up
memory when the deferred strategy is shut down.

As part of that, it splits strategy cleanup into two parts.  The
first is called before flush, while the latter is called after.
This prevents transitioning the SurfaceTexture into the released
state while the flush is still trying to talk to MediaCodec.  It's
unclear that would be safe.

BUG=619658

Review-Url: https://codereview.chromium.org/2095873005
Cr-Commit-Position: refs/heads/master@{#402187}
parent df8de5f8
...@@ -39,7 +39,7 @@ gl::ScopedJavaSurface AndroidCopyingBackingStrategy::Initialize( ...@@ -39,7 +39,7 @@ gl::ScopedJavaSurface AndroidCopyingBackingStrategy::Initialize(
return gl::ScopedJavaSurface(surface_texture_.get()); return gl::ScopedJavaSurface(surface_texture_.get());
} }
void AndroidCopyingBackingStrategy::Cleanup( void AndroidCopyingBackingStrategy::BeginCleanup(
bool have_context, bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
DCHECK(state_provider_->ThreadChecker().CalledOnValidThread()); DCHECK(state_provider_->ThreadChecker().CalledOnValidThread());
...@@ -51,6 +51,8 @@ void AndroidCopyingBackingStrategy::Cleanup( ...@@ -51,6 +51,8 @@ void AndroidCopyingBackingStrategy::Cleanup(
glDeleteTextures(1, &surface_texture_id_); glDeleteTextures(1, &surface_texture_id_);
} }
void AndroidCopyingBackingStrategy::EndCleanup() {}
scoped_refptr<gl::SurfaceTexture> scoped_refptr<gl::SurfaceTexture>
AndroidCopyingBackingStrategy::GetSurfaceTexture() const { AndroidCopyingBackingStrategy::GetSurfaceTexture() const {
return surface_texture_; return surface_texture_;
......
...@@ -35,9 +35,10 @@ class MEDIA_GPU_EXPORT AndroidCopyingBackingStrategy ...@@ -35,9 +35,10 @@ class MEDIA_GPU_EXPORT AndroidCopyingBackingStrategy
// AndroidVideoDecodeAccelerator::BackingStrategy // AndroidVideoDecodeAccelerator::BackingStrategy
gl::ScopedJavaSurface Initialize(int surface_view_id) override; gl::ScopedJavaSurface Initialize(int surface_view_id) override;
void Cleanup( void BeginCleanup(
bool have_context, bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) override; const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) override;
void EndCleanup() override;
scoped_refptr<gl::SurfaceTexture> GetSurfaceTexture() const override; scoped_refptr<gl::SurfaceTexture> GetSurfaceTexture() const override;
uint32_t GetTextureTarget() const override; uint32_t GetTextureTarget() const override;
gfx::Size GetPictureBufferSize() const override; gfx::Size GetPictureBufferSize() const override;
......
...@@ -61,16 +61,28 @@ gl::ScopedJavaSurface AndroidDeferredRenderingBackingStrategy::Initialize( ...@@ -61,16 +61,28 @@ gl::ScopedJavaSurface AndroidDeferredRenderingBackingStrategy::Initialize(
return gl::ScopedJavaSurface(surface_texture_.get()); return gl::ScopedJavaSurface(surface_texture_.get());
} }
void AndroidDeferredRenderingBackingStrategy::Cleanup( void AndroidDeferredRenderingBackingStrategy::BeginCleanup(
bool have_context, bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
// If we failed before Initialize, then do nothing. // If we failed before Initialize, then do nothing.
if (!shared_state_) if (!shared_state_)
return; return;
// TODO(liberato): we should release all codec buffers here without rendering.
// CodecChanged() will drop them, but is expected to be called after the codec
// is no longer accessible. It's unclear that VP8 flush in AVDA can't hang
// waiting for our buffers.
CodecChanged(nullptr); CodecChanged(nullptr);
} }
void AndroidDeferredRenderingBackingStrategy::EndCleanup() {
// Release the surface texture and any back buffers. This will preserve the
// front buffer, if any.
if (surface_texture_)
surface_texture_->ReleaseSurfaceTexture();
}
scoped_refptr<gl::SurfaceTexture> scoped_refptr<gl::SurfaceTexture>
AndroidDeferredRenderingBackingStrategy::GetSurfaceTexture() const { AndroidDeferredRenderingBackingStrategy::GetSurfaceTexture() const {
return surface_texture_; return surface_texture_;
......
...@@ -41,9 +41,10 @@ class MEDIA_GPU_EXPORT AndroidDeferredRenderingBackingStrategy ...@@ -41,9 +41,10 @@ class MEDIA_GPU_EXPORT AndroidDeferredRenderingBackingStrategy
// AndroidVideoDecodeAccelerator::BackingStrategy // AndroidVideoDecodeAccelerator::BackingStrategy
gl::ScopedJavaSurface Initialize(int surface_view_id) override; gl::ScopedJavaSurface Initialize(int surface_view_id) override;
void Cleanup( void BeginCleanup(
bool have_context, bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) override; const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) override;
void EndCleanup() override;
scoped_refptr<gl::SurfaceTexture> GetSurfaceTexture() const override; scoped_refptr<gl::SurfaceTexture> GetSurfaceTexture() const override;
uint32_t GetTextureTarget() const override; uint32_t GetTextureTarget() const override;
gfx::Size GetPictureBufferSize() const override; gfx::Size GetPictureBufferSize() const override;
......
...@@ -1364,7 +1364,7 @@ void AndroidVideoDecodeAccelerator::Destroy() { ...@@ -1364,7 +1364,7 @@ void AndroidVideoDecodeAccelerator::Destroy() {
LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
if (strategy_) if (strategy_)
strategy_->Cleanup(have_context, output_picture_buffers_); strategy_->BeginCleanup(have_context, output_picture_buffers_);
// If we have an OnFrameAvailable handler, tell it that we're going away. // If we have an OnFrameAvailable handler, tell it that we're going away.
if (on_frame_available_handler_) { if (on_frame_available_handler_) {
...@@ -1397,6 +1397,9 @@ void AndroidVideoDecodeAccelerator::ActualDestroy() { ...@@ -1397,6 +1397,9 @@ void AndroidVideoDecodeAccelerator::ActualDestroy() {
on_destroying_surface_cb_); on_destroying_surface_cb_);
} }
if (strategy_)
strategy_->EndCleanup();
AVDATimerManager* manager = g_avda_timer.Pointer(); AVDATimerManager* manager = g_avda_timer.Pointer();
// We no longer care about |surface_id|, in case we did before. It's okay // We no longer care about |surface_id|, in case we did before. It's okay
......
...@@ -60,10 +60,14 @@ class MEDIA_GPU_EXPORT AndroidVideoDecodeAccelerator ...@@ -60,10 +60,14 @@ class MEDIA_GPU_EXPORT AndroidVideoDecodeAccelerator
// Returns the Java surface to configure MediaCodec with. // Returns the Java surface to configure MediaCodec with.
virtual gl::ScopedJavaSurface Initialize(int surface_view_id) = 0; virtual gl::ScopedJavaSurface Initialize(int surface_view_id) = 0;
// Called before the AVDA does any Destroy() work. This will be // Called before the AVDA does any Destroy() work. The strategy should
// release any pending codec buffers, for example.
virtual void BeginCleanup(bool have_context,
const OutputBufferMap& buffer_map) = 0;
// Called before the AVDA closes up entirely. This will be
// the last call that the BackingStrategy receives. // the last call that the BackingStrategy receives.
virtual void Cleanup(bool have_context, virtual void EndCleanup() = 0;
const OutputBufferMap& buffer_map) = 0;
// This returns the SurfaceTexture created by Initialize, or nullptr if // This returns the SurfaceTexture created by Initialize, or nullptr if
// the strategy was initialized with a SurfaceView. // the strategy was initialized with a SurfaceView.
......
...@@ -60,4 +60,9 @@ class SurfaceTexturePlatformWrapper { ...@@ -60,4 +60,9 @@ class SurfaceTexturePlatformWrapper {
private static void detachFromGLContext(SurfaceTexture surfaceTexture) { private static void detachFromGLContext(SurfaceTexture surfaceTexture) {
surfaceTexture.detachFromGLContext(); surfaceTexture.detachFromGLContext();
} }
@CalledByNative
private static void release(SurfaceTexture surfaceTexture) {
surfaceTexture.release();
}
} }
...@@ -96,6 +96,11 @@ ANativeWindow* SurfaceTexture::CreateSurface() { ...@@ -96,6 +96,11 @@ ANativeWindow* SurfaceTexture::CreateSurface() {
return native_window; return native_window;
} }
void SurfaceTexture::ReleaseSurfaceTexture() {
JNIEnv* env = base::android::AttachCurrentThread();
Java_SurfaceTexturePlatformWrapper_release(env, j_surface_texture_.obj());
}
bool SurfaceTexture::RegisterSurfaceTexture(JNIEnv* env) { bool SurfaceTexture::RegisterSurfaceTexture(JNIEnv* env) {
return RegisterNativesImpl(env); return RegisterNativesImpl(env);
} }
......
...@@ -57,6 +57,11 @@ class GL_EXPORT SurfaceTexture ...@@ -57,6 +57,11 @@ class GL_EXPORT SurfaceTexture
// by calling ANativeWindow_release(). // by calling ANativeWindow_release().
ANativeWindow* CreateSurface(); ANativeWindow* CreateSurface();
// Release the SurfaceTexture back buffers. The SurfaceTexture is no longer
// usable after calling this. Note that this is not called 'Release', like
// the android API, because scoped_refptr<> calls that quite a bit.
void ReleaseSurfaceTexture();
const base::android::JavaRef<jobject>& j_surface_texture() const { const base::android::JavaRef<jobject>& j_surface_texture() const {
return j_surface_texture_; return j_surface_texture_;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment