123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- // Copyright 2014 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/vaapi/vaapi_picture_native_pixmap_ozone.h"
- #include "media/base/format_utils.h"
- #include "media/gpu/buffer_validation.h"
- #include "media/gpu/chromeos/platform_video_frame_utils.h"
- #include "media/gpu/macros.h"
- #include "media/gpu/vaapi/va_surface.h"
- #include "media/gpu/vaapi/vaapi_status.h"
- #include "media/gpu/vaapi/vaapi_wrapper.h"
- #include "ui/gfx/gpu_memory_buffer.h"
- #include "ui/gfx/linux/native_pixmap_dmabuf.h"
- #include "ui/gfx/native_pixmap.h"
- #include "ui/gl/gl_bindings.h"
- #include "ui/gl/gl_image_native_pixmap.h"
- #include "ui/gl/scoped_binders.h"
- #include "ui/ozone/public/ozone_platform.h"
- #include "ui/ozone/public/surface_factory_ozone.h"
- namespace media {
- VaapiPictureNativePixmapOzone::VaapiPictureNativePixmapOzone(
- scoped_refptr<VaapiWrapper> vaapi_wrapper,
- const MakeGLContextCurrentCallback& make_context_current_cb,
- const BindGLImageCallback& bind_image_cb,
- int32_t picture_buffer_id,
- const gfx::Size& size,
- const gfx::Size& visible_size,
- uint32_t texture_id,
- uint32_t client_texture_id,
- uint32_t texture_target)
- : VaapiPictureNativePixmap(std::move(vaapi_wrapper),
- make_context_current_cb,
- bind_image_cb,
- picture_buffer_id,
- size,
- visible_size,
- texture_id,
- client_texture_id,
- texture_target) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // Either |texture_id| and |client_texture_id| are both zero, or not.
- DCHECK((texture_id == 0 && client_texture_id == 0) ||
- (texture_id != 0 && client_texture_id != 0));
- }
- VaapiPictureNativePixmapOzone::~VaapiPictureNativePixmapOzone() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (gl_image_ && make_context_current_cb_.Run()) {
- gl_image_->ReleaseTexImage(texture_target_);
- DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR));
- }
- }
- VaapiStatus VaapiPictureNativePixmapOzone::Initialize(
- scoped_refptr<gfx::NativePixmap> pixmap) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(pixmap);
- DCHECK(pixmap->AreDmaBufFdsValid());
- // Create a |va_surface_| from dmabuf fds (pixmap->GetDmaBufFd)
- va_surface_ = vaapi_wrapper_->CreateVASurfaceForPixmap(pixmap);
- if (!va_surface_) {
- LOG(ERROR) << "Failed creating VASurface for NativePixmap";
- return VaapiStatus::Codes::kNoSurface;
- }
- // ARC++ has no texture ids.
- if (texture_id_ == 0 && client_texture_id_ == 0)
- return VaapiStatus::Codes::kOk;
- // Import dmabuf fds into the output gl texture through EGLImage.
- if (make_context_current_cb_ && !make_context_current_cb_.Run())
- return VaapiStatus::Codes::kBadContext;
- gl::ScopedTextureBinder texture_binder(texture_target_, texture_id_);
- const gfx::BufferFormat format = pixmap->GetBufferFormat();
- // TODO(b/220336463): plumb the right color space.
- auto image =
- base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format);
- if (!image->Initialize(std::move(pixmap))) {
- LOG(ERROR) << "Failed to create GLImage";
- return VaapiStatus::Codes::kFailedToInitializeImage;
- }
- gl_image_ = image;
- if (!gl_image_->BindTexImage(texture_target_)) {
- LOG(ERROR) << "Failed to bind texture to GLImage";
- return VaapiStatus::Codes::kFailedToBindTexture;
- }
- if (bind_image_cb_ &&
- !bind_image_cb_.Run(client_texture_id_, texture_target_, gl_image_,
- true /* can_bind_to_sampler */)) {
- LOG(ERROR) << "Failed to bind client_texture_id";
- return VaapiStatus::Codes::kFailedToBindImage;
- }
- return VaapiStatus::Codes::kOk;
- }
- VaapiStatus VaapiPictureNativePixmapOzone::Allocate(gfx::BufferFormat format) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
- ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
- auto pixmap = factory->CreateNativePixmap(
- gfx::kNullAcceleratedWidget, VK_NULL_HANDLE, size_, format,
- gfx::BufferUsage::SCANOUT_VDA_WRITE, /*framebuffer_size=*/visible_size_);
- if (!pixmap) {
- return VaapiStatus::Codes::kNoPixmap;
- }
- return Initialize(std::move(pixmap));
- }
- bool VaapiPictureNativePixmapOzone::ImportGpuMemoryBufferHandle(
- gfx::BufferFormat format,
- gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!CanImportGpuMemoryBufferHandle(size_, format,
- gpu_memory_buffer_handle)) {
- VLOGF(1) << "Can't import the given GpuMemoryBufferHandle";
- return false;
- }
- const auto& plane = gpu_memory_buffer_handle.native_pixmap_handle.planes[0];
- if (size_.width() > static_cast<int>(plane.stride) ||
- size_.GetArea() > static_cast<int>(plane.size)) {
- DLOG(ERROR) << "GpuMemoryBufferHandle (stride=" << plane.stride
- << ", size=" << plane.size
- << "is smaller than size_=" << size_.ToString();
- return false;
- }
- // gfx::NativePixmapDmaBuf() will take ownership of the handle.
- return Initialize(
- base::MakeRefCounted<gfx::NativePixmapDmaBuf>(
- size_, format,
- std::move(gpu_memory_buffer_handle.native_pixmap_handle)))
- .is_ok();
- }
- } // namespace media
|