Skip to content

Commit

Permalink
cc: Apply occlusion before creating quads in VideoLayerImpl.
Browse files Browse the repository at this point in the history
This makes the AppendQuads method query occlusion directly and subtract
it from the quads it would create before they are created, skipping
quads that are completely occluded and avoiding a malloc/free for them.

Depends on: https://codereview.chromium.org/203463015/

R=enne@chromium.org, enne
BUG=344962

Review URL: https://codereview.chromium.org/204823003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258365 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
danakj@chromium.org committed Mar 20, 2014
1 parent 0a1b984 commit 7c65344
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 11 deletions.
1 change: 1 addition & 0 deletions cc/cc_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'layers/tiled_layer_unittest.cc',
'layers/ui_resource_layer_impl_unittest.cc',
'layers/ui_resource_layer_unittest.cc',
'layers/video_layer_impl_unittest.cc',
'output/delegating_renderer_unittest.cc',
'output/filter_operations_unittest.cc',
'output/gl_renderer_unittest.cc',
Expand Down
31 changes: 20 additions & 11 deletions cc/layers/video_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,14 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,

gfx::Rect quad_rect(content_bounds());
gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
gfx::Rect visible_quad_rect(quad_rect);
gfx::Rect visible_rect = frame_->visible_rect();
gfx::Size coded_size = frame_->coded_size();

gfx::Rect visible_quad_rect = quad_sink->UnoccludedContentRect(
quad_rect, draw_properties().target_space_transform);
if (visible_quad_rect.IsEmpty())
return;

// Pixels for macroblocked formats.
float tex_width_scale =
static_cast<float>(visible_rect.width()) / coded_size.width();
Expand Down Expand Up @@ -168,7 +172,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
SK_ColorTRANSPARENT,
opacity,
flipped);
quad_sink->MaybeAppend(texture_quad.PassAs<DrawQuad>());
quad_sink->Append(texture_quad.PassAs<DrawQuad>());
break;
}
case VideoFrameExternalResources::YUV_RESOURCE: {
Expand All @@ -187,7 +191,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
frame_resources_[1],
frame_resources_[2],
frame_resources_.size() > 3 ? frame_resources_[3] : 0);
quad_sink->MaybeAppend(yuv_video_quad.PassAs<DrawQuad>());
quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>());
break;
}
case VideoFrameExternalResources::RGB_RESOURCE: {
Expand All @@ -211,7 +215,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
SK_ColorTRANSPARENT,
opacity,
flipped);
quad_sink->MaybeAppend(texture_quad.PassAs<DrawQuad>());
quad_sink->Append(texture_quad.PassAs<DrawQuad>());
break;
}
case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: {
Expand All @@ -229,7 +233,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
visible_quad_rect,
frame_resources_[0],
scale * provider_client_impl_->stream_texture_matrix());
quad_sink->MaybeAppend(stream_video_quad.PassAs<DrawQuad>());
quad_sink->Append(stream_video_quad.PassAs<DrawQuad>());
break;
}
case VideoFrameExternalResources::IO_SURFACE: {
Expand All @@ -246,7 +250,7 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
visible_size,
frame_resources_[0],
IOSurfaceDrawQuad::UNFLIPPED);
quad_sink->MaybeAppend(io_surface_quad.PassAs<DrawQuad>());
quad_sink->Append(io_surface_quad.PassAs<DrawQuad>());
break;
}
#if defined(VIDEO_HOLE)
Expand All @@ -263,11 +267,16 @@ void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,

// Create a solid color quad with transparent black and force no
// blending / no anti-aliasing.
solid_color_draw_quad->SetAll(
shared_quad_state, quad_rect, quad_rect, quad_rect, false,
SK_ColorTRANSPARENT, true);
quad_sink->MaybeAppend(solid_color_draw_quad.PassAs<DrawQuad>(),
append_quads_data);
gfx::Rect opaque_rect = quad_rect;
solid_color_draw_quad->SetAll(shared_quad_state,
quad_rect,
opaque_rect,
visible_quad_rect,
false,
SK_ColorTRANSPARENT,
true);
quad_sink->Append(solid_color_draw_quad.PassAs<DrawQuad>(),
append_quads_data);
break;
}
#endif // defined(VIDEO_HOLE)
Expand Down
80 changes: 80 additions & 0 deletions cc/layers/video_layer_impl_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2014 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/layers/video_layer_impl.h"

#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/single_thread_proxy.h"
#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

TEST(VideoLayerImplTest, Occlusion) {
gfx::Size layer_size(1000, 1000);
gfx::Size viewport_size(1000, 1000);

LayerTestCommon::LayerImplTest impl;
DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());

scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
gfx::Size(10, 10),
gfx::Rect(10, 10),
gfx::Size(10, 10),
base::TimeDelta());
FakeVideoFrameProvider provider;
provider.set_frame(video_frame);

VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider);
video_layer_impl->SetAnchorPoint(gfx::PointF());
video_layer_impl->SetBounds(layer_size);
video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);

impl.CalcDrawProps(viewport_size);

{
SCOPED_TRACE("No occlusion");
gfx::Rect occluded;
impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);

LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
gfx::Rect(layer_size));
EXPECT_EQ(1u, impl.quad_list().size());
}

{
SCOPED_TRACE("Full occlusion");
gfx::Rect occluded(video_layer_impl->visible_content_rect());
impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);

LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
EXPECT_EQ(impl.quad_list().size(), 0u);
}

{
SCOPED_TRACE("Partial occlusion");
gfx::Rect occluded(200, 0, 800, 1000);
impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);

size_t partially_occluded_count = 0;
LayerTestCommon::VerifyQuadsCoverRectWithOcclusion(
impl.quad_list(),
gfx::Rect(layer_size),
occluded,
&partially_occluded_count);
// The layer outputs one quad, which is partially occluded.
EXPECT_EQ(1u, impl.quad_list().size());
EXPECT_EQ(1u, partially_occluded_count);
}
}

} // namespace
} // namespace cc
1 change: 1 addition & 0 deletions cc/test/layer_test_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class LayerTestCommon {
return host_->host_impl()->resource_provider();
}
FakeLayerTreeHostImpl* host_impl() const { return host_->host_impl(); }
Proxy* proxy() const { return host_->host_impl()->proxy(); }
const QuadList& quad_list() const { return quad_culler_.quad_list(); }

private:
Expand Down

0 comments on commit 7c65344

Please sign in to comment.