Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1247)

Unified Diff: cc/output/overlay_unittest.cc

Issue 208213003: Plumb overlay processing into DirectRenderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ScopedGLLock Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/output/overlay_unittest.cc
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index ab22cb485508442ad778d6188befc7fb53f5d2ef..c8f069c57571c34635408e07b3e4c32ebca36fec 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/base/scoped_ptr_vector.h"
+#include "cc/output/gl_renderer.h"
#include "cc/output/output_surface.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/overlay_candidate_validator.h"
@@ -16,8 +17,12 @@
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_context_provider.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::_;
+using testing::Mock;
+
namespace cc {
namespace {
@@ -103,8 +108,7 @@ scoped_ptr<RenderPass> CreateRenderPass() {
output_rect,
output_rect,
gfx::Transform(),
- has_transparent_background,
- RenderPass::NO_OVERLAY);
+ has_transparent_background);
scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
shared_state->opacity = 1.f;
@@ -112,9 +116,8 @@ scoped_ptr<RenderPass> CreateRenderPass() {
return pass.Pass();
}
-scoped_ptr<TextureDrawQuad> CreateCandidateQuad(
- ResourceProvider* resource_provider,
- const SharedQuadState* shared_quad_state) {
+ResourceProvider::ResourceId CreateResource(
+ ResourceProvider* resource_provider) {
unsigned sync_point = 0;
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
@@ -122,9 +125,14 @@ scoped_ptr<TextureDrawQuad> CreateCandidateQuad(
scoped_ptr<SingleReleaseCallback> release_callback =
SingleReleaseCallback::Create(base::Bind(&MailboxReleased));
- ResourceProvider::ResourceId resource_id =
- resource_provider->CreateResourceFromTextureMailbox(
- mailbox, release_callback.Pass());
+ return resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, release_callback.Pass());
+}
+
+scoped_ptr<TextureDrawQuad> CreateCandidateQuad(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state) {
+ ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
bool premultiplied_alpha = false;
bool flipped = false;
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -169,7 +177,6 @@ static void CompareRenderPassLists(const RenderPassList& expected_list,
EXPECT_RECT_EQ(expected->damage_rect, actual->damage_rect);
EXPECT_EQ(expected->has_transparent_background,
actual->has_transparent_background);
- EXPECT_EQ(expected->overlay_state, actual->overlay_state);
EXPECT_EQ(expected->shared_quad_state_list.size(),
actual->shared_quad_state_list.size());
@@ -252,22 +259,24 @@ TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
pass_list.push_back(pass.Pass());
// Check for potential candidates.
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
- // This should have one more pass with an overlay.
- ASSERT_EQ(2U, pass_list.size());
+ ASSERT_EQ(1U, pass_list.size());
+ ASSERT_EQ(2U, candidate_list.size());
- RenderPass* overlay_pass = pass_list.front();
- EXPECT_EQ(RenderPass::SIMPLE_OVERLAY, overlay_pass->overlay_state);
RenderPass* main_pass = pass_list.back();
- EXPECT_EQ(RenderPass::NO_OVERLAY, main_pass->overlay_state);
-
- // Check that the quad is what we expect it to be.
- EXPECT_EQ(1U, overlay_pass->quad_list.size());
- const DrawQuad* overlay_quad = overlay_pass->quad_list.front();
- EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, overlay_quad->material);
- EXPECT_EQ(original_quad->resource_id,
- TextureDrawQuad::MaterialCast(overlay_quad)->resource_id);
+ // Check that the quad is gone.
+ EXPECT_EQ(2U, main_pass->quad_list.size());
+ const QuadList& quad_list = main_pass->quad_list;
+ for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
+ it != quad_list.BackToFrontEnd();
+ ++it) {
+ EXPECT_NE(DrawQuad::TEXTURE_CONTENT, (*it)->material);
+ }
+
+ // Check that the right resource id got extracted.
+ EXPECT_EQ(original_quad->resource_id, candidate_list.back().resource_id);
}
TEST_F(SingleOverlayOnTopTest, NoCandidates) {
@@ -283,7 +292,9 @@ TEST_F(SingleOverlayOnTopTest, NoCandidates) {
RenderPassList original_pass_list;
RenderPass::CopyAll(pass_list, &original_pass_list);
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(0U, candidate_list.size());
// There should be nothing new here.
CompareRenderPassLists(pass_list, original_pass_list);
}
@@ -306,7 +317,9 @@ TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
RenderPassList original_pass_list;
RenderPass::CopyAll(pass_list, &original_pass_list);
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(0U, candidate_list.size());
// There should be nothing new here.
CompareRenderPassLists(pass_list, original_pass_list);
}
@@ -330,11 +343,16 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
pass_list.push_back(pass.Pass());
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
// Check for potential candidates.
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(2U, candidate_list.size());
- // This should have one more pass with an overlay.
- ASSERT_EQ(3U, pass_list.size());
+ // This should be the same.
+ ASSERT_EQ(2U, pass_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
@@ -346,9 +364,10 @@ TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
- ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectBlending) {
@@ -360,9 +379,10 @@ TEST_F(SingleOverlayOnTopTest, RejectBlending) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ EXPECT_EQ(0U, candidate_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
@@ -374,9 +394,10 @@ TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ EXPECT_EQ(0U, candidate_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
@@ -388,9 +409,10 @@ TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ EXPECT_EQ(0U, candidate_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
@@ -402,9 +424,10 @@ TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ EXPECT_EQ(0U, candidate_list.size());
}
TEST_F(SingleOverlayOnTopTest, RejectTransform) {
@@ -417,9 +440,283 @@ TEST_F(SingleOverlayOnTopTest, RejectTransform) {
pass->quad_list.push_back(quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
- overlay_processor_->ProcessForOverlays(&pass_list);
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
ASSERT_EQ(1U, pass_list.size());
- EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+class OverlayInfoRendererGL : public GLRenderer {
+ public:
+ OverlayInfoRendererGL(RendererClient* client,
+ const LayerTreeSettings* settings,
+ OutputSurface* output_surface,
+ ResourceProvider* resource_provider)
+ : GLRenderer(client,
+ settings,
+ output_surface,
+ resource_provider,
+ NULL,
+ 0),
+ expect_overlays_(false) {}
+
+ MOCK_METHOD2(DoDrawQuad, void(DrawingFrame* frame, const DrawQuad* quad));
+
+ virtual void FinishDrawingFrame(DrawingFrame* frame) OVERRIDE {
+ GLRenderer::FinishDrawingFrame(frame);
+
+ if (!expect_overlays_) {
+ EXPECT_EQ(0U, frame->overlay_list.size());
+ return;
+ }
+
+ ASSERT_EQ(2U, frame->overlay_list.size());
+ EXPECT_NE(0U, frame->overlay_list.back().resource_id);
+ }
+
+ void set_expect_overlays(bool expect_overlays) {
+ expect_overlays_ = expect_overlays;
+ }
+
+ private:
+ bool expect_overlays_;
+};
+
+class FakeRendererClient : public RendererClient {
+ public:
+ // RendererClient methods.
+ virtual void SetFullRootLayerDamage() OVERRIDE {}
+};
+
+class MockOverlayScheduler {
+ public:
+ MOCK_METHOD5(Schedule,
+ void(int plane_z_order,
+ unsigned plane_transform,
+ unsigned overlay_texture_id,
+ const gfx::Rect& display_bounds,
+ const gfx::RectF& uv_rect));
+};
+
+class GLRendererWithOverlaysTest : public testing::Test {
+ protected:
+ GLRendererWithOverlaysTest() {
+ provider_ = TestContextProvider::Create();
+ output_surface_.reset(new OverlayOutputSurface(provider_));
+ CHECK(output_surface_->BindToClient(&output_surface_client_));
+ resource_provider_ =
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
+
+ provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
+ &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
+ }
+
+ void Init(bool use_validator) {
+ if (use_validator)
+ output_surface_->InitWithSingleOverlayValidator();
+
+ renderer_ =
+ make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
+ &settings_,
+ output_surface_.get(),
+ resource_provider_.get()));
+ }
+
+ void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
+
+ LayerTreeSettings settings_;
+ FakeOutputSurfaceClient output_surface_client_;
+ scoped_ptr<OverlayOutputSurface> output_surface_;
+ FakeRendererClient renderer_client_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<OverlayInfoRendererGL> renderer_;
+ scoped_refptr<TestContextProvider> provider_;
+ MockOverlayScheduler scheduler_;
+};
+
+TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(true);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ pass->quad_list.push_back(
+ CreateCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back())
+ .PassAs<DrawQuad>());
+
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Candidate pass was taken out and extra skipped pass added,
+ // so only draw 2 quads.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(2);
+ EXPECT_CALL(scheduler_,
+ Schedule(1,
+ OverlayCandidate::NONE,
+ _,
+ kOverlayRect,
+ BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
+ renderer_->DrawFrame(
+ &pass_list, NULL, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(false);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ pass->quad_list.push_back(
+ CreateCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back())
+ .PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // 3 quads in the pass, all should draw.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->DrawFrame(
+ &pass_list, NULL, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
+ bool use_validator = false;
+ Init(use_validator);
+ renderer_->set_expect_overlays(false);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ pass->quad_list.push_back(
+ CreateCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back())
+ .PassAs<DrawQuad>());
+
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Should see no overlays.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->DrawFrame(
+ &pass_list, NULL, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(true);
+
+ ResourceProvider::ResourceId resource1 =
+ CreateResource(resource_provider_.get());
+ ResourceProvider::ResourceId resource2 =
+ CreateResource(resource_provider_.get());
+
+ DirectRenderer::DrawingFrame frame1;
+ frame1.overlay_list.resize(2);
+ OverlayCandidate& overlay1 = frame1.overlay_list.back();
+ overlay1.resource_id = resource1;
+ overlay1.plane_z_order = 1;
+
+ DirectRenderer::DrawingFrame frame2;
+ frame2.overlay_list.resize(2);
+ OverlayCandidate& overlay2 = frame2.overlay_list.back();
+ overlay2.resource_id = resource2;
+ overlay2.plane_z_order = 1;
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->FinishDrawingFrame(&frame2);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // No overlays, release the resource.
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ DirectRenderer::DrawingFrame frame3;
+ renderer_->set_expect_overlays(false);
+ renderer_->FinishDrawingFrame(&frame3);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // Use the same buffer twice.
+ renderer_->set_expect_overlays(true);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->set_expect_overlays(false);
+ renderer_->FinishDrawingFrame(&frame3);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
}
} // namespace

Powered by Google App Engine
This is Rietveld 408576698