Adding binary files for platform_keys tests.
[chromium-blink-merge.git] / cc / test / layer_tree_pixel_test.cc
blobf7ab9c27e36fa731563fdda72f6181d558ddd197
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/layer_tree_pixel_test.h"
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "cc/base/switches.h"
10 #include "cc/layers/solid_color_layer.h"
11 #include "cc/layers/texture_layer.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/direct_renderer.h"
15 #include "cc/resources/texture_mailbox.h"
16 #include "cc/test/paths.h"
17 #include "cc/test/pixel_comparator.h"
18 #include "cc/test/pixel_test_output_surface.h"
19 #include "cc/test/pixel_test_software_output_device.h"
20 #include "cc/test/pixel_test_utils.h"
21 #include "cc/test/test_in_process_context_provider.h"
22 #include "cc/trees/layer_tree_impl.h"
23 #include "gpu/command_buffer/client/gl_in_process_context.h"
24 #include "gpu/command_buffer/client/gles2_implementation.h"
26 using gpu::gles2::GLES2Interface;
28 namespace cc {
30 LayerTreePixelTest::LayerTreePixelTest()
31 : pixel_comparator_(new ExactPixelComparator(true)),
32 test_type_(PIXEL_TEST_GL),
33 pending_texture_mailbox_callbacks_(0),
34 impl_side_painting_(true) {
37 LayerTreePixelTest::~LayerTreePixelTest() {}
39 scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() {
40 gfx::Size surface_expansion_size(40, 60);
41 scoped_ptr<PixelTestOutputSurface> output_surface;
43 switch (test_type_) {
44 case PIXEL_TEST_SOFTWARE: {
45 scoped_ptr<PixelTestSoftwareOutputDevice> software_output_device(
46 new PixelTestSoftwareOutputDevice);
47 software_output_device->set_surface_expansion_size(
48 surface_expansion_size);
49 output_surface = make_scoped_ptr(
50 new PixelTestOutputSurface(software_output_device.Pass()));
51 break;
53 case PIXEL_TEST_GL: {
54 bool flipped_output_surface = false;
55 output_surface = make_scoped_ptr(new PixelTestOutputSurface(
56 new TestInProcessContextProvider, new TestInProcessContextProvider,
57 flipped_output_surface));
58 break;
62 output_surface->set_surface_expansion_size(surface_expansion_size);
63 return output_surface.Pass();
66 void LayerTreePixelTest::CommitCompleteOnThread(LayerTreeHostImpl* impl) {
67 LayerTreeImpl* commit_tree =
68 impl->pending_tree() ? impl->pending_tree() : impl->active_tree();
69 if (commit_tree->source_frame_number() != 0)
70 return;
72 DirectRenderer* renderer = static_cast<DirectRenderer*>(impl->renderer());
73 renderer->SetEnlargePassTextureAmountForTesting(enlarge_texture_amount_);
75 gfx::Rect viewport = impl->DeviceViewport();
76 // The viewport has a 0,0 origin without external influence.
77 EXPECT_EQ(gfx::Point().ToString(), viewport.origin().ToString());
78 // Be that influence!
79 viewport += gfx::Vector2d(20, 10);
80 bool resourceless_software_draw = false;
81 gfx::Transform identity = gfx::Transform();
82 impl->SetExternalDrawConstraints(identity,
83 viewport,
84 viewport,
85 viewport,
86 identity,
87 resourceless_software_draw);
88 EXPECT_EQ(viewport.ToString(), impl->DeviceViewport().ToString());
91 scoped_ptr<CopyOutputRequest> LayerTreePixelTest::CreateCopyOutputRequest() {
92 return CopyOutputRequest::CreateBitmapRequest(
93 base::Bind(&LayerTreePixelTest::ReadbackResult, base::Unretained(this)));
96 void LayerTreePixelTest::ReadbackResult(scoped_ptr<CopyOutputResult> result) {
97 ASSERT_TRUE(result->HasBitmap());
98 result_bitmap_ = result->TakeBitmap().Pass();
99 EndTest();
102 void LayerTreePixelTest::BeginTest() {
103 Layer* target = readback_target_ ? readback_target_
104 : layer_tree_host()->root_layer();
105 target->RequestCopyOfOutput(CreateCopyOutputRequest().Pass());
106 PostSetNeedsCommitToMainThread();
109 void LayerTreePixelTest::AfterTest() {
110 base::FilePath test_data_dir;
111 EXPECT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
112 base::FilePath ref_file_path = test_data_dir.Append(ref_file_);
114 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
115 if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
116 EXPECT_TRUE(WritePNGFile(*result_bitmap_, ref_file_path, true));
117 EXPECT_TRUE(MatchesPNGFile(*result_bitmap_,
118 ref_file_path,
119 *pixel_comparator_));
122 scoped_refptr<SolidColorLayer> LayerTreePixelTest::CreateSolidColorLayer(
123 const gfx::Rect& rect, SkColor color) {
124 scoped_refptr<SolidColorLayer> layer = SolidColorLayer::Create();
125 layer->SetIsDrawable(true);
126 layer->SetBounds(rect.size());
127 layer->SetPosition(rect.origin());
128 layer->SetBackgroundColor(color);
129 return layer;
132 void LayerTreePixelTest::EndTest() {
133 // Drop TextureMailboxes on the main thread so that they can be cleaned up and
134 // the pending callbacks will fire.
135 for (size_t i = 0; i < texture_layers_.size(); ++i) {
136 texture_layers_[i]->SetTextureMailbox(TextureMailbox(), nullptr);
139 TryEndTest();
142 void LayerTreePixelTest::TryEndTest() {
143 if (!result_bitmap_)
144 return;
145 if (pending_texture_mailbox_callbacks_)
146 return;
147 LayerTreeTest::EndTest();
150 scoped_refptr<SolidColorLayer> LayerTreePixelTest::
151 CreateSolidColorLayerWithBorder(
152 const gfx::Rect& rect, SkColor color,
153 int border_width, SkColor border_color) {
154 scoped_refptr<SolidColorLayer> layer = CreateSolidColorLayer(rect, color);
155 scoped_refptr<SolidColorLayer> border_top = CreateSolidColorLayer(
156 gfx::Rect(0, 0, rect.width(), border_width), border_color);
157 scoped_refptr<SolidColorLayer> border_left = CreateSolidColorLayer(
158 gfx::Rect(0,
159 border_width,
160 border_width,
161 rect.height() - border_width * 2),
162 border_color);
163 scoped_refptr<SolidColorLayer> border_right =
164 CreateSolidColorLayer(gfx::Rect(rect.width() - border_width,
165 border_width,
166 border_width,
167 rect.height() - border_width * 2),
168 border_color);
169 scoped_refptr<SolidColorLayer> border_bottom = CreateSolidColorLayer(
170 gfx::Rect(0, rect.height() - border_width, rect.width(), border_width),
171 border_color);
172 layer->AddChild(border_top);
173 layer->AddChild(border_left);
174 layer->AddChild(border_right);
175 layer->AddChild(border_bottom);
176 return layer;
179 scoped_refptr<TextureLayer> LayerTreePixelTest::CreateTextureLayer(
180 const gfx::Rect& rect, const SkBitmap& bitmap) {
181 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(NULL);
182 layer->SetIsDrawable(true);
183 layer->SetBounds(rect.size());
184 layer->SetPosition(rect.origin());
186 TextureMailbox texture_mailbox;
187 scoped_ptr<SingleReleaseCallback> release_callback;
188 CopyBitmapToTextureMailboxAsTexture(
189 bitmap, &texture_mailbox, &release_callback);
190 layer->SetTextureMailbox(texture_mailbox, release_callback.Pass());
192 texture_layers_.push_back(layer);
193 pending_texture_mailbox_callbacks_++;
194 return layer;
197 void LayerTreePixelTest::RunPixelTest(
198 PixelTestType test_type,
199 scoped_refptr<Layer> content_root,
200 base::FilePath file_name) {
201 test_type_ = test_type;
202 content_root_ = content_root;
203 readback_target_ = NULL;
204 ref_file_ = file_name;
205 bool threaded = true;
206 RunTest(threaded, false, impl_side_painting_);
209 void LayerTreePixelTest::RunSingleThreadedPixelTest(
210 PixelTestType test_type,
211 scoped_refptr<Layer> content_root,
212 base::FilePath file_name) {
213 test_type_ = test_type;
214 content_root_ = content_root;
215 readback_target_ = NULL;
216 ref_file_ = file_name;
217 bool threaded = false;
218 RunTest(threaded, false, impl_side_painting_);
221 void LayerTreePixelTest::RunPixelTestWithReadbackTarget(
222 PixelTestType test_type,
223 scoped_refptr<Layer> content_root,
224 Layer* target,
225 base::FilePath file_name) {
226 test_type_ = test_type;
227 content_root_ = content_root;
228 readback_target_ = target;
229 ref_file_ = file_name;
230 RunTest(true, false, impl_side_painting_);
233 void LayerTreePixelTest::SetupTree() {
234 scoped_refptr<Layer> root = Layer::Create();
235 root->SetBounds(content_root_->bounds());
236 root->AddChild(content_root_);
237 layer_tree_host()->SetRootLayer(root);
238 LayerTreeTest::SetupTree();
241 scoped_ptr<SkBitmap> LayerTreePixelTest::CopyTextureMailboxToBitmap(
242 const gfx::Size& size,
243 const TextureMailbox& texture_mailbox) {
244 DCHECK(texture_mailbox.IsTexture());
245 if (!texture_mailbox.IsTexture())
246 return nullptr;
248 scoped_ptr<gpu::GLInProcessContext> context = CreateTestInProcessContext();
249 GLES2Interface* gl = context->GetImplementation();
251 if (texture_mailbox.sync_point())
252 gl->WaitSyncPointCHROMIUM(texture_mailbox.sync_point());
254 GLuint texture_id = 0;
255 gl->GenTextures(1, &texture_id);
256 gl->BindTexture(GL_TEXTURE_2D, texture_id);
257 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
258 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
259 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
260 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
261 gl->ConsumeTextureCHROMIUM(texture_mailbox.target(), texture_mailbox.name());
262 gl->BindTexture(GL_TEXTURE_2D, 0);
264 GLuint fbo = 0;
265 gl->GenFramebuffers(1, &fbo);
266 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
267 gl->FramebufferTexture2D(
268 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
269 EXPECT_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
270 gl->CheckFramebufferStatus(GL_FRAMEBUFFER));
272 scoped_ptr<uint8[]> pixels(new uint8[size.GetArea() * 4]);
273 gl->ReadPixels(0,
275 size.width(),
276 size.height(),
277 GL_RGBA,
278 GL_UNSIGNED_BYTE,
279 pixels.get());
281 gl->DeleteFramebuffers(1, &fbo);
282 gl->DeleteTextures(1, &texture_id);
284 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
285 bitmap->allocN32Pixels(size.width(), size.height());
287 uint8* out_pixels = static_cast<uint8*>(bitmap->getPixels());
289 size_t row_bytes = size.width() * 4;
290 size_t total_bytes = size.height() * row_bytes;
291 for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
292 // Flip Y axis.
293 size_t src_y = total_bytes - dest_y - row_bytes;
294 // Swizzle OpenGL -> Skia byte order.
295 for (size_t x = 0; x < row_bytes; x += 4) {
296 out_pixels[dest_y + x + SK_R32_SHIFT/8] = pixels.get()[src_y + x + 0];
297 out_pixels[dest_y + x + SK_G32_SHIFT/8] = pixels.get()[src_y + x + 1];
298 out_pixels[dest_y + x + SK_B32_SHIFT/8] = pixels.get()[src_y + x + 2];
299 out_pixels[dest_y + x + SK_A32_SHIFT/8] = pixels.get()[src_y + x + 3];
303 return bitmap.Pass();
306 void LayerTreePixelTest::ReleaseTextureMailbox(
307 scoped_ptr<gpu::GLInProcessContext> context,
308 uint32 texture,
309 uint32 sync_point,
310 bool lost_resource) {
311 GLES2Interface* gl = context->GetImplementation();
312 if (sync_point)
313 gl->WaitSyncPointCHROMIUM(sync_point);
314 gl->DeleteTextures(1, &texture);
315 pending_texture_mailbox_callbacks_--;
316 TryEndTest();
319 void LayerTreePixelTest::CopyBitmapToTextureMailboxAsTexture(
320 const SkBitmap& bitmap,
321 TextureMailbox* texture_mailbox,
322 scoped_ptr<SingleReleaseCallback>* release_callback) {
323 DCHECK_GT(bitmap.width(), 0);
324 DCHECK_GT(bitmap.height(), 0);
326 scoped_ptr<gpu::GLInProcessContext> context = CreateTestInProcessContext();
327 GLES2Interface* gl = context->GetImplementation();
329 GLuint texture_id = 0;
330 gl->GenTextures(1, &texture_id);
331 gl->BindTexture(GL_TEXTURE_2D, texture_id);
332 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
333 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
334 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
335 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
337 DCHECK_EQ(kN32_SkColorType, bitmap.colorType());
340 SkAutoLockPixels lock(bitmap);
342 size_t row_bytes = bitmap.width() * 4;
343 size_t total_bytes = bitmap.height() * row_bytes;
345 scoped_ptr<uint8[]> gl_pixels(new uint8[total_bytes]);
346 uint8* bitmap_pixels = static_cast<uint8*>(bitmap.getPixels());
348 for (size_t y = 0; y < total_bytes; y += row_bytes) {
349 // Flip Y axis.
350 size_t src_y = total_bytes - y - row_bytes;
351 // Swizzle Skia -> OpenGL byte order.
352 for (size_t x = 0; x < row_bytes; x += 4) {
353 gl_pixels.get()[y + x + 0] = bitmap_pixels[src_y + x + SK_R32_SHIFT/8];
354 gl_pixels.get()[y + x + 1] = bitmap_pixels[src_y + x + SK_G32_SHIFT/8];
355 gl_pixels.get()[y + x + 2] = bitmap_pixels[src_y + x + SK_B32_SHIFT/8];
356 gl_pixels.get()[y + x + 3] = bitmap_pixels[src_y + x + SK_A32_SHIFT/8];
360 gl->TexImage2D(GL_TEXTURE_2D,
362 GL_RGBA,
363 bitmap.width(),
364 bitmap.height(),
366 GL_RGBA,
367 GL_UNSIGNED_BYTE,
368 gl_pixels.get());
371 gpu::Mailbox mailbox;
372 gl->GenMailboxCHROMIUM(mailbox.name);
373 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
374 gl->BindTexture(GL_TEXTURE_2D, 0);
375 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
377 *texture_mailbox = TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point);
378 *release_callback = SingleReleaseCallback::Create(
379 base::Bind(&LayerTreePixelTest::ReleaseTextureMailbox,
380 base::Unretained(this),
381 base::Passed(&context),
382 texture_id));
385 } // namespace cc