1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/resources/video_resource_updater.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/output/gl_renderer.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/resources/resource_provider.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/video_frame.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/filters/skcanvas_video_renderer.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/size_conversions.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned kYUVResourceFormat = GL_LUMINANCE;
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned kRGBResourceFormat = GL_RGBA;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace cc {
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochVideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {}
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoFrameExternalResources::~VideoFrameExternalResources() {}
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : resource_provider_(resource_provider) {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoResourceUpdater::~VideoResourceUpdater() {
31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  while (!all_resources_.empty()) {
32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    resource_provider_->DeleteResource(all_resources_.back());
33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    all_resources_.pop_back();
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void VideoResourceUpdater::DeleteResource(unsigned resource_id) {
38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  resource_provider_->DeleteResource(resource_id);
39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  all_resources_.erase(std::remove(all_resources_.begin(),
40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                   all_resources_.end(),
41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                   resource_id));
42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochVideoFrameExternalResources VideoResourceUpdater::
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateExternalResourcesFromVideoFrame(
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const scoped_refptr<media::VideoFrame>& video_frame) {
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!VerifyFrame(video_frame))
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return VideoFrameExternalResources();
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE)
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CreateForHardwarePlanes(video_frame);
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  else
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return CreateForSoftwarePlanes(video_frame);
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool VideoResourceUpdater::VerifyFrame(
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<media::VideoFrame>& video_frame) {
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If these fail, we'll have to add logic that handles offset bitmap/texture
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // UVs. For now, just expect (0, 0) offset, since all our decoders so far
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // don't offset.
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(video_frame->visible_rect().x(), 0);
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(video_frame->visible_rect().y(), 0);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (video_frame->format()) {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Acceptable inputs.
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::YV12:
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::YV12A:
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::YV16:
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::NATIVE_TEXTURE:
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_TV)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::HOLE:
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Unacceptable inputs. ¯\(°_o)/¯
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::INVALID:
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::RGB32:
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::EMPTY:
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case media::VideoFrame::I420:
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For frames that we receive in software format, determine the dimensions of
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// each plane in the frame.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static gfx::Size SoftwarePlaneDimension(
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    media::VideoFrame::Format input_frame_format,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Size coded_size,
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum output_resource_format,
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int plane_index) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (output_resource_format == kYUVResourceFormat) {
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (plane_index == media::VideoFrame::kYPlane ||
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        plane_index == media::VideoFrame::kAPlane)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return coded_size;
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (input_frame_format) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::YV12:
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::YV12A:
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 0.5f));
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::YV16:
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f));
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::INVALID:
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::RGB32:
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::EMPTY:
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::I420:
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::NATIVE_TEXTURE:
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_TV)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case media::VideoFrame::HOLE:
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NOTREACHED();
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat));
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return coded_size;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<media::VideoFrame>& video_frame) {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  media::VideoFrame::Format input_frame_format = video_frame->format();
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_TV)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (input_frame_format == media::VideoFrame::HOLE) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    VideoFrameExternalResources external_resources;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    external_resources.type = VideoFrameExternalResources::HOLE;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return external_resources;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Only YUV software video frames are supported.
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(input_frame_format == media::VideoFrame::YV12 ||
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         input_frame_format == media::VideoFrame::YV12A ||
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         input_frame_format == media::VideoFrame::YV16);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (input_frame_format != media::VideoFrame::YV12 &&
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      input_frame_format != media::VideoFrame::YV12A &&
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      input_frame_format != media::VideoFrame::YV16)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return VideoFrameExternalResources();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool software_compositor = !resource_provider_->GraphicsContext3D();
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GLenum output_resource_format = kYUVResourceFormat;
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t output_plane_count =
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      (input_frame_format == media::VideoFrame::YV12A) ? 4 : 3;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // conversion here. That involves an extra copy of each frame to a bitmap.
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Obviously, this is suboptimal and should be addressed once ubercompositor
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // starts shaping up.
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (software_compositor) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_resource_format = kRGBResourceFormat;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_plane_count = 1;
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int max_resource_size = resource_provider_->max_texture_size();
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Size coded_frame_size = video_frame->coded_size();
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<PlaneResource> plane_resources;
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool allocation_success = true;
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < output_plane_count; ++i) {
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Size output_plane_resource_size =
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SoftwarePlaneDimension(input_frame_format,
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               coded_frame_size,
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               output_resource_format,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               i);
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (output_plane_resource_size.IsEmpty() ||
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_plane_resource_size.width() > max_resource_size ||
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_plane_resource_size.height() > max_resource_size) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      allocation_success = false;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ResourceProvider::ResourceId resource_id = 0;
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gpu::Mailbox mailbox;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Try recycle a previously-allocated resource.
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < recycled_resources_.size(); ++i) {
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (recycled_resources_[i].resource_format == output_resource_format &&
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          recycled_resources_[i].resource_size == output_plane_resource_size) {
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        resource_id = recycled_resources_[i].resource_id;
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        mailbox = recycled_resources_[i].mailbox;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        recycled_resources_.erase(recycled_resources_.begin() + i);
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (resource_id == 0) {
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // TODO(danakj): Abstract out hw/sw resource create/delete from
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // ResourceProvider and stop using ResourceProvider in this class.
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      resource_id =
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          resource_provider_->CreateResource(output_plane_resource_size,
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             output_resource_format,
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             ResourceProvider::TextureUsageAny);
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      DCHECK(mailbox.IsZero());
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!software_compositor) {
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        WebKit::WebGraphicsContext3D* context =
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            resource_provider_->GraphicsContext3D();
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        DCHECK(context);
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        GLC(context, context->genMailboxCHROMIUM(mailbox.name));
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (mailbox.IsZero()) {
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          resource_provider_->DeleteResource(resource_id);
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          resource_id = 0;
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        } else {
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          ResourceProvider::ScopedWriteLockGL lock(
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              resource_provider_, resource_id);
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          GLC(context, context->bindTexture(GL_TEXTURE_2D, lock.texture_id()));
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D,
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                       mailbox.name));
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        }
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (resource_id)
219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        all_resources_.push_back(resource_id);
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (resource_id == 0) {
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      allocation_success = false;
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(software_compositor || !mailbox.IsZero());
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    plane_resources.push_back(PlaneResource(resource_id,
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            output_plane_resource_size,
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            output_resource_format,
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                            mailbox));
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!allocation_success) {
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < plane_resources.size(); ++i)
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      DeleteResource(plane_resources[i].resource_id);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return VideoFrameExternalResources();
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VideoFrameExternalResources external_resources;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (software_compositor) {
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_EQ(plane_resources.size(), 1u);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_EQ(plane_resources[0].resource_format, kRGBResourceFormat);
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(plane_resources[0].mailbox.IsZero());
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!video_renderer_)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      video_renderer_.reset(new media::SkCanvasVideoRenderer);
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ResourceProvider::ScopedWriteLockSoftware lock(
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          resource_provider_, plane_resources[0].resource_id);
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      video_renderer_->Paint(video_frame.get(),
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             lock.sk_canvas(),
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             video_frame->visible_rect(),
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             0xff);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // In software mode, the resource provider won't be lost. Soon this callback
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // will be called directly from the resource provider, same as 3d
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // compositing mode, so this raw unretained resource_provider will always
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // be valid when the callback is fired.
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RecycleResourceData recycle_data = {
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[0].resource_id,
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[0].resource_size,
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[0].resource_format,
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      gpu::Mailbox()
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    };
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TextureMailbox::ReleaseCallback callback_to_free_resource =
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&RecycleResource,
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   AsWeakPtr(),
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   recycle_data);
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    external_resources.software_resources.push_back(
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        plane_resources[0].resource_id);
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    external_resources.software_release_callback = callback_to_free_resource;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return external_resources;
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < plane_resources.size(); ++i) {
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Update each plane's resource id with its content.
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_EQ(plane_resources[i].resource_format,
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              static_cast<unsigned>(kYUVResourceFormat));
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8_t* input_plane_pixels = video_frame->data(i);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Rect image_rect(0,
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         0,
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         video_frame->stride(i),
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         plane_resources[i].resource_size.height());
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Rect source_rect(plane_resources[i].resource_size);
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider_->SetPixels(plane_resources[i].resource_id,
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  input_plane_pixels,
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  image_rect,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  source_rect,
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  gfx::Vector2d());
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RecycleResourceData recycle_data = {
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[i].resource_id,
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[i].resource_size,
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      plane_resources[i].resource_format,
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      plane_resources[i].mailbox
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    };
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TextureMailbox::ReleaseCallback callback_to_free_resource =
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&RecycleResource,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   AsWeakPtr(),
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   recycle_data);
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    external_resources.mailboxes.push_back(
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        TextureMailbox(plane_resources[i].mailbox,
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       callback_to_free_resource));
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return external_resources;
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic void ReturnTexture(
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder,
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    unsigned sync_point,
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool lost_resource) {
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  mailbox_holder->Return(sync_point);
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<media::VideoFrame>& video_frame) {
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  media::VideoFrame::Format frame_format = video_frame->format();
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE);
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (frame_format != media::VideoFrame::NATIVE_TEXTURE)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return VideoFrameExternalResources();
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WebKit::WebGraphicsContext3D* context =
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      resource_provider_->GraphicsContext3D();
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!context)
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return VideoFrameExternalResources();
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VideoFrameExternalResources external_resources;
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (video_frame->texture_target()) {
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GL_TEXTURE_2D:
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GL_TEXTURE_EXTERNAL_OES:
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      external_resources.type =
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE;
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GL_TEXTURE_RECTANGLE_ARB:
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      external_resources.type = VideoFrameExternalResources::IO_SURFACE;
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return VideoFrameExternalResources();
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder =
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      video_frame->texture_mailbox();
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TextureMailbox::ReleaseCallback callback_to_return_resource =
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ReturnTexture, mailbox_holder);
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  external_resources.mailboxes.push_back(
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TextureMailbox(mailbox_holder->mailbox(),
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback_to_return_resource,
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     video_frame->texture_target(),
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     mailbox_holder->sync_point()));
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return external_resources;
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoResourceUpdater::RecycleResource(
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::WeakPtr<VideoResourceUpdater> updater,
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RecycleResourceData data,
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned sync_point,
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool lost_resource) {
375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!updater.get()) {
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Resource was already deleted.
377a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
378a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
379a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WebKit::WebGraphicsContext3D* context =
381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      updater->resource_provider_->GraphicsContext3D();
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (context && sync_point)
383a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GLC(context, context->waitSyncPoint(sync_point));
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (lost_resource) {
386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    updater->DeleteResource(data.resource_id);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Drop recycled resources that are the wrong format.
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!updater->recycled_resources_.empty() &&
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         updater->recycled_resources_.back().resource_format !=
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         data.resource_format) {
394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    updater->DeleteResource(updater->recycled_resources_.back().resource_id);
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    updater->recycled_resources_.pop_back();
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PlaneResource recycled_resource(data.resource_id,
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  data.resource_size,
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  data.resource_format,
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  data.mailbox);
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  updater->recycled_resources_.push_back(recycled_resource);
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace cc
406