1 // Copyright 2013 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.
5 #include "cc/test/pixel_test.h"
7 #include "base/path_service.h"
8 #include "base/run_loop.h"
9 #include "cc/output/compositor_frame_metadata.h"
10 #include "cc/output/copy_output_request.h"
11 #include "cc/output/copy_output_result.h"
12 #include "cc/output/gl_renderer.h"
13 #include "cc/output/output_surface_client.h"
14 #include "cc/output/software_renderer.h"
15 #include "cc/resources/resource_provider.h"
16 #include "cc/test/paths.h"
17 #include "cc/test/pixel_test_output_surface.h"
18 #include "cc/test/pixel_test_software_output_device.h"
19 #include "cc/test/pixel_test_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gl/gl_implementation.h"
22 #include "webkit/common/gpu/context_provider_in_process.h"
23 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
27 class PixelTest::PixelTestRendererClient
28 : public RendererClient
, public OutputSurfaceClient
{
30 explicit PixelTestRendererClient(gfx::Rect device_viewport
)
31 : device_viewport_(device_viewport
) {}
33 // RendererClient implementation.
34 virtual gfx::Rect
DeviceViewport() const OVERRIDE
{
35 return device_viewport_
;
37 virtual float DeviceScaleFactor() const OVERRIDE
{
40 virtual const LayerTreeSettings
& Settings() const OVERRIDE
{
43 virtual void SetFullRootLayerDamage() OVERRIDE
{}
44 virtual bool HasImplThread() const OVERRIDE
{ return false; }
45 virtual bool ShouldClearRootRenderPass() const OVERRIDE
{ return true; }
46 virtual CompositorFrameMetadata
MakeCompositorFrameMetadata() const
48 return CompositorFrameMetadata();
50 virtual bool AllowPartialSwap() const OVERRIDE
{
54 // OutputSurfaceClient implementation.
55 virtual bool DeferredInitialize(
56 scoped_refptr
<ContextProvider
> offscreen_context_provider
) OVERRIDE
{
59 virtual void SetNeedsRedrawRect(gfx::Rect damage_rect
) OVERRIDE
{}
60 virtual void BeginFrame(const BeginFrameArgs
& args
) OVERRIDE
{}
61 virtual void OnSwapBuffersComplete(const CompositorFrameAck
* ack
) OVERRIDE
{}
62 virtual void DidLoseOutputSurface() OVERRIDE
{}
63 virtual void SetExternalDrawConstraints(const gfx::Transform
& transform
,
64 gfx::Rect viewport
) OVERRIDE
{
65 device_viewport_
= viewport
;
67 virtual void SetMemoryPolicy(
68 const ManagedMemoryPolicy
& policy
, bool discard
) OVERRIDE
{}
71 gfx::Rect device_viewport_
;
72 LayerTreeSettings settings_
;
75 PixelTest::PixelTest()
76 : device_viewport_size_(gfx::Size(200, 200)),
78 new PixelTestRendererClient(gfx::Rect(device_viewport_size_
))) {}
80 PixelTest::~PixelTest() {}
82 bool PixelTest::RunPixelTest(RenderPassList
* pass_list
,
83 const base::FilePath
& ref_file
,
84 const PixelComparator
& comparator
) {
85 return RunPixelTestWithReadbackTarget(pass_list
,
91 bool PixelTest::RunPixelTestWithReadbackTarget(
92 RenderPassList
* pass_list
,
94 const base::FilePath
& ref_file
,
95 const PixelComparator
& comparator
) {
96 base::RunLoop run_loop
;
98 target
->copy_requests
.push_back(CopyOutputRequest::CreateBitmapRequest(
99 base::Bind(&PixelTest::ReadbackResult
,
100 base::Unretained(this),
101 run_loop
.QuitClosure())));
103 renderer_
->DecideRenderPassAllocationsForFrame(*pass_list
);
104 renderer_
->DrawFrame(pass_list
);
106 // Wait for the readback to complete.
107 resource_provider_
->Finish();
110 return PixelsMatchReference(ref_file
, comparator
);
113 void PixelTest::ReadbackResult(base::Closure quit_run_loop
,
114 scoped_ptr
<CopyOutputResult
> result
) {
115 ASSERT_TRUE(result
->HasBitmap());
116 result_bitmap_
= result
->TakeBitmap().Pass();
120 bool PixelTest::PixelsMatchReference(const base::FilePath
& ref_file
,
121 const PixelComparator
& comparator
) {
122 base::FilePath test_data_dir
;
123 if (!PathService::Get(cc::DIR_TEST_DATA
, &test_data_dir
))
126 // If this is false, we didn't set up a readback on a render pass.
131 // return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
133 return MatchesPNGFile(*result_bitmap_
,
134 test_data_dir
.Append(ref_file
),
138 void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend
) {
140 CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL
));
142 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl
;
143 scoped_ptr
<WebKit::WebGraphicsContext3D
> context3d(
144 WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
145 WebKit::WebGraphicsContext3D::Attributes()));
146 output_surface_
.reset(new PixelTestOutputSurface(
147 context3d
.PassAs
<WebKit::WebGraphicsContext3D
>()));
148 output_surface_
->BindToClient(fake_client_
.get());
150 resource_provider_
= ResourceProvider::Create(output_surface_
.get(), 0);
151 renderer_
= GLRenderer::Create(fake_client_
.get(),
152 output_surface_
.get(),
153 resource_provider_
.get(),
155 use_skia_gpu_backend
).PassAs
<DirectRenderer
>();
157 scoped_refptr
<webkit::gpu::ContextProviderInProcess
> offscreen_contexts
=
158 webkit::gpu::ContextProviderInProcess::Create();
159 ASSERT_TRUE(offscreen_contexts
->BindToCurrentThread());
160 resource_provider_
->set_offscreen_context_provider(offscreen_contexts
);
163 void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion
,
164 gfx::Vector2d viewport_offset
) {
165 static_cast<PixelTestOutputSurface
*>(output_surface_
.get())
166 ->set_surface_expansion_size(surface_expansion
);
167 static_cast<PixelTestOutputSurface
*>(output_surface_
.get())
168 ->set_viewport_offset(viewport_offset
);
169 SoftwareOutputDevice
* device
= output_surface_
->software_device();
171 static_cast<PixelTestSoftwareOutputDevice
*>(device
)
172 ->set_surface_expansion_size(surface_expansion
);
176 void PixelTest::SetUpSoftwareRenderer() {
179 scoped_ptr
<SoftwareOutputDevice
> device(new PixelTestSoftwareOutputDevice());
180 output_surface_
.reset(new PixelTestOutputSurface(device
.Pass()));
181 output_surface_
->BindToClient(fake_client_
.get());
182 resource_provider_
= ResourceProvider::Create(output_surface_
.get(), 0);
183 renderer_
= SoftwareRenderer::Create(
185 output_surface_
.get(),
186 resource_provider_
.get()).PassAs
<DirectRenderer
>();