summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorachaulk <achaulk@chromium.org>2015-04-01 10:26:08 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-01 17:27:23 +0000
commitf47b494165f7d03a8e92b1780acdf673a87cb454 (patch)
tree3c4f699bb048b95187abd58c157fad35cbe18020 /cc
parent9684384a5c73aaacf640d565039ad7357ee6d8da (diff)
downloadchromium_src-f47b494165f7d03a8e92b1780acdf673a87cb454.zip
chromium_src-f47b494165f7d03a8e92b1780acdf673a87cb454.tar.gz
chromium_src-f47b494165f7d03a8e92b1780acdf673a87cb454.tar.bz2
Add underlays and split off common overlay functionality
Review URL: https://codereview.chromium.org/979693005 Cr-Commit-Position: refs/heads/master@{#323274}
Diffstat (limited to 'cc')
-rw-r--r--cc/BUILD.gn4
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/output/overlay_strategy_common.cc135
-rw-r--r--cc/output/overlay_strategy_common.h49
-rw-r--r--cc/output/overlay_strategy_single_on_top.cc119
-rw-r--r--cc/output/overlay_strategy_single_on_top.h19
-rw-r--r--cc/output/overlay_strategy_underlay.cc69
-rw-r--r--cc/output/overlay_strategy_underlay.h32
-rw-r--r--cc/output/overlay_unittest.cc89
-rw-r--r--cc/quads/list_container.h6
-rw-r--r--cc/quads/list_container_unittest.cc52
11 files changed, 412 insertions, 166 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 2d4a393..ee83aec 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -248,8 +248,12 @@ component("cc") {
"output/overlay_candidate_validator.h",
"output/overlay_processor.cc",
"output/overlay_processor.h",
+ "output/overlay_strategy_common.cc",
+ "output/overlay_strategy_common.h",
"output/overlay_strategy_single_on_top.cc",
"output/overlay_strategy_single_on_top.h",
+ "output/overlay_strategy_underlay.cc",
+ "output/overlay_strategy_underlay.h",
"output/program_binding.cc",
"output/program_binding.h",
"output/render_surface_filters.cc",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index b2bc022..76957d5 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -300,8 +300,12 @@
'output/overlay_candidate_validator.h',
'output/overlay_processor.cc',
'output/overlay_processor.h',
+ 'output/overlay_strategy_common.cc',
+ 'output/overlay_strategy_common.h',
'output/overlay_strategy_single_on_top.cc',
'output/overlay_strategy_single_on_top.h',
+ 'output/overlay_strategy_underlay.cc',
+ 'output/overlay_strategy_underlay.h',
'output/program_binding.cc',
'output/program_binding.h',
'output/render_surface_filters.cc',
diff --git a/cc/output/overlay_strategy_common.cc b/cc/output/overlay_strategy_common.cc
new file mode 100644
index 0000000..b03fbba5
--- /dev/null
+++ b/cc/output/overlay_strategy_common.cc
@@ -0,0 +1,135 @@
+// Copyright 2015 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/output/overlay_strategy_common.h"
+
+#include <limits>
+
+#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/quads/stream_video_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/transform.h"
+
+namespace cc {
+
+OverlayStrategyCommon::OverlayStrategyCommon(
+ OverlayCandidateValidator* capability_checker,
+ ResourceProvider* resource_provider)
+ : capability_checker_(capability_checker),
+ resource_provider_(resource_provider) {
+}
+
+OverlayStrategyCommon::~OverlayStrategyCommon() {
+}
+
+bool OverlayStrategyCommon::IsOverlayQuad(const DrawQuad* draw_quad) {
+ unsigned int resource_id;
+ switch (draw_quad->material) {
+ case DrawQuad::TEXTURE_CONTENT:
+ resource_id = TextureDrawQuad::MaterialCast(draw_quad)->resource_id;
+ break;
+ case DrawQuad::STREAM_VIDEO_CONTENT:
+ resource_id = StreamVideoDrawQuad::MaterialCast(draw_quad)->resource_id;
+ break;
+ default:
+ return false;
+ }
+ return resource_provider_->AllowOverlay(resource_id);
+}
+
+bool OverlayStrategyCommon::IsInvisibleQuad(const DrawQuad* draw_quad) {
+ if (draw_quad->material == DrawQuad::SOLID_COLOR) {
+ const SolidColorDrawQuad* solid_quad =
+ SolidColorDrawQuad::MaterialCast(draw_quad);
+ SkColor color = solid_quad->color;
+ float opacity = solid_quad->opacity();
+ float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
+ return solid_quad->ShouldDrawWithBlending() &&
+ alpha < std::numeric_limits<float>::epsilon();
+ }
+ return false;
+}
+
+bool OverlayStrategyCommon::GetTextureQuadInfo(const TextureDrawQuad& quad,
+ OverlayCandidate* quad_info) {
+ gfx::OverlayTransform overlay_transform =
+ OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped);
+ if (quad.background_color != SK_ColorTRANSPARENT ||
+ quad.premultiplied_alpha ||
+ overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
+ return false;
+ quad_info->resource_id = quad.resource_id;
+ quad_info->transform = overlay_transform;
+ quad_info->uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
+ return true;
+}
+
+bool OverlayStrategyCommon::GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
+ OverlayCandidate* quad_info) {
+ gfx::OverlayTransform overlay_transform =
+ OverlayCandidate::GetOverlayTransform(quad.quadTransform(), false);
+ if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
+ return false;
+ if (!quad.matrix.IsScaleOrTranslation()) {
+ // We cannot handle anything other than scaling & translation for texture
+ // coordinates yet.
+ return false;
+ }
+ quad_info->resource_id = quad.resource_id;
+ quad_info->transform = overlay_transform;
+
+ gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
+ gfx::Point3F uv1 = gfx::Point3F(1, 1, 0);
+ quad.matrix.TransformPoint(&uv0);
+ quad.matrix.TransformPoint(&uv1);
+ gfx::Vector3dF delta = uv1 - uv0;
+ if (delta.x() < 0) {
+ quad_info->transform = OverlayCandidate::ModifyTransform(
+ quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL);
+ float x0 = uv0.x();
+ uv0.set_x(uv1.x());
+ uv1.set_x(x0);
+ delta.set_x(-delta.x());
+ }
+
+ if (delta.y() < 0) {
+ // In this situation, uv0y < uv1y. Since we overlay inverted, a request
+ // to invert the source texture means we can just output the texture
+ // normally and it will be correct.
+ quad_info->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y());
+ } else {
+ quad_info->transform = OverlayCandidate::ModifyTransform(
+ quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL);
+ quad_info->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y());
+ }
+ return true;
+}
+
+bool OverlayStrategyCommon::GetCandidateQuadInfo(const DrawQuad& draw_quad,
+ OverlayCandidate* quad_info) {
+ // All quad checks.
+ if (draw_quad.needs_blending || draw_quad.shared_quad_state->opacity != 1.f ||
+ draw_quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode)
+ return false;
+
+ if (draw_quad.material == DrawQuad::TEXTURE_CONTENT) {
+ const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(&draw_quad);
+ if (!GetTextureQuadInfo(quad, quad_info))
+ return false;
+ } else if (draw_quad.material == DrawQuad::STREAM_VIDEO_CONTENT) {
+ const StreamVideoDrawQuad& quad =
+ *StreamVideoDrawQuad::MaterialCast(&draw_quad);
+ if (!GetVideoQuadInfo(quad, quad_info))
+ return false;
+ }
+
+ quad_info->format = RGBA_8888;
+ quad_info->display_rect = OverlayCandidate::GetOverlayRect(
+ draw_quad.quadTransform(), draw_quad.rect);
+ return true;
+}
+
+} // namespace cc
diff --git a/cc/output/overlay_strategy_common.h b/cc/output/overlay_strategy_common.h
new file mode 100644
index 0000000..515a106
--- /dev/null
+++ b/cc/output/overlay_strategy_common.h
@@ -0,0 +1,49 @@
+// Copyright 2015 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_OUTPUT_OVERLAY_STRATEGY_COMMON_H_
+#define CC_OUTPUT_OVERLAY_STRATEGY_COMMON_H_
+
+#include "cc/base/cc_export.h"
+#include "cc/output/overlay_candidate.h"
+#include "cc/output/overlay_processor.h"
+
+namespace cc {
+class OverlayCandidateValidator;
+class StreamVideoDrawQuad;
+class TextureDrawQuad;
+class OverlayCandidate;
+
+class CC_EXPORT OverlayStrategyCommon : public OverlayProcessor::Strategy {
+ public:
+ OverlayStrategyCommon(OverlayCandidateValidator* capability_checker,
+ ResourceProvider* resource_provider);
+ ~OverlayStrategyCommon() override;
+
+ protected:
+ bool GetCandidateQuadInfo(const DrawQuad& draw_quad,
+ OverlayCandidate* quad_info);
+
+ // Returns true if |draw_quad| will not block quads underneath from becoming
+ // an overlay.
+ bool IsInvisibleQuad(const DrawQuad* draw_quad);
+
+ // Returns true if |draw_quad| is of a known quad type and contains an
+ // overlayable resource.
+ bool IsOverlayQuad(const DrawQuad* draw_quad);
+
+ bool GetTextureQuadInfo(const TextureDrawQuad& quad,
+ OverlayCandidate* quad_info);
+ bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
+ OverlayCandidate* quad_info);
+
+ OverlayCandidateValidator* capability_checker_;
+ ResourceProvider* resource_provider_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OverlayStrategyCommon);
+};
+} // namespace cc
+
+#endif // CC_OUTPUT_OVERLAY_STRATEGY_COMMON_H_
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc
index 71897ed..65b039e 100644
--- a/cc/output/overlay_strategy_single_on_top.cc
+++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -7,130 +7,13 @@
#include <limits>
#include "cc/quads/draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "ui/gfx/geometry/point3_f.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
namespace cc {
OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
OverlayCandidateValidator* capability_checker,
ResourceProvider* resource_provider)
- : capability_checker_(capability_checker),
- resource_provider_(resource_provider) {}
-
-bool OverlayStrategySingleOnTop::IsOverlayQuad(const DrawQuad* draw_quad) {
- unsigned int resource_id;
- switch (draw_quad->material) {
- case DrawQuad::TEXTURE_CONTENT:
- resource_id = TextureDrawQuad::MaterialCast(draw_quad)->resource_id;
- break;
- case DrawQuad::STREAM_VIDEO_CONTENT:
- resource_id = StreamVideoDrawQuad::MaterialCast(draw_quad)->resource_id;
- break;
- default:
- return false;
- }
- return resource_provider_->AllowOverlay(resource_id);
-}
-
-bool OverlayStrategySingleOnTop::GetTextureQuadInfo(
- const TextureDrawQuad& quad,
- OverlayCandidate* quad_info) {
- gfx::OverlayTransform overlay_transform =
- OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped);
- if (quad.background_color != SK_ColorTRANSPARENT ||
- quad.premultiplied_alpha ||
- overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
- return false;
- quad_info->resource_id = quad.resource_id;
- quad_info->transform = overlay_transform;
- quad_info->uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
- return true;
-}
-
-bool OverlayStrategySingleOnTop::GetVideoQuadInfo(
- const StreamVideoDrawQuad& quad,
- OverlayCandidate* quad_info) {
- gfx::OverlayTransform overlay_transform =
- OverlayCandidate::GetOverlayTransform(quad.quadTransform(), false);
- if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
- return false;
- if (!quad.matrix.IsScaleOrTranslation()) {
- // We cannot handle anything other than scaling & translation for texture
- // coordinates yet.
- return false;
- }
- quad_info->resource_id = quad.resource_id;
- quad_info->transform = overlay_transform;
-
- gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
- gfx::Point3F uv1 = gfx::Point3F(1, 1, 0);
- quad.matrix.TransformPoint(&uv0);
- quad.matrix.TransformPoint(&uv1);
- gfx::Vector3dF delta = uv1 - uv0;
- if (delta.x() < 0) {
- quad_info->transform = OverlayCandidate::ModifyTransform(
- quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL);
- float x0 = uv0.x();
- uv0.set_x(uv1.x());
- uv1.set_x(x0);
- delta.set_x(-delta.x());
- }
-
- if (delta.y() < 0) {
- // In this situation, uv0y < uv1y. Since we overlay inverted, a request
- // to invert the source texture means we can just output the texture
- // normally and it will be correct.
- quad_info->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y());
- } else {
- quad_info->transform = OverlayCandidate::ModifyTransform(
- quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL);
- quad_info->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y());
- }
- return true;
-}
-
-bool OverlayStrategySingleOnTop::GetCandidateQuadInfo(
- const DrawQuad& draw_quad,
- OverlayCandidate* quad_info) {
- // All quad checks.
- if (draw_quad.needs_blending || draw_quad.shared_quad_state->opacity != 1.f ||
- draw_quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode)
- return false;
-
- if (draw_quad.material == DrawQuad::TEXTURE_CONTENT) {
- const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(&draw_quad);
- if (!GetTextureQuadInfo(quad, quad_info))
- return false;
- } else if (draw_quad.material == DrawQuad::STREAM_VIDEO_CONTENT) {
- const StreamVideoDrawQuad& quad =
- *StreamVideoDrawQuad::MaterialCast(&draw_quad);
- if (!GetVideoQuadInfo(quad, quad_info))
- return false;
- }
-
- quad_info->format = RGBA_8888;
- quad_info->display_rect = OverlayCandidate::GetOverlayRect(
- draw_quad.quadTransform(), draw_quad.rect);
- return true;
-}
-
-bool OverlayStrategySingleOnTop::IsInvisibleQuad(const DrawQuad* draw_quad) {
- if (draw_quad->material == DrawQuad::SOLID_COLOR) {
- const SolidColorDrawQuad* solid_quad =
- SolidColorDrawQuad::MaterialCast(draw_quad);
- SkColor color = solid_quad->color;
- float opacity = solid_quad->opacity();
- float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
- // Ignore transparent solid color quads.
- return solid_quad->ShouldDrawWithBlending() &&
- alpha < std::numeric_limits<float>::epsilon();
- }
- return false;
+ : OverlayStrategyCommon(capability_checker, resource_provider) {
}
bool OverlayStrategySingleOnTop::Attempt(
diff --git a/cc/output/overlay_strategy_single_on_top.h b/cc/output/overlay_strategy_single_on_top.h
index a3fec0a..eeecd32 100644
--- a/cc/output/overlay_strategy_single_on_top.h
+++ b/cc/output/overlay_strategy_single_on_top.h
@@ -10,14 +10,14 @@
#include "cc/base/cc_export.h"
#include "cc/output/overlay_candidate.h"
#include "cc/output/overlay_processor.h"
+#include "cc/output/overlay_strategy_common.h"
#include "cc/quads/render_pass.h"
namespace cc {
-class OverlayCandidateValidator;
class StreamVideoDrawQuad;
class TextureDrawQuad;
-class CC_EXPORT OverlayStrategySingleOnTop : public OverlayProcessor::Strategy {
+class CC_EXPORT OverlayStrategySingleOnTop : public OverlayStrategyCommon {
public:
OverlayStrategySingleOnTop(OverlayCandidateValidator* capability_checker,
ResourceProvider* resource_provider);
@@ -25,21 +25,6 @@ class CC_EXPORT OverlayStrategySingleOnTop : public OverlayProcessor::Strategy {
OverlayCandidateList* candidate_list) override;
private:
- bool IsOverlayQuad(const DrawQuad* draw_quad);
- bool GetCandidateQuadInfo(const DrawQuad& draw_quad,
- OverlayCandidate* quad_info);
-
- // Returns true if |draw_quad| will not block quads underneath from becoming
- // an overlay.
- bool IsInvisibleQuad(const DrawQuad* draw_quad);
-
- bool GetTextureQuadInfo(const TextureDrawQuad& quad,
- OverlayCandidate* quad_info);
- bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
- OverlayCandidate* quad_info);
-
- OverlayCandidateValidator* capability_checker_;
- ResourceProvider* resource_provider_;
DISALLOW_COPY_AND_ASSIGN(OverlayStrategySingleOnTop);
};
diff --git a/cc/output/overlay_strategy_underlay.cc b/cc/output/overlay_strategy_underlay.cc
new file mode 100644
index 0000000..631ce03
--- /dev/null
+++ b/cc/output/overlay_strategy_underlay.cc
@@ -0,0 +1,69 @@
+// 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/output/overlay_strategy_underlay.h"
+
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/solid_color_draw_quad.h"
+
+namespace cc {
+
+OverlayStrategyUnderlay::OverlayStrategyUnderlay(
+ OverlayCandidateValidator* capability_checker,
+ ResourceProvider* resource_provider)
+ : OverlayStrategyCommon(capability_checker, resource_provider) {
+}
+
+bool OverlayStrategyUnderlay::Attempt(
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list) {
+ if (!capability_checker_)
+ return false;
+
+ RenderPass* root_render_pass = render_passes_in_draw_order->back();
+ DCHECK(root_render_pass);
+
+ OverlayCandidate candidate;
+ QuadList& quad_list = root_render_pass->quad_list;
+ auto candidate_iterator = quad_list.end();
+ for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
+ if (IsOverlayQuad(*it) && GetCandidateQuadInfo(**it, &candidate)) {
+ candidate_iterator = it;
+ break;
+ }
+ }
+ if (candidate_iterator == quad_list.end())
+ return false;
+
+ // Add our primary surface.
+ OverlayCandidateList candidates;
+ OverlayCandidate main_image;
+ main_image.display_rect = root_render_pass->output_rect;
+ candidates.push_back(main_image);
+
+ // Add the overlay.
+ candidate.plane_z_order = -1;
+ candidates.push_back(candidate);
+
+ // Check for support.
+ capability_checker_->CheckOverlaySupport(&candidates);
+
+ // If the candidate can be handled by an overlay, create a pass for it. We
+ // need to switch out the video quad with a black transparent one.
+ if (candidates[1].overlay_handled) {
+ const SharedQuadState* shared_quad_state =
+ candidate_iterator->shared_quad_state;
+ gfx::Rect rect = candidate_iterator->visible_rect;
+ SolidColorDrawQuad* replacement =
+ quad_list.ReplaceExistingElement<SolidColorDrawQuad>(
+ candidate_iterator);
+ replacement->SetAll(shared_quad_state, rect, rect, rect, false,
+ SK_ColorTRANSPARENT, true);
+ candidate_list->swap(candidates);
+ return true;
+ }
+ return false;
+}
+
+} // namespace cc
diff --git a/cc/output/overlay_strategy_underlay.h b/cc/output/overlay_strategy_underlay.h
new file mode 100644
index 0000000..881e170
--- /dev/null
+++ b/cc/output/overlay_strategy_underlay.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef CC_OUTPUT_OVERLAY_STRATEGY_UNDERLAY_H_
+#define CC_OUTPUT_OVERLAY_STRATEGY_UNDERLAY_H_
+
+#include "cc/output/overlay_strategy_common.h"
+
+namespace cc {
+class StreamVideoDrawQuad;
+class TextureDrawQuad;
+
+// The underlay strategy looks for a video quad without regard to quads above
+// it. The video is "underlaid" through a black transparent quad substituted
+// for the video quad. The overlay content can then be blended in by the
+// hardware under the the scene. This is only valid for overlay contents that
+// are fully opaque.
+class CC_EXPORT OverlayStrategyUnderlay : public OverlayStrategyCommon {
+ public:
+ OverlayStrategyUnderlay(OverlayCandidateValidator* capability_checker,
+ ResourceProvider* resource_provider);
+ bool Attempt(RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OverlayStrategyUnderlay);
+};
+
+} // namespace cc
+
+#endif // CC_OUTPUT_OVERLAY_STRATEGY_UNDERLAY_H_
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 75fbb6e..9849286 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -10,6 +10,7 @@
#include "cc/output/overlay_candidate_validator.h"
#include "cc/output/overlay_processor.h"
#include "cc/output/overlay_strategy_single_on_top.h"
+#include "cc/output/overlay_strategy_underlay.h"
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/stream_video_draw_quad.h"
@@ -69,30 +70,26 @@ void SingleOverlayValidator::CheckOverlaySupport(
candidate.overlay_handled = true;
}
+template <typename OverlayStrategyType>
class SingleOverlayProcessor : public OverlayProcessor {
public:
SingleOverlayProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider);
+ ResourceProvider* resource_provider)
+ : OverlayProcessor(surface, resource_provider) {
+ EXPECT_EQ(surface, surface_);
+ EXPECT_EQ(resource_provider, resource_provider_);
+ }
+
// Virtual to allow testing different strategies.
- void Initialize() override;
+ void Initialize() override {
+ OverlayCandidateValidator* candidates =
+ surface_->overlay_candidate_validator();
+ ASSERT_TRUE(candidates != NULL);
+ strategies_.push_back(scoped_ptr<Strategy>(
+ new OverlayStrategyType(candidates, resource_provider_)));
+ }
};
-SingleOverlayProcessor::SingleOverlayProcessor(
- OutputSurface* surface,
- ResourceProvider* resource_provider)
- : OverlayProcessor(surface, resource_provider) {
- EXPECT_EQ(surface, surface_);
- EXPECT_EQ(resource_provider, resource_provider_);
-}
-
-void SingleOverlayProcessor::Initialize() {
- OverlayCandidateValidator* candidates =
- surface_->overlay_candidate_validator();
- ASSERT_TRUE(candidates != NULL);
- strategies_.push_back(scoped_ptr<Strategy>(
- new OverlayStrategySingleOnTop(candidates, resource_provider_)));
-}
-
class DefaultOverlayProcessor : public OverlayProcessor {
public:
DefaultOverlayProcessor(OutputSurface* surface,
@@ -303,7 +300,8 @@ TEST(OverlayTest, OverlaysProcessorHasStrategy) {
EXPECT_GE(1U, overlay_processor->GetStrategyCount());
}
-class SingleOverlayOnTopTest : public testing::Test {
+template <typename OverlayStrategyType>
+class OverlayTest : public testing::Test {
protected:
void SetUp() override {
provider_ = TestContextProvider::Create();
@@ -321,7 +319,7 @@ class SingleOverlayOnTopTest : public testing::Test {
false,
1);
- overlay_processor_.reset(new SingleOverlayProcessor(
+ overlay_processor_.reset(new SingleOverlayProcessor<OverlayStrategyType>(
output_surface_.get(), resource_provider_.get()));
overlay_processor_->Initialize();
}
@@ -331,9 +329,12 @@ class SingleOverlayOnTopTest : public testing::Test {
FakeOutputSurfaceClient client_;
scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
scoped_ptr<ResourceProvider> resource_provider_;
- scoped_ptr<SingleOverlayProcessor> overlay_processor_;
+ scoped_ptr<SingleOverlayProcessor<OverlayStrategyType>> overlay_processor_;
};
+typedef OverlayTest<OverlayStrategySingleOnTop> SingleOverlayOnTopTest;
+typedef OverlayTest<OverlayStrategyUnderlay> UnderlayTest;
+
TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
scoped_ptr<RenderPass> pass = CreateRenderPass();
TextureDrawQuad* original_quad =
@@ -762,6 +763,52 @@ TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
EXPECT_EQ(2U, candidate_list.size());
}
+TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateCandidateQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ ASSERT_EQ(2U, candidate_list.size());
+ EXPECT_EQ(0, candidate_list[0].plane_z_order);
+ EXPECT_EQ(-1, candidate_list[1].plane_z_order);
+ EXPECT_EQ(2U, pass_list[0]->quad_list.size());
+ // The overlay quad should have changed to a SOLID_COLOR quad.
+ EXPECT_EQ(pass_list[0]->quad_list.back()->material, DrawQuad::SOLID_COLOR);
+}
+
+TEST_F(UnderlayTest, AllowOnTop) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ pass->CreateAndAppendSharedQuadState()->opacity = 0.5f;
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ ASSERT_EQ(2U, candidate_list.size());
+ EXPECT_EQ(0, candidate_list[0].plane_z_order);
+ EXPECT_EQ(-1, candidate_list[1].plane_z_order);
+ // The overlay quad should have changed to a SOLID_COLOR quad.
+ EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR);
+}
+
class OverlayInfoRendererGL : public GLRenderer {
public:
OverlayInfoRendererGL(RendererClient* client,
diff --git a/cc/quads/list_container.h b/cc/quads/list_container.h
index 7abbe27..38a34b8 100644
--- a/cc/quads/list_container.h
+++ b/cc/quads/list_container.h
@@ -209,6 +209,12 @@ class CC_EXPORT ListContainer {
return new (Allocate(sizeof(DerivedElementType)))
DerivedElementType(*source);
}
+ // Construct a new element on top of an existing one.
+ template <typename DerivedElementType>
+ DerivedElementType* ReplaceExistingElement(Iterator at) {
+ at->~BaseElementType();
+ return new (*at) DerivedElementType();
+ }
size_t size() const;
bool empty() const;
diff --git a/cc/quads/list_container_unittest.cc b/cc/quads/list_container_unittest.cc
index de88750..68e6061 100644
--- a/cc/quads/list_container_unittest.cc
+++ b/cc/quads/list_container_unittest.cc
@@ -54,16 +54,22 @@ class SimpleDrawQuadConstructMagicNumberTwo : public SimpleDrawQuad {
}
};
-class MockDrawQuad : public DrawQuad {
+class MockDrawQuad : public SimpleDrawQuadConstructMagicNumberOne {
public:
~MockDrawQuad() override { Destruct(); }
- void IterateResources(const ResourceIteratorCallback& callback) override {}
- void ExtendValue(base::trace_event::TracedValue* value) const override {}
MOCK_METHOD0(Destruct, void());
};
+class MockDrawQuadSubclass : public MockDrawQuad {
+ public:
+ MockDrawQuadSubclass() { set_value(kMagicNumberToUseForDrawQuadTwo); }
+};
+
+const size_t kLargestQuadSize =
+ std::max(LargestDrawQuadSize(), sizeof(MockDrawQuadSubclass));
+
TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
size_t size = 2;
SimpleDrawQuadConstructMagicNumberOne* dq_1 =
@@ -80,7 +86,7 @@ TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
}
TEST(ListContainerTest, DestructorCalled) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
size_t size = 1;
MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
@@ -91,7 +97,7 @@ TEST(ListContainerTest, DestructorCalled) {
}
TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
size_t size = 1;
MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
@@ -112,8 +118,34 @@ TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
separator.Call();
}
+TEST(ListContainerTest, ReplaceExistingElement) {
+ ListContainer<DrawQuad> list(kLargestQuadSize);
+ size_t size = 1;
+ MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(dq_1, list.front());
+
+ // Make sure destructor is called once during clear, and won't be called
+ // again.
+ testing::MockFunction<void()> separator;
+ {
+ testing::InSequence s;
+ EXPECT_CALL(*dq_1, Destruct());
+ EXPECT_CALL(separator, Call());
+ EXPECT_CALL(*dq_1, Destruct()).Times(0);
+ }
+
+ list.ReplaceExistingElement<MockDrawQuadSubclass>(list.begin());
+ EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_1->get_value());
+ separator.Call();
+
+ EXPECT_CALL(*dq_1, Destruct());
+ list.clear();
+}
+
TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
size_t size = 1;
MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
@@ -434,7 +466,7 @@ TEST(ListContainerTest, SimpleReverseInsertionSharedQuadState) {
}
TEST(ListContainerTest, SimpleDeletion) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
std::vector<SimpleDrawQuad*> sdq_list;
size_t size = 10;
for (size_t i = 0; i < size; ++i) {
@@ -456,7 +488,7 @@ TEST(ListContainerTest, SimpleDeletion) {
}
TEST(ListContainerTest, SimpleIterationAndManipulation) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
std::vector<SimpleDrawQuad*> sdq_list;
size_t size = 10;
for (size_t i = 0; i < size; ++i) {
@@ -481,7 +513,7 @@ TEST(ListContainerTest, SimpleIterationAndManipulation) {
}
TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDrawQuad) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize());
+ ListContainer<DrawQuad> list(kLargestQuadSize);
std::vector<SimpleDrawQuad*> dq_list;
size_t size = 10;
for (size_t i = 0; i < size; ++i) {