#include "media/renderers/video_resource_updater.h"
#include "ui/gfx/color_space.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/service/display/skia_renderer.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#endif
+
namespace cc {
// static
}
VideoLayerImpl::~VideoLayerImpl() {
+#if defined(TIZEN_TBM_SUPPORT)
+ ReleaseResources();
+#endif
if (!provider_client_impl_->Stopped()) {
// In impl side painting, we may have a pending and active layer
// associated with the video provider at the same time. Both have a ref
return false;
}
+#if defined(TIZEN_TBM_SUPPORT)
+ if (frame_->IsTBMBackend()) {
+ context_provider_ = layer_tree_impl()->context_provider();
+ if (!context_provider_)
+ return false;
+ // Pass a VideoFrame reference to OnVideoCompositingFinished() callback to
+ // ensure that VideoFrame object is valid.
+ // OnVideoCompositingFinished() callback is invoked when finish to use the
+ // resource on browser process.
+ // After OnVideoCompositingFinished() is invoked, VideoFrame object can be
+ // destroyed.
+ frame_->SetContextProvider(context_provider_);
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ frame_->CreateTbmTextureIfNeeded(gl);
+ 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.sync_token, frame_->visible_rect().size(),
+ viz::RGBA_8888, false);
+ resource_id_ = resource_provider->ImportResource(
+ transferable_resource,
+ base::BindOnce(&VideoLayerImpl::OnVideoCompositingFinished,
+ base::Unretained(this), frame_));
+#if defined(_DEBUG_TBM_VIDEO_RENDERING) && _DEBUG_TBM_VIDEO_RENDERING
+ LOG(INFO) << " Video frame > "
+ << ", texture_id:" << frame_->GetTbmTexture()
+ << ", resource_id:" << resource_id_
+ << ", size:" << frame_->visible_rect().size().ToString();
+#endif
+
+#if defined(_DEBUG_TBM_VIDEO_RENDERING_FPS) && _DEBUG_TBM_VIDEO_RENDERING_FPS
+ static media::VideoFrame* prev_frame = 0;
+ static int new_frame_cnt = 0;
+ static int frame_cnt = 0;
+ static base::TimeTicks last_tick = base::TimeTicks::Now();
+ const base::TimeTicks now = base::TimeTicks::Now();
+ const base::TimeDelta interval = now - last_tick;
+
+ if (prev_frame != frame_.get())
+ new_frame_cnt++;
+ prev_frame = frame_.get();
+ frame_cnt++;
+ if (interval >= base::TimeDelta::FromSeconds(1)) {
+ printf("VideoTBM[Draw] > [FPS]%.1f/%.1f\n",
+ new_frame_cnt / interval.InSecondsF(),
+ frame_cnt / interval.InSecondsF());
+ LOG(INFO) << "VideoTBM[Draw] > [FPS]"
+ << (new_frame_cnt / interval.InSecondsF()) << "/"
+ << (frame_cnt / interval.InSecondsF());
+ last_tick = now;
+ frame_cnt = 0;
+ new_frame_cnt = 0;
+ }
+#endif
+ }
+#endif
+
if (!updater_) {
const LayerTreeSettings& settings = layer_tree_impl()->settings();
// TODO(sergeyu): Pass RasterContextProvider when it's available. Then
settings.resource_settings.use_r16_texture,
layer_tree_impl()->max_texture_size());
}
+#if defined(TIZEN_TBM_SUPPORT)
+ updater_->ObtainFrameResources(frame_, resource_id_);
+#else
updater_->ObtainFrameResources(frame_);
+#endif
return true;
}
provider_client_impl_->ReleaseLock();
}
+#if defined(TIZEN_TBM_SUPPORT)
+void VideoLayerImpl::OnVideoCompositingFinished(
+ const scoped_refptr<media::VideoFrame> video_frame,
+ const gpu::SyncToken& sync_token,
+ bool lost_resource) {
+#if defined(USE_TTRACE)
+ TTRACE_WEB("VideoLayerImpl::OnVideoCompositingFinished");
+#endif
+#if defined(_DEBUG_TBM_VIDEO_RENDERING) && _DEBUG_TBM_VIDEO_RENDERING
+ LOG(INFO)
+ << "OnVideoCompositingFinished > resource was removed in ResourceProvider"
+ << ", tbm:" << video_frame->GetTbmBuffer().tbm_surface
+ << ", txt:" << video_frame->GetTbmTexture();
+#endif
+}
+#endif
+
SimpleEnclosedRegion VideoLayerImpl::VisibleOpaqueRegion() const {
// If we don't have a frame yet, then we don't have an opaque region.
if (!provider_client_impl_->HasCurrentFrame())
}
void VideoLayerImpl::ReleaseResources() {
+#if defined(TIZEN_TBM_SUPPORT)
+ scoped_refptr<media::VideoFrame> last_frame = frame_;
+ if (!frame_)
+ last_frame = provider_client_impl_->AcquireLockAndCurrentFrame();
+ if (last_frame)
+ last_frame->ReleaseTbm();
+ last_frame = nullptr;
+ if (!frame_)
+ provider_client_impl_->ReleaseLock();
+#endif
updater_ = nullptr;
}
#include "components/viz/common/resources/release_callback.h"
#include "media/base/video_transformation.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "components/viz/common/gpu/context_provider.h"
+#endif
+
namespace media {
class VideoFrame;
class VideoResourceUpdater;
const char* LayerTypeAsString() const override;
+#if defined(TIZEN_TBM_SUPPORT)
+ void OnVideoCompositingFinished(
+ const scoped_refptr<media::VideoFrame> video_frame,
+ const gpu::SyncToken& sync_token,
+ bool lost_resource);
+#endif
+
scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl_;
scoped_refptr<media::VideoFrame> frame_;
media::VideoTransformation video_transform_;
+#if defined(TIZEN_TBM_SUPPORT)
+ scoped_refptr<viz::ContextProvider> context_provider_;
+ viz::ResourceId resource_id_;
+#endif
+
std::unique_ptr<media::VideoResourceUpdater> updater_;
};
CASE_RETURN_OTHER(PIXEL_FORMAT_P016LE);
CASE_RETURN_OTHER(PIXEL_FORMAT_XR30);
CASE_RETURN_OTHER(PIXEL_FORMAT_XB30);
+#if defined(TIZEN_TBM_SUPPORT)
+ CASE_RETURN_OTHER(PIXEL_FORMAT_TBM_SURFACE);
+#endif
// PIXEL_FORMAT_UYVY, PIXEL_FORMAT_RGB32 and PIXEL_FORMAT_Y8 are deprecated.
case openscreen::cast::VideoDecoderConfig_Format_PIXEL_FORMAT_RGB32:
return absl::nullopt;
return true;
}
return base::FeatureList::IsEnabled(kUseSurfaceLayerForVideoDefault);
+#elif defined(TIZEN_MULTIMEDIA)
+ return false;
#else
return true;
#endif
.status_values[gpu::GPU_FEATURE_TYPE_CANVAS_OOP_RASTERIZATION] ==
gpu::kGpuFeatureStatusEnabled;
bool support_gles2_interface = false;
+#if defined(TIZEN_TBM_SUPPORT)
+ support_gles2_interface = true;
+#endif
bool support_grcontext = !support_oop_rasterization;
// Enable automatic flushes to improve canvas throughput.
// See https://crbug.com/880901
#define glCoverageModulationCHROMIUM GLES2_GET_FUN(CoverageModulationCHROMIUM)
#define glGetGraphicsResetStatusKHR GLES2_GET_FUN(GetGraphicsResetStatusKHR)
#define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR)
+#define glCreateTizenImageCHROMIUM GLES2_GET_FUN(CreateTizenImageCHROMIUM)
+#define glDestroyTizenImageCHROMIUM GLES2_GET_FUN(DestroyTizenImageCHROMIUM)
#define glBindFragDataLocationIndexedEXT \
GLES2_GET_FUN(BindFragDataLocationIndexedEXT)
#define glBindFragDataLocationEXT GLES2_GET_FUN(BindFragDataLocationEXT)
'extension': True,
'trace_level': 2,
},
+ 'CreateTizenImageCHROMIUM': {
+ 'type': 'NoCommand',
+ 'cmd_args':'gfx::TbmBufferHandle handle, GLsizei width,'
+ ' GLsizei height, GLenum internalformat',
+ 'result': ['GLuint'],
+ 'extension': True,
+ },
+ 'DestroyTizenImageCHROMIUM': {
+ 'type': 'NoCommand',
+ 'extension': True,
+ },
'InitializeDiscardableTextureCHROMIUM': {
'type': 'Custom',
'cmd_args': 'GLuint texture_id, uint32_t shm_id, '
void GL_APIENTRY GLES2BlendBarrierKHR() {
gles2::GetGLContext()->BlendBarrierKHR();
}
+GLuint GL_APIENTRY GLES2CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) {
+ return gles2::GetGLContext()->CreateTizenImageCHROMIUM(handle, width, height,
+ internalformat);
+}
+void GL_APIENTRY GLES2DestroyTizenImageCHROMIUM(GLuint image_id) {
+ gles2::GetGLContext()->DestroyTizenImageCHROMIUM(image_id);
+}
void GL_APIENTRY GLES2BindFragDataLocationIndexedEXT(GLuint program,
GLuint colorNumber,
GLuint index,
"glBlendBarrierKHR",
reinterpret_cast<GLES2FunctionPointer>(glBlendBarrierKHR),
},
+ {
+ "glCreateTizenImageCHROMIUM",
+ reinterpret_cast<GLES2FunctionPointer>(glCreateTizenImageCHROMIUM),
+ },
+ {
+ "glDestroyTizenImageCHROMIUM",
+ reinterpret_cast<GLES2FunctionPointer>(glDestroyTizenImageCHROMIUM),
+ },
{
"glBindFragDataLocationIndexedEXT",
reinterpret_cast<GLES2FunctionPointer>(
!ptr || \
(ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));
+#if defined(TIZEN_TBM_SUPPORT)
+#include "base/logging.h"
+#endif
+
namespace gpu {
namespace gles2 {
aggressively_free_resources_(false),
cached_extension_string_(nullptr) {
DCHECK(helper);
-
+#if defined(TIZEN_TBM_SUPPORT)
+ LOG(INFO) << __FUNCTION__ << " " << this;
+#endif
std::stringstream ss;
ss << std::hex << this;
this_in_hex_ = ss.str();
// shared memory (mapped_memory_) which will free the memory used
// by the queries. The GPU process when validating that memory is still
// shared will fail and abort (ie, it will stop running).
+#if defined(TIZEN_TBM_SUPPORT)
+ LOG(INFO) << __FUNCTION__ << " " << this;
+#endif
WaitForCmd();
query_tracker_.reset();
return false;
}
+#if defined(TIZEN_TBM_SUPPORT)
+GLuint GLES2Implementation::CreateTizenImageCHROMIUMHelper(
+ gfx::TbmBufferHandle buffer_handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) {
+ if (width <= 0) {
+ SetGLError(GL_INVALID_VALUE, "glCreateTizenImageCHROMIUM", "width <= 0");
+ return 0;
+ }
+
+ if (height <= 0) {
+ SetGLError(GL_INVALID_VALUE, "glCreateTizenImageCHROMIUM", "height <= 0");
+ return 0;
+ }
+
+ int32_t image_id = gpu_control_->CreateEGLImage(buffer_handle, width, height,
+ internalformat);
+ if (image_id < 0) {
+ SetGLError(GL_OUT_OF_MEMORY, "glCreateTizenImageCHROMIUM", "image_id < 0");
+ return 0;
+ }
+ return image_id;
+}
+#endif
+
+GLuint GLES2Implementation::CreateTizenImageCHROMIUM(
+ gfx::TbmBufferHandle buffer_handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG(
+ "[" << GetLogPrefix() << "] glCreateTizenImageCHROMIUM(" << buffer_handle
+ << ", " << width << ", " << height << ", "
+ << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")");
+#if defined(TIZEN_TBM_SUPPORT)
+ GLuint image_id = CreateTizenImageCHROMIUMHelper(buffer_handle, width, height,
+ internalformat);
+ CheckGLError();
+ return image_id;
+#else
+ return 0;
+#endif
+}
+
+void GLES2Implementation::DestroyTizenImageCHROMIUM(GLuint image_id) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyTizenImageCHROMIUM("
+ << image_id << ")");
+#if defined(TIZEN_TBM_SUPPORT)
+ // Flush the command stream to make sure all pending commands
+ // that may refer to the image_id are executed on the service side.
+ helper_->CommandBufferHelper::Flush();
+ gpu_control_->DestroyEGLImage(image_id);
+ CheckGLError();
+#endif
+}
+
bool GLES2Implementation::ValidateSize(const char* func, GLsizeiptr size) {
if (size < 0) {
SetGLError(GL_INVALID_VALUE, func, "size < 0");
const GLuint* baseInstances,
GLsizei drawcount);
+#if defined(TIZEN_TBM_SUPPORT)
+ GLuint CreateTizenImageCHROMIUMHelper(gfx::TbmBufferHandle buffer_handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat);
+#endif
+
// Helper for GetVertexAttrib
bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32_t* param);
void BlendBarrierKHR() override;
+GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) override;
+
+void DestroyTizenImageCHROMIUM(GLuint image_id) override;
+
void BindFragDataLocationIndexedEXT(GLuint program,
GLuint colorNumber,
GLuint index,
#include "base/compiler_specific.h"
#include "gpu/command_buffer/client/interface_base.h"
+#include "ui/gfx/tbm_buffer_handle.h"
namespace cc {
class ClientTransferCacheEntry;
virtual void CoverageModulationCHROMIUM(GLenum components) = 0;
virtual GLenum GetGraphicsResetStatusKHR() = 0;
virtual void BlendBarrierKHR() = 0;
+virtual GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) = 0;
+virtual void DestroyTizenImageCHROMIUM(GLuint image_id) = 0;
virtual void BindFragDataLocationIndexedEXT(GLuint program,
GLuint colorNumber,
GLuint index,
void CoverageModulationCHROMIUM(GLenum components) override;
GLenum GetGraphicsResetStatusKHR() override;
void BlendBarrierKHR() override;
+GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) override;
+void DestroyTizenImageCHROMIUM(GLuint image_id) override;
void BindFragDataLocationIndexedEXT(GLuint program,
GLuint colorNumber,
GLuint index,
return 0;
}
void GLES2InterfaceStub::BlendBarrierKHR() {}
+GLuint GLES2InterfaceStub::CreateTizenImageCHROMIUM(
+ gfx::TbmBufferHandle /* handle */,
+ GLsizei /* width */,
+ GLsizei /* height */,
+ GLenum /* internalformat */) {
+ return 0;
+}
+void GLES2InterfaceStub::DestroyTizenImageCHROMIUM(GLuint /* image_id */) {}
void GLES2InterfaceStub::BindFragDataLocationIndexedEXT(
GLuint /* program */,
GLuint /* colorNumber */,
void CoverageModulationCHROMIUM(GLenum components) override;
GLenum GetGraphicsResetStatusKHR() override;
void BlendBarrierKHR() override;
+GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) override;
+void DestroyTizenImageCHROMIUM(GLuint image_id) override;
void BindFragDataLocationIndexedEXT(GLuint program,
GLuint colorNumber,
GLuint index,
gl_->BlendBarrierKHR();
}
+GLuint GLES2TraceImplementation::CreateTizenImageCHROMIUM(
+ gfx::TbmBufferHandle handle,
+ GLsizei width,
+ GLsizei height,
+ GLenum internalformat) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateTizenImageCHROMIUM");
+ return gl_->CreateTizenImageCHROMIUM(handle, width, height, internalformat);
+}
+
+void GLES2TraceImplementation::DestroyTizenImageCHROMIUM(GLuint image_id) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DestroyTizenImageCHROMIUM");
+ gl_->DestroyTizenImageCHROMIUM(image_id);
+}
+
void GLES2TraceImplementation::BindFragDataLocationIndexedEXT(
GLuint program,
GLuint colorNumber,
#include "gpu/gpu_export.h"
#include "ui/gfx/overlay_transform.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/gfx/tbm_buffer_handle.h"
+#endif
+
extern "C" typedef struct _ClientBuffer* ClientBuffer;
extern "C" typedef struct _ClientGpuFence* ClientGpuFence;
virtual const Capabilities& GetCapabilities() const = 0;
+#if defined(TIZEN_TBM_SUPPORT)
+ virtual int32_t CreateEGLImage(gfx::TbmBufferHandle buffer_handle,
+ size_t width,
+ size_t height,
+ unsigned internalformat) {
+ return -1;
+ }
+ virtual void DestroyEGLImage(int32_t image_id) {}
+#endif
+
// Runs |callback| when a query created via glCreateQueryEXT() has cleared
// passed the glEndQueryEXT() point.
virtual void SignalQuery(uint32_t query, base::OnceClosure callback) = 0;
// Extension KHR_blend_equation_advanced
GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void);
+// for tizen
+GL_APICALL GLuint GL_APIENTRY glCreateTizenImageCHROMIUM (gfx::TbmBufferHandle handle, GLsizei width, GLsizei height, GLenum internalformat);
+GL_APICALL void GL_APIENTRY glDestroyTizenImageCHROMIUM (GLuint image_id);
+
// Extension EXT_blend_func_extended
GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLidProgram program, GLuint colorNumber, GLuint index, const char* name);
GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLidProgram program, GLuint colorNumber, const char* name);
return 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;
SurfaceHandle surface_handle) {
if (handle.type != gfx::NATIVE_PIXMAP)
return nullptr;
-
+#if defined(TIZEN_TBM_SUPPORT)
+ scoped_refptr<gl::GLImageNativePixmap> image(
+ new gl::GLImageNativePixmap(size, format));
+ if (!image->Initialize(handle)) {
+ LOG(ERROR) << "Failed to create GLImage";
+ return nullptr;
+ }
+ return image;
+#else
scoped_refptr<gfx::NativePixmap> pixmap;
// If CreateGpuMemoryBuffer was used to allocate this buffer then avoid
NOTREACHED();
return nullptr;
}
+#endif
}
bool GpuMemoryBufferFactoryNativePixmap::SupportsCreateAnonymousImage() const {
#if BUILDFLAG(IS_MAC)
#include "ui/gfx/mac/io_surface.h"
#endif
+#if defined(TIZEN_TBM_SUPPORT)
+#include "base/threading/thread_task_runner_handle.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"
+#endif
namespace media {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
case VideoFrame::STORAGE_DMABUFS:
return "DMABUFS";
+#endif
+#if defined(TIZEN_TBM_SUPPORT)
+ case VideoFrame::STORAGE_TBM_SURFACE:
+ return "TBM_SURFACE";
#endif
case VideoFrame::STORAGE_GPU_MEMORY_BUFFER:
return "GPU_MEMORY_BUFFER";
case PIXEL_FORMAT_XB30:
case PIXEL_FORMAT_BGRA:
case PIXEL_FORMAT_RGBAF16:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
break;
}
}
case PIXEL_FORMAT_XB30:
case PIXEL_FORMAT_BGRA:
case PIXEL_FORMAT_RGBAF16:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
return false;
case PIXEL_FORMAT_NV12:
case PIXEL_FORMAT_NV21:
timestamp, true);
}
+// static
+#if defined(TIZEN_TBM_SUPPORT)
+scoped_refptr<VideoFrame> VideoFrame::WrapTBMSurface(
+ const gfx::Size& size,
+ base::TimeDelta timestamp,
+ gfx::TbmBufferHandle handle) {
+ const VideoPixelFormat format = PIXEL_FORMAT_TBM_SURFACE;
+ const StorageType storage = STORAGE_TBM_SURFACE;
+ const gfx::Rect visible_rect = gfx::Rect(size);
+ if (!IsValidConfig(format, storage, size, visible_rect, size)) {
+ LOG(ERROR) << __FUNCTION__ << " WrapTBMSurface Invalid config."
+ << ConfigToString(format, storage, size, visible_rect, size);
+ return nullptr;
+ }
+
+ auto layout = VideoFrameLayout::Create(format, size);
+ if (!layout) {
+ LOG(ERROR) << "Invalid layout.";
+ return nullptr;
+ }
+
+ scoped_refptr<VideoFrame> frame(
+ new VideoFrame(*layout, storage, gfx::Rect(size), size, timestamp));
+ frame->buffer_handle_ = handle;
+ return frame;
+}
+#endif
+
// static
scoped_refptr<VideoFrame> VideoFrame::WrapNativeTextures(
VideoPixelFormat format,
return 1;
case PIXEL_FORMAT_MJPEG:
return 0;
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
case PIXEL_FORMAT_UNKNOWN:
break;
}
const gpu::MailboxHolder& VideoFrame::mailbox_holder(
size_t texture_index) const {
+#if defined(TIZEN_TBM_SUPPORT)
+ DCHECK(IsTBMBackend() || HasTextures());
+#else
DCHECK(HasTextures());
+#endif
DCHECK(IsValidPlane(format(), texture_index));
return wrapped_frame_ ? wrapped_frame_->mailbox_holder(texture_index)
: mailbox_holders_[texture_index];
}
gpu::SyncToken VideoFrame::UpdateReleaseSyncToken(SyncTokenClient* client) {
+#if defined(TIZEN_TBM_SUPPORT)
+ DCHECK(IsTBMBackend() || HasTextures());
+#else
DCHECK(HasTextures());
+#endif
if (wrapped_frame_) {
return wrapped_frame_->UpdateReleaseSyncToken(client);
}
natural_size_(natural_size),
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
dmabuf_fds_(base::MakeRefCounted<DmabufHolder>()),
+#endif
+#if defined(TIZEN_TBM_SUPPORT)
+ texture_id_(0),
+ gl_(nullptr),
+ image_id_(0),
#endif
timestamp_(timestamp),
unique_id_(g_unique_id_generator.GetNext()) {
return plane_size;
}
+#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) {
+#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);
+ }
+ 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_));
+ }
+}
+
+unsigned VideoFrame::CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl) {
+#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_));
+ return texture_id_;
+}
+#endif
+
} // namespace media
struct GpuMemoryBufferHandle;
}
+#if defined(TIZEN_TBM_SUPPORT)
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#include "components/viz/common/gpu/context_provider.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 {
+constexpr auto TBM_BO_NUM_MAX = 4;
+
class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
public:
static constexpr size_t kFrameSizeAlignment = 16;
STORAGE_DMABUFS = 5, // Each plane is stored into a DmaBuf.
#endif
STORAGE_GPU_MEMORY_BUFFER = 6,
+#if defined(TIZEN_TBM_SUPPORT)
+ STORAGE_TBM_SURFACE = 7,
+ STORAGE_MAX = STORAGE_TBM_SURFACE,
+#else
STORAGE_MAX = STORAGE_GPU_MEMORY_BUFFER,
+#endif
};
// CB to be called on the mailbox backing this frame and its GpuMemoryBuffers
const gfx::Rect& visible_rect,
const gfx::Size& natural_size);
+#if defined(TIZEN_TBM_SUPPORT)
+ // Needed when we have video-frame content in tbm surface.
+ static scoped_refptr<VideoFrame> WrapTBMSurface(const gfx::Size& size,
+ base::TimeDelta timestamp,
+ gfx::TbmBufferHandle handle);
+ bool IsTBMBackend() const { return storage_type_ == STORAGE_TBM_SURFACE; }
+ unsigned GetTbmTexture() { return texture_id_; }
+ unsigned CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl);
+ 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) {
+ context_provider_ = context_provider;
+ }
+#endif
+
// Creates a frame which indicates end-of-stream.
static scoped_refptr<VideoFrame> CreateEOSFrame();
std::vector<base::OnceClosure> done_callbacks_;
+#if defined(TIZEN_TBM_SUPPORT)
+ base::Lock tbm_lock_;
+ 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_;
+#endif
+
base::TimeDelta timestamp_;
base::Lock release_sync_token_lock_;
case PIXEL_FORMAT_UNKNOWN:
// Note: PIXEL_FORMAT_UNKNOWN is used for end-of-stream frame.
// Set its NumPlanes() to zero to avoid NOTREACHED().
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
return 0;
}
NOTREACHED() << "Unsupported video frame format: " << format;
return "PIXEL_FORMAT_YUV422AP10";
case PIXEL_FORMAT_YUV444AP10:
return "PIXEL_FORMAT_YUV444AP10";
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+ return "PIXEL_FORMAT_TBM_SURFACE";
+#endif
}
NOTREACHED() << "Invalid VideoPixelFormat provided: " << format;
return "";
case PIXEL_FORMAT_XB30:
case PIXEL_FORMAT_BGRA:
case PIXEL_FORMAT_RGBAF16:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
return false;
}
return false;
case PIXEL_FORMAT_P016LE:
case PIXEL_FORMAT_XR30:
case PIXEL_FORMAT_XB30:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
return true;
case PIXEL_FORMAT_I420A:
case PIXEL_FORMAT_ARGB:
size_t BitDepth(VideoPixelFormat format) {
switch (format) {
case PIXEL_FORMAT_UNKNOWN:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
NOTREACHED();
[[fallthrough]];
case PIXEL_FORMAT_I420:
PIXEL_FORMAT_YUV422AP10 = 37,
PIXEL_FORMAT_YUV444AP10 = 38,
- // Please update UMA histogram enumeration when adding new formats here.
+// Please update UMA histogram enumeration when adding new formats here.
+#if defined(TIZEN_TBM_SUPPORT)
+ PIXEL_FORMAT_TBM_SURFACE = 39,
+ PIXEL_FORMAT_MAX = PIXEL_FORMAT_TBM_SURFACE,
+#else
PIXEL_FORMAT_MAX =
PIXEL_FORMAT_YUV444AP10, // Must always be equal to largest entry logged.
+#endif
};
// These values are persisted to logs. Entries should not be renumbered and
import("//mojo/public/tools/bindings/mojom.gni")
+if (use_aura) {
+ import("//tizen_src/build/config/tizen_features.gni")
+}
+
+enabled_features = []
+if (tizen_tbm_support) {
+ enabled_features += [ "tizen_tbm_support" ]
+}
+
mojom("video_capture") {
generate_java = true
sources = [ "video_capture.mojom" ]
[MinVersion=1] YUV420AP10,
[MinVersion=1] YUV422AP10,
[MinVersion=1] YUV444AP10,
+
+ [EnableIf=tizen_tbm_support]
+ TBM_SURFACE,
};
[Stable, Extensible]
return media::mojom::VideoCapturePixelFormat::YUV422AP10;
case media::VideoPixelFormat::PIXEL_FORMAT_YUV444AP10:
return media::mojom::VideoCapturePixelFormat::YUV444AP10;
+#if defined(TIZEN_TBM_SUPPORT)
+ case media::VideoPixelFormat::PIXEL_FORMAT_TBM_SURFACE:
+ return media::mojom::VideoCapturePixelFormat::TBM_SURFACE;
+#endif
}
NOTREACHED();
return media::mojom::VideoCapturePixelFormat::I420;
case media::mojom::VideoCapturePixelFormat::YUV444AP10:
*output = media::PIXEL_FORMAT_YUV444AP10;
return true;
+#if defined(TIZEN_TBM_SUPPORT)
+ case media::mojom::VideoCapturePixelFormat::TBM_SURFACE:
+ *output = media::PIXEL_FORMAT_TBM_SURFACE;
+ return true;
+#endif
}
NOTREACHED();
return false;
import "mojo/public/mojom/base/shared_memory.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
+import "ui/gfx/mojom/buffer_types.mojom";
[EnableIf=is_win]
import "ui/gfx/mojom/buffer_types.mojom";
mojo_base.mojom.TimeDelta timestamp,
uint32 width,
uint32 height);
+
+ [EnableIf=tizen_multimedia]
+ OnNewTbmFrameAvailable(uint32 playerId,
+ gfx.mojom.TbmBufferHandle tbm_buffer_handle,
+ mojo_base.mojom.TimeDelta timestamp);
};
// Extension of the mojo::Renderer communication layer for HLS and Android
// StreamTexture's set-up.
InitiateScopedSurfaceRequest()
=> (mojo_base.mojom.UnguessableToken request_token);
+
+ [EnableIf=tizen_multimedia]
+ OnTbmBufferExhausted(gfx.mojom.TbmBufferHandle tbm_buffer_handle);
};
// Extension of the mojo::RendererClient communication layer for media flinging,
if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
!(media::IsYuvPlanar(video_frame->format()) ||
video_frame->format() == PIXEL_FORMAT_Y16 ||
+#if defined(TIZEN_TBM_SUPPORT)
+ video_frame->IsTBMBackend() ||
+#endif
video_frame->format() == PIXEL_FORMAT_ARGB ||
video_frame->format() == PIXEL_FORMAT_XRGB ||
video_frame->format() == PIXEL_FORMAT_ABGR ||
// |video_frame| is software.
// Holding |video_frame| longer than this call when using GPUVideoDecoder
// could cause problems since the pool of VideoFrames has a fixed size.
- if (video_frame->HasTextures()) {
+ if (video_frame->HasTextures()
+#if defined(TIZEN_TBM_SUPPORT)
+ && !video_frame->IsTBMBackend()
+#endif
+ ) {
DCHECK(raster_context_provider);
bool supports_oop_raster =
raster_context_provider->ContextCapabilities().supports_oop_raster;
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();
case PIXEL_FORMAT_YUV422AP10:
case PIXEL_FORMAT_YUV444AP10:
case PIXEL_FORMAT_UNKNOWN:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
break;
}
return VideoFrameResourceType::NONE;
}
void VideoResourceUpdater::ObtainFrameResources(
- scoped_refptr<VideoFrame> video_frame) {
+ scoped_refptr<VideoFrame> video_frame,
+ 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_type_ = VideoFrameResourceType::RGBA;
+ return;
+ }
+#endif
if (video_frame->metadata().overlay_plane_id.has_value()) {
// This is a hole punching VideoFrame, there is nothing to display.
overlay_plane_id_ = *video_frame->metadata().overlay_plane_id;
// 2. AppendQuads(): Add DrawQuads to CompositorFrame for video.
// 3. ReleaseFrameResources(): After the CompositorFrame has been submitted,
// remove imported resources from viz::ClientResourceProvider.
- void ObtainFrameResources(scoped_refptr<VideoFrame> video_frame);
+ void ObtainFrameResources(
+ scoped_refptr<VideoFrame> video_frame,
+ viz::ResourceId resource_id = viz::kInvalidResourceId);
void ReleaseFrameResources();
// Appends a quad representing |frame| to |render_pass|.
// At most one quad is expected to be appended, this is enforced by the users
case PIXEL_FORMAT_YUV422AP10:
case PIXEL_FORMAT_YUV444AP10:
case PIXEL_FORMAT_UNKNOWN:
+#if defined(TIZEN_TBM_SUPPORT)
+ case PIXEL_FORMAT_TBM_SURFACE:
+#endif
if (is_software_backed_video_frame) {
UMA_HISTOGRAM_ENUMERATION(
"Media.GpuMemoryBufferVideoFramePool.UnsupportedFormat",
# found in the LICENSE file.
import("//build/config/chromeos/ui_mode.gni")
import("//mojo/public/tools/bindings/mojom.gni")
+
+if (use_efl) {
+ import("//tizen_src/build/config/tizen_features.gni")
+}
+
mojom("mojom") {
generate_java = true
sources = [
]
},
]
+
+ enabled_features = []
+ if (tizen_tbm_support) {
+ enabled_features += [ "tizen_tbm_support" ]
+ }
}
mojom("resource_format") {
generate_java = true
PIXEL_FORMAT_P016LE = 29;
PIXEL_FORMAT_XR30 = 30;
PIXEL_FORMAT_XB30 = 31;
+ PIXEL_FORMAT_TBM_SURFACE = 32;
};
// Proto version of Chrome's media::ColorSpace.
defines += [ "EFL_BETA_API_SUPPORT" ]
}
}
- if (tizen_tbm_support) {
- defines += [ "TIZEN_TBM_SUPPORT" ]
- }
if (ewk_bringup) {
defines += [ "EWK_BRINGUP" ]
}
if (use_wayland) {
defines += [ "USE_WAYLAND" ]
}
+ if (tizen_tbm_support) {
+ defines += [ "TIZEN_TBM_SUPPORT" ]
+ }
if (tizen_multimedia_support) {
defines += [
"TIZEN_MULTIMEDIA_SUPPORT",
ADDITIONAL_GN_PARAMETERS+="tizen_multimedia=true
proprietary_codecs=true
tizen_web_speech_recognition=true
- tizen_tbm_support=false
+ tizen_tbm_support=true
"
}
]
}
-if (tizen_tbm_support) {
- external_content_browser_efl_sources += [
- "//tizen_src/chromium_impl/content/browser/media/browser_mediapacket_manager.cc",
- "//tizen_src/chromium_impl/content/browser/media/browser_mediapacket_manager.h",
- ]
-}
-
if (tizen_web_speech_recognition) {
external_content_browser_efl_sources += [
"//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc",
#include "tizen_src/chromium_impl/content/browser/media/media_player_renderer_web_contents_observer.h"
#include "tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h"
#include "tizen_src/chromium_impl/media/filters/media_player_esplusplayer.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)
+namespace media {
+void DestroyMediaPacket(void* media_packet, int player_id) {
+ MediaPlayerTizen* player =
+ MediaPlayerRegistry::GetInstance()->GetMediaPlayer(player_id);
+ if (!player) {
+ // TODO: All media packets should be removed before player is destroyed.
+ LOG(WARNING) << __func__
+ << " player already destroyed. player_id: " << player_id;
+ return;
+ }
+ player->DestroyMediaPacket(media_packet);
+}
+} // namespace media
+#endif
namespace content {
class TizenRendererImpl::RendererClientInternal final
renderer_->OnBufferUpdate(time);
}
+#if defined(TIZEN_TBM_SUPPORT)
+ void OnNewTbmFrameAvailable(uint32_t player_id,
+ const gfx::TbmBufferHandle& tbm_handle,
+ base::TimeDelta timestamp) override {
+ DCHECK(type_ == media::DemuxerStream::VIDEO);
+ renderer_->OnNewTbmFrameAvailable(player_id, tbm_handle, timestamp);
+ }
+#else
void OnNewFrameAvailable(uint32_t playerId,
base::UnsafeSharedMemoryRegion frame,
uint32_t size,
renderer_->OnNewFrameAvailable(playerId, std::move(frame), size, timestamp,
width, height);
}
+#endif
private:
media::DemuxerStream::Type type_;
media::DemuxerStream::VIDEO, this);
GetPlayer()->SetStreamInfo(media::DemuxerStream::VIDEO, video_stream_,
video_renderer_client_.get());
-
+#if defined(TIZEN_TBM_SUPPORT)
+ media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer()
+ ->SetFrameAvailableCallback(
+ base::BindRepeating(&TizenRendererImpl::OnNewTbmFrameAvailable,
+ base::Unretained(this)));
+#else
// Will be removed later by using |ClientExtention| interface.
media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer()
->SetFrameAvailableCallback(base::BindRepeating(
&TizenRendererImpl::OnNewFrameAvailable, base::Unretained(this)));
+#endif
}
}
client_extension_->OnBufferUpdate(time);
}
+#if defined(TIZEN_TBM_SUPPORT)
+void TizenRendererImpl::OnNewTbmFrameAvailable(uint32_t player_id,
+ gfx::TbmBufferHandle tbm_handle,
+ base::TimeDelta timestamp) {
+ client_extension_->OnNewTbmFrameAvailable(player_id, tbm_handle, timestamp);
+}
+
+void TizenRendererImpl::OnTbmBufferExhausted(
+ const gfx::TbmBufferHandle& tbm_handle) {
+ media_player_->DestroyMediaPacket(
+ reinterpret_cast<void*>(tbm_handle.media_packet));
+}
+#endif
+
} // namespace content
uint32_t width,
uint32_t height);
+#if defined(TIZEN_TBM_SUPPORT)
+ void OnNewTbmFrameAvailable(uint32_t player_id,
+ gfx::TbmBufferHandle tbm_handle,
+ base::TimeDelta timestamp);
+ void OnTbmBufferExhausted(const gfx::TbmBufferHandle& tbm_handle) override;
+#endif
+
private:
class RendererClientInternal;
const float kDefaultVolume = 1.0;
}
#endif
+#if defined(TIZEN_TBM_SUPPORT)
+void MediaPlayerRendererClient::OnTbmBufferExhausted(
+ media::VideoFrame* video_frame,
+ void* media_packet,
+ int player_id) {
+ 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);
+}
+
+void MediaPlayerRendererClient::OnNewTbmFrameAvailable(
+ uint32_t playerId,
+ const gfx::TbmBufferHandle& tbm_buffer_handle,
+ base::TimeDelta timestamp) {
+ 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);
+ video_frame->AddDestructionObserver(base::BindOnce(
+ &MediaPlayerRendererClient::OnTbmBufferExhausted,
+ weak_factory_.GetWeakPtr(), base::Unretained(video_frame.get()),
+ const_cast<void*>((const void*)tbm_buffer_handle.media_packet),
+ tbm_buffer_handle.player_id));
+
+ sink_->PaintSingleFrame(std::move(video_frame));
+}
+#endif
+
} // namespace content
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h"
+#endif
+
namespace content {
// MediaPlayerRendererClient lives in Renderer process and mirrors a
base::TimeDelta timestamp,
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);
+#endif
private:
void OnRemoteRendererInitialized(media::PipelineStatus status);
#include "base/logging.h"
#include "media/base/renderer_client.h"
#include "media/base/tizen/media_player_bridge_capi.h"
+#include "tizen_src/chromium_impl/media/filters/media_player_registry.h"
namespace media {
MediaPlayerBridgeCapiAdapter::MediaPlayerBridgeCapiAdapter(const GURL& url,
double volume)
- : url_(url), volume_(volume) {}
+ : url_(url), volume_(volume) {
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this);
+}
-MediaPlayerBridgeCapiAdapter::~MediaPlayerBridgeCapiAdapter() {}
+MediaPlayerBridgeCapiAdapter::~MediaPlayerBridgeCapiAdapter() {
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ MediaPlayerRegistry::GetInstance()->UnregisterMediaPlayer(player_id_);
+}
bool MediaPlayerBridgeCapiAdapter::CreatePlayer() {
if (media_player_)
void* media_packet = reinterpret_cast<void*>(tbm_handle.media_packet);
tbm_handle.media_packet = reinterpret_cast<uint64_t>(media_packet);
- tbm_handle.player_handle = reinterpret_cast<uint64_t>(this);
+ tbm_handle.player_id = player_id_;
tbm_handle.width = width_;
tbm_handle.height = height_;
bool is_initialized_ = false;
bool is_prepared_ = false;
+ int player_id_ = 0;
+
int width_ = 0;
int height_ = 0;
};
#include "media/base/decoder_buffer.h"
#include "media/base/renderer_client.h"
#include "third_party/libyuv/include/libyuv/convert.h"
+#include "tizen_src/chromium_impl/media/filters/media_player_registry.h"
namespace media {
using player_buffer_size_t = unsigned long long;
LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
weak_factory_.InvalidateWeakPtrs();
+ MediaPlayerRegistry::GetInstance()->UnregisterMediaPlayer(player_id_);
+
int error = esplusplayer_destroy(esplayer_);
if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
LOG(ERROR) << "esplusplayer_destroy failed, error #"
return;
}
+ player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this);
+
LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
<< " state:" << GetString(GetPlayerState());
return current_position_;
}
+#if defined(TIZEN_TBM_SUPPORT)
+void MediaPlayerESPlusPlayer::DestroyMediaPacket(void* media_packet) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::DestroyMediaPacket,
+ weak_factory_.GetWeakPtr(), media_packet));
+ return;
+ }
+
+ esplusplayer_decoded_buffer_destroy(
+ esplayer_, static_cast<esplusplayer_decoded_video_packet*>(media_packet));
+}
+#endif
+
esplusplayer_state MediaPlayerESPlusPlayer::GetPlayerState() {
return (esplayer_ ? esplusplayer_get_state(esplayer_)
: ESPLUSPLAYER_STATE_NONE);
<< ", duration:" << packet->duration << ", Player(" << esplayer_
<< ", state:" << GetString(GetPlayerState());
+#if defined(TIZEN_TBM_SUPPORT)
+ 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;
+ data_cb_.Run(0, tbm_handle, timestamp);
+#else
base::UnsafeSharedMemoryRegion shared_memory;
uint32_t shared_memory_size =
suf_info.planes[0].size + (suf_info.planes[0].size / 2);
sink_->PaintSingleFrame(video_frame);
}
+#endif
}
void MediaPlayerESPlusPlayer::OnFlushComplete() {
public:
static MediaPlayerESPlusPlayer* GetMediaPlayerESPlusPlayer();
+#if defined(TIZEN_TBM_SUPPORT)
+ using DataRequestCB = base::RepeatingCallback<
+ void(uint32_t, gfx::TbmBufferHandle, base::TimeDelta)>;
+#else
using DataRequestCB =
base::RepeatingCallback<void(uint32_t,
base::UnsafeSharedMemoryRegion,
base::TimeDelta,
uint32_t,
uint32_t)>;
+#endif
+
bool CreatePlayer() override;
void Initialize(VideoRendererSink* sink) override;
bool IsInitialized() override;
void SetFrameAvailableCallback(const DataRequestCB& datacb) override;
+#if defined(TIZEN_TBM_SUPPORT)
+ void DestroyMediaPacket(void* media_packet) override;
+#endif
+
// Callback handler
void OnReadyToPrepare(const esplusplayer_stream_type stream_type);
void OnPrepareComplete(bool result);
bool should_set_playback_rate_ = false;
base::OnceClosure flush_cb_;
+
+ int player_id_ = 0;
+
DataRequestCB data_cb_;
VideoRendererSink* sink_;
--- /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/media/filters/media_player_registry.h"
+
+#include "base/logging.h"
+#include "base/process/process_handle.h"
+
+namespace media {
+
+MediaPlayerRegistry* MediaPlayerRegistry::GetInstance() {
+ return base::Singleton<MediaPlayerRegistry>::get();
+}
+
+MediaPlayerRegistry::MediaPlayerRegistry() {
+ next_media_player_id_ = base::GetCurrentProcId();
+}
+
+MediaPlayerRegistry::~MediaPlayerRegistry() {}
+
+int MediaPlayerRegistry::RegisterMediaPlayer(MediaPlayerTizen* player) {
+ LOG(INFO) << __func__ << " player id: " << next_media_player_id_;
+ media_players_[next_media_player_id_] = player;
+ return next_media_player_id_++;
+}
+
+void MediaPlayerRegistry::UnregisterMediaPlayer(int player_id) {
+ LOG(INFO) << __func__ << " player id: " << player_id;
+ media_players_.erase(player_id);
+}
+
+MediaPlayerTizen* MediaPlayerRegistry::GetMediaPlayer(int player_id) {
+ std::map<int, MediaPlayerTizen*>::iterator iter =
+ media_players_.find(player_id);
+ if (iter != media_players_.end())
+ return iter->second;
+ return nullptr;
+}
+
+} // namespace media
--- /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 MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_
+#define MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_
+
+#include <map>
+
+#include "base/memory/singleton.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+class MediaPlayerTizen;
+
+class MEDIA_EXPORT MediaPlayerRegistry {
+ public:
+ static MediaPlayerRegistry* GetInstance();
+
+ int RegisterMediaPlayer(MediaPlayerTizen* player);
+ void UnregisterMediaPlayer(int player_id);
+
+ MediaPlayerTizen* GetMediaPlayer(int player_id);
+
+ private:
+ MediaPlayerRegistry();
+ ~MediaPlayerRegistry();
+
+ MediaPlayerRegistry(const MediaPlayerRegistry&) = delete;
+ MediaPlayerRegistry& operator=(const MediaPlayerRegistry&) = delete;
+
+ int next_media_player_id_;
+
+ std::map<int, MediaPlayerTizen*> media_players_;
+
+ friend struct base::DefaultSingletonTraits<MediaPlayerRegistry>;
+};
+
+} // namespace media
+
+#endif // MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_
"//tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h",
"//tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc",
"//tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h",
+ "//tizen_src/chromium_impl/media/filters/media_player_registry.cc",
+ "//tizen_src/chromium_impl/media/filters/media_player_registry.h",
"//tizen_src/chromium_impl/media/filters/media_player_tizen.h",
]
--- /dev/null
+// Copyright 2014 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_H
+#define UI_GFX_TBM_BUFFER_HANDLE_H
+
+#include <stddef.h>
+#include "ui/gfx/gfx_export.h"
+
+#if defined(TIZEN_TBM_SUPPORT)
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#endif
+
+namespace gfx {
+
+struct GFX_EXPORT TbmBufferHandle {
+ TbmBufferHandle() {}
+#if defined(TIZEN_TBM_SUPPORT)
+ uint32_t tbm_surface{0};
+ uint32_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;
+#endif
+};
+
+} // namespace gfx
+
+#endif
"//tizen_src/chromium_impl/ui/display/device_display_info_efl.cc",
"//tizen_src/chromium_impl/ui/display/device_display_info_efl.h",
"//tizen_src/chromium_impl/ui/display/device_display_info_observer_efl.h",
+ "//tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h",
]
# For //ui/gfx/x target
#elif BUILDFLAG(IS_ANDROID)
base::android::ScopedHardwareBufferHandle android_hardware_buffer;
#endif
+#if defined(TIZEN_TBM_SUPPORT)
+ uint32_t tbm_surface{0};
+ uint32_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;
+#endif
};
// This interface typically correspond to a type of shared memory that is also
import("//build/config/ozone.gni")
import("//mojo/public/tools/bindings/mojom.gni")
+if (use_efl) {
+ import("//tizen_src/build/config/tizen_features.gni")
+}
mojom("mojom") {
generate_java = true
if (ozone_platform_x11) {
enabled_features += [ "enable_x11_params" ]
}
+ if (tizen_tbm_support) {
+ enabled_features += [ "tizen_tbm_support" ]
+ }
shared_cpp_typemaps = [
{
mojom = "gfx.mojom.GpuMemoryBufferType"
cpp = "::gfx::GpuMemoryBufferType"
},
+ {
+ mojom = "gfx.mojom.TbmBufferHandle"
+ cpp = "::gfx::TbmBufferHandle"
+ },
]
traits_headers = [ "buffer_types_mojom_traits.h" ]
GpuMemoryBufferId id;
uint32 offset;
uint32 stride;
+
+ [EnableIf=tizen_tbm_support]
+ uint32 tbm_surface;
+
+ [EnableIf=tizen_tbm_support]
+ uint32 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;
+
GpuMemoryBufferPlatformHandle? platform_handle;
};
+
+// gfx::TbmBufferHandle
+struct TbmBufferHandle {
+ [EnableIf=tizen_tbm_support]
+ uint32 tbm_surface;
+
+ [EnableIf=tizen_tbm_support]
+ uint32 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;
+};
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))
+ return false;
+ base::span<int32_t> strides(out->strides);
+ if (!data.ReadStrides(&strides))
+ return false;
+#endif
gfx::mojom::GpuMemoryBufferPlatformHandlePtr platform_handle;
if (!data.ReadPlatformHandle(&platform_handle)) {
return false;
return false;
}
+#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;
+}
+
+// static
+base::span<const int32_t> StructTraits<
+ gfx::mojom::GpuMemoryBufferHandleDataView,
+ gfx::GpuMemoryBufferHandle>::strides(const gfx::GpuMemoryBufferHandle&
+ input) {
+ return input.strides;
+}
+
+bool StructTraits<gfx::mojom::TbmBufferHandleDataView, gfx::TbmBufferHandle>::
+ Read(gfx::mojom::TbmBufferHandleDataView data, gfx::TbmBufferHandle* out) {
+ 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))
+ return false;
+
+ base::span<int32_t> strides(out->strides);
+ if (!data.ReadStrides(&strides))
+ return false;
+ return true;
+}
+
+// static
+base::span<const int32_t>
+StructTraits<gfx::mojom::TbmBufferHandleDataView, gfx::TbmBufferHandle>::key(
+ const gfx::TbmBufferHandle& input) {
+ return input.key;
+}
+
+// static
+base::span<const int32_t>
+StructTraits<gfx::mojom::TbmBufferHandleDataView,
+ gfx::TbmBufferHandle>::strides(const gfx::TbmBufferHandle& input) {
+ return input.strides;
+}
+#endif
+
} // namespace mojo
#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"
+#endif
+
namespace mojo {
template <>
static uint32_t stride(const gfx::GpuMemoryBufferHandle& handle) {
return handle.stride;
}
+#if defined(TIZEN_TBM_SUPPORT)
+ static uint32_t tbm_surface(const gfx::GpuMemoryBufferHandle& handle) {
+ return handle.tbm_surface;
+ }
+ static uint32_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;
+ }
+#endif
static mojo::StructPtr<gfx::mojom::GpuMemoryBufferPlatformHandle>
platform_handle(gfx::GpuMemoryBufferHandle& handle);
gfx::GpuMemoryBufferHandle* handle);
};
+#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;
+ }
+ static uint32_t media_packet(const gfx::TbmBufferHandle& handle) {
+ return handle.media_packet;
+ }
+ static int32_t player_id(const gfx::TbmBufferHandle& handle) {
+ return handle.player_id;
+ }
+
+ static int32_t key_num(const gfx::TbmBufferHandle& handle) {
+ return handle.key_num;
+ }
+ 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) {
+ return handle.width;
+ }
+ static int32_t height(const gfx::TbmBufferHandle& handle) {
+ return handle.height;
+ }
+
+ static bool Read(gfx::mojom::TbmBufferHandleDataView data,
+ gfx::TbmBufferHandle* handle);
+};
+#endif
+
template <>
struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
EnumTraits<gfx::mojom::BufferPlane, gfx::BufferPlane> {
#include "ui/gl/gl_enums.h"
#include "ui/gl/gl_surface_egl.h"
+#if defined(TIZEN_TBM_SUPPORT)
+namespace media {
+void DestroyMediaPacket(void* media_packet_handle, int player_id);
+}
+#endif
+
namespace gl {
GLImageEGL::GLImageEGL(const gfx::Size& size)
GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(), egl_image_);
if (result == EGL_FALSE)
DLOG(ERROR) << "Error destroying EGLImage: " << ui::GetLastEGLErrorString();
+
+#if defined(TIZEN_TBM_SUPPORT)
+ media::DestroyMediaPacket(media_packet_, player_id_);
+#endif
}
bool GLImageEGL::Initialize(EGLContext context,
return success;
}
+#if defined(TIZEN_TBM_SUPPORT)
+bool GLImageEGL::Initialize(EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint* attrs,
+ void* media_packet,
+ int player_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
+ media_packet_ = media_packet;
+ player_id_ = player_id;
+
+ egl_image_ = eglCreateImageKHR(GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(),
+ EGL_NO_CONTEXT, target, buffer, attrs);
+ if (egl_image_ == EGL_NO_IMAGE_KHR) {
+ DLOG(ERROR) << "Error creating EGLImage: " << ui::GetLastEGLErrorString();
+ media::DestroyMediaPacket(media_packet_, player_id_);
+ return false;
+ }
+
+ return true;
+}
+#endif
+
gfx::Size GLImageEGL::GetSize() {
return size_;
}
class GL_EXPORT GLImageEGL : public GLImage {
public:
explicit GLImageEGL(const gfx::Size& size);
+#if defined(TIZEN_TBM_SUPPORT)
+ bool Initialize(unsigned target,
+ void* buffer,
+ const EGLint* attrs,
+ void* media_packet,
+ int player_id);
+#endif
GLImageEGL(const GLImageEGL&) = delete;
GLImageEGL& operator=(const GLImageEGL&) = delete;
const EGLint* attrs);
raw_ptr<void> egl_image_ /* EGLImageKHR */;
+#if defined(TIZEN_TBM_SUPPORT)
+ void* media_packet_;
+ int player_id_;
+#endif
const gfx::Size size_;
base::ThreadChecker thread_checker_;
};
#include "ui/gl/gl_enums.h"
#include "ui/gl/gl_surface_egl.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/gfx/gpu_memory_buffer.h"
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif
+
#define FOURCC(a, b, c, d) \
((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
(static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
GLImageNativePixmap::~GLImageNativePixmap() {}
+#if defined(TIZEN_TBM_SUPPORT)
+bool GLImageNativePixmap::Initialize(const gfx::GpuMemoryBufferHandle& handle) {
+ EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+ tbm_surface_h surface = reinterpret_cast<tbm_surface_h>(handle.tbm_surface);
+ if (!GLImageEGL::Initialize(EGL_NATIVE_SURFACE_TIZEN,
+ static_cast<EGLClientBuffer>(surface), attrs,
+ reinterpret_cast<void*>(handle.media_packet),
+ handle.player_id)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
+
bool GLImageNativePixmap::Initialize(scoped_refptr<gfx::NativePixmap> pixmap) {
DCHECK(!pixmap_);
if (GLInternalFormat(format_) == GL_NONE) {
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_image_egl.h"
+#if defined(TIZEN_TBM_SUPPORT)
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+namespace gfx {
+struct GpuMemoryBufferHandle;
+}
+#endif
+
namespace gl {
class GL_EXPORT GLImageNativePixmap : public gl::GLImageEGL {
gfx::BufferFormat format,
gfx::BufferPlane plane = gfx::BufferPlane::DEFAULT);
+#if defined(TIZEN_TBM_SUPPORT)
+ bool Initialize(const gfx::GpuMemoryBufferHandle& handle);
+#endif
// Create an EGLImage from a given NativePixmap.
bool Initialize(scoped_refptr<gfx::NativePixmap> pixmap);
bool InitializeForOverlay(scoped_refptr<gfx::NativePixmap> pixmap);
bool has_image_flush_external_;
bool has_image_dma_buf_export_;
bool did_initialize_;
+#if defined(TIZEN_TBM_SUPPORT)
+ tbm_bufmgr bufmgr_;
+ tbm_surface_h tbm_surf_;
+ tbm_bo bos_[4] = {0};
+ tbm_surface_info_s tbmsi_;
+#endif
};
} // namespace gl