blob: 83daac2e6b4baa6c540c9cc520aaab59efc94bb0 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/android/surface_texture_gl_owner.h"
#include <memory>
#include "base/android/scoped_hardware_buffer_fence_sync.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gpu/command_buffer/service/abstract_texture.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/scoped_make_current.h"
namespace media {
SurfaceTextureGLOwner::SurfaceTextureGLOwner(
std::unique_ptr<gpu::gles2::AbstractTexture> texture)
: TextureOwner(true /*binds_texture_on_update */, std::move(texture)),
surface_texture_(gl::SurfaceTexture::Create(GetTextureId())),
context_(gl::GLContext::GetCurrent()),
surface_(gl::GLSurface::GetCurrent()) {
DCHECK(context_);
DCHECK(surface_);
}
SurfaceTextureGLOwner::~SurfaceTextureGLOwner() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Clear the texture before we return, so that it can OnTextureDestroyed() if
// it hasn't already.
ClearAbstractTexture();
}
void SurfaceTextureGLOwner::OnTextureDestroyed(gpu::gles2::AbstractTexture*) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Make sure that the SurfaceTexture isn't using the GL objects.
surface_texture_ = nullptr;
}
void SurfaceTextureGLOwner::SetFrameAvailableCallback(
const base::RepeatingClosure& frame_available_cb) {
// Setting the callback to be run from any thread since |frame_available_cb|
// is thread safe.
surface_texture_->SetFrameAvailableCallbackOnAnyThread(frame_available_cb);
}
gl::ScopedJavaSurface SurfaceTextureGLOwner::CreateJavaSurface() const {
// |surface_texture_| might be null, but that's okay.
return gl::ScopedJavaSurface(surface_texture_.get());
}
void SurfaceTextureGLOwner::UpdateTexImage() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (surface_texture_)
surface_texture_->UpdateTexImage();
}
void SurfaceTextureGLOwner::EnsureTexImageBound() {
NOTREACHED();
}
void SurfaceTextureGLOwner::GetTransformMatrix(float mtx[]) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// If we don't have a SurfaceTexture, then the matrix doesn't matter. We
// still initialize it for good measure.
if (surface_texture_)
surface_texture_->GetTransformMatrix(mtx);
else
memset(mtx, 0, sizeof(mtx[0]) * 16);
}
void SurfaceTextureGLOwner::ReleaseBackBuffers() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (surface_texture_)
surface_texture_->ReleaseBackBuffers();
}
gl::GLContext* SurfaceTextureGLOwner::GetContext() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return context_.get();
}
gl::GLSurface* SurfaceTextureGLOwner::GetSurface() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return surface_.get();
}
std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
SurfaceTextureGLOwner::GetAHardwareBuffer() {
NOTREACHED() << "Don't use AHardwareBuffers with SurfaceTextureGLOwner";
return nullptr;
}
} // namespace media