blob: cec5dc9b96d5ef59ece283746be68ed781409a62 [file] [log] [blame]
revemanb195f41d2015-11-19 22:16:481// Copyright 2015 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
Fady Samuele4786072017-07-24 20:03:385#include "components/exo/surface.h"
David Reveman22587fbc2017-08-28 22:27:186
revemanb195f41d2015-11-19 22:16:487#include "base/bind.h"
Peng Huang76f5fd02017-09-01 00:59:398#include "base/command_line.h"
9#include "base/strings/stringprintf.h"
revemanb195f41d2015-11-19 22:16:4810#include "components/exo/buffer.h"
Peng Huang583c9dc62017-07-27 23:38:2811#include "components/exo/shell_surface.h"
David Reveman22587fbc2017-08-28 22:27:1812#include "components/exo/sub_surface.h"
revemanb195f41d2015-11-19 22:16:4813#include "components/exo/test/exo_test_base.h"
14#include "components/exo/test/exo_test_helper.h"
danakj5e0a12b2017-09-25 17:26:4915#include "components/viz/common/quads/compositor_frame.h"
danakje5805be2017-09-15 19:24:5516#include "components/viz/common/quads/texture_draw_quad.h"
Fady Samueldea5e8f2017-07-19 21:41:3317#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
Fady Samuele4786072017-07-24 20:03:3818#include "components/viz/service/surfaces/surface.h"
Fady Samuelc296f5fb2017-07-21 04:02:1919#include "components/viz/test/begin_frame_args_test.h"
Fady Samuele65ab0a12017-07-28 17:47:2520#include "components/viz/test/fake_external_begin_frame_source.h"
revemanb195f41d2015-11-19 22:16:4821#include "testing/gtest/include/gtest/gtest.h"
Peng Huang583c9dc62017-07-27 23:38:2822#include "third_party/khronos/GLES2/gl2.h"
jbauman45c06862016-06-23 19:35:0223#include "ui/aura/env.h"
jbauman3bf9b9c2016-06-07 01:33:1424#include "ui/compositor/layer_tree_owner.h"
Peng Huang76f5fd02017-09-01 00:59:3925#include "ui/display/display.h"
26#include "ui/display/display_switches.h"
27#include "ui/gfx/geometry/dip_util.h"
revemanb195f41d2015-11-19 22:16:4828#include "ui/gfx/gpu_memory_buffer.h"
jbauman3bf9b9c2016-06-07 01:33:1429#include "ui/wm/core/window_util.h"
revemanb195f41d2015-11-19 22:16:4830
31namespace exo {
32namespace {
33
Peng Huang76f5fd02017-09-01 00:59:3934class SurfaceTest : public test::ExoTestBase,
35 public ::testing::WithParamInterface<float> {
36 public:
37 SurfaceTest() = default;
38 ~SurfaceTest() override = default;
39 void SetUp() override {
40 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
41 // Set the device scale factor.
42 command_line->AppendSwitchASCII(
43 switches::kForceDeviceScaleFactor,
44 base::StringPrintf("%f", device_scale_factor()));
45 test::ExoTestBase::SetUp();
46 }
47
48 void TearDown() override {
49 test::ExoTestBase::TearDown();
50 display::Display::ResetForceDeviceScaleFactorForTesting();
51 }
52
53 float device_scale_factor() const { return GetParam(); }
54
55 gfx::Rect ToPixel(const gfx::Rect rect) {
56 return gfx::ConvertRectToPixel(device_scale_factor(), rect);
57 }
58
59 private:
60 DISALLOW_COPY_AND_ASSIGN(SurfaceTest);
61};
revemanb195f41d2015-11-19 22:16:4862
63void ReleaseBuffer(int* release_buffer_call_count) {
64 (*release_buffer_call_count)++;
65}
66
Peng Huang76f5fd02017-09-01 00:59:3967// Instantiate the Boolean which is used to toggle mouse and touch events in
68// the parameterized tests.
69INSTANTIATE_TEST_CASE_P(, SurfaceTest, testing::Values(1.0f, 1.25f, 2.0f));
70
71TEST_P(SurfaceTest, Attach) {
revemanb195f41d2015-11-19 22:16:4872 gfx::Size buffer_size(256, 256);
dcheng31759da2016-04-21 01:26:3173 std::unique_ptr<Buffer> buffer(
revemanc8623d5b2016-02-09 02:29:1074 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
revemanb195f41d2015-11-19 22:16:4875
76 // Set the release callback that will be run when buffer is no longer in use.
77 int release_buffer_call_count = 0;
78 buffer->set_release_callback(
79 base::Bind(&ReleaseBuffer, base::Unretained(&release_buffer_call_count)));
80
dcheng31759da2016-04-21 01:26:3181 std::unique_ptr<Surface> surface(new Surface);
revemanb195f41d2015-11-19 22:16:4882
83 // Attach the buffer to surface1.
revemanced21f862015-11-24 00:42:4984 surface->Attach(buffer.get());
85 surface->Commit();
revemanb195f41d2015-11-19 22:16:4886
revemanced21f862015-11-24 00:42:4987 // Commit without calling Attach() should have no effect.
88 surface->Commit();
89 EXPECT_EQ(0, release_buffer_call_count);
revemanb195f41d2015-11-19 22:16:4890
revemanced21f862015-11-24 00:42:4991 // Attach a null buffer to surface, this should release the previously
revemanb195f41d2015-11-19 22:16:4892 // attached buffer.
revemanced21f862015-11-24 00:42:4993 surface->Attach(nullptr);
94 surface->Commit();
danakjc7afae52017-06-20 21:12:4195 // LayerTreeFrameSinkHolder::ReclaimResources() gets called via
danakj2e3aca02017-06-23 22:58:5296 // CompositorFrameSinkClient interface. We need to wait here for the mojo
starazd8f4f642016-12-10 23:49:2097 // call to finish so that the release callback finishes running before
98 // the assertion below.
99 RunAllPendingInMessageLoop();
revemanced21f862015-11-24 00:42:49100 ASSERT_EQ(1, release_buffer_call_count);
revemanb195f41d2015-11-19 22:16:48101}
102
danakj5e0a12b2017-09-25 17:26:49103const viz::CompositorFrame& GetFrameFromSurface(ShellSurface* shell_surface) {
Dominik Laskowski0b3a6d1d2017-10-03 20:29:11104 viz::SurfaceId surface_id = shell_surface->host_window()->GetSurfaceId();
Lloyd Pique8b62e992017-09-07 21:24:52105 viz::SurfaceManager* surface_manager = aura::Env::GetInstance()
106 ->context_factory_private()
107 ->GetFrameSinkManager()
108 ->surface_manager();
danakj5e0a12b2017-09-25 17:26:49109 const viz::CompositorFrame& frame =
Lloyd Pique8b62e992017-09-07 21:24:52110 surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
111 return frame;
112}
113
Peng Huang76f5fd02017-09-01 00:59:39114TEST_P(SurfaceTest, Damage) {
revemanb195f41d2015-11-19 22:16:48115 gfx::Size buffer_size(256, 256);
dcheng31759da2016-04-21 01:26:31116 std::unique_ptr<Buffer> buffer(
revemanc8623d5b2016-02-09 02:29:10117 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
dcheng31759da2016-04-21 01:26:31118 std::unique_ptr<Surface> surface(new Surface);
David Revemand0ab1fb82017-09-18 22:27:57119 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
revemanb195f41d2015-11-19 22:16:48120
121 // Attach the buffer to the surface. This will update the pending bounds of
122 // the surface to the buffer size.
123 surface->Attach(buffer.get());
124
reveman5c353d52016-02-11 21:28:56125 // Mark areas inside the bounds of the surface as damaged. This should result
revemanb195f41d2015-11-19 22:16:48126 // in pending damage.
127 surface->Damage(gfx::Rect(0, 0, 10, 10));
reveman5c353d52016-02-11 21:28:56128 surface->Damage(gfx::Rect(10, 10, 10, 10));
129 EXPECT_TRUE(surface->HasPendingDamageForTesting(gfx::Rect(0, 0, 10, 10)));
130 EXPECT_TRUE(surface->HasPendingDamageForTesting(gfx::Rect(10, 10, 10, 10)));
131 EXPECT_FALSE(surface->HasPendingDamageForTesting(gfx::Rect(5, 5, 10, 10)));
reveman93f6cf72017-03-07 13:50:35132
133 // Check that damage larger than contents is handled correctly at commit.
134 surface->Damage(gfx::Rect(gfx::ScaleToCeiledSize(buffer_size, 2.0f)));
135 surface->Commit();
Lloyd Pique8b62e992017-09-07 21:24:52136 RunAllPendingInMessageLoop();
137
138 {
danakj5e0a12b2017-09-25 17:26:49139 const viz::CompositorFrame& frame =
140 GetFrameFromSurface(shell_surface.get());
David Reveman472ec3212017-11-11 04:19:03141 EXPECT_EQ(ToPixel(gfx::Rect(buffer_size)),
Lloyd Pique8b62e992017-09-07 21:24:52142 frame.render_pass_list.back()->damage_rect);
143 }
144
David Reveman472ec3212017-11-11 04:19:03145 gfx::RectF buffer_damage(32, 64, 16, 32);
146 gfx::Rect surface_damage = gfx::ToNearestRect(buffer_damage);
147
Lloyd Pique8b62e992017-09-07 21:24:52148 // Check that damage is correct for a non-square rectangle not at the origin.
David Reveman472ec3212017-11-11 04:19:03149 surface->Damage(surface_damage);
Lloyd Pique8b62e992017-09-07 21:24:52150 surface->Commit();
151 RunAllPendingInMessageLoop();
152
David Reveman472ec3212017-11-11 04:19:03153 // Adjust damage for DSF filtering and verify it below.
154 if (device_scale_factor() > 1.f)
155 buffer_damage.Inset(-1.f, -1.f);
156
Lloyd Pique8b62e992017-09-07 21:24:52157 {
danakj5e0a12b2017-09-25 17:26:49158 const viz::CompositorFrame& frame =
159 GetFrameFromSurface(shell_surface.get());
David Reveman472ec3212017-11-11 04:19:03160 EXPECT_TRUE(
161 gfx::RectF(frame.render_pass_list.back()->damage_rect)
162 .Contains(gfx::ScaleRect(buffer_damage, device_scale_factor())));
Lloyd Pique8b62e992017-09-07 21:24:52163 }
revemanb195f41d2015-11-19 22:16:48164}
165
166void SetFrameTime(base::TimeTicks* result, base::TimeTicks frame_time) {
167 *result = frame_time;
168}
169
Peng Huang76f5fd02017-09-01 00:59:39170TEST_P(SurfaceTest, RequestFrameCallback) {
dcheng31759da2016-04-21 01:26:31171 std::unique_ptr<Surface> surface(new Surface);
revemanb195f41d2015-11-19 22:16:48172
173 base::TimeTicks frame_time;
174 surface->RequestFrameCallback(
175 base::Bind(&SetFrameTime, base::Unretained(&frame_time)));
176 surface->Commit();
177
178 // Callback should not run synchronously.
179 EXPECT_TRUE(frame_time.is_null());
180}
181
Peng Huang76f5fd02017-09-01 00:59:39182TEST_P(SurfaceTest, SetOpaqueRegion) {
revemanca132dc2017-01-31 22:35:54183 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57184 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28185 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57186 auto surface = std::make_unique<Surface>();
187 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
revemanb195f41d2015-11-19 22:16:48188
revemanca132dc2017-01-31 22:35:54189 // Attaching a buffer with alpha channel.
190 surface->Attach(buffer.get());
revemanb195f41d2015-11-19 22:16:48191
revemanca132dc2017-01-31 22:35:54192 // Setting an opaque region that contains the buffer size doesn't require
193 // draw with blending.
Dominik Laskowski0dcf91352017-11-29 19:21:35194 surface->SetOpaqueRegion(gfx::Rect(256, 256));
revemanca132dc2017-01-31 22:35:54195 surface->Commit();
196 RunAllPendingInMessageLoop();
197
198 {
danakj5e0a12b2017-09-25 17:26:49199 const viz::CompositorFrame& frame =
200 GetFrameFromSurface(shell_surface.get());
revemanca132dc2017-01-31 22:35:54201 ASSERT_EQ(1u, frame.render_pass_list.size());
202 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
203 EXPECT_FALSE(frame.render_pass_list.back()
204 ->quad_list.back()
205 ->ShouldDrawWithBlending());
Peng Huang76f5fd02017-09-01 00:59:39206 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
Lloyd Piqued1e23fd2017-08-15 23:10:51207 frame.render_pass_list.back()->damage_rect);
revemanca132dc2017-01-31 22:35:54208 }
209
210 // Setting an empty opaque region requires draw with blending.
Dominik Laskowski0dcf91352017-11-29 19:21:35211 surface->SetOpaqueRegion(gfx::Rect());
revemanca132dc2017-01-31 22:35:54212 surface->Commit();
213 RunAllPendingInMessageLoop();
214
215 {
danakj5e0a12b2017-09-25 17:26:49216 const viz::CompositorFrame& frame =
217 GetFrameFromSurface(shell_surface.get());
revemanca132dc2017-01-31 22:35:54218 ASSERT_EQ(1u, frame.render_pass_list.size());
219 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
220 EXPECT_TRUE(frame.render_pass_list.back()
221 ->quad_list.back()
222 ->ShouldDrawWithBlending());
Peng Huang76f5fd02017-09-01 00:59:39223 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
Lloyd Piqued1e23fd2017-08-15 23:10:51224 frame.render_pass_list.back()->damage_rect);
revemanca132dc2017-01-31 22:35:54225 }
226
227 std::unique_ptr<Buffer> buffer_without_alpha(
228 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(
229 buffer_size, gfx::BufferFormat::RGBX_8888)));
230
231 // Attaching a buffer without an alpha channel doesn't require draw with
232 // blending.
233 surface->Attach(buffer_without_alpha.get());
234 surface->Commit();
235 RunAllPendingInMessageLoop();
236
237 {
danakj5e0a12b2017-09-25 17:26:49238 const viz::CompositorFrame& frame =
239 GetFrameFromSurface(shell_surface.get());
revemanca132dc2017-01-31 22:35:54240 ASSERT_EQ(1u, frame.render_pass_list.size());
241 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
242 EXPECT_FALSE(frame.render_pass_list.back()
243 ->quad_list.back()
244 ->ShouldDrawWithBlending());
Peng Huang76f5fd02017-09-01 00:59:39245 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 0, 0)),
Lloyd Piqued1e23fd2017-08-15 23:10:51246 frame.render_pass_list.back()->damage_rect);
revemanca132dc2017-01-31 22:35:54247 }
revemanb195f41d2015-11-19 22:16:48248}
249
Peng Huang76f5fd02017-09-01 00:59:39250TEST_P(SurfaceTest, SetInputRegion) {
Peng Huangb921f3f2017-09-27 20:01:23251 // Create a shell surface which size is 512x512.
252 auto surface = std::make_unique<Surface>();
253 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
254 gfx::Size buffer_size(512, 512);
255 auto buffer = std::make_unique<Buffer>(
256 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
257 surface->Attach(buffer.get());
258 surface->Commit();
Dominik Laskowski57064702017-11-30 10:31:41259
260 {
261 // Default input region should match surface bounds.
262 auto rects = surface->GetHitTestShapeRects();
263 ASSERT_TRUE(rects);
264 ASSERT_EQ(1u, rects->size());
265 ASSERT_EQ(gfx::Rect(512, 512), (*rects)[0]);
266 }
reveman2966d7702016-02-12 02:09:54267
Peng Huangb921f3f2017-09-27 20:01:23268 {
269 // Setting a non-empty input region should succeed.
Dominik Laskowski0dcf91352017-11-29 19:21:35270 surface->SetInputRegion(gfx::Rect(256, 256));
Peng Huangb921f3f2017-09-27 20:01:23271 surface->Commit();
reveman2966d7702016-02-12 02:09:54272
Dominik Laskowski57064702017-11-30 10:31:41273 auto rects = surface->GetHitTestShapeRects();
274 ASSERT_TRUE(rects);
Peng Huangb921f3f2017-09-27 20:01:23275 ASSERT_EQ(1u, rects->size());
276 ASSERT_EQ(gfx::Rect(256, 256), (*rects)[0]);
277 }
278
279 {
280 // Setting an empty input region should succeed.
Dominik Laskowski0dcf91352017-11-29 19:21:35281 surface->SetInputRegion(gfx::Rect());
Peng Huangb921f3f2017-09-27 20:01:23282 surface->Commit();
283
Dominik Laskowski57064702017-11-30 10:31:41284 EXPECT_FALSE(surface->GetHitTestShapeRects());
Peng Huangb921f3f2017-09-27 20:01:23285 }
286
287 {
Dominik Laskowski0dcf91352017-11-29 19:21:35288 cc::Region region = gfx::Rect(512, 512);
289 region.Subtract(gfx::Rect(0, 64, 64, 64));
290 region.Subtract(gfx::Rect(88, 88, 12, 55));
291 region.Subtract(gfx::Rect(100, 0, 33, 66));
Peng Huangb921f3f2017-09-27 20:01:23292
293 // Setting a non-rectangle input region should succeed.
Dominik Laskowski0dcf91352017-11-29 19:21:35294 surface->SetInputRegion(region);
Peng Huangb921f3f2017-09-27 20:01:23295 surface->Commit();
296
Peng Huangb921f3f2017-09-27 20:01:23297 auto rects = surface->GetHitTestShapeRects();
Dominik Laskowski57064702017-11-30 10:31:41298 ASSERT_TRUE(rects);
Peng Huangb921f3f2017-09-27 20:01:23299 ASSERT_EQ(10u, rects->size());
Dominik Laskowski0dcf91352017-11-29 19:21:35300 cc::Region result;
Peng Huangb921f3f2017-09-27 20:01:23301 for (const auto& r : *rects)
Dominik Laskowski0dcf91352017-11-29 19:21:35302 result.Union(r);
Peng Huangb921f3f2017-09-27 20:01:23303 ASSERT_EQ(result, region);
304 }
Dominik Laskowski57064702017-11-30 10:31:41305
306 {
307 // Input region should be clipped to surface bounds.
308 surface->SetInputRegion(gfx::Rect(-50, -50, 1000, 100));
309 surface->Commit();
310
311 auto rects = surface->GetHitTestShapeRects();
312 ASSERT_TRUE(rects);
313 ASSERT_EQ(1u, rects->size());
314 ASSERT_EQ(gfx::Rect(512, 50), (*rects)[0]);
315 }
316
317 {
318 // Hit test region should accumulate input regions of sub-surfaces.
319 gfx::Rect input_rect(50, 50, 100, 100);
320 surface->SetInputRegion(input_rect);
321
322 gfx::Rect child_input_rect(-50, -50, 1000, 100);
323 auto child_buffer = std::make_unique<Buffer>(
324 exo_test_helper()->CreateGpuMemoryBuffer(child_input_rect.size()));
325 auto child_surface = std::make_unique<Surface>();
326 auto sub_surface =
327 std::make_unique<SubSurface>(child_surface.get(), surface.get());
328 sub_surface->SetPosition(child_input_rect.origin());
329 child_surface->Attach(child_buffer.get());
330 child_surface->Commit();
331 surface->Commit();
332
333 auto rects = surface->GetHitTestShapeRects();
334 ASSERT_TRUE(rects);
335 ASSERT_EQ(2u, rects->size());
336 cc::Region result = cc::UnionRegions((*rects)[0], (*rects)[1]);
337 ASSERT_EQ(cc::UnionRegions(input_rect, child_input_rect), result);
338 }
reveman2966d7702016-02-12 02:09:54339}
340
Peng Huang76f5fd02017-09-01 00:59:39341TEST_P(SurfaceTest, SetBufferScale) {
reveman7efa4b02016-01-06 08:29:54342 gfx::Size buffer_size(512, 512);
David Revemand0ab1fb82017-09-18 22:27:57343 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28344 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57345 auto surface = std::make_unique<Surface>();
346 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
reveman7efa4b02016-01-06 08:29:54347
reveman2966d7702016-02-12 02:09:54348 // This will update the bounds of the surface and take the buffer scale into
349 // account.
reveman7efa4b02016-01-06 08:29:54350 const float kBufferScale = 2.0f;
reveman2966d7702016-02-12 02:09:54351 surface->Attach(buffer.get());
reveman7efa4b02016-01-06 08:29:54352 surface->SetBufferScale(kBufferScale);
reveman2966d7702016-02-12 02:09:54353 surface->Commit();
reveman7efa4b02016-01-06 08:29:54354 EXPECT_EQ(
355 gfx::ScaleToFlooredSize(buffer_size, 1.0f / kBufferScale).ToString(),
jbaumane3526252016-06-09 18:43:05356 surface->window()->bounds().size().ToString());
jbaumanb362a892016-06-17 03:30:56357 EXPECT_EQ(
358 gfx::ScaleToFlooredSize(buffer_size, 1.0f / kBufferScale).ToString(),
359 surface->content_size().ToString());
Lloyd Piqued1e23fd2017-08-15 23:10:51360
361 RunAllPendingInMessageLoop();
362
danakj5e0a12b2017-09-25 17:26:49363 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
Lloyd Piqued1e23fd2017-08-15 23:10:51364 ASSERT_EQ(1u, frame.render_pass_list.size());
Peng Huang76f5fd02017-09-01 00:59:39365 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 256, 256)),
Lloyd Piqued1e23fd2017-08-15 23:10:51366 frame.render_pass_list.back()->damage_rect);
reveman7efa4b02016-01-06 08:29:54367}
368
Peng Huang76f5fd02017-09-01 00:59:39369TEST_P(SurfaceTest, SetBufferTransform) {
David Revemanfca309b2017-08-24 18:18:11370 gfx::Size buffer_size(256, 512);
David Revemand0ab1fb82017-09-18 22:27:57371 auto buffer = std::make_unique<Buffer>(
David Revemanfca309b2017-08-24 18:18:11372 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57373 auto surface = std::make_unique<Surface>();
374 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
David Revemanfca309b2017-08-24 18:18:11375
376 // This will update the bounds of the surface and take the buffer transform
377 // into account.
378 surface->Attach(buffer.get());
379 surface->SetBufferTransform(Transform::ROTATE_90);
380 surface->Commit();
David Reveman22587fbc2017-08-28 22:27:18381 EXPECT_EQ(gfx::Size(buffer_size.height(), buffer_size.width()),
382 surface->window()->bounds().size());
383 EXPECT_EQ(gfx::Size(buffer_size.height(), buffer_size.width()),
384 surface->content_size());
David Revemanfca309b2017-08-24 18:18:11385
386 RunAllPendingInMessageLoop();
387
David Reveman22587fbc2017-08-28 22:27:18388 {
danakj5e0a12b2017-09-25 17:26:49389 const viz::CompositorFrame& frame =
390 GetFrameFromSurface(shell_surface.get());
David Reveman22587fbc2017-08-28 22:27:18391 ASSERT_EQ(1u, frame.render_pass_list.size());
Peng Huang76f5fd02017-09-01 00:59:39392 EXPECT_EQ(
393 ToPixel(gfx::Rect(0, 0, buffer_size.height(), buffer_size.width())),
394 frame.render_pass_list.back()->damage_rect);
danakje5805be2017-09-15 19:24:55395 const auto& quad_list = frame.render_pass_list[0]->quad_list;
David Reveman22587fbc2017-08-28 22:27:18396 ASSERT_EQ(1u, quad_list.size());
397 EXPECT_EQ(
Peng Huang76f5fd02017-09-01 00:59:39398 ToPixel(gfx::Rect(0, 0, 512, 256)),
David Reveman22587fbc2017-08-28 22:27:18399 cc::MathUtil::MapEnclosingClippedRect(
400 quad_list.front()->shared_quad_state->quad_to_target_transform,
401 quad_list.front()->rect));
402 }
403
404 gfx::Size child_buffer_size(64, 128);
David Revemand0ab1fb82017-09-18 22:27:57405 auto child_buffer = std::make_unique<Buffer>(
David Reveman22587fbc2017-08-28 22:27:18406 exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57407 auto child_surface = std::make_unique<Surface>();
David Reveman22587fbc2017-08-28 22:27:18408 auto sub_surface =
David Revemand0ab1fb82017-09-18 22:27:57409 std::make_unique<SubSurface>(child_surface.get(), surface.get());
David Reveman22587fbc2017-08-28 22:27:18410
411 // Set position to 20, 10.
412 gfx::Point child_position(20, 10);
413 sub_surface->SetPosition(child_position);
414
415 child_surface->Attach(child_buffer.get());
416 child_surface->SetBufferTransform(Transform::ROTATE_180);
417 const int kChildBufferScale = 2;
418 child_surface->SetBufferScale(kChildBufferScale);
419 child_surface->Commit();
420 surface->Commit();
421 EXPECT_EQ(
422 gfx::ScaleToRoundedSize(child_buffer_size, 1.0f / kChildBufferScale),
423 child_surface->window()->bounds().size());
424 EXPECT_EQ(
425 gfx::ScaleToRoundedSize(child_buffer_size, 1.0f / kChildBufferScale),
426 child_surface->content_size());
427
428 RunAllPendingInMessageLoop();
429
430 {
danakj5e0a12b2017-09-25 17:26:49431 const viz::CompositorFrame& frame =
432 GetFrameFromSurface(shell_surface.get());
David Reveman22587fbc2017-08-28 22:27:18433 ASSERT_EQ(1u, frame.render_pass_list.size());
danakje5805be2017-09-15 19:24:55434 const auto& quad_list = frame.render_pass_list[0]->quad_list;
David Reveman22587fbc2017-08-28 22:27:18435 ASSERT_EQ(2u, quad_list.size());
436 EXPECT_EQ(
Peng Huang76f5fd02017-09-01 00:59:39437 ToPixel(gfx::Rect(child_position,
438 gfx::ScaleToRoundedSize(child_buffer_size,
439 1.0f / kChildBufferScale))),
David Reveman22587fbc2017-08-28 22:27:18440 cc::MathUtil::MapEnclosingClippedRect(
441 quad_list.front()->shared_quad_state->quad_to_target_transform,
442 quad_list.front()->rect));
443 }
David Revemanfca309b2017-08-24 18:18:11444}
445
Peng Huang76f5fd02017-09-01 00:59:39446TEST_P(SurfaceTest, MirrorLayers) {
jbauman3bf9b9c2016-06-07 01:33:14447 gfx::Size buffer_size(512, 512);
David Revemand0ab1fb82017-09-18 22:27:57448 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28449 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57450 auto surface = std::make_unique<Surface>();
451 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
jbauman3bf9b9c2016-06-07 01:33:14452
453 surface->Attach(buffer.get());
454 surface->Commit();
455
Dominik Laskowski0b3a6d1d2017-10-03 20:29:11456 EXPECT_EQ(buffer_size, surface->window()->bounds().size());
457 EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
458 std::unique_ptr<ui::LayerTreeOwner> old_layer_owner =
459 ::wm::MirrorLayers(shell_surface->host_window(), false /* sync_bounds */);
460 EXPECT_EQ(buffer_size, surface->window()->bounds().size());
461 EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
jbauman3bf9b9c2016-06-07 01:33:14462 EXPECT_EQ(buffer_size, old_layer_owner->root()->bounds().size());
Dominik Laskowski0b3a6d1d2017-10-03 20:29:11463 EXPECT_TRUE(shell_surface->host_window()->layer()->has_external_content());
jbauman3bf9b9c2016-06-07 01:33:14464 EXPECT_TRUE(old_layer_owner->root()->has_external_content());
465}
466
Peng Huang76f5fd02017-09-01 00:59:39467TEST_P(SurfaceTest, SetViewport) {
reveman642d8c332016-02-19 19:55:44468 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57469 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28470 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57471 auto surface = std::make_unique<Surface>();
472 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
reveman642d8c332016-02-19 19:55:44473
474 // This will update the bounds of the surface and take the viewport into
475 // account.
476 surface->Attach(buffer.get());
477 gfx::Size viewport(256, 256);
478 surface->SetViewport(viewport);
479 surface->Commit();
jbaumanb362a892016-06-17 03:30:56480 EXPECT_EQ(viewport.ToString(), surface->content_size().ToString());
reveman14681352016-06-02 15:37:51481
482 // This will update the bounds of the surface and take the viewport2 into
483 // account.
484 gfx::Size viewport2(512, 512);
485 surface->SetViewport(viewport2);
486 surface->Commit();
jbaumane3526252016-06-09 18:43:05487 EXPECT_EQ(viewport2.ToString(),
488 surface->window()->bounds().size().ToString());
jbaumanb362a892016-06-17 03:30:56489 EXPECT_EQ(viewport2.ToString(), surface->content_size().ToString());
Lloyd Piqued1e23fd2017-08-15 23:10:51490
491 RunAllPendingInMessageLoop();
492
danakj5e0a12b2017-09-25 17:26:49493 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
Lloyd Piqued1e23fd2017-08-15 23:10:51494 ASSERT_EQ(1u, frame.render_pass_list.size());
Peng Huang76f5fd02017-09-01 00:59:39495 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 512, 512)),
Lloyd Piqued1e23fd2017-08-15 23:10:51496 frame.render_pass_list.back()->damage_rect);
reveman642d8c332016-02-19 19:55:44497}
498
Peng Huang76f5fd02017-09-01 00:59:39499TEST_P(SurfaceTest, SetCrop) {
reveman8e323902016-05-23 21:55:36500 gfx::Size buffer_size(16, 16);
David Revemand0ab1fb82017-09-18 22:27:57501 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28502 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57503 auto surface = std::make_unique<Surface>();
504 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
reveman8e323902016-05-23 21:55:36505
506 surface->Attach(buffer.get());
507 gfx::Size crop_size(12, 12);
508 surface->SetCrop(gfx::RectF(gfx::PointF(2.0, 2.0), gfx::SizeF(crop_size)));
509 surface->Commit();
jbaumane3526252016-06-09 18:43:05510 EXPECT_EQ(crop_size.ToString(),
511 surface->window()->bounds().size().ToString());
jbaumanb362a892016-06-17 03:30:56512 EXPECT_EQ(crop_size.ToString(), surface->content_size().ToString());
Lloyd Piqued1e23fd2017-08-15 23:10:51513
514 RunAllPendingInMessageLoop();
515
danakj5e0a12b2017-09-25 17:26:49516 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
Lloyd Piqued1e23fd2017-08-15 23:10:51517 ASSERT_EQ(1u, frame.render_pass_list.size());
Peng Huang76f5fd02017-09-01 00:59:39518 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 12, 12)),
Lloyd Piqued1e23fd2017-08-15 23:10:51519 frame.render_pass_list.back()->damage_rect);
reveman8e323902016-05-23 21:55:36520}
521
Lloyd Pique0a3045f2017-09-15 23:34:12522TEST_P(SurfaceTest, SetCropAndBufferTransform) {
523 gfx::Size buffer_size(128, 64);
David Revemand0ab1fb82017-09-18 22:27:57524 auto buffer = std::make_unique<Buffer>(
Lloyd Pique0a3045f2017-09-15 23:34:12525 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57526 auto surface = std::make_unique<Surface>();
527 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12528
529 const gfx::RectF crop_0(
530 gfx::SkRectToRectF(SkRect::MakeLTRB(0.03125f, 0.1875f, 0.4375f, 0.25f)));
531 const gfx::RectF crop_90(
532 gfx::SkRectToRectF(SkRect::MakeLTRB(0.875f, 0.0625f, 0.90625f, 0.875f)));
533 const gfx::RectF crop_180(
534 gfx::SkRectToRectF(SkRect::MakeLTRB(0.5625f, 0.75f, 0.96875f, 0.8125f)));
535 const gfx::RectF crop_270(
536 gfx::SkRectToRectF(SkRect::MakeLTRB(0.09375f, 0.125f, 0.125f, 0.9375f)));
537 const gfx::Rect target_with_no_viewport(ToPixel(gfx::Rect(gfx::Size(52, 4))));
538 const gfx::Rect target_with_viewport(ToPixel(gfx::Rect(gfx::Size(128, 64))));
539
540 surface->Attach(buffer.get());
541 gfx::Size crop_size(52, 4);
542 surface->SetCrop(gfx::RectF(gfx::PointF(4, 12), gfx::SizeF(crop_size)));
543 surface->SetBufferTransform(Transform::NORMAL);
544 surface->Commit();
545
546 RunAllPendingInMessageLoop();
547
548 {
danakj5e0a12b2017-09-25 17:26:49549 const viz::CompositorFrame& frame =
550 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12551 ASSERT_EQ(1u, frame.render_pass_list.size());
552 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
553 ASSERT_EQ(1u, quad_list.size());
554 const viz::TextureDrawQuad* quad =
555 viz::TextureDrawQuad::MaterialCast(quad_list.front());
556 EXPECT_EQ(crop_0.origin(), quad->uv_top_left);
557 EXPECT_EQ(crop_0.bottom_right(), quad->uv_bottom_right);
558 EXPECT_EQ(
559 ToPixel(gfx::Rect(0, 0, 52, 4)),
560 cc::MathUtil::MapEnclosingClippedRect(
561 quad->shared_quad_state->quad_to_target_transform, quad->rect));
562 }
563
564 surface->SetBufferTransform(Transform::ROTATE_90);
565 surface->Commit();
566
567 RunAllPendingInMessageLoop();
568
569 {
danakj5e0a12b2017-09-25 17:26:49570 const viz::CompositorFrame& frame =
571 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12572 ASSERT_EQ(1u, frame.render_pass_list.size());
573 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
574 ASSERT_EQ(1u, quad_list.size());
575 const viz::TextureDrawQuad* quad =
576 viz::TextureDrawQuad::MaterialCast(quad_list.front());
577 EXPECT_EQ(crop_90.origin(), quad->uv_top_left);
578 EXPECT_EQ(crop_90.bottom_right(), quad->uv_bottom_right);
579 EXPECT_EQ(
580 ToPixel(gfx::Rect(0, 0, 52, 4)),
581 cc::MathUtil::MapEnclosingClippedRect(
582 quad->shared_quad_state->quad_to_target_transform, quad->rect));
583 }
584
585 surface->SetBufferTransform(Transform::ROTATE_180);
586 surface->Commit();
587
588 RunAllPendingInMessageLoop();
589
590 {
danakj5e0a12b2017-09-25 17:26:49591 const viz::CompositorFrame& frame =
592 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12593 ASSERT_EQ(1u, frame.render_pass_list.size());
594 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
595 ASSERT_EQ(1u, quad_list.size());
596 const viz::TextureDrawQuad* quad =
597 viz::TextureDrawQuad::MaterialCast(quad_list.front());
598 EXPECT_EQ(crop_180.origin(), quad->uv_top_left);
599 EXPECT_EQ(crop_180.bottom_right(), quad->uv_bottom_right);
600 EXPECT_EQ(
601 ToPixel(gfx::Rect(0, 0, 52, 4)),
602 cc::MathUtil::MapEnclosingClippedRect(
603 quad->shared_quad_state->quad_to_target_transform, quad->rect));
604 }
605
606 surface->SetBufferTransform(Transform::ROTATE_270);
607 surface->Commit();
608
609 RunAllPendingInMessageLoop();
610
611 {
danakj5e0a12b2017-09-25 17:26:49612 const viz::CompositorFrame& frame =
613 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12614 ASSERT_EQ(1u, frame.render_pass_list.size());
615 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
616 ASSERT_EQ(1u, quad_list.size());
617 const viz::TextureDrawQuad* quad =
618 viz::TextureDrawQuad::MaterialCast(quad_list.front());
619 EXPECT_EQ(crop_270.origin(), quad->uv_top_left);
620 EXPECT_EQ(crop_270.bottom_right(), quad->uv_bottom_right);
621 EXPECT_EQ(
622 target_with_no_viewport,
623 cc::MathUtil::MapEnclosingClippedRect(
624 quad->shared_quad_state->quad_to_target_transform, quad->rect));
625 }
626
627 surface->SetViewport(gfx::Size(128, 64));
628 surface->SetBufferTransform(Transform::NORMAL);
629 surface->Commit();
630
631 RunAllPendingInMessageLoop();
632
633 {
danakj5e0a12b2017-09-25 17:26:49634 const viz::CompositorFrame& frame =
635 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12636 ASSERT_EQ(1u, frame.render_pass_list.size());
637 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
638 ASSERT_EQ(1u, quad_list.size());
639 const viz::TextureDrawQuad* quad =
640 viz::TextureDrawQuad::MaterialCast(quad_list.front());
641 EXPECT_EQ(crop_0.origin(), quad->uv_top_left);
642 EXPECT_EQ(crop_0.bottom_right(), quad->uv_bottom_right);
643 EXPECT_EQ(
644 target_with_viewport,
645 cc::MathUtil::MapEnclosingClippedRect(
646 quad->shared_quad_state->quad_to_target_transform, quad->rect));
647 }
648
649 surface->SetBufferTransform(Transform::ROTATE_90);
650 surface->Commit();
651
652 RunAllPendingInMessageLoop();
653
654 {
danakj5e0a12b2017-09-25 17:26:49655 const viz::CompositorFrame& frame =
656 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12657 ASSERT_EQ(1u, frame.render_pass_list.size());
658 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
659 ASSERT_EQ(1u, quad_list.size());
660 const viz::TextureDrawQuad* quad =
661 viz::TextureDrawQuad::MaterialCast(quad_list.front());
662 EXPECT_EQ(crop_90.origin(), quad->uv_top_left);
663 EXPECT_EQ(crop_90.bottom_right(), quad->uv_bottom_right);
664 EXPECT_EQ(
665 target_with_viewport,
666 cc::MathUtil::MapEnclosingClippedRect(
667 quad->shared_quad_state->quad_to_target_transform, quad->rect));
668 }
669
670 surface->SetBufferTransform(Transform::ROTATE_180);
671 surface->Commit();
672
673 RunAllPendingInMessageLoop();
674
675 {
danakj5e0a12b2017-09-25 17:26:49676 const viz::CompositorFrame& frame =
677 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12678 ASSERT_EQ(1u, frame.render_pass_list.size());
679 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
680 ASSERT_EQ(1u, quad_list.size());
681 const viz::TextureDrawQuad* quad =
682 viz::TextureDrawQuad::MaterialCast(quad_list.front());
683 EXPECT_EQ(crop_180.origin(), quad->uv_top_left);
684 EXPECT_EQ(crop_180.bottom_right(), quad->uv_bottom_right);
685 EXPECT_EQ(
686 target_with_viewport,
687 cc::MathUtil::MapEnclosingClippedRect(
688 quad->shared_quad_state->quad_to_target_transform, quad->rect));
689 }
690
691 surface->SetBufferTransform(Transform::ROTATE_270);
692 surface->Commit();
693
694 RunAllPendingInMessageLoop();
695
696 {
danakj5e0a12b2017-09-25 17:26:49697 const viz::CompositorFrame& frame =
698 GetFrameFromSurface(shell_surface.get());
Lloyd Pique0a3045f2017-09-15 23:34:12699 ASSERT_EQ(1u, frame.render_pass_list.size());
700 const viz::QuadList& quad_list = frame.render_pass_list[0]->quad_list;
701 ASSERT_EQ(1u, quad_list.size());
702 const viz::TextureDrawQuad* quad =
703 viz::TextureDrawQuad::MaterialCast(quad_list.front());
704 EXPECT_EQ(crop_270.origin(), quad->uv_top_left);
705 EXPECT_EQ(crop_270.bottom_right(), quad->uv_bottom_right);
706 EXPECT_EQ(
707 target_with_viewport,
708 cc::MathUtil::MapEnclosingClippedRect(
709 quad->shared_quad_state->quad_to_target_transform, quad->rect));
710 }
711}
712
Peng Huang76f5fd02017-09-01 00:59:39713TEST_P(SurfaceTest, SetBlendMode) {
revemanfca687e2016-05-10 21:44:48714 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57715 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28716 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
David Revemand0ab1fb82017-09-18 22:27:57717 auto surface = std::make_unique<Surface>();
718 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
revemanfca687e2016-05-10 21:44:48719
720 surface->Attach(buffer.get());
reedcc9c70f2016-11-22 04:26:01721 surface->SetBlendMode(SkBlendMode::kSrc);
revemanfca687e2016-05-10 21:44:48722 surface->Commit();
starazd8f4f642016-12-10 23:49:20723 RunAllPendingInMessageLoop();
revemanfca687e2016-05-10 21:44:48724
danakj5e0a12b2017-09-25 17:26:49725 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
samansce5c3c32016-11-18 13:47:34726 ASSERT_EQ(1u, frame.render_pass_list.size());
727 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
728 EXPECT_FALSE(frame.render_pass_list.back()
jbauman45c06862016-06-23 19:35:02729 ->quad_list.back()
730 ->ShouldDrawWithBlending());
revemanfca687e2016-05-10 21:44:48731}
732
Peng Huang76f5fd02017-09-01 00:59:39733TEST_P(SurfaceTest, OverlayCandidate) {
dcastagna3ee399982016-07-18 23:36:31734 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57735 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28736 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
737 true, true);
David Revemand0ab1fb82017-09-18 22:27:57738 auto surface = std::make_unique<Surface>();
739 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
dcastagna3ee399982016-07-18 23:36:31740
741 surface->Attach(buffer.get());
742 surface->Commit();
starazd8f4f642016-12-10 23:49:20743 RunAllPendingInMessageLoop();
dcastagna3ee399982016-07-18 23:36:31744
danakj5e0a12b2017-09-25 17:26:49745 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
samansce5c3c32016-11-18 13:47:34746 ASSERT_EQ(1u, frame.render_pass_list.size());
747 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
danakj1a010682017-09-07 20:08:19748 viz::DrawQuad* draw_quad = frame.render_pass_list.back()->quad_list.back();
749 ASSERT_EQ(viz::DrawQuad::TEXTURE_CONTENT, draw_quad->material);
dcastagna3ee399982016-07-18 23:36:31750
danakje5805be2017-09-15 19:24:55751 const viz::TextureDrawQuad* texture_quad =
752 viz::TextureDrawQuad::MaterialCast(draw_quad);
dcastagna3ee399982016-07-18 23:36:31753 EXPECT_FALSE(texture_quad->resource_size_in_pixels().IsEmpty());
754}
755
Peng Huang76f5fd02017-09-01 00:59:39756TEST_P(SurfaceTest, SetAlpha) {
revemanfca687e2016-05-10 21:44:48757 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57758 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28759 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
760 true, true);
David Revemand0ab1fb82017-09-18 22:27:57761 auto surface = std::make_unique<Surface>();
762 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
revemanfca687e2016-05-10 21:44:48763
Peng Huanga72f3a92017-10-05 00:32:27764 {
765 surface->Attach(buffer.get());
766 surface->SetAlpha(0.5f);
767 surface->Commit();
768 RunAllPendingInMessageLoop();
Lloyd Piqued1e23fd2017-08-15 23:10:51769
Peng Huanga72f3a92017-10-05 00:32:27770 const viz::CompositorFrame& frame =
771 GetFrameFromSurface(shell_surface.get());
772 ASSERT_EQ(1u, frame.render_pass_list.size());
773 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
774 ASSERT_EQ(1u, frame.resource_list.size());
775 ASSERT_EQ(1u, frame.resource_list.back().id);
776 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
777 frame.render_pass_list.back()->damage_rect);
778 }
779
780 {
781 surface->SetAlpha(0.f);
782 surface->Commit();
783 const viz::CompositorFrame& frame =
784 GetFrameFromSurface(shell_surface.get());
785 ASSERT_EQ(1u, frame.render_pass_list.size());
786 // No quad if alpha is 0.
787 ASSERT_EQ(0u, frame.render_pass_list.back()->quad_list.size());
788 ASSERT_EQ(0u, frame.resource_list.size());
789 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
790 frame.render_pass_list.back()->damage_rect);
791 }
792
793 {
794 surface->SetAlpha(1.f);
795 surface->Commit();
796 const viz::CompositorFrame& frame =
797 GetFrameFromSurface(shell_surface.get());
798 ASSERT_EQ(1u, frame.render_pass_list.size());
799 ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
800 ASSERT_EQ(1u, frame.resource_list.size());
801 // The resource should be updated again, the id should be changed.
802 ASSERT_EQ(2u, frame.resource_list.back().id);
803 EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
804 frame.render_pass_list.back()->damage_rect);
805 }
revemanfca687e2016-05-10 21:44:48806}
807
Peng Huang76f5fd02017-09-01 00:59:39808TEST_P(SurfaceTest, Commit) {
dcheng31759da2016-04-21 01:26:31809 std::unique_ptr<Surface> surface(new Surface);
revemanb195f41d2015-11-19 22:16:48810
811 // Calling commit without a buffer should succeed.
812 surface->Commit();
813}
814
Peng Huang76f5fd02017-09-01 00:59:39815TEST_P(SurfaceTest, SendsBeginFrameAcks) {
Fady Samuele65ab0a12017-07-28 17:47:25816 viz::FakeExternalBeginFrameSource source(0.f, false);
eseckler599d86bb2017-03-15 09:02:55817 gfx::Size buffer_size(1, 1);
David Revemand0ab1fb82017-09-18 22:27:57818 auto buffer = std::make_unique<Buffer>(
Peng Huang583c9dc62017-07-27 23:38:28819 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0,
820 true, true);
David Revemand0ab1fb82017-09-18 22:27:57821 auto surface = std::make_unique<Surface>();
822 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
Peng Huang583c9dc62017-07-27 23:38:28823 shell_surface->SetBeginFrameSource(&source);
eseckler599d86bb2017-03-15 09:02:55824 surface->Attach(buffer.get());
825
826 // Request a frame callback so that Surface now needs BeginFrames.
827 base::TimeTicks frame_time;
828 surface->RequestFrameCallback(
829 base::Bind(&SetFrameTime, base::Unretained(&frame_time)));
830 surface->Commit(); // Move callback from pending callbacks to current ones.
831 RunAllPendingInMessageLoop();
832
staraz09b06ca2017-04-06 23:27:21833 // Surface should add itself as observer during
834 // DidReceiveCompositorFrameAck().
Peng Huang583c9dc62017-07-27 23:38:28835 shell_surface->DidReceiveCompositorFrameAck();
eseckler599d86bb2017-03-15 09:02:55836 EXPECT_EQ(1u, source.num_observers());
837
Fady Samuelc296f5fb2017-07-21 04:02:19838 viz::BeginFrameArgs args(source.CreateBeginFrameArgs(BEGINFRAME_FROM_HERE));
eseckler599d86bb2017-03-15 09:02:55839 args.frame_time = base::TimeTicks::FromInternalValue(100);
840 source.TestOnBeginFrame(args); // Runs the frame callback.
841 EXPECT_EQ(args.frame_time, frame_time);
842
esecklerca6d7cb72017-05-26 11:33:47843 surface->Commit(); // Acknowledges the BeginFrame via CompositorFrame.
eseckler599d86bb2017-03-15 09:02:55844 RunAllPendingInMessageLoop();
845
danakj5e0a12b2017-09-25 17:26:49846 const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
Fady Samuelc296f5fb2017-07-21 04:02:19847 viz::BeginFrameAck expected_ack(args.source_id, args.sequence_number, true);
eseckler599d86bb2017-03-15 09:02:55848 EXPECT_EQ(expected_ack, frame.metadata.begin_frame_ack);
esecklerca6d7cb72017-05-26 11:33:47849
850 // TODO(eseckler): Add test for DidNotProduceFrame plumbing.
eseckler599d86bb2017-03-15 09:02:55851}
852
Eliot Courtney28e7aa52017-09-27 02:16:21853TEST_P(SurfaceTest, RemoveSubSurface) {
854 gfx::Size buffer_size(256, 256);
855 std::unique_ptr<Buffer> buffer(
856 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
857 std::unique_ptr<Surface> surface(new Surface);
858 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
859 surface->Attach(buffer.get());
860
861 // Create a subsurface:
862 gfx::Size child_buffer_size(64, 128);
863 auto child_buffer = std::make_unique<Buffer>(
864 exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size));
865 auto child_surface = std::make_unique<Surface>();
866 auto sub_surface =
867 std::make_unique<SubSurface>(child_surface.get(), surface.get());
868 sub_surface->SetPosition(gfx::Point(20, 10));
869 child_surface->Attach(child_buffer.get());
870 child_surface->Commit();
871 surface->Commit();
872 RunAllPendingInMessageLoop();
873
Peng Huangf925ebf2017-10-31 15:37:50874 // Remove the subsurface by destroying it. This should not damage |surface|.
875 // TODO(penghuang): Make the damage more precise for sub surface changes.
876 // https://crbug.com/779704
Eliot Courtney28e7aa52017-09-27 02:16:21877 sub_surface.reset();
Peng Huangf925ebf2017-10-31 15:37:50878 EXPECT_FALSE(surface->HasPendingDamageForTesting(gfx::Rect(20, 10, 64, 128)));
Eliot Courtney28e7aa52017-09-27 02:16:21879}
880
David Revemane6e23342017-11-07 06:18:06881TEST_P(SurfaceTest, DestroyAttachedBuffer) {
882 gfx::Size buffer_size(1, 1);
883 auto buffer = std::make_unique<Buffer>(
884 exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
885 auto surface = std::make_unique<Surface>();
886 auto shell_surface = std::make_unique<ShellSurface>(surface.get());
887
888 surface->Attach(buffer.get());
889 surface->Commit();
890 RunAllPendingInMessageLoop();
891
892 // Make sure surface size is still valid after buffer is destroyed.
893 buffer.reset();
894 surface->Commit();
895 EXPECT_FALSE(surface->content_size().IsEmpty());
896}
897
revemanb195f41d2015-11-19 22:16:48898} // namespace
899} // namespace exo