Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(645)

Unified Diff: cc/resources/video_resource_updater.cc

Issue 2242453002: Avoid planar YUV resources when one component EGL images are not supported (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: modify comment to explain the use of RGBA_8888 to trigger a driver workaround Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/video_resource_updater.cc
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index cdeb363e1ecdd4d6a3144fe6dfc105986996f61a..aa1e79ebea604238865e8d2c0540f1aa8486a104 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -172,6 +172,29 @@ VideoResourceUpdater::~VideoResourceUpdater() {
}
VideoResourceUpdater::ResourceList::iterator
+VideoResourceUpdater::RecycleOrAllocateTexture(
+ const gfx::Size& resource_size,
+ ResourceFormat resource_format,
+ const gfx::ColorSpace& color_space,
+ bool immutable_hint) {
+ for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
+ // Reuse resource if attributes match and the resource is a currently
+ // unreferenced texture.
+ if (it->resource_size() == resource_size &&
+ it->resource_format() == resource_format && !it->mailbox().IsZero() &&
+ !it->has_refs() &&
+ resource_provider_->GetTextureHint(it->resource_id()) !=
+ ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
+ return it;
+ }
+ }
+
+ // Otherwise allocate a new resource.
+ return AllocateResource(resource_size, resource_format, color_space, true,
+ immutable_hint);
+}
+
+VideoResourceUpdater::ResourceList::iterator
VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size,
ResourceFormat format,
const gfx::ColorSpace& color_space,
@@ -246,6 +269,54 @@ static gfx::Size SoftwarePlaneDimension(media::VideoFrame* input_frame,
return gfx::Size(plane_width, plane_height);
}
+// Create an RGB texture by software converting YUV planar data, for the case
+// where YUV planar textures are not renderable by the GPU.
+VideoFrameExternalResources
+VideoResourceUpdater::CreateRGBTextureForSoftwarePlanes(
+ media::VideoFrame* video_frame) {
+ DCHECK(media::IsYuvPlanar(video_frame->format()));
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ const ResourceFormat resource_format = ResourceFormat::RGBA_8888;
+ const gfx::Size output_plane_resource_size = video_frame->coded_size();
+ const bool is_immutable = false;
+
+ VideoResourceUpdater::ResourceList::iterator resource =
+ RecycleOrAllocateTexture(output_plane_resource_size, resource_format,
+ is_immutable);
+
+ resource->add_ref();
+
+ size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
+ output_plane_resource_size.width(), ResourceFormat::RGBA_8888);
+ size_t upload_image_stride =
+ MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u);
danakj 2016/08/25 01:25:39 If the format is RGBA8888 how can the bytes per ro
Tobias Sargeant 2016/08/26 15:52:11 True, removed.
+ size_t needed_size =
+ upload_image_stride * output_plane_resource_size.height();
+ if (upload_pixels_.size() < needed_size)
+ upload_pixels_.resize(needed_size);
+
+ media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
+ video_frame, &upload_pixels_[0], upload_image_stride);
+
+ resource_provider_->CopyToResource(
+ resource->resource_id(), &upload_pixels_[0], resource->resource_size());
+
+ gpu::SyncToken sync_token;
+ const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
+ gl->ShallowFlushCHROMIUM();
+ gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
+
+ VideoFrameExternalResources external_resources;
+
+ external_resources.mailboxes.push_back(
+ TextureMailbox(resource->mailbox(), sync_token, GL_TEXTURE_2D,
+ video_frame->coded_size(), false, false));
+ external_resources.release_callbacks.push_back(
+ base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id()));
+ external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
+ return external_resources;
+}
+
VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
scoped_refptr<media::VideoFrame> video_frame) {
TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
@@ -297,6 +368,15 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
ResourceFormat output_resource_format =
resource_provider_->YuvResourceFormat(bits_per_channel);
+ // If GPU compositing is enabled, but the output resource format
+ // returned by the resource provider is RGBA_8888, then a GPU driver
+ // bug workaround requires that YUV frames must be converted to RGB
+ // before texture upload.
+ if (!software_compositor &&
+ output_resource_format == ResourceFormat::RGBA_8888) {
+ return CreateRGBTextureForSoftwarePlanes(video_frame.get());
+ }
+
size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
// TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
@@ -424,12 +504,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
// uploading (including non-frame data to fill in the stride).
int video_stride_bytes = video_frame->stride(i);
- size_t bytes_per_row = ResourceUtil::UncheckedWidthInBytes<size_t>(
+ size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
resource_size_pixels.width(), plane_resource.resource_format());
// Use 4-byte row alignment (OpenGL default) for upload performance.
// Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
size_t upload_image_stride =
- MathUtil::UncheckedRoundUp<size_t>(bytes_per_row, 4u);
+ MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u);
bool needs_conversion = false;
int shift = 0;
@@ -564,28 +644,10 @@ void VideoResourceUpdater::CopyPlaneTexture(
// target to avoid loss of precision or dropping any alpha component.
const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888;
- // Search for an existing resource to reuse.
- VideoResourceUpdater::ResourceList::iterator resource = all_resources_.end();
-
- for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
- // Reuse resource if attributes match and the resource is a currently
- // unreferenced texture.
- if (it->resource_size() == output_plane_resource_size &&
- it->resource_format() == copy_target_format &&
- !it->mailbox().IsZero() && !it->has_refs() &&
- resource_provider_->GetTextureHint(it->resource_id()) !=
- ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
- resource = it;
- break;
- }
- }
-
- // Otherwise allocate a new resource.
- if (resource == all_resources_.end()) {
- const bool is_immutable = false;
- resource = AllocateResource(output_plane_resource_size, copy_target_format,
- video_frame->ColorSpace(), true, is_immutable);
- }
+ const bool is_immutable = false;
+ VideoResourceUpdater::ResourceList::iterator resource =
+ RecycleOrAllocateTexture(output_plane_resource_size, copy_target_format,
+ video_frame->ColorSpace(), is_immutable);
resource->add_ref();

Powered by Google App Engine
This is Rietveld 408576698