summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/layers/io_surface_layer_impl.cc34
-rw-r--r--cc/layers/io_surface_layer_impl.h3
-rw-r--r--cc/layers/video_frame_provider_client_impl.cc1
-rw-r--r--cc/layers/video_layer_impl.cc445
-rw-r--r--cc/layers/video_layer_impl.h42
-rw-r--r--cc/output/delegating_renderer_unittest.cc10
-rw-r--r--cc/output/gl_renderer.cc18
-rw-r--r--cc/quads/draw_quad_unittest.cc126
-rw-r--r--cc/quads/io_surface_draw_quad.cc13
-rw-r--r--cc/quads/io_surface_draw_quad.h6
-rw-r--r--cc/quads/stream_video_draw_quad.cc13
-rw-r--r--cc/quads/stream_video_draw_quad.h6
-rw-r--r--cc/quads/yuv_video_draw_quad.cc35
-rw-r--r--cc/quads/yuv_video_draw_quad.h18
-rw-r--r--cc/resources/video_resource_updater.cc326
-rw-r--r--cc/resources/video_resource_updater.h87
-rw-r--r--cc/test/render_pass_test_common.cc38
-rw-r--r--cc/test/test_web_graphics_context_3d.cc13
-rw-r--r--cc/test/test_web_graphics_context_3d.h6
-rw-r--r--cc/trees/layer_tree_host_unittest_delegated.cc11
-rw-r--r--content/common/cc_messages.h17
-rw-r--r--content/common/cc_messages_unittest.cc51
23 files changed, 777 insertions, 544 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 1ad272c..474ca6e 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -336,6 +336,8 @@
'layers/video_layer.h',
'layers/video_layer_impl.cc',
'layers/video_layer_impl.h',
+ 'resources/video_resource_updater.cc',
+ 'resources/video_resource_updater.h',
'scheduler/vsync_time_source.cc',
'scheduler/vsync_time_source.h',
'base/worker_pool.cc',
diff --git a/cc/layers/io_surface_layer_impl.cc b/cc/layers/io_surface_layer_impl.cc
index 2c95c00..2d4f9b7 100644
--- a/cc/layers/io_surface_layer_impl.cc
+++ b/cc/layers/io_surface_layer_impl.cc
@@ -27,11 +27,25 @@ IOSurfaceLayerImpl::~IOSurfaceLayerImpl() {
if (!io_surface_texture_id_)
return;
- OutputSurface* output_surface = layer_tree_impl()->output_surface();
- // FIXME: Implement this path for software compositing.
- WebKit::WebGraphicsContext3D* context3d = output_surface->context3d();
- if (context3d)
- context3d->deleteTexture(io_surface_texture_id_);
+ DestroyTexture();
+}
+
+void IOSurfaceLayerImpl::DestroyTexture() {
+ if (io_surface_resource_id_) {
+ ResourceProvider* resource_provider =
+ layer_tree_impl()->resource_provider();
+ resource_provider->DeleteResource(io_surface_resource_id_);
+ io_surface_resource_id_ = 0;
+ }
+
+ if (io_surface_texture_id_) {
+ OutputSurface* output_surface = layer_tree_impl()->output_surface();
+ // FIXME: Implement this path for software compositing.
+ WebKit::WebGraphicsContext3D* context3d = output_surface->context3d();
+ if (context3d)
+ context3d->deleteTexture(io_surface_texture_id_);
+ io_surface_texture_id_ = 0;
+ }
}
scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl(
@@ -59,8 +73,12 @@ void IOSurfaceLayerImpl::WillDraw(ResourceProvider* resource_provider) {
}
// FIXME: Do this in a way that we can track memory usage.
- if (!io_surface_texture_id_)
+ if (!io_surface_texture_id_) {
io_surface_texture_id_ = context3d->createTexture();
+ io_surface_resource_id_ =
+ resource_provider->CreateResourceFromExternalTexture(
+ io_surface_texture_id_);
+ }
GLC(context3d, context3d->activeTexture(GL_TEXTURE0));
GLC(context3d,
@@ -107,7 +125,7 @@ void IOSurfaceLayerImpl::AppendQuads(QuadSink* quad_sink,
quad_rect,
opaque_rect,
io_surface_size_,
- io_surface_texture_id_,
+ io_surface_resource_id_,
IOSurfaceDrawQuad::FLIPPED);
quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
}
@@ -125,7 +143,7 @@ void IOSurfaceLayerImpl::DumpLayerProperties(std::string* str,
void IOSurfaceLayerImpl::DidLoseOutputSurface() {
// We don't have a valid texture ID in the new context; however,
// the IOSurface is still valid.
- io_surface_texture_id_ = 0;
+ DestroyTexture();
io_surface_changed_ = true;
}
diff --git a/cc/layers/io_surface_layer_impl.h b/cc/layers/io_surface_layer_impl.h
index 1f40215..8c8f450 100644
--- a/cc/layers/io_surface_layer_impl.h
+++ b/cc/layers/io_surface_layer_impl.h
@@ -38,12 +38,15 @@ class CC_EXPORT IOSurfaceLayerImpl : public LayerImpl {
private:
IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id);
+ void DestroyTexture();
+
virtual const char* LayerTypeAsString() const OVERRIDE;
unsigned io_surface_id_;
gfx::Size io_surface_size_;
bool io_surface_changed_;
unsigned io_surface_texture_id_;
+ unsigned io_surface_resource_id_;
DISALLOW_COPY_AND_ASSIGN(IOSurfaceLayerImpl);
};
diff --git a/cc/layers/video_frame_provider_client_impl.cc b/cc/layers/video_frame_provider_client_impl.cc
index 6028683..732bbbb 100644
--- a/cc/layers/video_frame_provider_client_impl.cc
+++ b/cc/layers/video_frame_provider_client_impl.cc
@@ -6,6 +6,7 @@
#include "cc/base/math_util.h"
#include "cc/layers/video_layer_impl.h"
+#include "media/base/video_frame.h"
namespace cc {
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index f87cacc..233abce 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -4,21 +4,18 @@
#include "cc/layers/video_layer_impl.h"
+#include "base/bind.h"
#include "base/logging.h"
-#include "cc/base/math_util.h"
#include "cc/layers/quad_sink.h"
#include "cc/layers/video_frame_provider_client_impl.h"
-#include "cc/output/renderer.h"
#include "cc/quads/io_surface_draw_quad.h"
#include "cc/quads/stream_video_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "cc/resources/resource_provider.h"
#include "cc/trees/layer_tree_impl.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "media/filters/skcanvas_video_renderer.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
+#include "cc/trees/proxy.h"
+#include "media/base/video_frame.h"
#if defined(GOOGLE_TV)
#include "cc/quads/solid_color_draw_quad.h"
@@ -40,10 +37,7 @@ scoped_ptr<VideoLayerImpl> VideoLayerImpl::Create(
VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* tree_impl, int id)
: LayerImpl(tree_impl, id),
- frame_(NULL),
- format_(media::VideoFrame::INVALID),
- convert_yuv_(false),
- external_texture_resource_(0) {}
+ frame_(NULL) {}
VideoLayerImpl::~VideoLayerImpl() {
if (!provider_client_impl_->Stopped()) {
@@ -56,13 +50,6 @@ VideoLayerImpl::~VideoLayerImpl() {
DCHECK(layer_tree_impl()->proxy()->IsMainThreadBlocked());
provider_client_impl_->Stop();
}
- FreeFramePlanes(layer_tree_impl()->resource_provider());
-
-#ifndef NDEBUG
- for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i)
- DCHECK(!frame_planes_[i].resource_id);
- DCHECK(!external_texture_resource_);
-#endif
}
scoped_ptr<LayerImpl> VideoLayerImpl::CreateLayerImpl(
@@ -81,10 +68,11 @@ void VideoLayerImpl::DidBecomeActive() {
provider_client_impl_->set_active_video_layer(this);
}
+static void EmptyCallback(unsigned sync_point) {}
+
void VideoLayerImpl::WillDraw(ResourceProvider* resource_provider) {
LayerImpl::WillDraw(resource_provider);
-
// Explicitly acquire and release the provider mutex so it can be held from
// WillDraw to DidDraw. Since the compositor thread is in the middle of
// drawing, the layer will not be destroyed before DidDraw is called.
@@ -94,61 +82,40 @@ void VideoLayerImpl::WillDraw(ResourceProvider* resource_provider) {
// lock should not cause a deadlock.
frame_ = provider_client_impl_->AcquireLockAndCurrentFrame();
- WillDrawInternal(resource_provider);
- FreeUnusedFramePlanes(resource_provider);
-
- if (!frame_)
+ if (!frame_) {
provider_client_impl_->ReleaseLock();
-}
-
-void VideoLayerImpl::WillDrawInternal(ResourceProvider* resource_provider) {
- DCHECK(!external_texture_resource_);
-
- if (!frame_)
return;
+ }
- format_ = frame_->format();
-
-#if defined(GOOGLE_TV)
- if (format_ == media::VideoFrame::HOLE)
- return;
-#endif
-
- // If these fail, we'll have to add draw logic that handles offset bitmap/
- // texture UVs. For now, just expect (0, 0) offset, since all our decoders
- // so far don't offset.
- DCHECK_EQ(frame_->visible_rect().x(), 0);
- DCHECK_EQ(frame_->visible_rect().y(), 0);
-
- if (format_ == media::VideoFrame::INVALID) {
- provider_client_impl_->PutCurrentFrame(frame_);
- frame_ = NULL;
- return;
+ if (!updater_)
+ updater_.reset(new VideoResourceUpdater(resource_provider));
+
+ VideoFrameExternalResources external_resources;
+ if (frame_->format() == media::VideoFrame::NATIVE_TEXTURE) {
+ // TODO(danakj): To make this work for ubercomp, push this code out to
+ // WebMediaPlayer and have it set a callback so it knows it can reuse the
+ // texture.
+ TextureMailbox::ReleaseCallback empty_callback = base::Bind(&EmptyCallback);
+ external_resources = updater_->CreateForHardwarePlanes(
+ frame_, empty_callback);
+ } else {
+ external_resources = updater_->CreateForSoftwarePlanes(frame_);
}
- // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
- // conversion here. That involves an extra copy of each frame to a bitmap.
- // Obviously, this is suboptimal and should be addressed once ubercompositor
- // starts shaping up.
- convert_yuv_ =
- resource_provider->default_resource_type() == ResourceProvider::Bitmap &&
- (format_ == media::VideoFrame::YV12 ||
- format_ == media::VideoFrame::YV16);
-
- if (convert_yuv_)
- format_ = media::VideoFrame::RGB32;
-
- if (!SetupFramePlanes(resource_provider)) {
- provider_client_impl_->PutCurrentFrame(frame_);
- frame_ = NULL;
+ frame_resource_type_ = external_resources.type;
+
+ if (external_resources.type ==
+ VideoFrameExternalResources::SOFTWARE_RESOURCE) {
+ software_resources_ = external_resources.software_resources;
+ software_release_callback_ =
+ external_resources.software_release_callback;
return;
}
- if (format_ == media::VideoFrame::NATIVE_TEXTURE &&
- frame_->texture_target() == GL_TEXTURE_2D) {
- external_texture_resource_ =
- resource_provider->CreateResourceFromExternalTexture(
- frame_->texture_id());
+ for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) {
+ frame_resources_.push_back(
+ resource_provider->CreateResourceFromTextureMailbox(
+ external_resources.mailboxes[i]));
}
}
@@ -161,64 +128,62 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
quad_sink->UseSharedQuadState(CreateSharedQuadState());
AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
- // TODO(danakj): When we pass quads out of process, we need to double-buffer,
- // or otherwise synchonize use of all textures in the quad.
-
gfx::Rect quad_rect(content_bounds());
gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
gfx::Rect visible_rect = frame_->visible_rect();
gfx::Size coded_size = frame_->coded_size();
- // pixels for macroblocked formats.
+ // Pixels for macroblocked formats.
float tex_width_scale =
static_cast<float>(visible_rect.width()) / coded_size.width();
float tex_height_scale =
static_cast<float>(visible_rect.height()) / coded_size.height();
-#if defined(GOOGLE_TV)
- // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not
- // maintained by the general compositor team. Please contact the following
- // people instead:
- //
- // wonsik@chromium.org
- // ycheo@chromium.org
-
- if (frame_->format() == media::VideoFrame::HOLE) {
- scoped_ptr<SolidColorDrawQuad> solid_color_draw_quad =
- SolidColorDrawQuad::Create();
- // Create a solid color quad with transparent black and force no
- // blending.
- solid_color_draw_quad->SetAll(
- shared_quad_state, quad_rect, quad_rect, quad_rect, false,
- SK_ColorTRANSPARENT);
- quad_sink->Append(solid_color_draw_quad.PassAs<DrawQuad>(),
- append_quads_data);
- return;
- }
-#endif
-
- switch (format_) {
- case media::VideoFrame::YV12:
- case media::VideoFrame::YV16: {
- // YUV software decoder.
- const FramePlane& y_plane = frame_planes_[media::VideoFrame::kYPlane];
- const FramePlane& u_plane = frame_planes_[media::VideoFrame::kUPlane];
- const FramePlane& v_plane = frame_planes_[media::VideoFrame::kVPlane];
+ switch (frame_resource_type_) {
+ // TODO(danakj): Remove this, hide it in the hardware path.
+ case VideoFrameExternalResources::SOFTWARE_RESOURCE: {
+ DCHECK_EQ(frame_resources_.size(), 0u);
+ DCHECK_EQ(software_resources_.size(), 1u);
+ if (software_resources_.size() < 1u)
+ break;
+ bool premultiplied_alpha = true;
+ gfx::PointF uv_top_left(0.f, 0.f);
+ gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale);
+ float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ bool flipped = false;
+ scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create();
+ texture_quad->SetNew(shared_quad_state,
+ quad_rect,
+ opaque_rect,
+ software_resources_[0],
+ premultiplied_alpha,
+ uv_top_left,
+ uv_bottom_right,
+ opacity,
+ flipped);
+ quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data);
+ break;
+ }
+ case VideoFrameExternalResources::YUV_RESOURCE: {
+ DCHECK_EQ(frame_resources_.size(), 3u);
+ if (frame_resources_.size() < 3u)
+ break;
gfx::SizeF tex_scale(tex_width_scale, tex_height_scale);
scoped_ptr<YUVVideoDrawQuad> yuv_video_quad = YUVVideoDrawQuad::Create();
yuv_video_quad->SetNew(shared_quad_state,
quad_rect,
opaque_rect,
tex_scale,
- y_plane,
- u_plane,
- v_plane);
+ frame_resources_[0],
+ frame_resources_[1],
+ frame_resources_[2]);
quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>(), append_quads_data);
break;
}
- case media::VideoFrame::RGB32: {
- // RGBA software decoder: a converted YUV frame (see: convert_yuv_).
- const FramePlane& plane = frame_planes_[media::VideoFrame::kRGBPlane];
+ case VideoFrameExternalResources::RGB_RESOURCE: {
+ DCHECK_EQ(frame_resources_.size(), 1u);
+ if (frame_resources_.size() < 1u)
+ break;
bool premultiplied_alpha = true;
gfx::PointF uv_top_left(0.f, 0.f);
gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale);
@@ -228,7 +193,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
texture_quad->SetNew(shared_quad_state,
quad_rect,
opaque_rect,
- plane.resource_id,
+ frame_resources_[0],
premultiplied_alpha,
uv_top_left,
uv_bottom_right,
@@ -237,70 +202,64 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data);
break;
}
- case media::VideoFrame::NATIVE_TEXTURE:
- switch (frame_->texture_target()) {
- case GL_TEXTURE_2D: {
- // NativeTexture hardware decoder.
- bool premultiplied_alpha = true;
- gfx::PointF uv_top_left(0.f, 0.f);
- gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale);
- float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
- bool flipped = false;
- scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create();
- texture_quad->SetNew(shared_quad_state,
- quad_rect,
- opaque_rect,
- external_texture_resource_,
- premultiplied_alpha,
- uv_top_left,
- uv_bottom_right,
- opacity,
- flipped);
- quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data);
- break;
- }
- case GL_TEXTURE_RECTANGLE_ARB: {
- gfx::Size visible_size(visible_rect.width(), visible_rect.height());
- scoped_ptr<IOSurfaceDrawQuad> io_surface_quad =
- IOSurfaceDrawQuad::Create();
- io_surface_quad->SetNew(shared_quad_state,
- quad_rect,
- opaque_rect,
- visible_size,
- frame_->texture_id(),
- IOSurfaceDrawQuad::UNFLIPPED);
- quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(),
- append_quads_data);
- break;
- }
- case GL_TEXTURE_EXTERNAL_OES: {
- // StreamTexture hardware decoder.
- gfx::Transform transform(
- provider_client_impl_->stream_texture_matrix());
- transform.Scale(tex_width_scale, tex_height_scale);
- scoped_ptr<StreamVideoDrawQuad> stream_video_quad =
- StreamVideoDrawQuad::Create();
- stream_video_quad->SetNew(shared_quad_state,
- quad_rect,
- opaque_rect,
- frame_->texture_id(),
- transform);
- quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(),
- append_quads_data);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
+ case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: {
+ DCHECK_EQ(frame_resources_.size(), 1u);
+ if (frame_resources_.size() < 1u)
+ break;
+ gfx::Transform transform(
+ provider_client_impl_->stream_texture_matrix());
+ transform.Scale(tex_width_scale, tex_height_scale);
+ scoped_ptr<StreamVideoDrawQuad> stream_video_quad =
+ StreamVideoDrawQuad::Create();
+ stream_video_quad->SetNew(shared_quad_state,
+ quad_rect,
+ opaque_rect,
+ frame_resources_[0],
+ transform);
+ quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(),
+ append_quads_data);
break;
- case media::VideoFrame::INVALID:
- case media::VideoFrame::EMPTY:
- case media::VideoFrame::I420:
+ }
+ case VideoFrameExternalResources::IO_SURFACE: {
+ DCHECK_EQ(frame_resources_.size(), 1u);
+ if (frame_resources_.size() < 1u)
+ break;
+ gfx::Size visible_size(visible_rect.width(), visible_rect.height());
+ scoped_ptr<IOSurfaceDrawQuad> io_surface_quad =
+ IOSurfaceDrawQuad::Create();
+ io_surface_quad->SetNew(shared_quad_state,
+ quad_rect,
+ opaque_rect,
+ visible_size,
+ frame_resources_[0],
+ IOSurfaceDrawQuad::UNFLIPPED);
+ quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(),
+ append_quads_data);
+ break;
+ }
#if defined(GOOGLE_TV)
- case media::VideoFrame::HOLE:
+ // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not
+ // maintained by the general compositor team. Please contact the following
+ // people instead:
+ //
+ // wonsik@chromium.org
+ // ycheo@chromium.org
+ case VideoFrameExternalResources::HOLE: {
+ DCHECK_EQ(frame_resources_.size(), 0u);
+ scoped_ptr<SolidColorDrawQuad> solid_color_draw_quad =
+ SolidColorDrawQuad::Create();
+ // Create a solid color quad with transparent black and force no
+ // blending.
+ solid_color_draw_quad->SetAll(
+ shared_quad_state, quad_rect, quad_rect, quad_rect, false,
+ SK_ColorTRANSPARENT);
+ quad_sink->Append(solid_color_draw_quad.PassAs<DrawQuad>(),
+ append_quads_data);
+ break;
+ }
#endif
- NOTREACHED();
+ case VideoFrameExternalResources::NONE:
+ NOTIMPLEMENTED();
break;
}
}
@@ -311,15 +270,17 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) {
if (!frame_)
return;
- if (format_ == media::VideoFrame::NATIVE_TEXTURE &&
- frame_->texture_target() == GL_TEXTURE_2D) {
- DCHECK(external_texture_resource_);
- // TODO(danakj): the following assert will not be true when sending
- // resources to a parent compositor. We will probably need to hold on to
- // frame_ for longer, and have several "current frames" in the pipeline.
- DCHECK(!resource_provider->InUseByConsumer(external_texture_resource_));
- resource_provider->DeleteResource(external_texture_resource_);
- external_texture_resource_ = 0;
+ if (frame_resource_type_ ==
+ VideoFrameExternalResources::SOFTWARE_RESOURCE) {
+ for (size_t i = 0; i < software_resources_.size(); ++i)
+ software_release_callback_.Run(0);
+
+ software_resources_.clear();
+ software_release_callback_.Reset();
+ } else {
+ for (size_t i = 0; i < frame_resources_.size(); ++i)
+ resource_provider->DeleteResource(frame_resources_[i]);
+ frame_resources_.clear();
}
provider_client_impl_->PutCurrentFrame(frame_);
@@ -328,140 +289,8 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) {
provider_client_impl_->ReleaseLock();
}
-static gfx::Size VideoFrameDimension(media::VideoFrame* frame, int plane) {
- gfx::Size dimensions = frame->coded_size();
- switch (frame->format()) {
- case media::VideoFrame::YV12:
- if (plane != media::VideoFrame::kYPlane) {
- dimensions.set_width(dimensions.width() / 2);
- dimensions.set_height(dimensions.height() / 2);
- }
- break;
- case media::VideoFrame::YV16:
- if (plane != media::VideoFrame::kYPlane)
- dimensions.set_width(dimensions.width() / 2);
- break;
- default:
- break;
- }
- return dimensions;
-}
-
-bool VideoLayerImpl::FramePlane::AllocateData(
- ResourceProvider* resource_provider) {
- if (resource_id)
- return true;
-
- resource_id = resource_provider->CreateResource(
- size, format, ResourceProvider::TextureUsageAny);
- return resource_id != 0;
-}
-
-void VideoLayerImpl::FramePlane::FreeData(ResourceProvider* resource_provider) {
- if (!resource_id)
- return;
-
- resource_provider->DeleteResource(resource_id);
- resource_id = 0;
-}
-
-// Convert media::VideoFrame::Format to OpenGL enum values.
-static GLenum ConvertVFCFormatToGLenum(const media::VideoFrame::Format format) {
- switch (format) {
- case media::VideoFrame::YV12:
- case media::VideoFrame::YV16:
- return GL_LUMINANCE;
- case media::VideoFrame::RGB32:
- return GL_RGBA;
- case media::VideoFrame::NATIVE_TEXTURE:
-#if defined(GOOGLE_TV)
- case media::VideoFrame::HOLE:
-#endif
- case media::VideoFrame::INVALID:
- case media::VideoFrame::EMPTY:
- case media::VideoFrame::I420:
- NOTREACHED();
- break;
- }
- return GL_INVALID_VALUE;
-}
-
-bool VideoLayerImpl::SetupFramePlanes(ResourceProvider* resource_provider) {
- const size_t plane_count = media::VideoFrame::NumPlanes(format_);
- if (!plane_count)
- return true;
-
- const int max_texture_size = resource_provider->max_texture_size();
- const GLenum pixel_format = ConvertVFCFormatToGLenum(format_);
- for (size_t plane_index = 0; plane_index < plane_count; ++plane_index) {
- VideoLayerImpl::FramePlane* plane = &frame_planes_[plane_index];
-
- gfx::Size required_texture_size = VideoFrameDimension(frame_, plane_index);
- // TODO(danakj): Remove the test against max_texture_size when tiled layers
- // are implemented.
- if (required_texture_size.IsEmpty() ||
- required_texture_size.width() > max_texture_size ||
- required_texture_size.height() > max_texture_size)
- return false;
-
- if (plane->size != required_texture_size || plane->format != pixel_format) {
- plane->FreeData(resource_provider);
- plane->size = required_texture_size;
- plane->format = pixel_format;
- }
-
- if (!plane->AllocateData(resource_provider))
- return false;
- }
-
- if (convert_yuv_) {
- if (!video_renderer_)
- video_renderer_.reset(new media::SkCanvasVideoRenderer);
- const VideoLayerImpl::FramePlane& plane =
- frame_planes_[media::VideoFrame::kRGBPlane];
- ResourceProvider::ScopedWriteLockSoftware lock(resource_provider,
- plane.resource_id);
- video_renderer_->Paint(frame_,
- lock.sk_canvas(),
- frame_->visible_rect(),
- 0xff);
- return true;
- }
-
- for (size_t plane_index = 0; plane_index < plane_count; ++plane_index) {
- const VideoLayerImpl::FramePlane& plane = frame_planes_[plane_index];
- // Only planar formats planes should need upload.
- DCHECK_EQ(plane.format, static_cast<unsigned>(GL_LUMINANCE));
- const uint8_t* software_plane_pixels = frame_->data(plane_index);
- gfx::Rect image_rect(0,
- 0,
- frame_->stride(plane_index),
- plane.size.height());
- gfx::Rect source_rect(plane.size);
- resource_provider->SetPixels(plane.resource_id,
- software_plane_pixels,
- image_rect,
- source_rect,
- gfx::Vector2d());
- }
- return true;
-}
-
-void VideoLayerImpl::FreeFramePlanes(ResourceProvider* resource_provider) {
- for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i)
- frame_planes_[i].FreeData(resource_provider);
-}
-
-void VideoLayerImpl::FreeUnusedFramePlanes(
- ResourceProvider* resource_provider) {
- size_t first_unused_plane = (frame_ ? media::VideoFrame::NumPlanes(format_)
- : 0);
- for (size_t i = first_unused_plane; i < media::VideoFrame::kMaxPlanes; ++i)
- frame_planes_[i].FreeData(resource_provider);
-}
-
void VideoLayerImpl::DidLoseOutputSurface() {
- FreeFramePlanes(layer_tree_impl()->resource_provider());
+ updater_.reset();
}
void VideoLayerImpl::SetNeedsRedraw() {
diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h
index da1c53f..b272f8f 100644
--- a/cc/layers/video_layer_impl.h
+++ b/cc/layers/video_layer_impl.h
@@ -5,22 +5,16 @@
#ifndef CC_LAYERS_VIDEO_LAYER_IMPL_H_
#define CC_LAYERS_VIDEO_LAYER_IMPL_H_
-#include "base/callback.h"
-#include "base/synchronization/lock.h"
#include "cc/base/cc_export.h"
#include "cc/layers/layer_impl.h"
-#include "cc/layers/video_frame_provider.h"
-#include "media/base/video_frame.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/transform.h"
+#include "cc/resources/video_resource_updater.h"
namespace media {
-class SkCanvasVideoRenderer;
+class VideoFrame;
}
namespace cc {
-class LayerTreeHostImpl;
+class VideoFrameProvider;
class VideoFrameProviderClientImpl;
class CC_EXPORT VideoLayerImpl : public LayerImpl {
@@ -46,37 +40,23 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
void SetProviderClientImpl(
scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl);
- struct FramePlane {
- ResourceProvider::ResourceId resource_id;
- gfx::Size size;
- GLenum format;
-
- FramePlane() : resource_id(0), format(GL_LUMINANCE) {}
-
- bool AllocateData(ResourceProvider* resource_provider);
- void FreeData(ResourceProvider* resource_provider);
- };
-
private:
VideoLayerImpl(LayerTreeImpl* tree_impl, int id);
virtual const char* LayerTypeAsString() const OVERRIDE;
- void WillDrawInternal(ResourceProvider* resource_provider);
- bool SetupFramePlanes(ResourceProvider* resource_provider);
- void FreeFramePlanes(ResourceProvider* resource_provider);
- void FreeUnusedFramePlanes(ResourceProvider* resource_provider);
-
scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl_;
scoped_refptr<media::VideoFrame> frame_;
- media::VideoFrame::Format format_;
- bool convert_yuv_;
- ResourceProvider::ResourceId external_texture_resource_;
- scoped_ptr<media::SkCanvasVideoRenderer> video_renderer_;
- // Each index in this array corresponds to a plane in media::VideoFrame.
- FramePlane frame_planes_[media::VideoFrame::kMaxPlanes];
+ scoped_ptr<VideoResourceUpdater> updater_;
+ VideoFrameExternalResources::ResourceType frame_resource_type_;
+ std::vector<ResourceProvider::ResourceId> frame_resources_;
+
+ // TODO(danakj): Remove these, hide software path inside ResourceProvider and
+ // ExternalResource (aka TextureMailbox) classes.
+ std::vector<unsigned> software_resources_;
+ TextureMailbox::ReleaseCallback software_release_callback_;
DISALLOW_COPY_AND_ASSIGN(VideoLayerImpl);
};
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
index e270860..cf85cb9 100644
--- a/cc/output/delegating_renderer_unittest.cc
+++ b/cc/output/delegating_renderer_unittest.cc
@@ -120,12 +120,12 @@ class DelegatingRendererTestResources : public DelegatingRendererTest {
ASSERT_TRUE(last_frame.delegated_frame_data);
EXPECT_EQ(2u, last_frame.delegated_frame_data->render_pass_list.size());
- // Each render pass has 7 resources in it. And the root render pass has a
- // mask resource used when drawing the child render pass. The number 7 may
- // change if AppendOneOfEveryQuadType is updated, and the value here should
- // be updated accordingly.
+ // Each render pass has 9 resources in it. And the root render pass has a
+ // mask resource used when drawing the child render pass. The number 9 may
+ // change if AppendOneOfEveryQuadType() is updated, and the value here
+ // should be updated accordingly.
EXPECT_EQ(
- 15u, last_frame.delegated_frame_data->resource_list.size());
+ 19u, last_frame.delegated_frame_data->resource_list.size());
EndTest();
}
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index d449ee7..14b5365 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -1342,19 +1342,15 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
const VideoYUVProgram* program = GetVideoYUVProgram(texCoordPrecision);
DCHECK(program && (program->initialized() || IsContextLost()));
- const VideoLayerImpl::FramePlane& y_plane = quad->y_plane;
- const VideoLayerImpl::FramePlane& u_plane = quad->u_plane;
- const VideoLayerImpl::FramePlane& v_plane = quad->v_plane;
-
GLC(Context(), Context()->activeTexture(GL_TEXTURE1));
ResourceProvider::ScopedSamplerGL y_plane_lock(
- resource_provider_, y_plane.resource_id, GL_TEXTURE_2D, GL_LINEAR);
+ resource_provider_, quad->y_plane_resource_id, GL_TEXTURE_2D, GL_LINEAR);
GLC(Context(), Context()->activeTexture(GL_TEXTURE2));
ResourceProvider::ScopedSamplerGL u_plane_lock(
- resource_provider_, u_plane.resource_id, GL_TEXTURE_2D, GL_LINEAR);
+ resource_provider_, quad->u_plane_resource_id, GL_TEXTURE_2D, GL_LINEAR);
GLC(Context(), Context()->activeTexture(GL_TEXTURE3));
ResourceProvider::ScopedSamplerGL v_plane_lock(
- resource_provider_, v_plane.resource_id, GL_TEXTURE_2D, GL_LINEAR);
+ resource_provider_, quad->v_plane_resource_id, GL_TEXTURE_2D, GL_LINEAR);
SetUseProgram(program->program());
@@ -1424,8 +1420,10 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
Context()->uniformMatrix4fv(
program->vertex_shader().tex_matrix_location(), 1, false, gl_matrix));
+ ResourceProvider::ScopedReadLockGL lock(resource_provider_,
+ quad->resource_id);
GLC(Context(),
- Context()->bindTexture(GL_TEXTURE_EXTERNAL_OES, quad->texture_id));
+ Context()->bindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id()));
GLC(Context(),
Context()->uniform1i(program->fragment_shader().sampler_location(), 0));
@@ -1722,9 +1720,11 @@ void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
Context()->uniform1fv(
binding.vertex_opacity_location, 4, vertex_opacity));
+ ResourceProvider::ScopedReadLockGL lock(resource_provider_,
+ quad->io_surface_resource_id);
GLC(Context(),
Context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB,
- quad->io_surface_texture_id));
+ lock.texture_id()));
DrawQuadGeometry(
frame, quad->quadTransform(), quad->rect, binding.matrix_location);
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc
index 7177e6b..ae5a7f1 100644
--- a/cc/quads/draw_quad_unittest.cc
+++ b/cc/quads/draw_quad_unittest.cc
@@ -336,22 +336,22 @@ TEST(DrawQuadTest, CopyDebugBorderDrawQuad) {
TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
gfx::Size size(58, 95);
- unsigned texture_id = 72;
+ ResourceProvider::ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
CREATE_SHARED_STATE();
CREATE_QUAD_4_NEW(
- IOSurfaceDrawQuad, opaque_rect, size, texture_id, orientation);
+ IOSurfaceDrawQuad, opaque_rect, size, resource_id, orientation);
EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(size, copy_quad->io_surface_size);
- EXPECT_EQ(texture_id, copy_quad->io_surface_texture_id);
+ EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
EXPECT_EQ(orientation, copy_quad->orientation);
- CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, texture_id, orientation);
+ CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, resource_id, orientation);
EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
EXPECT_EQ(size, copy_quad->io_surface_size);
- EXPECT_EQ(texture_id, copy_quad->io_surface_texture_id);
+ EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
EXPECT_EQ(orientation, copy_quad->orientation);
}
@@ -430,19 +430,19 @@ TEST(DrawQuadTest, CopySolidColorDrawQuad) {
TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
- unsigned texture_id = 64;
+ ResourceProvider::ResourceId resource_id = 64;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
CREATE_SHARED_STATE();
- CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, texture_id, matrix);
+ CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, resource_id, matrix);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
- EXPECT_EQ(texture_id, copy_quad->texture_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id);
EXPECT_EQ(matrix, copy_quad->matrix);
- CREATE_QUAD_2_ALL(StreamVideoDrawQuad, texture_id, matrix);
+ CREATE_QUAD_2_ALL(StreamVideoDrawQuad, resource_id, matrix);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
- EXPECT_EQ(texture_id, copy_quad->texture_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id);
EXPECT_EQ(matrix, copy_quad->matrix);
}
@@ -617,47 +617,34 @@ TEST(DrawQuadTest, CopyTileDrawQuad) {
TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
gfx::SizeF tex_scale(0.75f, 0.5f);
- VideoLayerImpl::FramePlane y_plane;
- y_plane.resource_id = 45;
- y_plane.size = gfx::Size(34, 23);
- y_plane.format = 8;
- VideoLayerImpl::FramePlane u_plane;
- u_plane.resource_id = 532;
- u_plane.size = gfx::Size(134, 16);
- u_plane.format = 2;
- VideoLayerImpl::FramePlane v_plane;
- v_plane.resource_id = 4;
- v_plane.size = gfx::Size(456, 486);
- v_plane.format = 46;
+ ResourceProvider::ResourceId y_plane_resource_id = 45;
+ ResourceProvider::ResourceId u_plane_resource_id = 532;
+ ResourceProvider::ResourceId v_plane_resource_id = 4;
CREATE_SHARED_STATE();
- CREATE_QUAD_5_NEW(
- YUVVideoDrawQuad, opaque_rect, tex_scale, y_plane, u_plane, v_plane);
+ CREATE_QUAD_5_NEW(YUVVideoDrawQuad,
+ opaque_rect,
+ tex_scale,
+ y_plane_resource_id,
+ u_plane_resource_id,
+ v_plane_resource_id);
EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(tex_scale, copy_quad->tex_scale);
- EXPECT_EQ(y_plane.resource_id, copy_quad->y_plane.resource_id);
- EXPECT_EQ(y_plane.size, copy_quad->y_plane.size);
- EXPECT_EQ(y_plane.format, copy_quad->y_plane.format);
- EXPECT_EQ(u_plane.resource_id, copy_quad->u_plane.resource_id);
- EXPECT_EQ(u_plane.size, copy_quad->u_plane.size);
- EXPECT_EQ(u_plane.format, copy_quad->u_plane.format);
- EXPECT_EQ(v_plane.resource_id, copy_quad->v_plane.resource_id);
- EXPECT_EQ(v_plane.size, copy_quad->v_plane.size);
- EXPECT_EQ(v_plane.format, copy_quad->v_plane.format);
-
- CREATE_QUAD_4_ALL(YUVVideoDrawQuad, tex_scale, y_plane, u_plane, v_plane);
+ EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
+ EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
+ EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
+
+ CREATE_QUAD_4_ALL(YUVVideoDrawQuad,
+ tex_scale,
+ y_plane_resource_id,
+ u_plane_resource_id,
+ v_plane_resource_id);
EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
EXPECT_EQ(tex_scale, copy_quad->tex_scale);
- EXPECT_EQ(y_plane.resource_id, copy_quad->y_plane.resource_id);
- EXPECT_EQ(y_plane.size, copy_quad->y_plane.size);
- EXPECT_EQ(y_plane.format, copy_quad->y_plane.format);
- EXPECT_EQ(u_plane.resource_id, copy_quad->u_plane.resource_id);
- EXPECT_EQ(u_plane.size, copy_quad->u_plane.size);
- EXPECT_EQ(u_plane.format, copy_quad->u_plane.format);
- EXPECT_EQ(v_plane.resource_id, copy_quad->v_plane.resource_id);
- EXPECT_EQ(v_plane.size, copy_quad->v_plane.size);
- EXPECT_EQ(v_plane.format, copy_quad->v_plane.format);
+ EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
+ EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
+ EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
}
TEST(DrawQuadTest, CopyPictureDrawQuad) {
@@ -742,13 +729,15 @@ TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) {
TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
gfx::Size size(58, 95);
- unsigned texture_id = 72;
+ ResourceProvider::ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
CREATE_SHARED_STATE();
CREATE_QUAD_4_NEW(
- IOSurfaceDrawQuad, opaque_rect, size, texture_id, orientation);
- EXPECT_EQ(0, IterateAndCount(quad_new.get()));
+ IOSurfaceDrawQuad, opaque_rect, size, resource_id, orientation);
+ EXPECT_EQ(resource_id, quad_new->io_surface_resource_id);
+ EXPECT_EQ(1, IterateAndCount(quad_new.get()));
+ EXPECT_EQ(resource_id + 1, quad_new->io_surface_resource_id);
}
TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) {
@@ -793,12 +782,14 @@ TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
- unsigned texture_id = 64;
+ ResourceProvider::ResourceId resource_id = 64;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
CREATE_SHARED_STATE();
- CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, texture_id, matrix);
- EXPECT_EQ(0, IterateAndCount(quad_new.get()));
+ CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, resource_id, matrix);
+ EXPECT_EQ(resource_id, quad_new->resource_id);
+ EXPECT_EQ(1, IterateAndCount(quad_new.get()));
+ EXPECT_EQ(resource_id + 1, quad_new->resource_id);
}
TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
@@ -846,30 +837,25 @@ TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
gfx::Rect opaque_rect(3, 7, 10, 12);
gfx::SizeF tex_scale(0.75f, 0.5f);
- VideoLayerImpl::FramePlane y_plane;
- y_plane.resource_id = 45;
- y_plane.size = gfx::Size(34, 23);
- y_plane.format = 8;
- VideoLayerImpl::FramePlane u_plane;
- u_plane.resource_id = 532;
- u_plane.size = gfx::Size(134, 16);
- u_plane.format = 2;
- VideoLayerImpl::FramePlane v_plane;
- v_plane.resource_id = 4;
- v_plane.size = gfx::Size(456, 486);
- v_plane.format = 46;
+ ResourceProvider::ResourceId y_plane_resource_id = 45;
+ ResourceProvider::ResourceId u_plane_resource_id = 532;
+ ResourceProvider::ResourceId v_plane_resource_id = 4;
CREATE_SHARED_STATE();
- CREATE_QUAD_5_NEW(
- YUVVideoDrawQuad, opaque_rect, tex_scale, y_plane, u_plane, v_plane);
+ CREATE_QUAD_5_NEW(YUVVideoDrawQuad,
+ opaque_rect,
+ tex_scale,
+ y_plane_resource_id,
+ u_plane_resource_id,
+ v_plane_resource_id);
EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
- EXPECT_EQ(y_plane.resource_id, quad_new->y_plane.resource_id);
- EXPECT_EQ(u_plane.resource_id, quad_new->u_plane.resource_id);
- EXPECT_EQ(v_plane.resource_id, quad_new->v_plane.resource_id);
+ EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id);
+ EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id);
+ EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id);
EXPECT_EQ(3, IterateAndCount(quad_new.get()));
- EXPECT_EQ(y_plane.resource_id + 1, quad_new->y_plane.resource_id);
- EXPECT_EQ(u_plane.resource_id + 1, quad_new->u_plane.resource_id);
- EXPECT_EQ(v_plane.resource_id + 1, quad_new->v_plane.resource_id);
+ EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id);
+ EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id);
+ EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id);
}
TEST_F(DrawQuadIteratorTest, PictureDrawQuad) {
diff --git a/cc/quads/io_surface_draw_quad.cc b/cc/quads/io_surface_draw_quad.cc
index eb4aa20..1bbf8a4 100644
--- a/cc/quads/io_surface_draw_quad.cc
+++ b/cc/quads/io_surface_draw_quad.cc
@@ -9,7 +9,7 @@
namespace cc {
IOSurfaceDrawQuad::IOSurfaceDrawQuad()
- : io_surface_texture_id(0),
+ : io_surface_resource_id(0),
orientation(FLIPPED) {
}
@@ -21,14 +21,14 @@ void IOSurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
gfx::Rect rect,
gfx::Rect opaque_rect,
gfx::Size io_surface_size,
- unsigned io_surface_texture_id,
+ unsigned io_surface_resource_id,
Orientation orientation) {
gfx::Rect visible_rect = rect;
bool needs_blending = false;
DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->io_surface_size = io_surface_size;
- this->io_surface_texture_id = io_surface_texture_id;
+ this->io_surface_resource_id = io_surface_resource_id;
this->orientation = orientation;
}
@@ -38,19 +38,18 @@ void IOSurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
gfx::Rect visible_rect,
bool needs_blending,
gfx::Size io_surface_size,
- unsigned io_surface_texture_id,
+ unsigned io_surface_resource_id,
Orientation orientation) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->io_surface_size = io_surface_size;
- this->io_surface_texture_id = io_surface_texture_id;
+ this->io_surface_resource_id = io_surface_resource_id;
this->orientation = orientation;
}
void IOSurfaceDrawQuad::IterateResources(
const ResourceIteratorCallback& callback) {
- // TODO(danakj): Convert to TextureDrawQuad?
- NOTIMPLEMENTED();
+ io_surface_resource_id = callback.Run(io_surface_resource_id);
}
const IOSurfaceDrawQuad* IOSurfaceDrawQuad::MaterialCast(
diff --git a/cc/quads/io_surface_draw_quad.h b/cc/quads/io_surface_draw_quad.h
index 38dabf8..1a30c90 100644
--- a/cc/quads/io_surface_draw_quad.h
+++ b/cc/quads/io_surface_draw_quad.h
@@ -25,7 +25,7 @@ class CC_EXPORT IOSurfaceDrawQuad : public DrawQuad {
gfx::Rect rect,
gfx::Rect opaque_rect,
gfx::Size io_surface_size,
- unsigned io_surface_texture_id,
+ unsigned io_surface_resource_id,
Orientation orientation);
void SetAll(const SharedQuadState* shared_quad_state,
@@ -34,11 +34,11 @@ class CC_EXPORT IOSurfaceDrawQuad : public DrawQuad {
gfx::Rect visible_rect,
bool needs_blending,
gfx::Size io_surface_size,
- unsigned io_surface_texture_id,
+ unsigned io_surface_resource_id,
Orientation orientation);
gfx::Size io_surface_size;
- unsigned io_surface_texture_id;
+ unsigned io_surface_resource_id;
Orientation orientation;
virtual void IterateResources(const ResourceIteratorCallback& callback)
diff --git a/cc/quads/stream_video_draw_quad.cc b/cc/quads/stream_video_draw_quad.cc
index 89e4003..831304f 100644
--- a/cc/quads/stream_video_draw_quad.cc
+++ b/cc/quads/stream_video_draw_quad.cc
@@ -8,7 +8,7 @@
namespace cc {
-StreamVideoDrawQuad::StreamVideoDrawQuad() : texture_id(0) {}
+StreamVideoDrawQuad::StreamVideoDrawQuad() : resource_id(0) {}
scoped_ptr<StreamVideoDrawQuad> StreamVideoDrawQuad::Create() {
return make_scoped_ptr(new StreamVideoDrawQuad);
@@ -17,13 +17,13 @@ scoped_ptr<StreamVideoDrawQuad> StreamVideoDrawQuad::Create() {
void StreamVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
gfx::Rect rect,
gfx::Rect opaque_rect,
- unsigned texture_id,
+ unsigned resource_id,
const gfx::Transform& matrix) {
gfx::Rect visible_rect = rect;
bool needs_blending = false;
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->texture_id = texture_id;
+ this->resource_id = resource_id;
this->matrix = matrix;
}
@@ -32,18 +32,17 @@ void StreamVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
gfx::Rect opaque_rect,
gfx::Rect visible_rect,
bool needs_blending,
- unsigned texture_id,
+ unsigned resource_id,
const gfx::Transform& matrix) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->texture_id = texture_id;
+ this->resource_id = resource_id;
this->matrix = matrix;
}
void StreamVideoDrawQuad::IterateResources(
const ResourceIteratorCallback& callback) {
- // TODO(danakj): Convert to TextureDrawQuad?
- NOTIMPLEMENTED();
+ resource_id = callback.Run(resource_id);
}
const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
diff --git a/cc/quads/stream_video_draw_quad.h b/cc/quads/stream_video_draw_quad.h
index e6a46b4..0ce31af 100644
--- a/cc/quads/stream_video_draw_quad.h
+++ b/cc/quads/stream_video_draw_quad.h
@@ -19,7 +19,7 @@ class CC_EXPORT StreamVideoDrawQuad : public DrawQuad {
void SetNew(const SharedQuadState* shared_quad_state,
gfx::Rect rect,
gfx::Rect opaque_rect,
- unsigned texture_id,
+ unsigned resource_id,
const gfx::Transform& matrix);
void SetAll(const SharedQuadState* shared_quad_state,
@@ -27,10 +27,10 @@ class CC_EXPORT StreamVideoDrawQuad : public DrawQuad {
gfx::Rect opaque_rect,
gfx::Rect visible_rect,
bool needs_blending,
- unsigned texture_id,
+ unsigned resource_id,
const gfx::Transform& matrix);
- unsigned texture_id;
+ unsigned resource_id;
gfx::Transform matrix;
virtual void IterateResources(const ResourceIteratorCallback& callback)
diff --git a/cc/quads/yuv_video_draw_quad.cc b/cc/quads/yuv_video_draw_quad.cc
index 7876861..f63c612 100644
--- a/cc/quads/yuv_video_draw_quad.cc
+++ b/cc/quads/yuv_video_draw_quad.cc
@@ -8,7 +8,10 @@
namespace cc {
-YUVVideoDrawQuad::YUVVideoDrawQuad() {}
+YUVVideoDrawQuad::YUVVideoDrawQuad()
+ : y_plane_resource_id(0),
+ u_plane_resource_id(0),
+ v_plane_resource_id(0) {}
YUVVideoDrawQuad::~YUVVideoDrawQuad() {}
scoped_ptr<YUVVideoDrawQuad> YUVVideoDrawQuad::Create() {
@@ -19,17 +22,17 @@ void YUVVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
gfx::Rect rect,
gfx::Rect opaque_rect,
gfx::SizeF tex_scale,
- const VideoLayerImpl::FramePlane& y_plane,
- const VideoLayerImpl::FramePlane& u_plane,
- const VideoLayerImpl::FramePlane& v_plane) {
+ unsigned y_plane_resource_id,
+ unsigned u_plane_resource_id,
+ unsigned v_plane_resource_id) {
gfx::Rect visible_rect = rect;
bool needs_blending = false;
DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->tex_scale = tex_scale;
- this->y_plane = y_plane;
- this->u_plane = u_plane;
- this->v_plane = v_plane;
+ this->y_plane_resource_id = y_plane_resource_id;
+ this->u_plane_resource_id = u_plane_resource_id;
+ this->v_plane_resource_id = v_plane_resource_id;
}
void YUVVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
@@ -38,22 +41,22 @@ void YUVVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
gfx::Rect visible_rect,
bool needs_blending,
gfx::SizeF tex_scale,
- const VideoLayerImpl::FramePlane& y_plane,
- const VideoLayerImpl::FramePlane& u_plane,
- const VideoLayerImpl::FramePlane& v_plane) {
+ unsigned y_plane_resource_id,
+ unsigned u_plane_resource_id,
+ unsigned v_plane_resource_id) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->tex_scale = tex_scale;
- this->y_plane = y_plane;
- this->u_plane = u_plane;
- this->v_plane = v_plane;
+ this->y_plane_resource_id = y_plane_resource_id;
+ this->u_plane_resource_id = u_plane_resource_id;
+ this->v_plane_resource_id = v_plane_resource_id;
}
void YUVVideoDrawQuad::IterateResources(
const ResourceIteratorCallback& callback) {
- y_plane.resource_id = callback.Run(y_plane.resource_id);
- u_plane.resource_id = callback.Run(u_plane.resource_id);
- v_plane.resource_id = callback.Run(v_plane.resource_id);
+ y_plane_resource_id = callback.Run(y_plane_resource_id);
+ u_plane_resource_id = callback.Run(u_plane_resource_id);
+ v_plane_resource_id = callback.Run(v_plane_resource_id);
}
const YUVVideoDrawQuad* YUVVideoDrawQuad::MaterialCast(
diff --git a/cc/quads/yuv_video_draw_quad.h b/cc/quads/yuv_video_draw_quad.h
index 8885a5a..9d54227 100644
--- a/cc/quads/yuv_video_draw_quad.h
+++ b/cc/quads/yuv_video_draw_quad.h
@@ -23,9 +23,9 @@ class CC_EXPORT YUVVideoDrawQuad : public DrawQuad {
gfx::Rect rect,
gfx::Rect opaque_rect,
gfx::SizeF tex_scale,
- const VideoLayerImpl::FramePlane& y_plane,
- const VideoLayerImpl::FramePlane& u_plane,
- const VideoLayerImpl::FramePlane& v_plane);
+ unsigned y_plane_resource_id,
+ unsigned u_plane_resource_id,
+ unsigned v_plane_resource_id);
void SetAll(const SharedQuadState* shared_quad_state,
gfx::Rect rect,
@@ -33,14 +33,14 @@ class CC_EXPORT YUVVideoDrawQuad : public DrawQuad {
gfx::Rect visible_rect,
bool needs_blending,
gfx::SizeF tex_scale,
- const VideoLayerImpl::FramePlane& y_plane,
- const VideoLayerImpl::FramePlane& u_plane,
- const VideoLayerImpl::FramePlane& v_plane);
+ unsigned y_plane_resource_id,
+ unsigned u_plane_resource_id,
+ unsigned v_plane_resource_id);
gfx::SizeF tex_scale;
- VideoLayerImpl::FramePlane y_plane;
- VideoLayerImpl::FramePlane u_plane;
- VideoLayerImpl::FramePlane v_plane;
+ unsigned y_plane_resource_id;
+ unsigned u_plane_resource_id;
+ unsigned v_plane_resource_id;
virtual void IterateResources(const ResourceIteratorCallback& callback)
OVERRIDE;
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
new file mode 100644
index 0000000..ca2d3bb
--- /dev/null
+++ b/cc/resources/video_resource_updater.cc
@@ -0,0 +1,326 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/resources/video_resource_updater.h"
+
+#include "base/bind.h"
+#include "cc/output/gl_renderer.h"
+#include "cc/resources/resource_provider.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "media/base/video_frame.h"
+#include "media/filters/skcanvas_video_renderer.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
+#include "ui/gfx/size_conversions.h"
+
+const unsigned kYUVResourceFormat = GL_LUMINANCE;
+const unsigned kRGBResourceFormat = GL_RGBA;
+
+namespace cc {
+
+VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {}
+
+VideoFrameExternalResources::~VideoFrameExternalResources() {}
+
+VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider)
+ : resource_provider_(resource_provider) {
+}
+
+VideoResourceUpdater::~VideoResourceUpdater() {}
+
+bool VideoResourceUpdater::VerifyFrame(
+ const scoped_refptr<media::VideoFrame>& video_frame) {
+ // If these fail, we'll have to add logic that handles offset bitmap/texture
+ // UVs. For now, just expect (0, 0) offset, since all our decoders so far
+ // don't offset.
+ DCHECK_EQ(video_frame->visible_rect().x(), 0);
+ DCHECK_EQ(video_frame->visible_rect().y(), 0);
+
+ switch (video_frame->format()) {
+ // Acceptable inputs.
+ case media::VideoFrame::YV12:
+ case media::VideoFrame::YV16:
+ case media::VideoFrame::NATIVE_TEXTURE:
+#if defined(GOOGLE_TV)
+ case media::VideoFrame::HOLE:
+#endif
+ return true;
+
+ // Unacceptable inputs. ¯\(°_o)/¯
+ case media::VideoFrame::INVALID:
+ case media::VideoFrame::RGB32:
+ case media::VideoFrame::EMPTY:
+ case media::VideoFrame::I420:
+ break;
+ }
+ return false;
+}
+
+// For frames that we receive in software format, determine the dimensions of
+// each plane in the frame.
+static gfx::Size SoftwarePlaneDimension(
+ media::VideoFrame::Format input_frame_format,
+ gfx::Size coded_size,
+ GLenum output_resource_format,
+ int plane_index) {
+ if (output_resource_format == kYUVResourceFormat) {
+ if (plane_index == media::VideoFrame::kYPlane)
+ return coded_size;
+
+ switch (input_frame_format) {
+ case media::VideoFrame::YV12:
+ return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 0.5f));
+ case media::VideoFrame::YV16:
+ return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f));
+
+ case media::VideoFrame::INVALID:
+ case media::VideoFrame::RGB32:
+ case media::VideoFrame::EMPTY:
+ case media::VideoFrame::I420:
+ case media::VideoFrame::NATIVE_TEXTURE:
+#if defined(GOOGLE_TV)
+ case media::VideoFrame::HOLE:
+#endif
+ NOTREACHED();
+ }
+ }
+
+ DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat));
+ 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))
+ return VideoFrameExternalResources();
+
+ media::VideoFrame::Format input_frame_format = video_frame->format();
+
+#if defined(GOOGLE_TV)
+ if (input_frame_format == media::VideoFrame::HOLE) {
+ VideoFrameExternalResources external_resources;
+ external_resources.type = VideoFrameExternalResources::HOLE;
+ return external_resources;
+ }
+#endif
+
+ // Only YUV software video frames are supported.
+ DCHECK(input_frame_format == media::VideoFrame::YV12 ||
+ input_frame_format == media::VideoFrame::YV16);
+ if (input_frame_format != media::VideoFrame::YV12 &&
+ input_frame_format != media::VideoFrame::YV16)
+ return VideoFrameExternalResources();
+
+ bool software_compositor = !resource_provider_->GraphicsContext3D();
+
+ GLenum output_resource_format = kYUVResourceFormat;
+ size_t output_plane_count = 3;
+
+ // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
+ // conversion here. That involves an extra copy of each frame to a bitmap.
+ // Obviously, this is suboptimal and should be addressed once ubercompositor
+ // starts shaping up.
+ if (software_compositor) {
+ output_resource_format = kRGBResourceFormat;
+ output_plane_count = 1;
+ }
+
+ int max_resource_size = resource_provider_->max_texture_size();
+ gfx::Size coded_frame_size = video_frame->coded_size();
+
+ ResourceProvider::ResourceIdArray plane_resources;
+ bool allocation_success = true;
+
+ for (size_t i = 0; i < output_plane_count; ++i) {
+ gfx::Size plane_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) {
+ 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);
+ if (resource_id == 0) {
+ allocation_success = false;
+ break;
+ }
+
+ plane_resources.push_back(resource_id);
+ }
+
+ if (!allocation_success) {
+ for (size_t i = 0; i < plane_resources.size(); ++i)
+ resource_provider_->DeleteResource(plane_resources[i]);
+ return VideoFrameExternalResources();
+ }
+
+ VideoFrameExternalResources external_resources;
+
+ if (software_compositor) {
+ DCHECK_EQ(output_resource_format, kRGBResourceFormat);
+ DCHECK_EQ(plane_resources.size(), 1u);
+
+ if (!video_renderer_)
+ video_renderer_.reset(new media::SkCanvasVideoRenderer);
+
+ {
+ ResourceProvider::ScopedWriteLockSoftware lock(
+ resource_provider_, plane_resources[0]);
+ video_renderer_->Paint(video_frame,
+ lock.sk_canvas(),
+ video_frame->visible_rect(),
+ 0xff);
+ }
+
+ // In software mode, the resource provider won't be lost. Soon this callback
+ // will be called directly from the resource provider, same as 3d
+ // 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::Unretained(resource_provider_),
+ plane_resources[0]);
+ external_resources.software_resources.push_back(plane_resources[0]);
+ 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) {
+ // 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);
+
+ 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,
+ input_plane_pixels,
+ image_rect,
+ source_rect,
+ gfx::Vector2d());
+
+ gpu::Mailbox mailbox;
+ {
+ ResourceProvider::ScopedWriteLockGL lock(
+ resource_provider_, output_plane_resource_id);
+
+ GLC(context, context->genMailboxCHROMIUM(mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, lock.texture_id()));
+ GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D,
+ mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
+ }
+
+ // 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::Unretained(resource_provider_),
+ output_plane_resource_id);
+ external_resources.mailboxes.push_back(
+ TextureMailbox(mailbox, callback_to_free_resource));
+ }
+
+ external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
+ return external_resources;
+}
+
+VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
+ const scoped_refptr<media::VideoFrame>& video_frame,
+ const TextureMailbox::ReleaseCallback& release_callback) {
+ if (!VerifyFrame(video_frame))
+ return VideoFrameExternalResources();
+
+ media::VideoFrame::Format frame_format = video_frame->format();
+
+ DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE);
+ if (frame_format != media::VideoFrame::NATIVE_TEXTURE)
+ return VideoFrameExternalResources();
+
+ WebKit::WebGraphicsContext3D* context =
+ resource_provider_->GraphicsContext3D();
+ if (!context)
+ return VideoFrameExternalResources();
+
+ VideoFrameExternalResources external_resources;
+ switch (video_frame->texture_target()) {
+ case GL_TEXTURE_2D:
+ external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
+ break;
+ case GL_TEXTURE_EXTERNAL_OES:
+ external_resources.type =
+ VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE;
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ external_resources.type = VideoFrameExternalResources::IO_SURFACE;
+ break;
+ default:
+ NOTREACHED();
+ return VideoFrameExternalResources();
+ }
+
+ gpu::Mailbox mailbox;
+ GLC(context, context->genMailboxCHROMIUM(mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, video_frame->texture_id()));
+ GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
+
+ TextureMailbox::ReleaseCallback callback_to_return_resource =
+ base::Bind(&ReturnTexture,
+ base::Unretained(resource_provider_),
+ release_callback,
+ video_frame->texture_id(),
+ mailbox);
+ external_resources.mailboxes.push_back(
+ TextureMailbox(mailbox, callback_to_return_resource));
+ return external_resources;
+}
+
+// static
+void VideoResourceUpdater::ReturnTexture(
+ ResourceProvider* resource_provider,
+ TextureMailbox::ReleaseCallback callback,
+ unsigned texture_id,
+ gpu::Mailbox mailbox,
+ unsigned sync_point) {
+ WebKit::WebGraphicsContext3D* context =
+ resource_provider->GraphicsContext3D();
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, texture_id));
+ GLC(context, context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
+ callback.Run(sync_point);
+}
+
+} // namespace cc
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h
new file mode 100644
index 0000000..fba59fc
--- /dev/null
+++ b/cc/resources/video_resource_updater.h
@@ -0,0 +1,87 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_
+#define CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/resources/texture_mailbox.h"
+
+namespace media {
+class SkCanvasVideoRenderer;
+class VideoFrame;
+}
+
+namespace cc {
+class ResourceProvider;
+
+class VideoFrameExternalResources {
+ public:
+ // Specifies what type of data is contained in the mailboxes, as well as how
+ // many mailboxes will be present.
+ enum ResourceType {
+ NONE,
+ YUV_RESOURCE,
+ RGB_RESOURCE,
+ STREAM_TEXTURE_RESOURCE,
+ IO_SURFACE,
+
+#if defined(GOOGLE_TV)
+ // TODO(danakj): Implement this with a solid color layer instead of a video
+ // frame and video layer.
+ HOLE,
+#endif
+
+ // TODO(danakj): Remove this and abstract TextureMailbox into
+ // "ExternalResource" that can hold a hardware or software backing.
+ SOFTWARE_RESOURCE
+ };
+
+ ResourceType type;
+ std::vector<TextureMailbox> mailboxes;
+
+ // TODO(danakj): Remove these too.
+ std::vector<unsigned> software_resources;
+ TextureMailbox::ReleaseCallback software_release_callback;
+
+ VideoFrameExternalResources();
+ ~VideoFrameExternalResources();
+};
+
+// VideoResourceUpdater is by the video system to produce frame content as
+// resources consumable by the compositor.
+class VideoResourceUpdater {
+ public:
+ explicit VideoResourceUpdater(ResourceProvider* resource_provider);
+ ~VideoResourceUpdater();
+
+ VideoFrameExternalResources CreateForHardwarePlanes(
+ const scoped_refptr<media::VideoFrame>& video_frame,
+ const TextureMailbox::ReleaseCallback& release_callback);
+
+ VideoFrameExternalResources CreateForSoftwarePlanes(
+ const scoped_refptr<media::VideoFrame>& video_frame);
+
+ private:
+ bool VerifyFrame(const scoped_refptr<media::VideoFrame>& video_frame);
+
+ static void ReturnTexture(ResourceProvider* resource_provider,
+ TextureMailbox::ReleaseCallback callback,
+ unsigned texture_id,
+ gpu::Mailbox mailbox,
+ unsigned sync_point);
+
+ ResourceProvider* resource_provider_;
+ scoped_ptr<media::SkCanvasVideoRenderer> video_renderer_;
+
+ DISALLOW_COPY_AND_ASSIGN(VideoResourceUpdater);
+};
+
+} // namespace cc
+
+#endif // CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_
diff --git a/cc/test/render_pass_test_common.cc b/cc/test/render_pass_test_common.cc
index 7ceaef9..c4f6310 100644
--- a/cc/test/render_pass_test_common.cc
+++ b/cc/test/render_pass_test_common.cc
@@ -33,14 +33,6 @@ void TestRenderPass::AppendOneOfEveryQuadType(
gfx::Rect rect(0, 0, 100, 100);
gfx::Rect opaque_rect(10, 10, 80, 80);
const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
- cc::ResourceProvider::ResourceId texture_resource =
- resource_provider->CreateResource(
- gfx::Size(20, 12),
- resource_provider->best_texture_format(),
- ResourceProvider::TextureUsageAny);
- resource_provider->AllocateForTesting(texture_resource);
- unsigned texture_id = ResourceProvider::ScopedReadLockGL(
- resource_provider, texture_resource).texture_id();
cc::ResourceProvider::ResourceId resource1 =
resource_provider->CreateResource(
gfx::Size(45, 5),
@@ -71,6 +63,18 @@ void TestRenderPass::AppendOneOfEveryQuadType(
resource_provider->best_texture_format(),
ResourceProvider::TextureUsageAny);
resource_provider->AllocateForTesting(resource5);
+ cc::ResourceProvider::ResourceId resource6 =
+ resource_provider->CreateResource(
+ gfx::Size(64, 92),
+ resource_provider->best_texture_format(),
+ ResourceProvider::TextureUsageAny);
+ resource_provider->AllocateForTesting(resource6);
+ cc::ResourceProvider::ResourceId resource7 =
+ resource_provider->CreateResource(
+ gfx::Size(9, 14),
+ resource_provider->best_texture_format(),
+ ResourceProvider::TextureUsageAny);
+ resource_provider->AllocateForTesting(resource7);
scoped_ptr<cc::SharedQuadState> shared_state = cc::SharedQuadState::Create();
shared_state->SetAll(gfx::Transform(),
@@ -101,7 +105,7 @@ void TestRenderPass::AppendOneOfEveryQuadType(
rect,
opaque_rect,
gfx::Size(50, 50),
- texture_id,
+ resource7,
cc::IOSurfaceDrawQuad::FLIPPED);
AppendQuad(io_surface_quad.PassAs<DrawQuad>());
@@ -147,7 +151,7 @@ void TestRenderPass::AppendOneOfEveryQuadType(
stream_video_quad->SetNew(shared_state.get(),
rect,
opaque_rect,
- texture_id,
+ resource6,
gfx::Transform());
AppendQuad(stream_video_quad.PassAs<DrawQuad>());
@@ -202,16 +206,14 @@ void TestRenderPass::AppendOneOfEveryQuadType(
false);
AppendQuad(tile_quad.PassAs<DrawQuad>());
- cc::VideoLayerImpl::FramePlane planes[3];
+ ResourceProvider::ResourceId plane_resources[3];
for (int i = 0; i < 3; ++i) {
- planes[i].resource_id =
+ plane_resources[i] =
resource_provider->CreateResource(
gfx::Size(20, 12),
resource_provider->best_texture_format(),
ResourceProvider::TextureUsageAny);
- resource_provider->AllocateForTesting(planes[i].resource_id);
- planes[i].size = gfx::Size(100, 100);
- planes[i].format = GL_LUMINANCE;
+ resource_provider->AllocateForTesting(plane_resources[i]);
}
scoped_ptr<cc::YUVVideoDrawQuad> yuv_quad =
cc::YUVVideoDrawQuad::Create();
@@ -219,9 +221,9 @@ void TestRenderPass::AppendOneOfEveryQuadType(
rect,
opaque_rect,
gfx::Size(100, 100),
- planes[0],
- planes[1],
- planes[2]);
+ plane_resources[0],
+ plane_resources[1],
+ plane_resources[2]);
AppendQuad(yuv_quad.PassAs<DrawQuad>());
AppendSharedQuadState(transformed_state.Pass());
diff --git a/cc/test/test_web_graphics_context_3d.cc b/cc/test/test_web_graphics_context_3d.cc
index 0663f77..462f603 100644
--- a/cc/test/test_web_graphics_context_3d.cc
+++ b/cc/test/test_web_graphics_context_3d.cc
@@ -295,6 +295,19 @@ void TestWebGraphicsContext3D::getQueryObjectuivEXT(
*params = 1;
}
+
+void TestWebGraphicsContext3D::genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox) {
+ static char mailbox_name1 = '1';
+ static char mailbox_name2 = '1';
+ mailbox[0] = mailbox_name1;
+ mailbox[1] = mailbox_name2;
+ mailbox[2] = '\0';
+ if (++mailbox_name1 == 0) {
+ mailbox_name1 = '1';
+ ++mailbox_name2;
+ }
+}
+
void TestWebGraphicsContext3D::setContextLostCallback(
WebGraphicsContextLostCallback* callback) {
context_lost_callback_ = callback;
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h
index 47f2054..82dd63e 100644
--- a/cc/test/test_web_graphics_context_3d.h
+++ b/cc/test/test_web_graphics_context_3d.h
@@ -89,6 +89,12 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
WebKit::WGC3Denum pname,
WebKit::WGC3Duint* params);
+ virtual void genMailboxCHROMIUM(WebKit::WGC3Dbyte* mailbox);
+ virtual void produceTextureCHROMIUM(WebKit::WGC3Denum target,
+ const WebKit::WGC3Dbyte* mailbox) { }
+ virtual void consumeTextureCHROMIUM(WebKit::WGC3Denum target,
+ const WebKit::WGC3Dbyte* mailbox) { }
+
virtual void setContextLostCallback(
WebGraphicsContextLostCallback* callback);
diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc
index f16b2ef..b0bc59e 100644
--- a/cc/trees/layer_tree_host_unittest_delegated.cc
+++ b/cc/trees/layer_tree_host_unittest_delegated.cc
@@ -1108,6 +1108,9 @@ class LayerTreeHostDelegatedTestResourceSentToParent
TransferableResourceArray transferable_resources;
host_impl->resource_provider()->PrepareSendToParent(
resources_for_parent, &transferable_resources);
+
+ resource_in_grandparent = transferable_resources[0];
+ EXPECT_EQ(map.find(999)->second, resource_in_grandparent.id);
break;
}
case 2: {
@@ -1120,10 +1123,10 @@ class LayerTreeHostDelegatedTestResourceSentToParent
EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
// Receive 999 back from the grandparent.
- TransferableResource resource;
- resource.id = map.find(999)->second;
+ EXPECT_EQ(map.find(999)->second, resource_in_grandparent.id);
TransferableResourceArray transferable_resources;
- transferable_resources.push_back(resource);
+ transferable_resources.push_back(resource_in_grandparent);
+
host_impl->resource_provider()->ReceiveFromParent(
transferable_resources);
break;
@@ -1139,6 +1142,8 @@ class LayerTreeHostDelegatedTestResourceSentToParent
}
virtual void AfterTest() OVERRIDE {}
+
+ TransferableResource resource_in_grandparent;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestResourceSentToParent);
diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h
index 3cc7b9e..e12acf1 100644
--- a/content/common/cc_messages.h
+++ b/content/common/cc_messages.h
@@ -4,7 +4,6 @@
//
// IPC Messages sent between compositor instances.
-#include "cc/layers/video_layer_impl.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/quads/checkerboard_draw_quad.h"
@@ -115,12 +114,6 @@ IPC_STRUCT_TRAITS_BEGIN(cc::RenderPass::Id)
IPC_STRUCT_TRAITS_MEMBER(index)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(cc::VideoLayerImpl::FramePlane)
- IPC_STRUCT_TRAITS_MEMBER(resource_id)
- IPC_STRUCT_TRAITS_MEMBER(size)
- IPC_STRUCT_TRAITS_MEMBER(format)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(material)
IPC_STRUCT_TRAITS_MEMBER(rect)
@@ -143,7 +136,7 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::IOSurfaceDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(io_surface_size)
- IPC_STRUCT_TRAITS_MEMBER(io_surface_texture_id)
+ IPC_STRUCT_TRAITS_MEMBER(io_surface_resource_id)
IPC_STRUCT_TRAITS_MEMBER(orientation)
IPC_STRUCT_TRAITS_END()
@@ -166,7 +159,7 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::StreamVideoDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(texture_id)
+ IPC_STRUCT_TRAITS_MEMBER(resource_id)
IPC_STRUCT_TRAITS_MEMBER(matrix)
IPC_STRUCT_TRAITS_END()
@@ -194,9 +187,9 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::YUVVideoDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(tex_scale)
- IPC_STRUCT_TRAITS_MEMBER(y_plane)
- IPC_STRUCT_TRAITS_MEMBER(u_plane)
- IPC_STRUCT_TRAITS_MEMBER(v_plane)
+ IPC_STRUCT_TRAITS_MEMBER(y_plane_resource_id)
+ IPC_STRUCT_TRAITS_MEMBER(u_plane_resource_id)
+ IPC_STRUCT_TRAITS_MEMBER(v_plane_resource_id)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::SharedQuadState)
diff --git a/content/common/cc_messages_unittest.cc b/content/common/cc_messages_unittest.cc
index c665467..d442b23 100644
--- a/content/common/cc_messages_unittest.cc
+++ b/content/common/cc_messages_unittest.cc
@@ -122,7 +122,7 @@ class CCMessagesTest : public testing::Test {
void Compare(const IOSurfaceDrawQuad* a, const IOSurfaceDrawQuad* b) {
EXPECT_EQ(a->io_surface_size.ToString(), b->io_surface_size.ToString());
- EXPECT_EQ(a->io_surface_texture_id, b->io_surface_texture_id);
+ EXPECT_EQ(a->io_surface_resource_id, b->io_surface_resource_id);
EXPECT_EQ(a->orientation, b->orientation);
}
@@ -142,7 +142,7 @@ class CCMessagesTest : public testing::Test {
}
void Compare(const StreamVideoDrawQuad* a, const StreamVideoDrawQuad* b) {
- EXPECT_EQ(a->texture_id, b->texture_id);
+ EXPECT_EQ(a->resource_id, b->resource_id);
EXPECT_EQ(a->matrix, b->matrix);
}
@@ -167,15 +167,9 @@ class CCMessagesTest : public testing::Test {
void Compare(const YUVVideoDrawQuad* a, const YUVVideoDrawQuad* b) {
EXPECT_EQ(a->tex_scale, b->tex_scale);
- EXPECT_EQ(a->y_plane.resource_id, b->y_plane.resource_id);
- EXPECT_EQ(a->y_plane.size.ToString(), b->y_plane.size.ToString());
- EXPECT_EQ(a->y_plane.format, b->y_plane.format);
- EXPECT_EQ(a->u_plane.resource_id, b->u_plane.resource_id);
- EXPECT_EQ(a->u_plane.size.ToString(), b->u_plane.size.ToString());
- EXPECT_EQ(a->u_plane.format, b->u_plane.format);
- EXPECT_EQ(a->v_plane.resource_id, b->v_plane.resource_id);
- EXPECT_EQ(a->v_plane.size.ToString(), b->v_plane.size.ToString());
- EXPECT_EQ(a->v_plane.format, b->v_plane.format);
+ EXPECT_EQ(a->y_plane_resource_id, b->y_plane_resource_id);
+ EXPECT_EQ(a->u_plane_resource_id, b->u_plane_resource_id);
+ EXPECT_EQ(a->v_plane_resource_id, b->v_plane_resource_id);
}
void Compare(const TransferableResource& a, const TransferableResource& b) {
@@ -218,22 +212,9 @@ TEST_F(CCMessagesTest, AllQuads) {
IOSurfaceDrawQuad::Orientation arbitrary_orientation =
IOSurfaceDrawQuad::UNFLIPPED;
RenderPass::Id arbitrary_id(10, 14);
- ResourceProvider::ResourceId arbitrary_resourceid = 55;
-
- VideoLayerImpl::FramePlane arbitrary_plane1;
- arbitrary_plane1.resource_id = arbitrary_resourceid;
- arbitrary_plane1.size = arbitrary_size1;
- arbitrary_plane1.format = arbitrary_int;
-
- VideoLayerImpl::FramePlane arbitrary_plane2;
- arbitrary_plane2.resource_id = arbitrary_resourceid;
- arbitrary_plane2.size = arbitrary_size2;
- arbitrary_plane2.format = arbitrary_int;
-
- VideoLayerImpl::FramePlane arbitrary_plane3;
- arbitrary_plane3.resource_id = arbitrary_resourceid;
- arbitrary_plane3.size = arbitrary_size3;
- arbitrary_plane3.format = arbitrary_int;
+ ResourceProvider::ResourceId arbitrary_resourceid1 = 55;
+ ResourceProvider::ResourceId arbitrary_resourceid2 = 47;
+ ResourceProvider::ResourceId arbitrary_resourceid3 = 23;
WebFilterOperations arbitrary_filters1;
arbitrary_filters1.append(WebFilterOperation::createGrayscaleFilter(
@@ -286,7 +267,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect1,
arbitrary_bool1,
arbitrary_size1,
- arbitrary_int,
+ arbitrary_resourceid3,
arbitrary_orientation);
scoped_ptr<DrawQuad> iosurface_cmp = iosurface_in->Copy(
iosurface_in->shared_quad_state);
@@ -300,7 +281,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_bool1,
arbitrary_id,
arbitrary_bool2,
- arbitrary_resourceid,
+ arbitrary_resourceid2,
arbitrary_rect1,
arbitrary_rectf1,
arbitrary_filters1,
@@ -345,7 +326,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_int,
+ arbitrary_resourceid2,
arbitrary_matrix);
scoped_ptr<DrawQuad> streamvideo_cmp = streamvideo_in->Copy(
streamvideo_in->shared_quad_state);
@@ -356,7 +337,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_resourceid,
+ arbitrary_resourceid1,
arbitrary_bool2,
arbitrary_pointf1,
arbitrary_pointf2,
@@ -371,7 +352,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_resourceid,
+ arbitrary_resourceid3,
arbitrary_rectf1,
arbitrary_size1,
arbitrary_bool2);
@@ -386,9 +367,9 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect3,
arbitrary_bool1,
arbitrary_sizef1,
- arbitrary_plane1,
- arbitrary_plane2,
- arbitrary_plane3);
+ arbitrary_resourceid1,
+ arbitrary_resourceid2,
+ arbitrary_resourceid3);
scoped_ptr<DrawQuad> yuvvideo_cmp = yuvvideo_in->Copy(
yuvvideo_in->shared_quad_state);