- add sources.
[platform/framework/web/crosswalk.git] / src / cc / test / pixel_test.cc
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.
4
5 #include "cc/test/pixel_test.h"
6
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "base/run_loop.h"
10 #include "cc/base/switches.h"
11 #include "cc/output/compositor_frame_metadata.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/gl_renderer.h"
15 #include "cc/output/output_surface_client.h"
16 #include "cc/output/software_renderer.h"
17 #include "cc/resources/resource_provider.h"
18 #include "cc/resources/texture_mailbox_deleter.h"
19 #include "cc/test/paths.h"
20 #include "cc/test/pixel_test_output_surface.h"
21 #include "cc/test/pixel_test_software_output_device.h"
22 #include "cc/test/pixel_test_utils.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/gl/gl_implementation.h"
25 #include "webkit/common/gpu/context_provider_in_process.h"
26 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
27
28 namespace cc {
29
30 class PixelTest::PixelTestRendererClient
31     : public RendererClient, public OutputSurfaceClient {
32  public:
33   explicit PixelTestRendererClient(gfx::Rect device_viewport)
34       : device_viewport_(device_viewport), device_clip_(device_viewport) {}
35
36   // RendererClient implementation.
37   virtual gfx::Rect DeviceViewport() const OVERRIDE {
38     return device_viewport_;
39   }
40   virtual gfx::Rect DeviceClip() const OVERRIDE { return device_clip_; }
41   virtual void SetFullRootLayerDamage() OVERRIDE {}
42   virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const
43       OVERRIDE {
44     return CompositorFrameMetadata();
45   }
46
47   // OutputSurfaceClient implementation.
48   virtual bool DeferredInitialize(
49       scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE {
50     return false;
51   }
52   virtual void ReleaseGL() OVERRIDE {}
53   virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
54   virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
55   virtual void OnSwapBuffersComplete() OVERRIDE {}
56   virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {}
57   virtual void DidLoseOutputSurface() OVERRIDE {}
58   virtual void SetExternalDrawConstraints(
59       const gfx::Transform& transform,
60       gfx::Rect viewport,
61       gfx::Rect clip,
62       bool valid_for_tile_management) OVERRIDE {
63     device_viewport_ = viewport;
64     device_clip_ = clip;
65   }
66   virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE {}
67   virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {}
68
69  private:
70   gfx::Rect device_viewport_;
71   gfx::Rect device_clip_;
72 };
73
74 PixelTest::PixelTest()
75     : device_viewport_size_(gfx::Size(200, 200)),
76       disable_picture_quad_image_filtering_(false),
77       fake_client_(
78           new PixelTestRendererClient(gfx::Rect(device_viewport_size_))) {}
79
80 PixelTest::~PixelTest() {}
81
82 bool PixelTest::RunPixelTest(RenderPassList* pass_list,
83                              OffscreenContextOption provide_offscreen_context,
84                              const base::FilePath& ref_file,
85                              const PixelComparator& comparator) {
86   return RunPixelTestWithReadbackTarget(pass_list,
87                                         pass_list->back(),
88                                         provide_offscreen_context,
89                                         ref_file,
90                                         comparator);
91 }
92
93 bool PixelTest::RunPixelTestWithReadbackTarget(
94     RenderPassList* pass_list,
95     RenderPass* target,
96     OffscreenContextOption provide_offscreen_context,
97     const base::FilePath& ref_file,
98     const PixelComparator& comparator) {
99   base::RunLoop run_loop;
100
101   target->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest(
102       base::Bind(&PixelTest::ReadbackResult,
103                  base::Unretained(this),
104                  run_loop.QuitClosure())));
105
106   scoped_refptr<webkit::gpu::ContextProviderInProcess> offscreen_contexts;
107   switch (provide_offscreen_context) {
108     case NoOffscreenContext:
109       break;
110     case WithOffscreenContext:
111       offscreen_contexts =
112           webkit::gpu::ContextProviderInProcess::CreateOffscreen();
113       CHECK(offscreen_contexts->BindToCurrentThread());
114       break;
115   }
116
117   float device_scale_factor = 1.f;
118   bool allow_partial_swap = true;
119
120   renderer_->DecideRenderPassAllocationsForFrame(*pass_list);
121   renderer_->DrawFrame(pass_list,
122                        offscreen_contexts.get(),
123                        device_scale_factor,
124                        allow_partial_swap,
125                        disable_picture_quad_image_filtering_);
126
127   // Wait for the readback to complete.
128   resource_provider_->Finish();
129   run_loop.Run();
130
131   return PixelsMatchReference(ref_file, comparator);
132 }
133
134 void PixelTest::ReadbackResult(base::Closure quit_run_loop,
135                                scoped_ptr<CopyOutputResult> result) {
136   ASSERT_TRUE(result->HasBitmap());
137   result_bitmap_ = result->TakeBitmap().Pass();
138   quit_run_loop.Run();
139 }
140
141 bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
142                                      const PixelComparator& comparator) {
143   base::FilePath test_data_dir;
144   if (!PathService::Get(cc::DIR_TEST_DATA, &test_data_dir))
145     return false;
146
147   // If this is false, we didn't set up a readback on a render pass.
148   if (!result_bitmap_)
149     return false;
150
151   CommandLine* cmd = CommandLine::ForCurrentProcess();
152   if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
153     return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
154
155   return MatchesPNGFile(*result_bitmap_,
156                         test_data_dir.Append(ref_file),
157                         comparator);
158 }
159
160 void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
161   CHECK(fake_client_);
162   CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL));
163
164   using webkit::gpu::ContextProviderInProcess;
165   output_surface_.reset(new PixelTestOutputSurface(
166       ContextProviderInProcess::CreateOffscreen()));
167   output_surface_->BindToClient(fake_client_.get());
168
169   resource_provider_ =
170       ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
171
172   texture_mailbox_deleter_ = make_scoped_ptr(new TextureMailboxDeleter);
173
174   renderer_ = GLRenderer::Create(fake_client_.get(),
175                                  &settings_,
176                                  output_surface_.get(),
177                                  resource_provider_.get(),
178                                  texture_mailbox_deleter_.get(),
179                                  0,
180                                  use_skia_gpu_backend).PassAs<DirectRenderer>();
181 }
182
183 void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion,
184                                       gfx::Vector2d viewport_offset) {
185   static_cast<PixelTestOutputSurface*>(output_surface_.get())
186       ->set_surface_expansion_size(surface_expansion);
187   static_cast<PixelTestOutputSurface*>(output_surface_.get())
188       ->set_viewport_offset(viewport_offset);
189   SoftwareOutputDevice* device = output_surface_->software_device();
190   if (device) {
191     static_cast<PixelTestSoftwareOutputDevice*>(device)
192         ->set_surface_expansion_size(surface_expansion);
193   }
194 }
195
196 void PixelTest::ForceDeviceClip(gfx::Rect clip) {
197   static_cast<PixelTestOutputSurface*>(output_surface_.get())
198       ->set_device_clip(clip);
199 }
200
201 void PixelTest::EnableExternalStencilTest() {
202   static_cast<PixelTestOutputSurface*>(output_surface_.get())
203       ->set_has_external_stencil_test(true);
204 }
205
206 void PixelTest::SetUpSoftwareRenderer() {
207   CHECK(fake_client_);
208
209   scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice());
210   output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
211   output_surface_->BindToClient(fake_client_.get());
212   resource_provider_ =
213       ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
214   renderer_ = SoftwareRenderer::Create(fake_client_.get(),
215                                        &settings_,
216                                        output_surface_.get(),
217                                        resource_provider_.get())
218       .PassAs<DirectRenderer>();
219 }
220
221 }  // namespace cc