From f35e232a94af088f5a1a231f2489a5b06460bffe Mon Sep 17 00:00:00 2001 From: "leandrogracia@chromium.org" Date: Sat, 15 Dec 2012 21:45:52 +0000 Subject: [Android WebView] Tie together Chrome's browser compositor with the Android View system. This patch introduces a new feature to the compositor: - A setting to enable cleaning the framebuffer, disabled by default. This prevents destroying data below us when rendering non-rectangular views (e.g. during a rotation). A second required feature will be added by a later patch: - A device scissor rect that intersects any scissor calculation. Used to ensure we never render outside where the Android View System tells us. There are also some issues with the Android View side regarding the restoration of the GL state. This patch introduces a temporary workaround by reading and manually restoring the state changed by the compositor. This will go out as soon as the problem is fixed in the Android side. BUG=161409,154180 Review URL: https://chromiumcodereview.appspot.com/11316310 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173324 0039d316-1c4b-4281-b951-d872f2087c98 --- cc/software_renderer_unittest.cc | 65 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'cc/software_renderer_unittest.cc') diff --git a/cc/software_renderer_unittest.cc b/cc/software_renderer_unittest.cc index 529d9c7..f61a7e3 100644 --- a/cc/software_renderer_unittest.cc +++ b/cc/software_renderer_unittest.cc @@ -13,6 +13,7 @@ #include "cc/test/fake_software_output_device.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/render_pass_test_common.h" +#include "cc/test/render_pass_test_utils.h" #include "cc/tile_draw_quad.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,6 +26,11 @@ namespace { class SoftwareRendererTest : public testing::Test, public RendererClient { public: + SoftwareRendererTest() + : m_shouldClearRootRenderPass(true) + { + } + void initializeRenderer() { m_outputSurface = FakeOutputSurface::CreateSoftware(scoped_ptr(new FakeSoftwareOutputDevice)); m_resourceProvider = ResourceProvider::create(m_outputSurface.get()); @@ -35,7 +41,8 @@ public: FakeOutputSurface* outputSurface() const { return m_outputSurface.get(); } ResourceProvider* resourceProvider() const { return m_resourceProvider.get(); } SoftwareRenderer* renderer() const { return m_renderer.get(); } - void setViewportSize(gfx::Size viewportSize) { m_viewportSize = viewportSize; } + void setViewportSize(const gfx::Size& viewportSize) { m_viewportSize = viewportSize; } + void setShouldClearRootRenderPass(bool clearRootRenderPass) { m_shouldClearRootRenderPass = clearRootRenderPass; } // RendererClient implementation. virtual const gfx::Size& deviceViewportSize() const OVERRIDE { return m_viewportSize; } @@ -46,6 +53,7 @@ public: virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE { }; virtual void enforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE { }; virtual bool hasImplThread() const OVERRIDE { return false; } + virtual bool shouldClearRootRenderPass() const OVERRIDE { return m_shouldClearRootRenderPass; } protected: scoped_ptr m_outputSurface; @@ -53,6 +61,7 @@ protected: scoped_ptr m_renderer; gfx::Size m_viewportSize; LayerTreeSettings m_settings; + bool m_shouldClearRootRenderPass; }; TEST_F(SoftwareRendererTest, solidColorQuad) @@ -154,5 +163,59 @@ TEST_F(SoftwareRendererTest, tileQuad) EXPECT_EQ(SK_ColorCYAN, pixels[outerPixels - outerSize.width() - 2]); } +TEST_F(SoftwareRendererTest, shouldClearRootRenderPass) +{ + gfx::Rect viewportRect(gfx::Size(100, 100)); + size_t viewportPixels = viewportRect.width() * viewportRect.height(); + setViewportSize(viewportRect.size()); + setShouldClearRootRenderPass(false); + initializeRenderer(); + + RenderPassList list; + RenderPassIdHashMap hashmap; + ScopedPtrVector renderPasses; + scoped_array pixels(new SkColor[viewportPixels]); + + // Draw a fullscreen green quad in a first frame. + RenderPass::Id rootClearPassId(1, 0); + TestRenderPass* rootClearPass = addRenderPass(renderPasses, rootClearPassId, viewportRect, gfx::Transform()); + addQuad(rootClearPass, viewportRect, SK_ColorGREEN); + + list.push_back(rootClearPass); + hashmap.set(rootClearPassId, renderPasses.take(0)); + + renderer()->decideRenderPassAllocationsForFrame(list); + renderer()->drawFrame(list, hashmap); + renderer()->getFramebufferPixels(pixels.get(), viewportRect); + + EXPECT_EQ(SK_ColorGREEN, pixels[0]); + EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); + + renderPasses.clear(); + hashmap.clear(); + list.clear(); + + // Draw a smaller magenta rect without filling the viewport in a separate frame. + gfx::Rect smallerRect(20, 20, 60, 60); + + RenderPass::Id rootSmallerPassId(2, 0); + TestRenderPass* rootSmallerPass = addRenderPass(renderPasses, rootSmallerPassId, viewportRect, gfx::Transform()); + addQuad(rootSmallerPass, smallerRect, SK_ColorMAGENTA); + + list.push_back(rootSmallerPass); + hashmap.set(rootSmallerPassId, renderPasses.take(0)); + + renderer()->decideRenderPassAllocationsForFrame(list); + renderer()->drawFrame(list, hashmap); + renderer()->getFramebufferPixels(pixels.get(), viewportRect); + + // If we didn't clear, the borders should still be green. + EXPECT_EQ(SK_ColorGREEN, pixels[0]); + EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); + + EXPECT_EQ(SK_ColorMAGENTA, pixels[smallerRect.y() * viewportRect.width() + smallerRect.x()]); + EXPECT_EQ(SK_ColorMAGENTA, pixels[(smallerRect.bottom() - 1) * viewportRect.width() + smallerRect.right() - 1]); +} + } // namespace } // namespace cc -- cgit v1.1