| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cc/software_renderer.h" | |
| 6 | |
| 7 #include "cc/compositor_frame_metadata.h" | |
| 8 #include "cc/quad_sink.h" | |
| 9 #include "cc/render_pass.h" | |
| 10 #include "cc/render_pass_draw_quad.h" | |
| 11 #include "cc/software_output_device.h" | |
| 12 #include "cc/solid_color_draw_quad.h" | |
| 13 #include "cc/test/animation_test_common.h" | |
| 14 #include "cc/test/fake_output_surface.h" | |
| 15 #include "cc/test/geometry_test_utils.h" | |
| 16 #include "cc/test/render_pass_test_common.h" | |
| 17 #include "cc/test/render_pass_test_utils.h" | |
| 18 #include "cc/tile_draw_quad.h" | |
| 19 #include "testing/gmock/include/gmock/gmock.h" | |
| 20 #include "testing/gtest/include/gtest/gtest.h" | |
| 21 | |
| 22 using namespace WebKit; | |
| 23 | |
| 24 namespace cc { | |
| 25 namespace { | |
| 26 | |
| 27 class SoftwareRendererTest : public testing::Test, public RendererClient { | |
| 28 public: | |
| 29 SoftwareRendererTest() | |
| 30 : m_shouldClearRootRenderPass(true) | |
| 31 { | |
| 32 } | |
| 33 | |
| 34 void initializeRenderer() { | |
| 35 m_outputSurface = FakeOutputSurface::CreateSoftware(make_scoped_ptr(new
SoftwareOutputDevice)); | |
| 36 resource_provider_ = ResourceProvider::Create(m_outputSurface.get()); | |
| 37 m_renderer = SoftwareRenderer::Create(this, m_outputSurface.get(), resou
rceProvider()); | |
| 38 } | |
| 39 | |
| 40 ResourceProvider* resourceProvider() const { return resource_provider_.get()
; } | |
| 41 SoftwareRenderer* renderer() const { return m_renderer.get(); } | |
| 42 void setViewportSize(const gfx::Size& viewportSize) { m_viewportSize = viewp
ortSize; } | |
| 43 void setShouldClearRootRenderPass(bool clearRootRenderPass) { m_shouldClearR
ootRenderPass = clearRootRenderPass; } | |
| 44 | |
| 45 // RendererClient implementation. | |
| 46 virtual gfx::Size DeviceViewportSize() const OVERRIDE { return m_viewportSiz
e; } | |
| 47 virtual const LayerTreeSettings& Settings() const OVERRIDE { return m_settin
gs; } | |
| 48 virtual void DidLoseOutputSurface() OVERRIDE { } | |
| 49 virtual void OnSwapBuffersComplete() OVERRIDE { } | |
| 50 virtual void SetFullRootLayerDamage() OVERRIDE { } | |
| 51 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERR
IDE { }; | |
| 52 virtual void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) O
VERRIDE { }; | |
| 53 virtual bool HasImplThread() const OVERRIDE { return false; } | |
| 54 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return m_shouldCle
arRootRenderPass; } | |
| 55 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const | |
| 56 OVERRIDE { return CompositorFrameMetadata(); } | |
| 57 | |
| 58 protected: | |
| 59 scoped_ptr<FakeOutputSurface> m_outputSurface; | |
| 60 scoped_ptr<ResourceProvider> resource_provider_; | |
| 61 scoped_ptr<SoftwareRenderer> m_renderer; | |
| 62 gfx::Size m_viewportSize; | |
| 63 LayerTreeSettings m_settings; | |
| 64 bool m_shouldClearRootRenderPass; | |
| 65 }; | |
| 66 | |
| 67 TEST_F(SoftwareRendererTest, solidColorQuad) | |
| 68 { | |
| 69 gfx::Size outerSize(100, 100); | |
| 70 int outerPixels = outerSize.width() * outerSize.height(); | |
| 71 gfx::Size innerSize(98, 98); | |
| 72 gfx::Rect outerRect(outerSize); | |
| 73 gfx::Rect innerRect(gfx::Point(1, 1), innerSize); | |
| 74 setViewportSize(outerSize); | |
| 75 | |
| 76 initializeRenderer(); | |
| 77 | |
| 78 scoped_ptr<SharedQuadState> sharedQuadState = SharedQuadState::Create(); | |
| 79 sharedQuadState->SetAll(gfx::Transform(), outerSize, outerRect, outerRect, f
alse, 1.0); | |
| 80 RenderPass::Id root_render_passId = RenderPass::Id(1, 1); | |
| 81 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); | |
| 82 root_render_pass->SetNew(root_render_passId, outerRect, outerRect, gfx::Tran
sform()); | |
| 83 scoped_ptr<SolidColorDrawQuad> outerQuad = SolidColorDrawQuad::Create(); | |
| 84 outerQuad->SetNew(sharedQuadState.get(), outerRect, SK_ColorYELLOW); | |
| 85 scoped_ptr<SolidColorDrawQuad> innerQuad = SolidColorDrawQuad::Create(); | |
| 86 innerQuad->SetNew(sharedQuadState.get(), innerRect, SK_ColorCYAN); | |
| 87 root_render_pass->AppendQuad(innerQuad.PassAs<DrawQuad>()); | |
| 88 root_render_pass->AppendQuad(outerQuad.PassAs<DrawQuad>()); | |
| 89 | |
| 90 RenderPassList list; | |
| 91 list.push_back(root_render_pass.PassAs<RenderPass>()); | |
| 92 renderer()->DrawFrame(list); | |
| 93 | |
| 94 scoped_array<SkColor> pixels(new SkColor[DeviceViewportSize().width() * Devi
ceViewportSize().height()]); | |
| 95 renderer()->GetFramebufferPixels(pixels.get(), outerRect); | |
| 96 | |
| 97 // FIXME: This fails on Android. Endianness maybe? | |
| 98 // Yellow: expects 0xFFFFFF00, was 0xFF00FFFF on android. | |
| 99 // Cyan: expects 0xFF00FFFF, was 0xFFFFFF00 on android. | |
| 100 // http://crbug.com/154528 | |
| 101 #ifndef OS_ANDROID | |
| 102 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | |
| 103 EXPECT_EQ(SK_ColorYELLOW, pixels[outerPixels - 1]); | |
| 104 EXPECT_EQ(SK_ColorCYAN, pixels[outerSize.width() + 1]); | |
| 105 EXPECT_EQ(SK_ColorCYAN, pixels[outerPixels - outerSize.width() - 2]); | |
| 106 #endif | |
| 107 } | |
| 108 | |
| 109 TEST_F(SoftwareRendererTest, tileQuad) | |
| 110 { | |
| 111 gfx::Size outerSize(100, 100); | |
| 112 int outerPixels = outerSize.width() * outerSize.height(); | |
| 113 gfx::Size innerSize(98, 98); | |
| 114 int innerPixels = innerSize.width() * innerSize.height(); | |
| 115 gfx::Rect outerRect(outerSize); | |
| 116 gfx::Rect innerRect(gfx::Point(1, 1), innerSize); | |
| 117 setViewportSize(outerSize); | |
| 118 initializeRenderer(); | |
| 119 | |
| 120 ResourceProvider::ResourceId resourceYellow = resourceProvider()->CreateReso
urce(outerSize, GL_RGBA, ResourceProvider::TextureUsageAny); | |
| 121 ResourceProvider::ResourceId resourceCyan = resourceProvider()->CreateResour
ce(innerSize, GL_RGBA, ResourceProvider::TextureUsageAny); | |
| 122 | |
| 123 SkColor yellow = SK_ColorYELLOW; | |
| 124 SkColor cyan = SK_ColorCYAN; | |
| 125 scoped_array<SkColor> yellowPixels(new SkColor[outerPixels]); | |
| 126 scoped_array<SkColor> cyanPixels(new SkColor[innerPixels]); | |
| 127 for (int i = 0; i < outerPixels; i++) | |
| 128 yellowPixels[i] = yellow; | |
| 129 for (int i = 0; i < innerPixels; i++) | |
| 130 cyanPixels[i] = cyan; | |
| 131 | |
| 132 resourceProvider()->SetPixels(resourceYellow, reinterpret_cast<uint8_t*>(yel
lowPixels.get()), gfx::Rect(outerSize), gfx::Rect(outerSize), gfx::Vector2d()); | |
| 133 resourceProvider()->SetPixels(resourceCyan, reinterpret_cast<uint8_t*>(cyanP
ixels.get()), gfx::Rect(innerSize), gfx::Rect(innerSize), gfx::Vector2d()); | |
| 134 | |
| 135 gfx::Rect rootRect = gfx::Rect(DeviceViewportSize()); | |
| 136 | |
| 137 scoped_ptr<SharedQuadState> sharedQuadState = SharedQuadState::Create(); | |
| 138 sharedQuadState->SetAll(gfx::Transform(), outerSize, outerRect, outerRect, f
alse, 1.0); | |
| 139 RenderPass::Id root_render_passId = RenderPass::Id(1, 1); | |
| 140 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); | |
| 141 root_render_pass->SetNew(root_render_passId, rootRect, rootRect, gfx::Transf
orm()); | |
| 142 scoped_ptr<TileDrawQuad> outerQuad = TileDrawQuad::Create(); | |
| 143 outerQuad->SetNew(sharedQuadState.get(), outerRect, outerRect, resourceYello
w, gfx::RectF(outerSize), outerSize, false); | |
| 144 scoped_ptr<TileDrawQuad> innerQuad = TileDrawQuad::Create(); | |
| 145 innerQuad->SetNew(sharedQuadState.get(), innerRect, innerRect, resourceCyan,
gfx::RectF(innerSize), innerSize, false); | |
| 146 root_render_pass->AppendQuad(innerQuad.PassAs<DrawQuad>()); | |
| 147 root_render_pass->AppendQuad(outerQuad.PassAs<DrawQuad>()); | |
| 148 | |
| 149 RenderPassList list; | |
| 150 list.push_back(root_render_pass.PassAs<RenderPass>()); | |
| 151 renderer()->DrawFrame(list); | |
| 152 | |
| 153 scoped_array<SkColor> pixels(new SkColor[DeviceViewportSize().width() * Devi
ceViewportSize().height()]); | |
| 154 renderer()->GetFramebufferPixels(pixels.get(), outerRect); | |
| 155 | |
| 156 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | |
| 157 EXPECT_EQ(SK_ColorYELLOW, pixels[outerPixels - 1]); | |
| 158 EXPECT_EQ(SK_ColorCYAN, pixels[outerSize.width() + 1]); | |
| 159 EXPECT_EQ(SK_ColorCYAN, pixels[outerPixels - outerSize.width() - 2]); | |
| 160 } | |
| 161 | |
| 162 TEST_F(SoftwareRendererTest, shouldClearRootRenderPass) | |
| 163 { | |
| 164 gfx::Rect viewportRect(gfx::Size(100, 100)); | |
| 165 size_t viewportPixels = viewportRect.width() * viewportRect.height(); | |
| 166 setViewportSize(viewportRect.size()); | |
| 167 setShouldClearRootRenderPass(false); | |
| 168 initializeRenderer(); | |
| 169 | |
| 170 RenderPassList list; | |
| 171 scoped_array<SkColor> pixels(new SkColor[viewportPixels]); | |
| 172 | |
| 173 // Draw a fullscreen green quad in a first frame. | |
| 174 RenderPass::Id rootClearPassId(1, 0); | |
| 175 TestRenderPass* rootClearPass = addRenderPass(list, rootClearPassId, viewpor
tRect, gfx::Transform()); | |
| 176 addQuad(rootClearPass, viewportRect, SK_ColorGREEN); | |
| 177 | |
| 178 renderer()->DecideRenderPassAllocationsForFrame(list); | |
| 179 renderer()->DrawFrame(list); | |
| 180 renderer()->GetFramebufferPixels(pixels.get(), viewportRect); | |
| 181 | |
| 182 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | |
| 183 EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); | |
| 184 | |
| 185 list.clear(); | |
| 186 | |
| 187 // Draw a smaller magenta rect without filling the viewport in a separate fr
ame. | |
| 188 gfx::Rect smallerRect(20, 20, 60, 60); | |
| 189 | |
| 190 RenderPass::Id rootSmallerPassId(2, 0); | |
| 191 TestRenderPass* rootSmallerPass = addRenderPass(list, rootSmallerPassId, vie
wportRect, gfx::Transform()); | |
| 192 addQuad(rootSmallerPass, smallerRect, SK_ColorMAGENTA); | |
| 193 | |
| 194 renderer()->DecideRenderPassAllocationsForFrame(list); | |
| 195 renderer()->DrawFrame(list); | |
| 196 renderer()->GetFramebufferPixels(pixels.get(), viewportRect); | |
| 197 | |
| 198 // If we didn't clear, the borders should still be green. | |
| 199 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | |
| 200 EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); | |
| 201 | |
| 202 EXPECT_EQ(SK_ColorMAGENTA, pixels[smallerRect.y() * viewportRect.width() + s
mallerRect.x()]); | |
| 203 EXPECT_EQ(SK_ColorMAGENTA, pixels[(smallerRect.bottom() - 1) * viewportRect.
width() + smallerRect.right() - 1]); | |
| 204 } | |
| 205 | |
| 206 } // namespace | |
| 207 } // namespace cc | |
| OLD | NEW |