Commit e8195ff6 authored by Nathan Zabriskie's avatar Nathan Zabriskie Committed by Commit Bot

Revert "Move CPU VideoFrame YUV Uploading code into yuv_util"

This reverts commit eeb9431b.

Reason for revert: This CL seems to have caused flakiness in some PaintCanvasVideoRendererWithGLTests. Reverting to investigate before attempting to reland the change.

TBR=khushalsagar@chromium.org

Original change's description:
> Move CPU VideoFrame YUV Uploading code into yuv_util
>
> This patch unifies CPU VideoFrame uploading/conversion code for OOPR
> and GPU rasterization. Now clients can call ConvertFromVideoFrameYUV
> with CPU backed VideoFrames in addition to wrapped frames.
>
> Bug: 1058992
> Change-Id: I89c37179b12fe1375fa7a6f7d919f135f77b5857
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2200084
> Commit-Queue: Nathan Zabriskie <nazabris@microsoft.com>
> Reviewed-by: Khushal <khushalsagar@chromium.org>
> Reviewed-by: Dan Sanders <sandersd@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#770729}

TBR=kbr@chromium.org,sandersd@chromium.org,khushalsagar@chromium.org,nazabris@microsoft.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 1058992, 1085516
Change-Id: I74ad2b483b89eaf729ee279bd7438243e2bb52a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2212560
Commit-Queue: Nathan Zabriskie <nazabris@microsoft.com>
Reviewed-by: default avatarNathan Zabriskie <nazabris@microsoft.com>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#771240}
parent ef5a5ebd
......@@ -39,8 +39,6 @@ GLenum SkColorTypeToGLDataFormat(SkColorType color_type) {
return GL_RGBA;
case kBGRA_8888_SkColorType:
return GL_BGRA_EXT;
case kGray_8_SkColorType:
return GL_LUMINANCE;
default:
DLOG(ERROR) << "Unknown SkColorType " << color_type;
}
......@@ -52,7 +50,6 @@ GLenum SkColorTypeToGLDataType(SkColorType color_type) {
switch (color_type) {
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
case kGray_8_SkColorType:
return GL_UNSIGNED_BYTE;
default:
DLOG(ERROR) << "Unknown SkColorType " << color_type;
......@@ -173,19 +170,17 @@ void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
GLuint row_bytes,
const SkImageInfo& src_info,
const void* src_pixels) {
DCHECK_GE(row_bytes, src_info.minRowBytes());
DCHECK_EQ(row_bytes, src_info.minRowBytes());
GLuint texture_id = CreateAndConsumeForGpuRaster(dest_mailbox);
BeginSharedImageAccessDirectCHROMIUM(
texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, row_bytes / src_info.bytesPerPixel());
gl_->BindTexture(texture_target, texture_id);
gl_->TexSubImage2D(texture_target, 0, dst_x_offset, dst_y_offset,
src_info.width(), src_info.height(),
SkColorTypeToGLDataFormat(src_info.colorType()),
SkColorTypeToGLDataType(src_info.colorType()), src_pixels);
gl_->BindTexture(texture_target, 0);
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
EndSharedImageAccessDirectCHROMIUM(texture_id);
DeleteGpuRasterTexture(texture_id);
......
......@@ -212,6 +212,16 @@ GLuint SynchronizeAndImportMailbox(gpu::gles2::GLES2Interface* gl,
: gl->CreateAndConsumeTextureCHROMIUM(mailbox.name);
}
// TODO(crbug.com/1023270): Remove this ctor once we're no longer relying on
// texture ids for Mailbox access as that is only supported on
// RasterImplementationGLES.
GLuint SynchronizeAndImportMailbox(gpu::raster::RasterInterface* ri,
const gpu::SyncToken& sync_token,
const gpu::Mailbox& mailbox) {
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
return ri->CreateAndConsumeForGpuRaster(mailbox);
}
const gpu::MailboxHolder& GetVideoFrameMailboxHolder(VideoFrame* video_frame) {
DCHECK(video_frame->HasTextures());
DCHECK_EQ(video_frame->NumTextures(), 1u);
......@@ -1351,6 +1361,11 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameYUVDataToGLTexture(
bool premultiply_alpha,
bool flip_y) {
DCHECK(raster_context_provider);
GrContext* gr_context = raster_context_provider->GrContext();
if (!gr_context) {
return false;
}
if (!video_frame.IsMappable()) {
return false;
}
......@@ -1358,7 +1373,47 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameYUVDataToGLTexture(
if (video_frame.format() != media::PIXEL_FORMAT_I420) {
return false;
}
// Could handle NV12 here as well. See NewSkImageFromVideoFrameYUV.
// Could handle NV12 here as well. See NewSkImageFromVideoFrameYUVTextures.
static constexpr size_t kNumPlanes = 3;
DCHECK_EQ(video_frame.NumPlanes(video_frame.format()), kNumPlanes);
// Y,U,V GPU-side SkImages. (These must outlive the yuv_textures).
sk_sp<SkImage> yuv_images[kNumPlanes]{};
// Y,U,V GPU textures from those SkImages.
// (A GrBackendTexture is a non-owned reference to the SkImage's texture.)
GrBackendTexture yuv_textures[kNumPlanes]{};
// Upload the whole coded image area (not visible rect).
gfx::Size y_tex_size = video_frame.coded_size();
gfx::Size uv_tex_size((y_tex_size.width() + 1) / 2,
(y_tex_size.height() + 1) / 2);
for (size_t plane = 0; plane < kNumPlanes; ++plane) {
const uint8_t* data = video_frame.data(plane);
int plane_stride = video_frame.stride(plane);
bool is_y_plane = plane == media::VideoFrame::kYPlane;
gfx::Size tex_size = is_y_plane ? y_tex_size : uv_tex_size;
int data_size = plane_stride * (tex_size.height() - 1) + tex_size.width();
// Create a CPU-side SkImage from the channel.
sk_sp<SkData> sk_data = SkData::MakeWithoutCopy(data, data_size);
DCHECK(sk_data);
SkImageInfo image_info =
SkImageInfo::Make(tex_size.width(), tex_size.height(),
kGray_8_SkColorType, kUnknown_SkAlphaType);
sk_sp<SkImage> plane_image_cpu =
SkImage::MakeRasterData(image_info, sk_data, plane_stride);
DCHECK(plane_image_cpu);
// Upload the CPU-side SkImage into a GPU-side SkImage.
// (Note the original video_frame data is no longer used after this point.)
yuv_images[plane] = plane_image_cpu->makeTextureImage(gr_context);
DCHECK(yuv_images[plane]);
// Extract the backend texture from the GPU-side image.
yuv_textures[plane] = yuv_images[plane]->getBackendTexture(false);
}
auto* sii = raster_context_provider->SharedImageInterface();
gpu::raster::RasterInterface* source_ri =
......@@ -1366,38 +1421,51 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameYUVDataToGLTexture(
// We need a shared image to receive the intermediate RGB result. Try to reuse
// one if compatible, otherwise create a new one.
gpu::SyncToken token;
if (!yuv_cache_.mailbox.IsZero() &&
yuv_cache_.size == video_frame.coded_size() &&
if (yuv_cache_.texture && yuv_cache_.size == video_frame.coded_size() &&
yuv_cache_.raster_context_provider == raster_context_provider) {
token = yuv_cache_.sync_token;
source_ri->WaitSyncTokenCHROMIUM(yuv_cache_.sync_token.GetConstData());
} else {
yuv_cache_.Reset();
yuv_cache_.raster_context_provider = raster_context_provider;
yuv_cache_.size = video_frame.coded_size();
uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2;
if (raster_context_provider->ContextCapabilities().supports_oop_raster) {
usage |= gpu::SHARED_IMAGE_USAGE_RASTER |
gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
}
yuv_cache_.mailbox = sii->CreateSharedImage(viz::ResourceFormat::RGBA_8888,
video_frame.coded_size(),
gfx::ColorSpace(), usage);
token = sii->GenUnverifiedSyncToken();
yuv_cache_.mailbox = sii->CreateSharedImage(
viz::ResourceFormat::RGBA_8888, video_frame.coded_size(),
gfx::ColorSpace(), gpu::SHARED_IMAGE_USAGE_GLES2);
yuv_cache_.texture = SynchronizeAndImportMailbox(
source_ri, sii->GenUnverifiedSyncToken(), yuv_cache_.mailbox);
}
// On the source Raster context, do the YUV->RGB conversion.
gpu::MailboxHolder dest_holder;
dest_holder.mailbox = yuv_cache_.mailbox;
dest_holder.texture_target = GL_TEXTURE_2D;
dest_holder.sync_token = token;
ConvertFromVideoFrameYUV(&video_frame, raster_context_provider, dest_holder);
// On the source GL context, do the YUV->RGB conversion using Skia.
gpu::SyncToken post_conversion_sync_token;
source_ri->GenUnverifiedSyncTokenCHROMIUM(
post_conversion_sync_token.GetData());
{
source_ri->BeginSharedImageAccessDirectCHROMIUM(
yuv_cache_.texture, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
GrGLTextureInfo backend_texture = {};
backend_texture.fTarget = GL_TEXTURE_2D;
backend_texture.fID = yuv_cache_.texture;
backend_texture.fFormat = GL_RGBA8;
GrBackendTexture result_texture(video_frame.coded_size().width(),
video_frame.coded_size().height(),
GrMipMapped::kNo, backend_texture);
sk_sp<SkImage> yuv_image = YUVGrBackendTexturesToSkImage(
gr_context, video_frame.ColorSpace(), video_frame.format(),
yuv_textures, result_texture);
gr_context->flushAndSubmit();
source_ri->EndSharedImageAccessDirectCHROMIUM(yuv_cache_.texture);
source_ri->GenUnverifiedSyncTokenCHROMIUM(
post_conversion_sync_token.GetData());
if (!yuv_image) {
// Conversion failed. Note the last use sync token for destruction.
yuv_cache_.sync_token = post_conversion_sync_token;
yuv_cache_.Reset();
return false;
}
}
// On the destination GL context, do a copy (with cropping) into the
// destination texture.
......@@ -1711,17 +1779,18 @@ PaintCanvasVideoRenderer::YUVTextureCache::YUVTextureCache() = default;
PaintCanvasVideoRenderer::YUVTextureCache::~YUVTextureCache() = default;
void PaintCanvasVideoRenderer::YUVTextureCache::Reset() {
if (mailbox.IsZero())
if (!texture)
return;
DCHECK(raster_context_provider);
gpu::raster::RasterInterface* ri = raster_context_provider->RasterInterface();
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
ri->DeleteGpuRasterTexture(texture);
texture = 0;
ri->OrderingBarrierCHROMIUM();
auto* sii = raster_context_provider->SharedImageInterface();
sii->DestroySharedImage(sync_token, mailbox);
mailbox.SetZero();
// Kick off the GL work up to the OrderingBarrierCHROMIUM above as well as the
// SharedImageInterface work, to ensure the shared image memory is released in
......
......@@ -271,6 +271,9 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
// The shared image backing the texture.
gpu::Mailbox mailbox;
// The GL texture.
uint32_t texture = 0;
// A SyncToken after last usage, used for reusing or destroying texture and
// shared image.
gpu::SyncToken sync_token;
......
This diff is collapsed.
......@@ -29,15 +29,14 @@ class VideoFrame;
// Converts a YUV video frame to RGB format and stores the results in the
// provided mailbox. The caller of this function maintains ownership of the
// mailbox. Automatically handles upload of CPU memory backed VideoFrames in
// I420 format. VideoFrames that wrap external textures can be I420 or NV12
// format.
// mailbox.
MEDIA_EXPORT void ConvertFromVideoFrameYUV(
const VideoFrame* video_frame,
viz::RasterContextProvider* raster_context_provider,
const gpu::MailboxHolder& dest_mailbox_holder);
MEDIA_EXPORT sk_sp<SkImage> NewSkImageFromVideoFrameYUV(
MEDIA_EXPORT sk_sp<SkImage>
NewSkImageFromVideoFrameYUVTexturesWithExternalBackend(
const VideoFrame* video_frame,
viz::RasterContextProvider* raster_context_provider,
unsigned int texture_target,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment