Commit 2906d8e0 authored by achaulk@chromium.org's avatar achaulk@chromium.org

Let OverlayStrategySingleOnTop select non-topmost quad

Old code was too restrictive, and did not properly select the correct quad.
New code chooses the topmost overlayable plane that does not intersect any
rects above it.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288049 0039d316-1c4b-4281-b951-d872f2087c98
parent 51470c5a
...@@ -28,13 +28,38 @@ bool OverlayStrategySingleOnTop::Attempt( ...@@ -28,13 +28,38 @@ bool OverlayStrategySingleOnTop::Attempt(
DCHECK(root_render_pass); DCHECK(root_render_pass);
QuadList& quad_list = root_render_pass->quad_list; QuadList& quad_list = root_render_pass->quad_list;
const DrawQuad* candidate_quad = quad_list.front(); QuadList::iterator candidate_iterator = quad_list.end();
if (candidate_quad->material != DrawQuad::TEXTURE_CONTENT) for (QuadList::iterator it = quad_list.begin(); it != quad_list.end(); ++it) {
return false; const DrawQuad* draw_quad = *it;
if (draw_quad->material == DrawQuad::TEXTURE_CONTENT) {
const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(candidate_quad); const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(draw_quad);
if (!resource_provider_->AllowOverlay(quad.resource_id)) if (!resource_provider_->AllowOverlay(quad.resource_id)) {
continue;
}
// Check that no prior quads overlap it.
bool intersects = false;
gfx::RectF rect = draw_quad->rect;
draw_quad->quadTransform().TransformRect(&rect);
for (QuadList::iterator overlap_iter = quad_list.begin();
overlap_iter != it;
++overlap_iter) {
gfx::RectF overlap_rect = (*overlap_iter)->rect;
(*overlap_iter)->quadTransform().TransformRect(&overlap_rect);
if (rect.Intersects(overlap_rect)) {
intersects = true;
break;
}
}
if (intersects)
continue;
candidate_iterator = it;
break;
}
}
if (candidate_iterator == quad_list.end())
return false; return false;
const TextureDrawQuad& quad =
*TextureDrawQuad::MaterialCast(*candidate_iterator);
// Simple quads only. // Simple quads only.
gfx::OverlayTransform overlay_transform = gfx::OverlayTransform overlay_transform =
...@@ -69,8 +94,7 @@ bool OverlayStrategySingleOnTop::Attempt( ...@@ -69,8 +94,7 @@ bool OverlayStrategySingleOnTop::Attempt(
// If the candidate can be handled by an overlay, create a pass for it. // If the candidate can be handled by an overlay, create a pass for it.
if (candidates[1].overlay_handled) { if (candidates[1].overlay_handled) {
scoped_ptr<DrawQuad> overlay_quad = quad_list.take(quad_list.begin()); quad_list.erase(candidate_iterator);
quad_list.erase(quad_list.begin());
candidate_list->swap(candidates); candidate_list->swap(candidates);
return true; return true;
} }
......
...@@ -28,6 +28,8 @@ namespace cc { ...@@ -28,6 +28,8 @@ namespace cc {
namespace { namespace {
const gfx::Rect kOverlayRect(0, 0, 128, 128); const gfx::Rect kOverlayRect(0, 0, 128, 128);
const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
const gfx::PointF kUVTopLeft(0.1f, 0.2f); const gfx::PointF kUVTopLeft(0.1f, 0.2f);
const gfx::PointF kUVBottomRight(1.0f, 1.0f); const gfx::PointF kUVBottomRight(1.0f, 1.0f);
...@@ -43,7 +45,10 @@ void SingleOverlayValidator::CheckOverlaySupport( ...@@ -43,7 +45,10 @@ void SingleOverlayValidator::CheckOverlaySupport(
ASSERT_EQ(2U, surfaces->size()); ASSERT_EQ(2U, surfaces->size());
OverlayCandidate& candidate = surfaces->back(); OverlayCandidate& candidate = surfaces->back();
EXPECT_EQ(kOverlayRect.ToString(), candidate.display_rect.ToString()); if (candidate.display_rect.width() == 64)
EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
else
EXPECT_EQ(kOverlayRect, candidate.display_rect);
EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(), EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
candidate.uv_rect.ToString()); candidate.uv_rect.ToString());
candidate.overlay_handled = true; candidate.overlay_handled = true;
...@@ -129,9 +134,10 @@ ResourceProvider::ResourceId CreateResource( ...@@ -129,9 +134,10 @@ ResourceProvider::ResourceId CreateResource(
mailbox, release_callback.Pass()); mailbox, release_callback.Pass());
} }
TextureDrawQuad* CreateCandidateQuad(ResourceProvider* resource_provider, TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
const SharedQuadState* shared_quad_state, const SharedQuadState* shared_quad_state,
RenderPass* render_pass) { RenderPass* render_pass,
const gfx::Rect& rect) {
ResourceProvider::ResourceId resource_id = CreateResource(resource_provider); ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
bool premultiplied_alpha = false; bool premultiplied_alpha = false;
bool flipped = false; bool flipped = false;
...@@ -140,9 +146,9 @@ TextureDrawQuad* CreateCandidateQuad(ResourceProvider* resource_provider, ...@@ -140,9 +146,9 @@ TextureDrawQuad* CreateCandidateQuad(ResourceProvider* resource_provider,
TextureDrawQuad* overlay_quad = TextureDrawQuad* overlay_quad =
render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
overlay_quad->SetNew(shared_quad_state, overlay_quad->SetNew(shared_quad_state,
kOverlayRect, rect,
kOverlayRect, rect,
kOverlayRect, rect,
resource_id, resource_id,
premultiplied_alpha, premultiplied_alpha,
kUVTopLeft, kUVTopLeft,
...@@ -154,13 +160,28 @@ TextureDrawQuad* CreateCandidateQuad(ResourceProvider* resource_provider, ...@@ -154,13 +160,28 @@ TextureDrawQuad* CreateCandidateQuad(ResourceProvider* resource_provider,
return overlay_quad; return overlay_quad;
} }
void CreateCheckeredQuad(ResourceProvider* resource_provider, TextureDrawQuad* CreateFullscreenCandidateQuad(
const SharedQuadState* shared_quad_state, ResourceProvider* resource_provider,
RenderPass* render_pass) { const SharedQuadState* shared_quad_state,
RenderPass* render_pass) {
return CreateCandidateQuadAt(
resource_provider, shared_quad_state, render_pass, kOverlayRect);
}
void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
const SharedQuadState* shared_quad_state,
RenderPass* render_pass,
const gfx::Rect& rect) {
CheckerboardDrawQuad* checkerboard_quad = CheckerboardDrawQuad* checkerboard_quad =
render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
checkerboard_quad->SetNew( checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor());
shared_quad_state, kOverlayRect, kOverlayRect, SkColor()); }
void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
const SharedQuadState* shared_quad_state,
RenderPass* render_pass) {
CreateCheckeredQuadAt(
resource_provider, shared_quad_state, render_pass, kOverlayRect);
} }
static void CompareRenderPassLists(const RenderPassList& expected_list, static void CompareRenderPassLists(const RenderPassList& expected_list,
...@@ -250,18 +271,18 @@ class SingleOverlayOnTopTest : public testing::Test { ...@@ -250,18 +271,18 @@ class SingleOverlayOnTopTest : public testing::Test {
TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) { TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
TextureDrawQuad* original_quad = TextureDrawQuad* original_quad =
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
unsigned original_resource_id = original_quad->resource_id; unsigned original_resource_id = original_quad->resource_id;
// Add something behind it. // Add something behind it.
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -289,12 +310,12 @@ TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) { ...@@ -289,12 +310,12 @@ TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
TEST_F(SingleOverlayOnTopTest, NoCandidates) { TEST_F(SingleOverlayOnTopTest, NoCandidates) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -311,16 +332,16 @@ TEST_F(SingleOverlayOnTopTest, NoCandidates) { ...@@ -311,16 +332,16 @@ TEST_F(SingleOverlayOnTopTest, NoCandidates) {
TEST_F(SingleOverlayOnTopTest, OccludedCandidates) { TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -341,17 +362,17 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) { ...@@ -341,17 +362,17 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
pass_list.push_back(CreateRenderPass()); pass_list.push_back(CreateRenderPass());
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
// Add something behind it. // Add something behind it.
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -370,9 +391,9 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) { ...@@ -370,9 +391,9 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) { TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
TextureDrawQuad* quad = TextureDrawQuad* quad =
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
quad->premultiplied_alpha = true; quad->premultiplied_alpha = true;
RenderPassList pass_list; RenderPassList pass_list;
...@@ -386,9 +407,9 @@ TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) { ...@@ -386,9 +407,9 @@ TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
TEST_F(SingleOverlayOnTopTest, RejectBlending) { TEST_F(SingleOverlayOnTopTest, RejectBlending) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
TextureDrawQuad* quad = TextureDrawQuad* quad =
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
quad->needs_blending = true; quad->needs_blending = true;
RenderPassList pass_list; RenderPassList pass_list;
...@@ -402,9 +423,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBlending) { ...@@ -402,9 +423,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBlending) {
TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) { TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
TextureDrawQuad* quad = TextureDrawQuad* quad =
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
quad->background_color = SK_ColorBLACK; quad->background_color = SK_ColorBLACK;
RenderPassList pass_list; RenderPassList pass_list;
...@@ -417,9 +438,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) { ...@@ -417,9 +438,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
TEST_F(SingleOverlayOnTopTest, RejectBlendMode) { TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode; pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
RenderPassList pass_list; RenderPassList pass_list;
...@@ -432,9 +453,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBlendMode) { ...@@ -432,9 +453,9 @@ TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
TEST_F(SingleOverlayOnTopTest, RejectOpacity) { TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
pass->shared_quad_state_list.back()->opacity = 0.5f; pass->shared_quad_state_list.back()->opacity = 0.5f;
RenderPassList pass_list; RenderPassList pass_list;
...@@ -447,9 +468,9 @@ TEST_F(SingleOverlayOnTopTest, RejectOpacity) { ...@@ -447,9 +468,9 @@ TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
TEST_F(SingleOverlayOnTopTest, RejectTransform) { TEST_F(SingleOverlayOnTopTest, RejectTransform) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f, pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f,
2.f); 2.f);
...@@ -461,6 +482,29 @@ TEST_F(SingleOverlayOnTopTest, RejectTransform) { ...@@ -461,6 +482,29 @@ TEST_F(SingleOverlayOnTopTest, RejectTransform) {
EXPECT_EQ(0U, candidate_list.size()); EXPECT_EQ(0U, candidate_list.size());
} }
TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCheckeredQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(),
pass.get(),
kOverlayTopLeftRect);
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(),
pass.get(),
kOverlayBottomRightRect);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
RenderPassList original_pass_list;
RenderPass::CopyAll(pass_list, &original_pass_list);
OverlayCandidateList candidate_list;
overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
EXPECT_EQ(1U, pass_list.size());
EXPECT_EQ(2U, candidate_list.size());
}
class OverlayInfoRendererGL : public GLRenderer { class OverlayInfoRendererGL : public GLRenderer {
public: public:
OverlayInfoRendererGL(RendererClient* client, OverlayInfoRendererGL(RendererClient* client,
...@@ -559,16 +603,16 @@ TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) { ...@@ -559,16 +603,16 @@ TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -598,16 +642,16 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) { ...@@ -598,16 +642,16 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
...@@ -631,16 +675,16 @@ TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) { ...@@ -631,16 +675,16 @@ TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
scoped_ptr<RenderPass> pass = CreateRenderPass(); scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuad(resource_provider_.get(), CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
CreateCheckeredQuad(resource_provider_.get(), CreateFullscreenCheckeredQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass->shared_quad_state_list.back(),
pass.get()); pass.get());
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(pass.Pass()); pass_list.push_back(pass.Pass());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment