This patch enables the build with TIZEN_TBM_SUPPORT. Further functionality is to be added later.
This patch also uses the default software path for video playback.
Change-Id: Ie614eb67f05adc7b6568575b91663bdb8317f6bf
Signed-off-by: pranayc1 <pranay.c1@samsung.com>
// After OnVideoCompositingFinished() is invoked, VideoFrame object can be
// destroyed.
frame_->SetContextProvider(context_provider_);
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
- frame_->CreateTbmTextureIfNeeded(gl);
+ gpu::raster::RasterInterface* ri = context_provider_->RasterInterface();
+ frame_->CreateTbmTextureIfNeeded(ri);
const gpu::MailboxHolder& mailbox_holder = frame_->mailbox_holder(0);
auto transferable_resource = viz::TransferableResource::MakeGpu(
- mailbox_holder.mailbox, GL_LINEAR, mailbox_holder.texture_target,
+ mailbox_holder.mailbox, mailbox_holder.texture_target,
mailbox_holder.sync_token, frame_->visible_rect().size(),
- viz::RGBA_8888, false);
+ viz::SinglePlaneFormat::kRGBA_8888, /*is_overlay_candidate=*/false,
+ viz::TransferableResource::ResourceSource::kVideo);
resource_id_ = resource_provider->ImportResource(
transferable_resource,
base::BindOnce(&VideoLayerImpl::OnVideoCompositingFinished,
new_frame_cnt++;
prev_frame = frame_.get();
frame_cnt++;
- if (interval >= base::TimeDelta::FromSeconds(1)) {
+ if (interval >= base::Seconds(1)) {
printf("VideoTBM[Draw] > [FPS]%.1f/%.1f\n",
new_frame_cnt / interval.InSecondsF(),
frame_cnt / interval.InSecondsF());
#include "media/base/video_transformation.h"
#if defined(TIZEN_TBM_SUPPORT)
-#include "components/viz/common/gpu/context_provider.h"
+#include "components/viz/common/gpu/raster_context_provider.h"
#endif
#if defined(TIZEN_VIDEO_HOLE)
#include "ui/gfx/geometry/rect.h"
media::VideoTransformation video_transform_;
#if defined(TIZEN_TBM_SUPPORT)
- scoped_refptr<viz::ContextProvider> context_provider_;
+ scoped_refptr<viz::RasterContextProvider> context_provider_;
viz::ResourceId resource_id_;
#endif
}
} // namespace gpu
+#if defined(TIZEN_TBM_SUPPORT)
+namespace cc {
+class VideoLayerImpl;
+}
+#endif
+
+namespace media {
+class VideoResourceUpdater;
+#if defined(TIZEN_TBM_SUPPORT)
+class VideoFrame;
+class PaintCanvasVideoRenderer;
+#endif
+} // namespace media
+
namespace viz {
class VIZ_COMMON_EXPORT RasterContextProvider {
protected:
virtual ~RasterContextProvider() = default;
-};
+#if defined(TIZEN_TBM_SUPPORT)
+ friend cc::VideoLayerImpl;
+ friend media::VideoFrame;
+ friend media::PaintCanvasVideoRenderer;
+#endif
+};
} // namespace viz
#endif // COMPONENTS_VIZ_COMMON_GPU_RASTER_CONTEXT_PROVIDER_H_
RenderWidgetHostViewAura* rwhv_aura = static_cast<RenderWidgetHostViewAura*>(
web_contents_->GetRenderWidgetHostView());
if (rwhv_aura) {
-#if defined(TIZEN_TBM_SUPPORT)
+#if defined(TIZEN_TBM_SUPPORT) && !defined(EWK_BRINGUP) // FIXME: m130 bringup
if (rwhv_aura->GetCompositor() &&
rwhv_aura->GetCompositor()->use_tbm_surface_for_offscreen_rendering()) {
display::DeviceDisplayInfoEfl display_info;
allow_external_sampling_without_native_buffers_for_testing = allow;
}
+#if defined(TIZEN_TBM_SUPPORT)
+ClientSharedImage::ClientSharedImage(const Mailbox& mailbox,
+ const SharedImageMetadata& metadata)
+ : mailbox_(mailbox), metadata_(metadata) {
+ CHECK(!mailbox.IsZero());
+}
+#endif
+
ClientSharedImage::ClientSharedImage(
const Mailbox& mailbox,
const SharedImageMetadata& metadata,
}
ClientSharedImage::~ClientSharedImage() {
+#if !defined(TIZEN_TBM_SUPPORT)
if (!HasHolder()) {
return;
}
if (sii) {
sii->DestroySharedImage(destruction_sync_token_, mailbox_);
}
+#endif
}
std::unique_ptr<ClientSharedImage::ScopedMapping> ClientSharedImage::Map() {
// provides a native buffer.
static void AllowExternalSamplingWithoutNativeBuffersForTesting(bool allow);
+#if defined(TIZEN_TBM_SUPPORT)
+ // TBM ClientSharedImage
+ ClientSharedImage(const Mailbox& mailbox,
+ const SharedImageMetadata& metadata);
+#endif
// `sii_holder` must not be null.
ClientSharedImage(const Mailbox& mailbox,
const SharedImageMetadata& metadata,
gpu::SurfaceHandle surface_handle,
gfx::BufferUsage buffer_usage) {
NOTREACHED_IN_MIGRATION();
+#if defined(TIZEN_TBM_SUPPORT)
+ return base::MakeRefCounted<ClientSharedImage>(Mailbox(), si_info.meta);
+#else
return base::MakeRefCounted<ClientSharedImage>(Mailbox(), si_info.meta,
GenUnverifiedSyncToken(),
holder_, gfx::EMPTY_BUFFER);
+#endif
}
SharedImageUsageSet SharedImageInterface::UsageForMailbox(
#include "gpu/command_buffer/service/shared_image/dawn_egl_image_representation.h"
#endif
+#if defined(TIZEN_TBM_SUPPORT)
+#include <tbm_surface.h>
+
+#include "ui/gfx/gpu_memory_buffer.h"
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+
+namespace media {
+void DestroyMediaPacket(void* media_packet_handle, int player_id);
+}
+#endif
+
namespace gpu {
class EGLImageBacking::TextureHolder : public base::RefCounted<TextureHolder> {
}
}
+#if defined(TIZEN_TBM_SUPPORT)
+EGLImageBacking::EGLImageBacking(
+ const Mailbox& mailbox,
+ viz::SharedImageFormat format,
+ const gfx::Size& size,
+ const gfx::ColorSpace& color_space,
+ GrSurfaceOrigin surface_origin,
+ SkAlphaType alpha_type,
+ SharedImageUsageSet usage,
+ size_t estimated_size,
+ const std::vector<GLCommonImageBackingFactory::FormatInfo>& format_info,
+ const GpuDriverBugWorkarounds& workarounds,
+ bool use_passthrough,
+ gfx::GpuMemoryBufferHandle handle)
+ : ClearTrackingSharedImageBacking(mailbox,
+ format,
+ size,
+ color_space,
+ surface_origin,
+ alpha_type,
+ usage,
+ "",
+ estimated_size,
+ true /*is_thread_safe*/),
+ format_info_(format_info),
+ use_passthrough_(use_passthrough) {
+ std::vector<scoped_refptr<EGLImageBacking::TextureHolder>> texture_holders;
+ texture_holders.push_back(GenEGLImageSibling(std::move(handle)));
+ source_texture_holders_ = texture_holders;
+}
+#endif
+
EGLImageBacking::~EGLImageBacking() {
CHECK(source_texture_holders_.empty());
+#if defined(TIZEN_TBM_SUPPORT)
+ media::DestroyMediaPacket(media_packet_, player_id_);
+#endif
}
SharedImageBackingType EGLImageBacking::GetType() const {
return texture_holders;
}
+#if defined(TIZEN_TBM_SUPPORT)
+scoped_refptr<EGLImageBacking::TextureHolder>
+EGLImageBacking::GenEGLImageSibling(gfx::GpuMemoryBufferHandle handle) {
+ // Create a gles2::texture.
+ GLenum target = GL_TEXTURE_EXTERNAL_OES;
+ gl::GLApi* api = gl::g_current_gl_context;
+ GLuint service_id = 0;
+ auto [tbm_buffer_handle, release_cb] =
+ gfx::ToTbmBufferHandle(handle.tbm_buffer_handle_ip);
+ // Closure to automatically release TbmBufferHandle when not needed
+ base::ScopedClosureRunner tbm_buffer_handle_release_cb_closure(
+ std::move(release_cb));
+
+ tbm_surface_h surface =
+ reinterpret_cast<tbm_surface_h>(tbm_buffer_handle.tbm_surface);
+ media_packet_ = reinterpret_cast<void*>(tbm_buffer_handle.media_packet);
+ player_id_ = tbm_buffer_handle.player_id;
+
+ EGLImageKHR egl_image;
+ {
+ AutoLock auto_lock(this);
+ const EGLint egl_attrib_list[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE};
+ egl_images_.clear();
+ egl_images_.push_back(gl::MakeScopedEGLImage(
+ EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN,
+ reinterpret_cast<EGLClientBuffer>(surface), egl_attrib_list));
+ if (!egl_images_[0].get()) {
+ LOG(ERROR) << __FUNCTION__ << " Error creating EGL Image ";
+ media::DestroyMediaPacket(media_packet_, player_id_);
+ return {};
+ }
+
+ egl_image = egl_images_[0].get();
+ }
+
+ api->glGenTexturesFn(1, &service_id);
+ gl::ScopedTextureBinder texture_binder(target, service_id);
+
+ api->glTexParameteriFn(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ api->glTexParameteriFn(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ SetCleared();
+
+ // We already have the |egl_image_|, just bind it to the new
+ // texture to make it an EGLImage sibling.
+ glEGLImageTargetTexture2DOES(target, egl_image);
+ DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError());
+ DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+
+ gfx::Rect cleared_rect;
+ if (IsCleared()) {
+ cleared_rect = gfx::Rect(size());
+ }
+
+ auto* texture = gles2::CreateGLES2TextureWithLightRef(
+ service_id, GL_TEXTURE_EXTERNAL_OES);
+
+ texture->SetLevelInfo(GL_TEXTURE_EXTERNAL_OES, 0, format_info_[0].gl_format,
+ size().width(), size().height(), 1, 0,
+ format_info_[0].gl_format, format_info_[0].gl_type,
+ cleared_rect);
+
+ texture->SetImmutable(true /*immutable*/, false /*immutable_storage*/);
+ return base::MakeRefCounted<TextureHolder>(std::move(texture));
+}
+#endif
+
void EGLImageBacking::MarkForDestruction() {
AutoLock auto_lock(this);
DCHECK(!have_context() || created_on_context_ == gl::g_current_gl_context);
bool use_passthrough,
base::span<const uint8_t> pixel_data);
+#if defined(TIZEN_TBM_SUPPORT)
+ EGLImageBacking(
+ const Mailbox& mailbox,
+ viz::SharedImageFormat format,
+ const gfx::Size& size,
+ const gfx::ColorSpace& color_space,
+ GrSurfaceOrigin surface_origin,
+ SkAlphaType alpha_type,
+ gpu::SharedImageUsageSet usage,
+ size_t estimated_size,
+ const std::vector<GLCommonImageBackingFactory::FormatInfo>& format_into,
+ const GpuDriverBugWorkarounds& workarounds,
+ bool use_passthrough,
+ gfx::GpuMemoryBufferHandle handle);
+#endif
+
EGLImageBacking(const EGLImageBacking&) = delete;
EGLImageBacking& operator=(const EGLImageBacking&) = delete;
std::vector<scoped_refptr<TextureHolder>> GenEGLImageSiblings(
base::span<const uint8_t> pixel_data);
+#if defined(TIZEN_TBM_SUPPORT)
+ scoped_refptr<TextureHolder> GenEGLImageSibling(
+ gfx::GpuMemoryBufferHandle handle);
+ void* media_packet_ = nullptr;
+ int player_id_ = 0;
+#endif
+
const std::vector<GLCommonImageBackingFactory::FormatInfo> format_info_;
std::vector<scoped_refptr<TextureHolder>> source_texture_holders_;
raw_ptr<gl::GLApi> created_on_context_;
SharedImageUsageSet usage,
std::string debug_label,
gfx::GpuMemoryBufferHandle handle) {
+#if defined(TIZEN_TBM_SUPPORT)
+ return MakeEglImageBacking(mailbox, format, size, color_space, surface_origin,
+ alpha_type, usage, std::move(handle));
+#else
NOTREACHED();
+#endif
}
bool EGLImageBackingFactory::IsSupported(SharedImageUsageSet usage,
}
// Doesn't support gmb for now
+#if defined(TIZEN_TBM_SUPPORT)
+ if (gmb_type != gfx::NATIVE_PIXMAP && gmb_type != gfx::EMPTY_BUFFER) {
+#else
if (gmb_type != gfx::EMPTY_BUFFER) {
+#endif
return false;
}
return SharedImageBackingType::kEGLImage;
}
+#if defined(TIZEN_TBM_SUPPORT)
+std::unique_ptr<SharedImageBacking> EGLImageBackingFactory::MakeEglImageBacking(
+ const Mailbox& mailbox,
+ viz::SharedImageFormat format,
+ const gfx::Size& size,
+ const gfx::ColorSpace& color_space,
+ GrSurfaceOrigin surface_origin,
+ SkAlphaType alpha_type,
+ SharedImageUsageSet usage,
+ gfx::GpuMemoryBufferHandle handle) {
+ // Calculate SharedImage size in bytes.
+ auto estimated_size = format.MaybeEstimatedSizeInBytes(size);
+ if (!estimated_size) {
+ DLOG(ERROR) << "MakeEglImageBacking: Failed to calculate SharedImage size";
+ return nullptr;
+ }
+
+ // EGLImageBacking only supports single-planar textures (so far).
+ auto format_info = GetFormatInfo(format);
+
+ return std::make_unique<EGLImageBacking>(
+ mailbox, format, size, color_space, surface_origin, alpha_type, usage,
+ estimated_size.value(), format_info, workarounds_, use_passthrough_,
+ std::move(handle));
+}
+#endif
+
} // namespace gpu
SharedImageUsageSet usage,
std::string debug_label,
base::span<const uint8_t> pixel_data);
+
+#if defined(TIZEN_TBM_SUPPORT)
+ std::unique_ptr<SharedImageBacking> MakeEglImageBacking(
+ const Mailbox& mailbox,
+ viz::SharedImageFormat format,
+ const gfx::Size& size,
+ const gfx::ColorSpace& color_space,
+ GrSurfaceOrigin surface_origin,
+ SkAlphaType alpha_type,
+ SharedImageUsageSet usage,
+ gfx::GpuMemoryBufferHandle handle);
+#endif
};
} // namespace gpu
return false;
}
+#if defined(TIZEN_TBM_SUPPORT)
+ return true;
+#endif
+
// If we have initial data to upload, ensure it is sized appropriately.
if (!pixel_data.empty()) {
DCHECK_EQ(format_infos.size(), 1u);
gl::g_current_gl_driver->ext.b_GL_OES_EGL_image) {
auto egl_backing_factory = std::make_unique<EGLImageBackingFactory>(
gpu_preferences_, workarounds_, feature_info.get());
+#if defined(TIZEN_TBM_SUPPORT)
+ // Store egl_backing_factory_ for creating video frames
+ egl_backing_factory_ = egl_backing_factory.get();
+#endif
+
factories_.push_back(std::move(egl_backing_factory));
}
bool use_compound = false;
SharedImageBackingFactory* factory =
GetFactoryByUsage(usage, format, size, {}, gmb_type);
-
+#if defined(TIZEN_TBM_SUPPORT)
+ if (buffer_handle.tbm_buffer_handle_ip.is_video_frame) {
+ bool share_between_threads = IsSharedBetweenThreads(usage);
+ if (egl_backing_factory_ &&
+ egl_backing_factory_->CanCreateSharedImage(
+ usage, format, size, share_between_threads, gmb_type,
+ gr_context_type_, /*pixel_data=*/{})) {
+ factory = egl_backing_factory_;
+ } else {
+ LOG(ERROR) << __FUNCTION__
+ << " Couldn't Create EGL Image Factory or Cannot Create "
+ "Shared Image ";
+ factory = nullptr;
+ return false;
+ }
+ }
+#endif
if (!factory && gmb_type == gfx::SHARED_MEMORY_BUFFER &&
!IsSharedBetweenThreads(usage)) {
// Check if CompoundImageBacking can hold shared memory buffer plus
// Array of all the backing factories to choose from for creating shared
// images.
std::vector<std::unique_ptr<SharedImageBackingFactory>> factories_;
+#if defined(TIZEN_TBM_SUPPORT)
+ raw_ptr<SharedImageBackingFactory> egl_backing_factory_ = nullptr;
+#endif
#if BUILDFLAG(IS_WIN)
// Used for creating swap chains
return gl_capabilities_;
}
-#if defined(TIZEN_TBM_SUPPORT)
-int32_t CommandBufferProxyImpl::CreateEGLImage(
- gfx::TbmBufferHandle buffer_handle,
- size_t width,
- size_t height,
- unsigned internalformat) {
- CheckLock();
- base::AutoLock lock(last_state_lock_);
- if (last_state_.error != gpu::error::kNoError)
- return -1;
-
- int32_t new_id = channel_->ReserveImageId();
-
- auto params = mojom::CreateImageParams::New();
- params->id = new_id;
- params->size = gfx::Size(width, height);
- params->format = gfx::BufferFormat::RGBA_8888;
- params->plane = gfx::BufferPlane::DEFAULT;
- params->image_release_count = 0;
-
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::NATIVE_PIXMAP;
- handle.tbm_surface = reinterpret_cast<uintptr_t>(buffer_handle.tbm_surface);
- handle.media_packet = reinterpret_cast<uintptr_t>(buffer_handle.media_packet);
- handle.player_id = buffer_handle.player_id;
- handle.key_num = buffer_handle.key_num;
- for (int i = 0; i < handle.key_num; ++i) {
- handle.key[i] = buffer_handle.key[i];
- handle.strides[i] = buffer_handle.strides[i];
- LOG(ERROR) << "exported key values " << handle.key[i];
- }
- handle.width = width;
- handle.height = height;
-
- params->gpu_memory_buffer = std::move(handle);
- command_buffer_->CreateImage(std::move(params));
- return new_id;
-}
-
-void CommandBufferProxyImpl::DestroyEGLImage(int32_t image_id) {
- CheckLock();
- base::AutoLock lock(last_state_lock_);
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- command_buffer_->DestroyImage(image_id);
-}
-#endif
-
void CommandBufferProxyImpl::SetLock(base::Lock* lock) {
lock_ = lock;
}
return shared_state_shm_;
}
-#if defined(TIZEN_TBM_SUPPORT)
- int32_t CreateEGLImage(gfx::TbmBufferHandle buffer_handle,
- size_t width,
- size_t height,
- unsigned internalformat) override;
- void DestroyEGLImage(int32_t image_id) override;
-#endif
-
private:
typedef std::map<int32_t, scoped_refptr<gpu::Buffer>> TransferBufferMap;
typedef std::unordered_map<uint32_t, base::OnceClosure> SignalTaskMap;
#include "ui/gfx/mac/io_surface.h"
#endif
#if defined(TIZEN_TBM_SUPPORT)
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "media/base/bind_to_current_loop.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#endif
namespace media {
}
#if defined(TIZEN_TBM_SUPPORT)
-void ReleaseTbmTexture(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- gpu::gles2::GLES2Interface* gl,
- uint32_t texture,
- uint32_t image,
- scoped_refptr<viz::ContextProvider> context_provider,
- const gpu::SyncToken& release_sync_point) {
+void ReleaseTbmTexture(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ gpu::raster::RasterInterface* ri,
+ scoped_refptr<gpu::ClientSharedImage> client_shared_image,
+ scoped_refptr<viz::RasterContextProvider> context_provider,
+ const gpu::SyncToken& release_sync_point) {
#if defined(USE_TTRACE)
TTRACE(TTRACE_TAG_WEB, "ReleaseTbmTexture");
#endif
DCHECK(task_runner->BelongsToCurrentThread());
- const uint32_t target = GL_TEXTURE_EXTERNAL_OES;
- LOG(INFO) << "VideoFrame > --ReleaseTbmTexture >"
- << ", img:" << image << ", txt:" << texture;
- if (release_sync_point.HasData())
- gl->WaitSyncTokenCHROMIUM(release_sync_point.GetConstData());
- if (image) {
- gl->BindTexture(target, texture);
- gl->ReleaseTexImage2DCHROMIUM(target, image);
- gl->DestroyTizenImageCHROMIUM(image);
+ if (context_provider->SharedImageInterface() && client_shared_image) {
+ context_provider->SharedImageInterface()->DestroySharedImage(
+ release_sync_point, std::move(client_shared_image->mailbox()));
}
- gl->DeleteTextures(1, &texture);
}
void VideoFrame::ReleaseTbm() {
- if (mailbox_holders_and_gmb_release_cb_) {
- gpu::SyncToken release_sync_token;
- {
- // To ensure that changes to |release_sync_token_| are visible on this
- // thread (imply a memory barrier).
- base::AutoLock locker(release_sync_token_lock_);
- release_sync_token = release_sync_token_;
- }
- std::move(mailbox_holders_and_gmb_release_cb_)
- .Run(release_sync_token, std::move(gpu_memory_buffer_));
+ if (!mailbox_holder_and_gmb_release_cb_) {
+ return;
+ }
+ gpu::SyncToken release_sync_token;
+ {
+ // To ensure that changes to |release_sync_token_| are visible on this
+ // thread (imply a memory barrier).
+ base::AutoLock locker(release_sync_token_lock_);
+ release_sync_token = release_sync_token_;
}
+ std::move(mailbox_holder_and_gmb_release_cb_)
+ .Run(release_sync_token, std::move(gpu_memory_buffer_));
}
-unsigned VideoFrame::CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl) {
+unsigned VideoFrame::CreateTbmTextureIfNeeded(
+ gpu::raster::RasterInterface* ri) {
#if defined(USE_TTRACE)
TTRACE(TTRACE_TAG_WEB, "VideoFrameCompositor::CreateTbmTextureIfNeeded");
#endif
base::AutoLock autolock(tbm_lock_);
- if (!gl || texture_id_)
- return (gl_ == gl) ? texture_id_ : 0;
-
- gl_ = gl;
- unsigned image = gl->CreateTizenImageCHROMIUM(
- buffer_handle_, visible_rect().width(), visible_rect().height(), GL_RGBA);
- gl->GenTextures(1, &texture_id_);
- gl->BindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
- gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
- gl->BindTexImage2DCHROMIUM(GL_TEXTURE_EXTERNAL_OES, image);
-
- LOG(INFO) << "CreateTbmTextureIfNeeded img:" << image
- << ", txt:" << texture_id_;
-
- gpu::Mailbox mailbox;
- gl->ProduceTextureDirectCHROMIUM(texture_id_, mailbox.name);
- gl->ShallowFlushCHROMIUM();
- gpu::SyncToken sync_token;
- gl->GenSyncTokenCHROMIUM(sync_token.GetData());
- mailbox_holders_[kARGBPlane] =
- gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_EXTERNAL_OES);
-
- SetReleaseMailboxCB(base::BindOnce(ReleaseTbmTexture,
- base::ThreadTaskRunnerHandle::Get(), gl,
- texture_id_, image, context_provider_));
+ sii_ = context_provider_->SharedImageInterface();
+ if (!ri || !sii_ || texture_id_) {
+ return (ri_ == ri) ? texture_id_ : 0;
+ }
+
+ ri_ = ri;
+
+ viz::SharedImageFormat format = viz::SinglePlaneFormat::kRGBA_8888;
+ gfx::Size buffer_size =
+ gfx::Size(visible_rect().width(), visible_rect().height());
+
+ gfx::GpuMemoryBufferHandle handle;
+ handle.tbm_buffer_handle_ip =
+ gfx::ToTbmBufferHandleInterProcess(buffer_handle_);
+
+ client_shared_image_ =
+ sii_->CreateSharedImage({format, buffer_size, gfx::ColorSpace(),
+ kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
+ gpu::SHARED_IMAGE_USAGE_GLES2_READ |
+ gpu::SHARED_IMAGE_USAGE_DISPLAY_READ,
+ "TBM_BUFFER"},
+ std::move(handle));
+
+ if (!client_shared_image_) {
+ LOG(ERROR) << __FUNCTION__ << " Shared Image couldn't be created ";
+ return 0;
+ }
+
+ gpu::SyncToken sync_token = sii_->GenUnverifiedSyncToken();
+ ri_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
+
+ mailbox_holder_ = gpu::MailboxHolder(client_shared_image_->mailbox(),
+ sync_token, GL_TEXTURE_EXTERNAL_OES);
+ SetReleaseMailboxCB(base::BindOnce(
+ ReleaseTbmTexture, base::SingleThreadTaskRunner::GetCurrentDefault(), ri,
+ client_shared_image_, context_provider_));
return texture_id_;
}
#endif
#include <tbm_bufmgr.h>
#include <tbm_surface.h>
#include <tbm_surface_internal.h>
-#include "components/viz/common/gpu/context_provider.h"
+
+#include "components/viz/common/gpu/raster_context_provider.h"
+#include "gpu/command_buffer/client/client_shared_image.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "ui/gfx/tbm_buffer_handle.h"
+
#define _DEBUG_TBM_VIDEO_RENDERING 0
#define _DEBUG_TBM_VIDEO_RENDERING_FPS 0
+
namespace gpu {
namespace gles2 {
class GLES2Interface;
}
} // namespace gpu
-#endif
namespace media {
-
-#if defined(TIZEN_TBM_SUPPORT)
constexpr auto TBM_BO_NUM_MAX = 4;
+} // namespace media
#endif
+namespace media {
// Specifies the type of shared image format used by media video
// encoder/decoder. Currently, we have (1) one shared image (and texture)
// created for single planar formats eg. RGBA (2) multiple shared images created
gfx::TbmBufferHandle handle);
bool IsTBMBackend() const { return storage_type_ == STORAGE_TBM_SURFACE; }
unsigned GetTbmTexture() { return texture_id_; }
- unsigned CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl);
+ unsigned CreateTbmTextureIfNeeded(gpu::raster::RasterInterface* ri);
void ReleaseTbm();
void SetTbmTexture(unsigned texture) { texture_id_ = texture; }
gfx::TbmBufferHandle GetTbmBuffer() { return buffer_handle_; }
unsigned GetImageID() { return image_id_; }
void SetImageID(unsigned image_id) { image_id_ = image_id; }
void SetContextProvider(
- scoped_refptr<viz::ContextProvider> context_provider) {
+ scoped_refptr<viz::RasterContextProvider> context_provider) {
context_provider_ = context_provider;
}
#endif
mutable base::Lock tbm_map_lock_;
gfx::TbmBufferHandle buffer_handle_;
unsigned texture_id_;
- gpu::gles2::GLES2Interface* gl_;
- unsigned image_id_;
- scoped_refptr<viz::ContextProvider> context_provider_;
+ gpu::raster::RasterInterface* ri_ = nullptr;
+ gpu::gles2::GLES2Interface* gl_ = nullptr;
+ gpu::SharedImageInterface* sii_ = nullptr;
+ unsigned image_id_;
+ scoped_refptr<viz::RasterContextProvider> context_provider_;
+ scoped_refptr<gpu::ClientSharedImage> client_shared_image_;
mutable tbm_bo bo_[TBM_BO_NUM_MAX] = {nullptr};
mutable tbm_bo_handle bo_handle_[TBM_BO_NUM_MAX] = {
{nullptr},
enabled_features += [ "is_tizen_tv" ]
}
+ if (tizen_tbm_support) {
+ enabled_features += [ "tizen_tbm_support" ]
+ }
+
shared_typemaps = [
{
types = [
[EnableIf=tizen_tbm_support]
OnNewTbmFrameAvailable(uint32 playerId,
- gfx.mojom.TbmBufferHandle tbm_buffer_handle,
+ gfx.mojom.TbmBufferHandleInterProcess tbm_buffer_handle,
mojo_base.mojom.TimeDelta timestamp);
};
=> (mojo_base.mojom.UnguessableToken request_token);
[EnableIf=tizen_tbm_support]
- OnTbmBufferExhausted(gfx.mojom.TbmBufferHandle tbm_buffer_handle);
+ OnMediaPacketExhausted(uint64 media_packet);
};
// Extension of the mojo::RendererClient communication layer for media flinging,
cc::PaintImage::GetNextContentId());
} else {
cache_.emplace(video_frame->unique_id());
-#if defined(TIZEN_TBM_SUPPORT)
- gpu::gles2::GLES2Interface* gl = raster_context_provider->ContextGL();
- unsigned source_texture = 0;
- gl->GenTextures(1, &source_texture);
- DCHECK(source_texture);
- gl->BindTexture(GL_TEXTURE_2D, source_texture);
-
- CopyMailboxToTexture(
- gl, video_frame->coded_size(), video_frame->visible_rect(),
- video_frame->mailbox_holder(0).mailbox,
- video_frame->mailbox_holder(0).sync_token, GL_TEXTURE_2D,
- source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0, false, false);
-
- GrGLTextureInfo source_texture_info;
- source_texture_info.fID = source_texture;
- source_texture_info.fTarget = GL_TEXTURE_2D;
- source_texture_info.fFormat = GL_RGBA8_OES;
- GrBackendTexture source_backend_texture(
- video_frame->coded_size().width(), video_frame->coded_size().height(),
- GrMipMapped::kNo, source_texture_info);
-
- paint_image_builder.set_image(
- SkImage::MakeFromAdoptedTexture(
- raster_context_provider->GrContext(), source_backend_texture,
- kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
- kPremul_SkAlphaType, video_frame->ColorSpace().ToSkColorSpace()),
- cc::PaintImage::GetNextContentId());
-
-#else
paint_image_builder.set_paint_image_generator(
sk_make_sp<VideoImageGenerator>(video_frame));
-#endif
}
cache_->paint_image = paint_image_builder.TakePaintImage();
viz::ResourceId external_resource_id) {
#if defined(TIZEN_TBM_SUPPORT)
if (video_frame->IsTBMBackend()) {
- frame_resources_.emplace_back(external_resource_id,
- video_frame->coded_size());
+ frame_resource_id_ = external_resource_id;
frame_resource_type_ = VideoFrameResourceType::RGBA;
return;
}
proprietary_codecs=true
tizen_audio_io=true
tizen_web_speech_recognition=true
- tizen_tbm_support=false
+ tizen_tbm_support=true
ffmpeg_branding=\"Chrome\"
"
#include "tizen_src/chromium_impl/content/browser/media/media_player_renderer_web_contents_observer.h"
#include "tizen_src/chromium_impl/media/filters/media_player_registry.h"
#include "tizen_src/chromium_impl/media/filters/media_player_tizen.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h"
+#endif
#if defined(TIZEN_VIDEO_HOLE)
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
void TizenRendererImpl::OnNewTbmFrameAvailable(uint32_t player_id,
gfx::TbmBufferHandle tbm_handle,
base::TimeDelta timestamp) {
- client_extension_->OnNewTbmFrameAvailable(player_id, tbm_handle, timestamp);
+ client_extension_->OnNewTbmFrameAvailable(
+ player_id, gfx::ToTbmBufferHandleInterProcess(tbm_handle), timestamp);
}
-void TizenRendererImpl::OnTbmBufferExhausted(
- const gfx::TbmBufferHandle& tbm_handle) {
- media_player_->DestroyMediaPacket(
- reinterpret_cast<void*>(tbm_handle.media_packet));
+void TizenRendererImpl::OnMediaPacketExhausted(uint64_t media_packet) {
+ media_player_->DestroyMediaPacket(reinterpret_cast<void*>(media_packet));
}
-#else
+#endif
void TizenRendererImpl::OnNewFrameAvailable(
uint32_t playerId,
base::UnsafeSharedMemoryRegion frame,
client_extension_->OnNewFrameAvailable(playerId, std::move(frame), size,
timestamp, width, height);
}
-#endif
} // namespace content
#include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h"
#include "ui/gfx/geometry/size.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h"
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h"
+#endif
+
namespace base {
class SingleThreadTaskRunner;
}
void OnNewTbmFrameAvailable(uint32_t player_id,
gfx::TbmBufferHandle tbm_handle,
base::TimeDelta timestamp) override;
- void OnTbmBufferExhausted(const gfx::TbmBufferHandle& tbm_handle) override;
-#else
+ void OnMediaPacketExhausted(uint64_t media_packet) override;
+#endif
void OnNewFrameAvailable(uint32_t playerId,
base::UnsafeSharedMemoryRegion frame,
uint32_t size,
base::TimeDelta timestamp,
uint32_t width,
uint32_t height) override;
-#endif
#if BUILDFLAG(IS_TIZEN_TV)
content::WebContentsDelegate* GetWebContentsDelegate() const override;
#include "base/functional/bind.h"
#include "third_party/libyuv/include/libyuv/convert.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/gfx/tbm_buffer_handle.h"
+#include "ui/gfx/tbm_buffer_handle_inter_process.h"
+#endif
+
namespace content {
MediaPlayerRendererClient::MediaPlayerRendererClient(
}
#if defined(TIZEN_TBM_SUPPORT)
-void MediaPlayerRendererClient::OnTbmBufferExhausted(
+void MediaPlayerRendererClient::OnMediaPacketExhausted(
media::VideoFrame* video_frame,
- void* media_packet,
- int player_id) {
+ uintptr_t media_packet) {
// In this case, media packet will be released in destructor of |GLImageEGL|.
if (video_frame->GetTbmTexture())
return;
- gfx::TbmBufferHandle tbm_handle;
- tbm_handle.media_packet = reinterpret_cast<uintptr_t>(media_packet);
- tbm_handle.player_id = player_id;
- renderer_extension_remote_->OnTbmBufferExhausted(tbm_handle);
+ renderer_extension_remote_->OnMediaPacketExhausted(media_packet);
}
void MediaPlayerRendererClient::OnNewTbmFrameAvailable(
uint32_t playerId,
- const gfx::TbmBufferHandle& tbm_buffer_handle,
+ const gfx::TbmBufferHandleInterProcess tbm_buffer_handle_inter_process,
base::TimeDelta timestamp) {
+ auto [tbm_buffer_handle, tbm_surface_release_cb_runner] =
+ gfx::ToTbmBufferHandle(tbm_buffer_handle_inter_process);
gfx::Size size(tbm_buffer_handle.width, tbm_buffer_handle.height);
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::WrapTBMSurface(size, timestamp, tbm_buffer_handle);
+ if (!video_frame) {
+ LOG(ERROR) << "Failed to wrap TBM surface";
+ return;
+ }
+
+ video_frame->AddDestructionObserver(tbm_surface_release_cb_runner.Release());
video_frame->AddDestructionObserver(base::BindOnce(
- &MediaPlayerRendererClient::OnTbmBufferExhausted,
+ &MediaPlayerRendererClient::OnMediaPacketExhausted,
weak_factory_.GetWeakPtr(), base::Unretained(video_frame.get()),
- const_cast<void*>((const void*)tbm_buffer_handle.media_packet),
- tbm_buffer_handle.player_id));
+ reinterpret_cast<uintptr_t>(tbm_buffer_handle.media_packet)));
#if defined(TIZEN_VIDEO_HOLE) && !BUILDFLAG(IS_TIZEN_TV)
if (!is_video_hole_ || (is_video_hole_ && !is_fullscreen_))
#include "mojo/public/cpp/bindings/remote.h"
#if defined(TIZEN_TBM_SUPPORT)
-#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h"
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h"
#endif
namespace content {
uint32_t width,
uint32_t height) override;
#if defined(TIZEN_TBM_SUPPORT)
- void OnNewTbmFrameAvailable(uint32_t playerId,
- const gfx::TbmBufferHandle& tbm_buffer_handle,
- base::TimeDelta timestamp) override;
- void OnTbmBufferExhausted(media::VideoFrame* video_frame,
- void* media_packet,
- int player_id);
+ void OnNewTbmFrameAvailable(
+ uint32_t playerId,
+ gfx::TbmBufferHandleInterProcess tbm_buffer_handle_inter_process,
+ base::TimeDelta timestamp) override;
+ void OnMediaPacketExhausted(media::VideoFrame* video_frame,
+ uintptr_t media_packet);
#endif
private:
// generating a new timestamp in here.
base::TimeDelta timestamp = GetCurrentTime();
-#if defined(TIZEN_TBM_SUPPORT)
+#if defined(TIZEN_TBM_SUPPORT) && !defined(EWK_BRINGUP)
gfx::TbmBufferHandle tbm_handle;
tbm_handle.tbm_surface = reinterpret_cast<uint64_t>(tbm_surface);
tbm_handle.media_packet = reinterpret_cast<uint64_t>(packet.release());
+ tbm_handle.is_video_frame = true;
OnNewTbmBufferAvailable(player_id_, tbm_handle, timestamp);
#else
base::UnsafeSharedMemoryRegion shared_memory;
return;
}
}
-
- OnNewFrameAvailable(player_id_, std::move(shared_memory), shared_memory_size,
- timestamp);
#endif
}
GetMediaPlayerClient()->OnNewTbmFrameAvailable(player_id, tbm_handle,
timestamp);
}
-#else
-void MediaPlayerBridgeCapi::OnNewFrameAvailable(
- int player_id,
- base::UnsafeSharedMemoryRegion shm_region,
- uint32_t length,
- base::TimeDelta timestamp) {
- NOTIMPLEMENTED();
-}
#endif
} // namespace media
void OnNewTbmBufferAvailable(int player_id,
gfx::TbmBufferHandle tbm_handle,
base::TimeDelta timestamp);
-#else
- void OnNewFrameAvailable(int player_id,
- base::UnsafeSharedMemoryRegion shm_region,
- uint32_t length,
- base::TimeDelta timestamp);
#endif
MediaPlayerTizenClient* GetMediaPlayerClient() const override {
return client_;
<< ", duration:" << packet->duration << ", Player(" << esplayer_
<< ", state:" << GetString(GetPlayerState());
-#if defined(TIZEN_TBM_SUPPORT)
+#if defined(TIZEN_TBM_SUPPORT) && !defined(EWK_BRINGUP)
gfx::TbmBufferHandle tbm_handle;
tbm_handle.tbm_surface = reinterpret_cast<uint64_t>(tbm_surface);
tbm_handle.media_packet = reinterpret_cast<uint64_t>(packet);
tbm_handle.player_id = player_id_;
tbm_handle.width = width;
tbm_handle.height = height;
+ tbm_handle.is_video_frame = true;
GetMediaPlayerClient()->OnNewTbmFrameAvailable(0, tbm_handle, timestamp);
#else
virtual void OnNewTbmFrameAvailable(uint32_t player_id,
gfx::TbmBufferHandle tbm_buffer_handle,
base::TimeDelta timestamp) = 0;
-#else
+#endif
virtual void OnNewFrameAvailable(uint32_t playerId,
base::UnsafeSharedMemoryRegion frame,
uint32_t size,
base::TimeDelta timestamp,
uint32_t width,
uint32_t height) = 0;
-#endif
#if BUILDFLAG(IS_TIZEN_TV)
virtual bool PlaybackNotificationEnabled() = 0;
#endif
namespace gfx {
+#if defined(TIZEN_TBM_SUPPORT)
+// There are 2 flows could trigger TBM destroy: GLImageEGL::~GLImageEGL()
+// and TizenEsPlusPlayerRenderer::ReleaseTbmBuffer;
+// Define a type to specify how to destroy TBM.
+enum TbmDestroyType {
+ // triggered by GLImageEGL::~GLImageEGL()
+ kDestroyTbmByEgl = 0,
+ // triggered by video frame DestructionObserver
+ kDestroyTbmByVideoFrame = 1,
+};
+#endif
struct GFX_EXPORT TbmBufferHandle {
TbmBufferHandle() {}
#if defined(TIZEN_TBM_SUPPORT)
+ bool is_video_frame = false;
size_t tbm_surface{0};
size_t media_packet{0};
+ TbmDestroyType tbm_destroy_type = kDestroyTbmByEgl;
int32_t player_id = 0;
int32_t key_num = 0;
- int32_t key[4];
- int32_t strides[4];
+ int32_t key[4] = {0};
+ int32_t strides[4] = {0};
int32_t width = 0;
int32_t height = 0;
+ uint64_t pts = 0;
+ uint64_t duration = 0;
#endif
};
--- /dev/null
+// Copyright 2022 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h"
+
+#include <memory>
+
+#include "base/functional/callback_helpers.h"
+#include "base/logging.h"
+#include "tizen_src/chromium_impl/ui/gfx/tbm_utils.h"
+#include "ui/gfx/tbm_buffer_handle.h"
+
+namespace gfx {
+
+std::vector<base::ScopedFD> GetBufferObjectFdsFromSurface(
+ tbm_surface_h tbm_surface) {
+ if (!tbm_surface) {
+ LOG(WARNING) << "Provided TBM Surface is null";
+ return {};
+ }
+
+ std::vector<base::ScopedFD> result{};
+
+ size_t tbm_bos_count = tbm_surface_internal_get_num_bos(tbm_surface);
+ result.reserve(tbm_bos_count);
+
+ for (auto i = 0u; i < tbm_bos_count; ++i) {
+ // tbm_surface_internal_get_bo does not increase reference count for tbm_bo
+ auto tbm_bo = tbm_surface_internal_get_bo(tbm_surface, i);
+ if (!tbm_bo) {
+ LOG(WARNING) << "Failed to get tbm_bo from tbm_surface_h";
+ return {};
+ }
+ result.emplace_back(tbm_bo_export_fd(tbm_bo));
+ }
+
+ return result;
+}
+
+TbmSurfaceParameters GetTbmParamsFromSurface(tbm_surface_h tbm_surface) {
+ if (!tbm_surface) {
+ LOG(WARNING) << "Provided TBM Surface is null";
+ return {};
+ }
+
+ tbm_surface_info_s tbm_si{};
+ auto ret = tbm_surface_get_info(tbm_surface, &tbm_si);
+ if (ret != TBM_SURFACE_ERROR_NONE) {
+ LOG(WARNING)
+ << "Failed to get tbm_surface_info_s from tbm_surface_h, result = "
+ << ret;
+ return {};
+ }
+
+ std::vector<TbmSurfacePlaneParameters> result_params;
+ result_params.reserve(tbm_si.num_planes);
+
+ for (uint32_t i = 0; i < tbm_si.num_planes; ++i) {
+ result_params.emplace_back(
+ TbmSurfacePlaneParameters{.offset = tbm_si.planes[i].offset,
+ .size = tbm_si.planes[i].size,
+ .stride = tbm_si.planes[i].stride});
+ }
+
+ return {tbm_si.format,
+ std::move(result_params),
+ {static_cast<int32_t>(tbm_si.width),
+ static_cast<int32_t>(tbm_si.height)}};
+}
+
+TbmBufferHandleInterProcess ToTbmBufferHandleInterProcess(
+ const TbmBufferHandle& tbm_buffer) {
+ TbmBufferHandleInterProcess tbm_buffer_ip;
+
+ if (!tbm_buffer.tbm_surface) {
+ LOG(WARNING) << "Provided TBM Surface is null";
+ return {};
+ }
+
+ auto buffer_mgr = TbmBufMgrType(tbm_bufmgr_init(-1));
+
+ if (!buffer_mgr) {
+ LOG(WARNING) << "TBM buffer manager was not created successfully";
+ return {};
+ }
+
+ auto tbm_surface = reinterpret_cast<tbm_surface_h>(tbm_buffer.tbm_surface);
+
+ tbm_buffer_ip.fds = GetBufferObjectFdsFromSurface(tbm_surface);
+ if (tbm_buffer_ip.fds.empty()) {
+ LOG(WARNING) << "Failed to get buffer object FDs from tbm surface";
+ return {};
+ }
+
+ auto tbm_params = GetTbmParamsFromSurface(tbm_surface);
+ if (!tbm_params.IsValid()) {
+ LOG(WARNING) << "Failed to get TBM parameters from tbm surface";
+ return {};
+ }
+ tbm_buffer_ip.is_video_frame = tbm_buffer.is_video_frame;
+ tbm_buffer_ip.tbm_format = tbm_params.format;
+ tbm_buffer_ip.planes = std::move(tbm_params.planes);
+
+ tbm_buffer_ip.media_packet = tbm_buffer.media_packet;
+ tbm_buffer_ip.player_id = tbm_buffer.player_id;
+ tbm_buffer_ip.width = tbm_buffer.width;
+ tbm_buffer_ip.height = tbm_buffer.height;
+ tbm_buffer_ip.tbm_destroy_type = tbm_buffer.tbm_destroy_type;
+ tbm_buffer_ip.pts = tbm_buffer.pts;
+ tbm_buffer_ip.duration = tbm_buffer.duration;
+
+ return tbm_buffer_ip;
+}
+
+std::pair<TbmBufferHandle, TbmSurfaceReleaseCbRunner> ToTbmBufferHandle(
+ const TbmBufferHandleInterProcess& tbm_buffer_ip) {
+ std::pair<TbmBufferHandle, TbmSurfaceReleaseCbRunner> out_pair;
+
+ TbmBufferHandle tbm_buffer;
+ auto buffer_mgr = TbmBufMgrType(tbm_bufmgr_init(-1));
+
+ if (!buffer_mgr) {
+ LOG(WARNING) << "TBM buffer manager was not created successfully";
+ return out_pair;
+ }
+
+ tbm_buffer.media_packet = tbm_buffer_ip.media_packet;
+ tbm_buffer.player_id = tbm_buffer_ip.player_id;
+ tbm_buffer.is_video_frame = tbm_buffer_ip.is_video_frame;
+
+ tbm_buffer.key_num = tbm_buffer_ip.fds.size();
+
+ std::vector<TbmBOType> bos;
+ std::vector<tbm_bo> bos_raw;
+ bos.reserve(tbm_buffer_ip.fds.size());
+ bos_raw.reserve(tbm_buffer_ip.fds.size());
+
+ for (uint32_t i = 0; i < tbm_buffer_ip.fds.size(); ++i) {
+ bos.emplace_back(
+ tbm_bo_import_fd(buffer_mgr.get(), tbm_buffer_ip.fds[i].get()));
+
+ if (!bos.back()) {
+ LOG(WARNING) << "Failed to import tbm_bo from fd";
+ return out_pair;
+ }
+
+ bos_raw.emplace_back(bos.back().get());
+ tbm_buffer.key[i] = tbm_bo_export(bos_raw.back());
+ }
+
+ TbmSurfaceReleaseCbRunner release_cb;
+ {
+ tbm_surface_info_s tbm_si{};
+ tbm_si.bpp = tbm_surface_internal_get_bpp(tbm_buffer_ip.tbm_format);
+ tbm_si.num_planes = tbm_buffer_ip.planes.size();
+ tbm_si.format = tbm_buffer_ip.tbm_format;
+ tbm_si.width = tbm_buffer_ip.width;
+ tbm_si.height = tbm_buffer_ip.height;
+ for (uint32_t i = 0; i < tbm_buffer_ip.planes.size(); ++i) {
+ tbm_si.planes[i].offset = tbm_buffer_ip.planes[i].offset;
+ tbm_si.planes[i].size = tbm_buffer_ip.planes[i].size;
+ tbm_si.planes[i].stride = tbm_buffer_ip.planes[i].stride;
+ tbm_si.size += tbm_si.planes[i].size;
+
+ tbm_buffer.strides[i] = tbm_buffer_ip.planes[i].stride;
+ }
+
+ auto tbm_surface = tbm_surface_internal_create_with_bos(
+ &tbm_si, bos_raw.data(), bos_raw.size());
+
+ if (!tbm_surface) {
+ LOG(WARNING) << "Failed to create tbm_surface_h from provided tbm_bo's";
+ return out_pair;
+ }
+
+ tbm_buffer.tbm_surface =
+ reinterpret_cast<decltype(tbm_buffer.tbm_surface)>(tbm_surface);
+
+ release_cb = base::ScopedClosureRunner{base::BindOnce(
+ [](tbm_surface_h tbm_surface) { tbm_surface_destroy(tbm_surface); },
+ tbm_surface)};
+ }
+
+ tbm_buffer.width = tbm_buffer_ip.width;
+ tbm_buffer.height = tbm_buffer_ip.height;
+
+ tbm_buffer.tbm_destroy_type = tbm_buffer_ip.tbm_destroy_type;
+ tbm_buffer.pts = tbm_buffer_ip.pts;
+ tbm_buffer.duration = tbm_buffer_ip.duration;
+
+ out_pair = std::make_pair(std::move(tbm_buffer), std::move(release_cb));
+
+ return out_pair;
+}
+
+} // namespace gfx
--- /dev/null
+// Copyright 2022 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_TBM_BUFFER_HANDLE_INTER_PROCESS_H
+#define UI_GFX_TBM_BUFFER_HANDLE_INTER_PROCESS_H
+
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#include <array>
+#include <utility>
+
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
+#include "mojo/public/cpp/platform/platform_handle.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/gfx_export.h"
+#include "ui/gfx/tbm_buffer_handle.h"
+
+namespace gfx {
+
+struct GFX_EXPORT TbmSurfacePlaneParameters {
+ uint32_t offset{0};
+ uint32_t size{0};
+ uint32_t stride{0};
+};
+
+struct GFX_EXPORT TbmSurfaceParameters {
+ tbm_format format{0};
+ std::vector<TbmSurfacePlaneParameters> planes;
+ Size size;
+
+ bool IsValid() const { return format && !planes.empty() && !size.IsEmpty(); }
+};
+
+struct GFX_EXPORT TbmBufferHandleInterProcess {
+ bool is_video_frame = false;
+ size_t media_packet{0};
+ int32_t player_id{-1};
+ TbmDestroyType tbm_destroy_type{kDestroyTbmByEgl};
+ std::vector<base::ScopedFD> fds{};
+ int32_t tbm_format{-1};
+ std::vector<TbmSurfacePlaneParameters> planes;
+ int32_t width{-1};
+ int32_t height{-1};
+ uint64_t pts{0};
+ uint64_t duration{0};
+};
+
+std::vector<base::ScopedFD> GetBufferObjectFdsFromSurface(
+ tbm_surface_h tbm_surface);
+
+TbmSurfaceParameters GetTbmParamsFromSurface(tbm_surface_h tbm_surface);
+
+TbmBufferHandleInterProcess ToTbmBufferHandleInterProcess(
+ const TbmBufferHandle&);
+
+using TbmSurfaceReleaseCbRunner = base::ScopedClosureRunner;
+std::pair<TbmBufferHandle, TbmSurfaceReleaseCbRunner> ToTbmBufferHandle(
+ const TbmBufferHandleInterProcess&);
+
+} // namespace gfx
+
+#endif // UI_GFX_TBM_BUFFER_HANDLE_INTER_PROCESS_H
--- /dev/null
+// Copyright 2022 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/tbm_surface.h"
+
+#include <tbm_bo.h>
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#include "base/logging.h"
+
+namespace gfx {
+
+std::unique_ptr<TbmSurface> TbmSurface::ImportTbmSurface(
+ const NativePixmapHandle& native_pixmap_handle,
+ const gfx::Size& picture_size) {
+ // Currently this class supports only NV12 TBMs.
+ constexpr static const size_t kNV12Planes = 2;
+ if (native_pixmap_handle.planes.size() != kNV12Planes) {
+ LOG(ERROR) << "Invalid pixmap handle, expected 2 planes, got: "
+ << native_pixmap_handle.planes.size();
+ return nullptr;
+ }
+
+ tbm_surface_info_s tbmsi{};
+ tbmsi.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12);
+ tbmsi.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12);
+ tbmsi.format = TBM_FORMAT_NV12;
+ tbmsi.width = picture_size.width();
+ tbmsi.height = picture_size.height();
+
+ auto buf_mgr = TbmBufMgrType(tbm_bufmgr_init(-1));
+ if (!buf_mgr) {
+ LOG(ERROR) << "Cannot create buffer manager";
+ return nullptr;
+ }
+
+ std::vector<TbmBOType> bos;
+ std::vector<tbm_bo> bos_raw;
+ bos.reserve(native_pixmap_handle.planes.size());
+ bos_raw.reserve(native_pixmap_handle.planes.size());
+
+ for (size_t i = 0; i < native_pixmap_handle.planes.size(); ++i) {
+ if (!native_pixmap_handle.planes[i].fd.is_valid()) {
+ LOG(ERROR) << "Invalid FD, cannot import";
+ return nullptr;
+ }
+ bos.emplace_back(tbm_bo_import_fd(buf_mgr.get(),
+ native_pixmap_handle.planes[i].fd.get()));
+ bos_raw.emplace_back(bos.back().get());
+ // TBM surface must contain different buffer objects.
+ if (i > 0 && bos[i].get() == bos[i - 1].get()) {
+ return nullptr;
+ }
+
+ tbmsi.planes[i].offset = native_pixmap_handle.planes[i].offset;
+ tbmsi.planes[i].size = native_pixmap_handle.planes[i].size;
+ tbmsi.planes[i].stride = native_pixmap_handle.planes[i].stride;
+ tbmsi.size += tbmsi.planes[i].size;
+ }
+
+ auto surface = TbmSurfaceType(tbm_surface_internal_create_with_bos(
+ &tbmsi, bos_raw.data(), bos_raw.size()));
+
+ if (!surface) {
+ LOG(ERROR) << "Cannot create surface";
+ return nullptr;
+ }
+ return std::make_unique<TbmSurface>(std::move(buf_mgr), std::move(surface));
+}
+
+TbmSurface::TbmSurface(TbmBufMgrType buf_mgr, TbmSurfaceType handle)
+ : buf_mgr_(std::move(buf_mgr)), handle_(std::move(handle)) {}
+
+} // namespace gfx
--- /dev/null
+// Copyright 2022 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_SURFACE_H_
+#define TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_SURFACE_H_
+
+#include <memory>
+
+#include "tizen_src/chromium_impl/ui/gfx/tbm_utils.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/native_pixmap_handle.h"
+
+namespace gfx {
+
+class TbmSurface {
+ public:
+ static std::unique_ptr<TbmSurface> ImportTbmSurface(
+ const NativePixmapHandle& native_pixmap_handle,
+ const gfx::Size& picture_size);
+
+ tbm_surface_h operator*() const { return handle_.get(); }
+
+ private:
+ // GCC compiler requires namespace specification for `Tbm*` wrappers,
+ // otherwise compile error is being reported.
+ friend std::unique_ptr<TbmSurface> std::make_unique<TbmSurface>(
+ gfx::TbmBufMgrType&&,
+ gfx::TbmSurfaceType&&);
+
+ TbmSurface(TbmBufMgrType buf_mgr, TbmSurfaceType handle);
+
+ TbmBufMgrType buf_mgr_;
+ TbmSurfaceType handle_;
+};
+
+} // namespace gfx
+
+#endif // TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_SURFACE_H_
--- /dev/null
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tizen_src/chromium_impl/ui/gfx/tbm_utils.h"
+
+#include <tbm_bo.h>
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+namespace gfx {
+
+void TbmBODeleter::operator()(tbm_bo bo) {
+ tbm_bo_unref(bo);
+}
+
+void TbmSurfaceDeleter::operator()(tbm_surface_h surface) {
+ tbm_surface_internal_destroy(surface);
+}
+
+void TbmBufMgrDeleter::operator()(tbm_bufmgr bufmgr) {
+ tbm_bufmgr_deinit(bufmgr);
+}
+
+} // namespace gfx
--- /dev/null
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_UTILS_H_
+#define TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_UTILS_H_
+
+#include <tbm_type.h>
+#include <tbm_type_common.h>
+
+#include <memory>
+
+namespace gfx {
+
+struct TbmBODeleter {
+ void operator()(tbm_bo bo);
+};
+
+struct TbmSurfaceDeleter {
+ void operator()(tbm_surface_h surface);
+};
+
+struct TbmBufMgrDeleter {
+ void operator()(tbm_bufmgr bufmgr);
+};
+
+using TbmBOType =
+ std::unique_ptr<std::remove_pointer<tbm_bo>::type, TbmBODeleter>;
+
+using TbmSurfaceType = std::unique_ptr<std::remove_pointer<tbm_surface_h>::type,
+ TbmSurfaceDeleter>;
+
+using TbmBufMgrType =
+ std::unique_ptr<std::remove_pointer<tbm_bufmgr>::type, TbmBufMgrDeleter>;
+} // namespace gfx
+
+#endif // TIZEN_SRC_CHROMIUM_IMPL_UI_GFX_TBM_UTILS_H_
"//tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h",
]
+if (tizen_tbm_support) {
+ external_ui_gfx_sources += [
+ "//tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.cc",
+ "//tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h",
+ "//tizen_src/chromium_impl/ui/gfx/tbm_utils.cc",
+ "//tizen_src/chromium_impl/ui/gfx/tbm_utils.h",
+ ]
+ if (tizen_product_tv) {
+ external_ui_gfx_sources += [
+ "//tizen_src/chromium_impl/ui/gfx/tbm_surface.cc",
+ "//tizen_src/chromium_impl/ui/gfx/tbm_surface.h",
+ ]
+ }
+}
+
# For //ui/gfx/x target
external_ui_gfx_x11_sources =
[ "//tizen_src/chromium_impl/ui/gfx/x/x11_types_override.cc" ]
#include "base/android/scoped_hardware_buffer_handle.h"
#endif
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/gfx/tbm_buffer_handle_inter_process.h"
+#endif
+
namespace base {
namespace trace_event {
class ProcessMemoryDump;
base::android::ScopedHardwareBufferHandle android_hardware_buffer;
#endif
#if defined(TIZEN_TBM_SUPPORT)
- size_t tbm_surface{0};
- size_t media_packet{0};
- int32_t player_id = 0;
- int32_t key_num = 0;
- int32_t key[4];
- int32_t strides[4];
- int32_t width = 0;
- int32_t height = 0;
+ TbmBufferHandleInterProcess tbm_buffer_handle_ip;
#endif
};
cpp = "::gfx::GpuMemoryBufferType"
},
{
- mojom = "gfx.mojom.TbmBufferHandle"
- cpp = "::gfx::TbmBufferHandle"
+ mojom = "gfx.mojom.TbmBufferHandleInterProcess"
+ cpp = "::gfx::TbmBufferHandleInterProcess"
+ move_only = true
},
]
int32 id;
};
+// gfx::TbmDestroyType
+[EnableIf=tizen_tbm_support]
+enum TbmDestroyType {
+ kDestroyTbmByEgl = 0,
+ kDestroyTbmByVideoFrame = 1,
+};
+
// gfx::GpuMemoryBufferHandle
struct GpuMemoryBufferHandle {
GpuMemoryBufferId id;
uint32 stride;
[EnableIf=tizen_tbm_support]
- uint64 tbm_surface;
-
- [EnableIf=tizen_tbm_support]
- uint64 media_packet;
-
- [EnableIf=tizen_tbm_support]
- int32 player_id;
-
- [EnableIf=tizen_tbm_support]
- int32 key_num;
-
- [EnableIf=tizen_tbm_support]
- array<int32, 4> key;
-
- [EnableIf=tizen_tbm_support]
- array<int32, 4> strides;
-
- [EnableIf=tizen_tbm_support]
- int32 width;
-
- [EnableIf=tizen_tbm_support]
- int32 height;
+ TbmBufferHandleInterProcess tbm_buffer_handle_ip;
GpuMemoryBufferPlatformHandle? platform_handle;
};
-// gfx::TbmBufferHandle
-struct TbmBufferHandle {
- [EnableIf=tizen_tbm_support]
- uint32 tbm_surface;
-
- [EnableIf=tizen_tbm_support]
- uint32 media_packet;
+// gfx::TbmBufferPlaneParameters
+[EnableIf=tizen_tbm_support]
+struct TbmSurfacePlaneParameters {
+ uint32 offset;
+ uint32 size;
+ uint32 stride;
+};
- [EnableIf=tizen_tbm_support]
+// gfx::TbmBufferHandleInterProcess
+[EnableIf=tizen_tbm_support]
+struct TbmBufferHandleInterProcess {
+ bool is_video_frame;
+ uint64 media_packet;
int32 player_id;
-
- [EnableIf=tizen_tbm_support]
- int32 key_num;
-
- [EnableIf=tizen_tbm_support]
- array<int32, 4> key;
-
- [EnableIf=tizen_tbm_support]
- array<int32, 4> strides;
-
- [EnableIf=tizen_tbm_support]
+ TbmDestroyType tbm_destroy_type;
+ array<handle<platform>> fds;
+ int32 tbm_format;
+ array<TbmSurfacePlaneParameters> planes;
int32 width;
-
- [EnableIf=tizen_tbm_support]
int32 height;
-};
+ uint64 pts;
+ uint64 duration;
+};
\ No newline at end of file
#include "ui/gfx/mojom/buffer_types_mojom_traits.h"
+#include <algorithm>
+#include <iterator>
+
#include "build/build_config.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "mojo/public/cpp/platform/platform_handle.h"
+#include "ui/gfx/tbm_buffer_handle_inter_process.h"
+#endif
+
#if BUILDFLAG(IS_ANDROID)
#include "base/android/scoped_hardware_buffer_handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
out->offset = data.offset();
out->stride = data.stride();
#if defined(TIZEN_TBM_SUPPORT)
- out->tbm_surface = data.tbm_surface();
- out->media_packet = data.media_packet();
- out->player_id = data.player_id();
- out->key_num = data.key_num();
- out->width = data.width();
- out->height = data.height();
- base::span<int32_t> key(out->key);
- if (!data.ReadKey(&key))
+ gfx::TbmBufferHandleInterProcess tbm_buffer_handle_ip;
+ if (!data.ReadTbmBufferHandleIp(&tbm_buffer_handle_ip)) {
return false;
+ }
- base::span<int32_t> strides(out->strides);
- if (!data.ReadStrides(&strides))
- return false;
+ out->tbm_buffer_handle_ip = std::move(tbm_buffer_handle_ip);
#endif
gfx::mojom::GpuMemoryBufferPlatformHandlePtr platform_handle;
if (!data.ReadPlatformHandle(&platform_handle)) {
}
#if defined(TIZEN_TBM_SUPPORT)
-// static
-base::span<const int32_t> StructTraits<
- gfx::mojom::GpuMemoryBufferHandleDataView,
- gfx::GpuMemoryBufferHandle>::key(const gfx::GpuMemoryBufferHandle& input) {
- return input.key;
+bool StructTraits<gfx::mojom::TbmSurfacePlaneParametersDataView,
+ gfx::TbmSurfacePlaneParameters>::
+ Read(gfx::mojom::TbmSurfacePlaneParametersDataView data,
+ gfx::TbmSurfacePlaneParameters* out) {
+ out->offset = data.offset();
+ out->size = data.size();
+ out->stride = data.stride();
+
+ return true;
}
-// static
-base::span<const int32_t> StructTraits<
- gfx::mojom::GpuMemoryBufferHandleDataView,
- gfx::GpuMemoryBufferHandle>::strides(const gfx::GpuMemoryBufferHandle&
- input) {
- return input.strides;
+std::vector<mojo::PlatformHandle> StructTraits<
+ gfx::mojom::TbmBufferHandleInterProcessDataView,
+ gfx::TbmBufferHandleInterProcess>::fds(gfx::TbmBufferHandleInterProcess&
+ input) {
+ std::vector<mojo::PlatformHandle> platform_handles;
+ platform_handles.reserve(input.fds.size());
+ std::transform(std::make_move_iterator(input.fds.begin()),
+ std::make_move_iterator(input.fds.end()),
+ std::back_inserter(platform_handles), [](base::ScopedFD&& fd) {
+ return mojo::PlatformHandle(std::move(fd));
+ });
+ return platform_handles;
+}
+
+std::vector<gfx::TbmSurfacePlaneParameters> StructTraits<
+ gfx::mojom::TbmBufferHandleInterProcessDataView,
+ gfx::TbmBufferHandleInterProcess>::planes(gfx::TbmBufferHandleInterProcess&
+ input) {
+ return std::move(input.planes);
}
-bool StructTraits<gfx::mojom::TbmBufferHandleDataView, gfx::TbmBufferHandle>::
- Read(gfx::mojom::TbmBufferHandleDataView data, gfx::TbmBufferHandle* out) {
- out->tbm_surface = data.tbm_surface();
+bool StructTraits<gfx::mojom::TbmBufferHandleInterProcessDataView,
+ gfx::TbmBufferHandleInterProcess>::
+ Read(gfx::mojom::TbmBufferHandleInterProcessDataView data,
+ gfx::TbmBufferHandleInterProcess* out) {
+ out->is_video_frame = data.is_video_frame();
out->media_packet = data.media_packet();
out->player_id = data.player_id();
- out->key_num = data.key_num();
- out->width = data.width();
- out->height = data.height();
- base::span<int32_t> key(out->key);
- if (!data.ReadKey(&key))
+
+ if (!data.ReadTbmDestroyType(&out->tbm_destroy_type)) {
return false;
+ }
- base::span<int32_t> strides(out->strides);
- if (!data.ReadStrides(&strides))
+ std::vector<mojo::PlatformHandle> fds;
+ if (!data.ReadFds(&fds)) {
return false;
- return true;
-}
+ }
-// static
-base::span<const int32_t>
-StructTraits<gfx::mojom::TbmBufferHandleDataView, gfx::TbmBufferHandle>::key(
- const gfx::TbmBufferHandle& input) {
- return input.key;
-}
+ out->fds.clear();
+ out->fds.reserve(fds.size());
+ std::transform(fds.begin(), fds.end(), std::back_inserter(out->fds),
+ [](mojo::PlatformHandle& handle) { return handle.TakeFD(); });
-// static
-base::span<const int32_t>
-StructTraits<gfx::mojom::TbmBufferHandleDataView,
- gfx::TbmBufferHandle>::strides(const gfx::TbmBufferHandle& input) {
- return input.strides;
+ out->tbm_format = data.tbm_format();
+
+ std::vector<gfx::TbmSurfacePlaneParameters> planes;
+ if (!data.ReadPlanes(&planes)) {
+ return false;
+ }
+
+ out->planes = std::move(planes);
+ out->width = data.width();
+ out->height = data.height();
+ out->pts = data.pts();
+ out->duration = data.duration();
+
+ return true;
}
#endif
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "mojo/public/cpp/platform/platform_handle.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/mojom/buffer_types.mojom-shared.h"
#include "ui/gfx/mojom/native_handle_types.mojom.h"
#if defined(TIZEN_TBM_SUPPORT)
-#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h"
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h"
#endif
namespace mojo {
return handle.stride;
}
#if defined(TIZEN_TBM_SUPPORT)
- static size_t tbm_surface(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.tbm_surface;
- }
- static size_t media_packet(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.media_packet;
- }
- static int32_t player_id(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.player_id;
- }
-
- static int32_t key_num(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.key_num;
- }
- static base::span<const int32_t> key(const gfx::GpuMemoryBufferHandle& input);
- static base::span<const int32_t> strides(
- const gfx::GpuMemoryBufferHandle& input);
-
- static int32_t width(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.width;
- }
- static int32_t height(const gfx::GpuMemoryBufferHandle& handle) {
- return handle.height;
+ static gfx::TbmBufferHandleInterProcess tbm_buffer_handle_ip(
+ gfx::GpuMemoryBufferHandle& handle) {
+ return std::move(handle.tbm_buffer_handle_ip);
}
#endif
static mojo::StructPtr<gfx::mojom::GpuMemoryBufferPlatformHandle>
#if defined(TIZEN_TBM_SUPPORT)
template <>
struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
- StructTraits<gfx::mojom::TbmBufferHandleDataView, gfx::TbmBufferHandle> {
- static uint32_t tbm_surface(const gfx::TbmBufferHandle& handle) {
- return handle.tbm_surface;
+ StructTraits<gfx::mojom::TbmSurfacePlaneParametersDataView,
+ gfx::TbmSurfacePlaneParameters> {
+ static uint32_t offset(const gfx::TbmSurfacePlaneParameters& handle) {
+ return handle.offset;
+ }
+ static uint32_t size(const gfx::TbmSurfacePlaneParameters& handle) {
+ return handle.size;
+ }
+ static uint32_t stride(const gfx::TbmSurfacePlaneParameters& handle) {
+ return handle.stride;
}
- static uint32_t media_packet(const gfx::TbmBufferHandle& handle) {
+ static bool Read(gfx::mojom::TbmSurfacePlaneParametersDataView data,
+ gfx::TbmSurfacePlaneParameters* handle);
+};
+
+template <>
+struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
+ StructTraits<gfx::mojom::TbmBufferHandleInterProcessDataView,
+ gfx::TbmBufferHandleInterProcess> {
+ static bool is_video_frame(const gfx::TbmBufferHandleInterProcess& handle) {
+ return handle.is_video_frame;
+ }
+ static size_t media_packet(const gfx::TbmBufferHandleInterProcess& handle) {
return handle.media_packet;
}
- static int32_t player_id(const gfx::TbmBufferHandle& handle) {
+ static int32_t player_id(const gfx::TbmBufferHandleInterProcess& handle) {
return handle.player_id;
}
-
- static int32_t key_num(const gfx::TbmBufferHandle& handle) {
- return handle.key_num;
+ static gfx::TbmDestroyType tbm_destroy_type(
+ const gfx::TbmBufferHandleInterProcess& handle) {
+ return handle.tbm_destroy_type;
}
- static base::span<const int32_t> key(const gfx::TbmBufferHandle& input);
- static base::span<const int32_t> strides(const gfx::TbmBufferHandle& input);
-
- static int32_t width(const gfx::TbmBufferHandle& handle) {
+ static std::vector<mojo::PlatformHandle> fds(
+ gfx::TbmBufferHandleInterProcess& input);
+ static int32_t tbm_format(const gfx::TbmBufferHandleInterProcess& handle) {
+ return handle.tbm_format;
+ }
+ static std::vector<gfx::TbmSurfacePlaneParameters> planes(
+ gfx::TbmBufferHandleInterProcess& input);
+ static int32_t width(const gfx::TbmBufferHandleInterProcess& handle) {
return handle.width;
}
- static int32_t height(const gfx::TbmBufferHandle& handle) {
+ static int32_t height(const gfx::TbmBufferHandleInterProcess& handle) {
return handle.height;
}
+ static uint64_t pts(const gfx::TbmBufferHandleInterProcess& handle) {
+ return handle.pts;
+ }
+ static uint64_t duration(const gfx::TbmBufferHandleInterProcess& handle) {
+ return handle.duration;
+ }
+ static bool Read(gfx::mojom::TbmBufferHandleInterProcessDataView data,
+ gfx::TbmBufferHandleInterProcess* handle);
+};
+
+template <>
+struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
+ EnumTraits<gfx::mojom::TbmDestroyType, gfx::TbmDestroyType> {
+ static gfx::mojom::TbmDestroyType ToMojom(gfx::TbmDestroyType type) {
+ switch (type) {
+ case gfx::TbmDestroyType::kDestroyTbmByVideoFrame:
+ return gfx::mojom::TbmDestroyType::kDestroyTbmByVideoFrame;
+ case gfx::TbmDestroyType::kDestroyTbmByEgl:
+ return gfx::mojom::TbmDestroyType::kDestroyTbmByEgl;
+ }
+ NOTREACHED();
+ return gfx::mojom::TbmDestroyType::kDestroyTbmByVideoFrame;
+ }
- static bool Read(gfx::mojom::TbmBufferHandleDataView data,
- gfx::TbmBufferHandle* handle);
+ static bool FromMojom(gfx::mojom::TbmDestroyType input,
+ gfx::TbmDestroyType* out) {
+ switch (input) {
+ case gfx::mojom::TbmDestroyType::kDestroyTbmByVideoFrame:
+ *out = gfx::TbmDestroyType::kDestroyTbmByVideoFrame;
+ return true;
+ case gfx::mojom::TbmDestroyType::kDestroyTbmByEgl:
+ *out = gfx::TbmDestroyType::kDestroyTbmByEgl;
+ return true;
+ }
+ NOTREACHED();
+ return false;
+ }
};
#endif