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

Unified Diff: cc/resources/video_resource_updater.cc

Issue 13959005: cc: Recycle resources for software video decode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Destroy recycled textures when VRU shuts down Created 7 years, 8 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
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/resources/video_resource_updater.cc
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index ca2d3bb9d7c211ef818b9bed2bb25e8613107212..bb8e41d7e860420dbbfdf661e48600d1fadf235b 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -27,7 +27,12 @@ VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider)
: resource_provider_(resource_provider) {
}
-VideoResourceUpdater::~VideoResourceUpdater() {}
+VideoResourceUpdater::~VideoResourceUpdater() {
+ while (!recycled_resources_.empty()) {
+ resource_provider_->DeleteResource(recycled_resources_.back().resource_id);
+ recycled_resources_.pop_back();
+ }
+}
bool VideoResourceUpdater::VerifyFrame(
const scoped_refptr<media::VideoFrame>& video_frame) {
@@ -90,12 +95,6 @@ static gfx::Size SoftwarePlaneDimension(
return coded_size;
}
-static void ReleaseResource(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id,
- unsigned sync_point) {
- resource_provider->DeleteResource(resource_id);
-}
-
VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
const scoped_refptr<media::VideoFrame>& video_frame) {
if (!VerifyFrame(video_frame))
@@ -135,54 +134,75 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
int max_resource_size = resource_provider_->max_texture_size();
gfx::Size coded_frame_size = video_frame->coded_size();
- ResourceProvider::ResourceIdArray plane_resources;
+ std::vector<PlaneResource> plane_resources;
bool allocation_success = true;
for (size_t i = 0; i < output_plane_count; ++i) {
- gfx::Size plane_size =
+ gfx::Size output_plane_resource_size =
SoftwarePlaneDimension(input_frame_format,
coded_frame_size,
output_resource_format,
i);
- if (plane_size.IsEmpty() ||
- plane_size.width() > max_resource_size ||
- plane_size.height() > max_resource_size) {
+ if (output_plane_resource_size.IsEmpty() ||
+ output_plane_resource_size.width() > max_resource_size ||
+ output_plane_resource_size.height() > max_resource_size) {
allocation_success = false;
break;
}
- // TODO(danakj): Could recycle resources that we previously allocated and
- // were returned to us.
- ResourceProvider::ResourceId resource_id =
- resource_provider_->CreateResource(plane_size,
- output_resource_format,
- ResourceProvider::TextureUsageAny);
+ ResourceProvider::ResourceId resource_id = 0;
+ unsigned sync_point = 0;
+
+ // Try recycle a previously-allocated resource.
+ for (size_t i = 0; i < recycled_resources_.size(); ++i) {
+ if (recycled_resources_[i].resource_format == output_resource_format &&
+ recycled_resources_[i].resource_size == output_plane_resource_size) {
+ resource_id = recycled_resources_[i].resource_id;
+ sync_point = recycled_resources_[i].sync_point;
+ recycled_resources_.erase(recycled_resources_.begin() + i);
+ break;
+ }
+ }
+
+ if (resource_id == 0) {
+ // TODO(danakj): Abstract out hw/sw resource create/delete from
+ // ResourceProvider and stop using ResourceProvider in this class.
+ resource_id =
+ resource_provider_->CreateResource(output_plane_resource_size,
+ output_resource_format,
+ ResourceProvider::TextureUsageAny);
+ }
+
if (resource_id == 0) {
allocation_success = false;
break;
}
- plane_resources.push_back(resource_id);
+ plane_resources.push_back(PlaneResource(resource_id,
+ output_plane_resource_size,
+ output_resource_format,
+ sync_point));
}
if (!allocation_success) {
for (size_t i = 0; i < plane_resources.size(); ++i)
- resource_provider_->DeleteResource(plane_resources[i]);
+ resource_provider_->DeleteResource(plane_resources[i].resource_id);
return VideoFrameExternalResources();
}
VideoFrameExternalResources external_resources;
if (software_compositor) {
- DCHECK_EQ(output_resource_format, kRGBResourceFormat);
DCHECK_EQ(plane_resources.size(), 1u);
+ DCHECK_EQ(plane_resources[0].resource_format, kRGBResourceFormat);
+ DCHECK_EQ(plane_resources[0].sync_point, 0u);
if (!video_renderer_)
video_renderer_.reset(new media::SkCanvasVideoRenderer);
{
ResourceProvider::ScopedWriteLockSoftware lock(
- resource_provider_, plane_resources[0]);
+ resource_provider_, plane_resources[0].resource_id);
video_renderer_->Paint(video_frame,
lock.sk_canvas(),
video_frame->visible_rect(),
@@ -194,38 +214,38 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
// compositing mode, so this raw unretained resource_provider will always
// be valid when the callback is fired.
TextureMailbox::ReleaseCallback callback_to_free_resource =
- base::Bind(&ReleaseResource,
+ base::Bind(&RecycleResource,
+ AsWeakPtr(),
base::Unretained(resource_provider_),
- plane_resources[0]);
- external_resources.software_resources.push_back(plane_resources[0]);
+ plane_resources[0].resource_id,
+ plane_resources[0].resource_size,
+ plane_resources[0].resource_format,
+ gpu::Mailbox());
+ external_resources.software_resources.push_back(
+ plane_resources[0].resource_id);
external_resources.software_release_callback = callback_to_free_resource;
external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
return external_resources;
}
- DCHECK_EQ(output_resource_format,
- static_cast<unsigned>(kYUVResourceFormat));
-
WebKit::WebGraphicsContext3D* context =
resource_provider_->GraphicsContext3D();
DCHECK(context);
- for (size_t plane = 0; plane < plane_resources.size(); ++plane) {
+ for (size_t i = 0; i < plane_resources.size(); ++i) {
// Update each plane's resource id with its content.
- ResourceProvider::ResourceId output_plane_resource_id =
- plane_resources[plane];
- gfx::Size plane_size =
- SoftwarePlaneDimension(input_frame_format,
- coded_frame_size,
- output_resource_format,
- plane);
- const uint8_t* input_plane_pixels = video_frame->data(plane);
+ DCHECK_EQ(plane_resources[i].resource_format,
+ static_cast<unsigned>(kYUVResourceFormat));
+
+ const uint8_t* input_plane_pixels = video_frame->data(i);
- gfx::Rect image_rect(
- 0, 0, video_frame->stride(plane), plane_size.height());
- gfx::Rect source_rect(plane_size);
- resource_provider_->SetPixels(output_plane_resource_id,
+ gfx::Rect image_rect(0,
+ 0,
+ video_frame->stride(i),
+ plane_resources[i].resource_size.height());
+ gfx::Rect source_rect(plane_resources[i].resource_size);
+ resource_provider_->SetPixels(plane_resources[i].resource_id,
input_plane_pixels,
image_rect,
source_rect,
@@ -234,7 +254,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
gpu::Mailbox mailbox;
{
ResourceProvider::ScopedWriteLockGL lock(
- resource_provider_, output_plane_resource_id);
+ resource_provider_, plane_resources[i].resource_id);
GLC(context, context->genMailboxCHROMIUM(mailbox.name));
GLC(context, context->bindTexture(GL_TEXTURE_2D, lock.texture_id()));
@@ -246,11 +266,17 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
// This callback is called by the resource provider itself, so it's okay to
// use an unretained raw pointer here.
TextureMailbox::ReleaseCallback callback_to_free_resource =
- base::Bind(&ReleaseResource,
+ base::Bind(&RecycleResource,
+ AsWeakPtr(),
base::Unretained(resource_provider_),
- output_plane_resource_id);
+ plane_resources[i].resource_id,
+ plane_resources[i].resource_size,
+ plane_resources[i].resource_format,
+ mailbox);
external_resources.mailboxes.push_back(
- TextureMailbox(mailbox, callback_to_free_resource));
+ TextureMailbox(mailbox,
+ callback_to_free_resource,
+ plane_resources[i].sync_point));
}
external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
@@ -323,4 +349,43 @@ void VideoResourceUpdater::ReturnTexture(
callback.Run(sync_point);
}
+// static
+void VideoResourceUpdater::RecycleResource(
+ base::WeakPtr<VideoResourceUpdater> updater,
+ ResourceProvider* resource_provider,
+ unsigned resource_id,
+ gfx::Size resource_size,
+ unsigned resource_format,
+ gpu::Mailbox mailbox,
+ unsigned sync_point) {
+ WebKit::WebGraphicsContext3D* context =
+ resource_provider->GraphicsContext3D();
+ if (context) {
+ ResourceProvider::ScopedWriteLockGL lock(resource_provider, resource_id);
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, lock.texture_id()));
+ GLC(context, context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
+ }
+
+ if (!updater) {
+ resource_provider->DeleteResource(resource_id);
+ return;
+ }
+
+ // Drop recycled resources that are the wrong format.
+ while (!updater->recycled_resources_.empty() &&
+ updater->recycled_resources_.back().resource_format !=
+ resource_format) {
+ resource_provider->DeleteResource(
+ updater->recycled_resources_.back().resource_id);
+ updater->recycled_resources_.pop_back();
+ }
+
+ PlaneResource recycled_resource(resource_id,
+ resource_size,
+ resource_format,
+ sync_point);
+ updater->recycled_resources_.push_back(recycled_resource);
+}
+
} // namespace cc
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698