| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <map> | 5 #include <map> |
| 6 #include <queue> | 6 #include <queue> |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "android_webview/browser/browser_view_renderer.h" | 9 #include "android_webview/browser/browser_view_renderer.h" |
| 10 #include "android_webview/browser/child_frame.h" | 10 #include "android_webview/browser/child_frame.h" |
| 11 #include "android_webview/browser/compositor_frame_consumer.h" | 11 #include "android_webview/browser/compositor_frame_consumer.h" |
| 12 #include "android_webview/browser/render_thread_manager.h" |
| 12 #include "android_webview/browser/test/rendering_test.h" | 13 #include "android_webview/browser/test/rendering_test.h" |
| 13 #include "base/location.h" | 14 #include "base/location.h" |
| 14 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 15 #include "cc/output/compositor_frame.h" | 16 #include "cc/output/compositor_frame.h" |
| 16 #include "content/public/test/test_synchronous_compositor_android.h" | 17 #include "content/public/test/test_synchronous_compositor_android.h" |
| 17 | 18 |
| 18 namespace android_webview { | 19 namespace android_webview { |
| 19 | 20 |
| 20 class SmokeTest : public RenderingTest { | 21 class SmokeTest : public RenderingTest { |
| 21 void StartTest() override { browser_view_renderer_->PostInvalidate(); } | 22 void StartTest() override { browser_view_renderer_->PostInvalidate(); } |
| 22 | 23 |
| 23 void DidDrawOnRT(RenderThreadManager* functor) override { | 24 void DidDrawOnRT() override { EndTest(); } |
| 24 EndTest(); | |
| 25 } | |
| 26 }; | 25 }; |
| 27 | 26 |
| 28 RENDERING_TEST_F(SmokeTest); | 27 RENDERING_TEST_F(SmokeTest); |
| 29 | 28 |
| 30 class ClearViewTest : public RenderingTest { | 29 class ClearViewTest : public RenderingTest { |
| 31 public: | 30 public: |
| 32 ClearViewTest() : on_draw_count_(0) {} | 31 ClearViewTest() : on_draw_count_(0) {} |
| 33 | 32 |
| 34 void StartTest() override { | 33 void StartTest() override { |
| 35 browser_view_renderer_->PostInvalidate(); | 34 browser_view_renderer_->PostInvalidate(); |
| 36 browser_view_renderer_->ClearView(); | 35 browser_view_renderer_->ClearView(); |
| 37 } | 36 } |
| 38 | 37 |
| 39 void DidOnDraw(bool success) override { | 38 void DidOnDraw(bool success) override { |
| 40 on_draw_count_++; | 39 on_draw_count_++; |
| 41 if (on_draw_count_ == 1) { | 40 if (on_draw_count_ == 1) { |
| 42 // First OnDraw should be skipped due to ClearView. | 41 // First OnDraw should be skipped due to ClearView. |
| 43 EXPECT_FALSE(success); | 42 EXPECT_FALSE(success); |
| 44 browser_view_renderer_->DidUpdateContent(); // Unset ClearView. | 43 browser_view_renderer_->DidUpdateContent(); // Unset ClearView. |
| 45 browser_view_renderer_->PostInvalidate(); | 44 browser_view_renderer_->PostInvalidate(); |
| 46 } else { | 45 } else { |
| 47 // Following OnDraws should succeed. | 46 // Following OnDraws should succeed. |
| 48 EXPECT_TRUE(success); | 47 EXPECT_TRUE(success); |
| 49 } | 48 } |
| 50 } | 49 } |
| 51 | 50 |
| 52 void DidDrawOnRT(RenderThreadManager* functor) override { | 51 void DidDrawOnRT() override { EndTest(); } |
| 53 EndTest(); | 52 |
| 54 } | |
| 55 private: | 53 private: |
| 56 int on_draw_count_; | 54 int on_draw_count_; |
| 57 }; | 55 }; |
| 58 | 56 |
| 59 RENDERING_TEST_F(ClearViewTest); | 57 RENDERING_TEST_F(ClearViewTest); |
| 60 | 58 |
| 61 class TestAnimateInAndOutOfScreen : public RenderingTest { | 59 class TestAnimateInAndOutOfScreen : public RenderingTest { |
| 62 public: | 60 public: |
| 63 TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {} | 61 TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {} |
| 64 | 62 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 80 // draw constraints of BVR is updated to initial constraints. | 78 // draw constraints of BVR is updated to initial constraints. |
| 81 if (on_draw_count_ == 1 || on_draw_count_ == 2) | 79 if (on_draw_count_ == 1 || on_draw_count_ == 2) |
| 82 browser_view_renderer_->PrepareToDraw(gfx::Vector2d(), gfx::Rect()); | 80 browser_view_renderer_->PrepareToDraw(gfx::Vector2d(), gfx::Rect()); |
| 83 } | 81 } |
| 84 | 82 |
| 85 void DidOnDraw(bool success) override { | 83 void DidOnDraw(bool success) override { |
| 86 EXPECT_TRUE(success); | 84 EXPECT_TRUE(success); |
| 87 on_draw_count_++; | 85 on_draw_count_++; |
| 88 } | 86 } |
| 89 | 87 |
| 90 bool WillDrawOnRT(RenderThreadManager* functor, | 88 bool WillDrawOnRT(AwDrawGLInfo* draw_info) override { |
| 91 AwDrawGLInfo* draw_info) override { | |
| 92 if (draw_gl_count_on_rt_ == 1) { | 89 if (draw_gl_count_on_rt_ == 1) { |
| 93 draw_gl_count_on_rt_++; | 90 draw_gl_count_on_rt_++; |
| 94 ui_task_runner_->PostTask( | 91 ui_task_runner_->PostTask( |
| 95 FROM_HERE, | 92 FROM_HERE, |
| 96 base::Bind(&RenderingTest::PostInvalidate, base::Unretained(this))); | 93 base::Bind(&RenderingTest::PostInvalidate, base::Unretained(this))); |
| 97 return false; | 94 return false; |
| 98 } | 95 } |
| 99 | 96 |
| 100 draw_info->width = window_->surface_size().width(); | 97 draw_info->width = window_->surface_size().width(); |
| 101 draw_info->height = window_->surface_size().height(); | 98 draw_info->height = window_->surface_size().height(); |
| 102 draw_info->is_layer = false; | 99 draw_info->is_layer = false; |
| 103 | 100 |
| 104 gfx::Transform transform; | 101 gfx::Transform transform; |
| 105 if (draw_gl_count_on_rt_ == 0) | 102 if (draw_gl_count_on_rt_ == 0) |
| 106 transform = new_constraints_.transform; | 103 transform = new_constraints_.transform; |
| 107 | 104 |
| 108 transform.matrix().asColMajorf(draw_info->transform); | 105 transform.matrix().asColMajorf(draw_info->transform); |
| 109 return true; | 106 return true; |
| 110 } | 107 } |
| 111 | 108 |
| 112 void DidDrawOnRT(RenderThreadManager* functor) override { | 109 void DidDrawOnRT() override { draw_gl_count_on_rt_++; } |
| 113 draw_gl_count_on_rt_++; | |
| 114 } | |
| 115 | 110 |
| 116 bool DrawConstraintsEquals( | 111 bool DrawConstraintsEquals( |
| 117 const ParentCompositorDrawConstraints& constraints1, | 112 const ParentCompositorDrawConstraints& constraints1, |
| 118 const ParentCompositorDrawConstraints& constraints2) { | 113 const ParentCompositorDrawConstraints& constraints2) { |
| 119 if (constraints1.is_layer != constraints2.is_layer || | 114 if (constraints1.is_layer != constraints2.is_layer || |
| 120 constraints1.transform != constraints2.transform) | 115 constraints1.transform != constraints2.transform) |
| 121 return false; | 116 return false; |
| 122 | 117 |
| 123 return !constraints1.is_layer || | 118 return !constraints1.is_layer || |
| 124 constraints1.surface_rect_empty == constraints2.surface_rect_empty; | 119 constraints1.surface_rect_empty == constraints2.surface_rect_empty; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 } | 182 } |
| 188 on_draw_count_++; | 183 on_draw_count_++; |
| 189 } | 184 } |
| 190 | 185 |
| 191 private: | 186 private: |
| 192 int on_draw_count_; | 187 int on_draw_count_; |
| 193 }; | 188 }; |
| 194 | 189 |
| 195 RENDERING_TEST_F(CompositorNoFrameTest); | 190 RENDERING_TEST_F(CompositorNoFrameTest); |
| 196 | 191 |
| 197 class SwitchOutputSurfaceIdTest : public RenderingTest { | 192 class ResourceRenderingTest : public RenderingTest { |
| 198 public: | 193 public: |
| 194 using ResourceCountMap = std::map<cc::ResourceId, int>; |
| 195 using OutputSurfaceResourceCountMap = std::map<uint32_t, ResourceCountMap>; |
| 196 |
| 197 virtual std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame( |
| 198 int frame_number) = 0; |
| 199 |
| 200 void StartTest() override { |
| 201 frame_number_ = 0; |
| 202 AdvanceFrame(); |
| 203 } |
| 204 |
| 205 void WillOnDraw() override { |
| 206 if (next_frame_) { |
| 207 compositor_->SetHardwareFrame(next_frame_->output_surface_id, |
| 208 std::move(next_frame_->frame)); |
| 209 } |
| 210 } |
| 211 |
| 212 void DidOnDraw(bool success) override { |
| 213 EXPECT_EQ(next_frame_ != nullptr, success); |
| 214 if (!AdvanceFrame()) { |
| 215 ui_task_runner_->PostTask(FROM_HERE, |
| 216 base::Bind(&ResourceRenderingTest::CheckResults, |
| 217 base::Unretained(this))); |
| 218 } |
| 219 } |
| 220 |
| 221 OutputSurfaceResourceCountMap GetReturnedResourceCounts() { |
| 222 OutputSurfaceResourceCountMap counts; |
| 223 content::TestSynchronousCompositor::FrameAckArray returned_resources_array; |
| 224 compositor_->SwapReturnedResources(&returned_resources_array); |
| 225 for (const auto& resources : returned_resources_array) { |
| 226 for (const auto& returned_resource : resources.resources) { |
| 227 counts[resources.output_surface_id][returned_resource.id] += |
| 228 returned_resource.count; |
| 229 } |
| 230 } |
| 231 return counts; |
| 232 } |
| 233 |
| 234 virtual void CheckResults() = 0; |
| 235 |
| 236 private: |
| 237 bool AdvanceFrame() { |
| 238 next_frame_ = GetFrame(frame_number_++); |
| 239 if (next_frame_) { |
| 240 browser_view_renderer_->PostInvalidate(); |
| 241 return true; |
| 242 } |
| 243 return false; |
| 244 } |
| 245 |
| 246 std::unique_ptr<content::SynchronousCompositor::Frame> next_frame_; |
| 247 int frame_number_; |
| 248 }; |
| 249 |
| 250 class SwitchOutputSurfaceIdTest : public ResourceRenderingTest { |
| 199 struct FrameInfo { | 251 struct FrameInfo { |
| 200 uint32_t output_surface_id; | 252 uint32_t output_surface_id; |
| 201 cc::ResourceId resource_id; // Each frame contains a single resource. | 253 cc::ResourceId resource_id; // Each frame contains a single resource. |
| 202 }; | 254 }; |
| 203 | 255 |
| 204 void StartTest() override { | 256 std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame( |
| 205 last_output_surface_id_ = 0; | 257 int frame_number) override { |
| 206 FrameInfo infos[] = { | 258 static const FrameInfo infos[] = { |
| 207 // First output surface. | 259 // First output surface. |
| 208 {0u, 1u}, {0u, 1u}, {0u, 2u}, {0u, 2u}, {0u, 3u}, {0u, 3u}, {0u, 4u}, | 260 {0u, 1u}, |
| 261 {0u, 1u}, |
| 262 {0u, 2u}, |
| 263 {0u, 2u}, |
| 264 {0u, 3u}, |
| 265 {0u, 3u}, |
| 266 {0u, 4u}, |
| 209 // Second output surface. | 267 // Second output surface. |
| 210 {1u, 1u}, {1u, 1u}, {1u, 2u}, {1u, 2u}, {1u, 3u}, {1u, 3u}, {1u, 4u}, | 268 {1u, 1u}, |
| 269 {1u, 1u}, |
| 270 {1u, 2u}, |
| 271 {1u, 2u}, |
| 272 {1u, 3u}, |
| 273 {1u, 3u}, |
| 274 {1u, 4u}, |
| 211 }; | 275 }; |
| 212 for (const auto& info : infos) { | 276 if (frame_number >= static_cast<int>(arraysize(infos))) { |
| 213 content::SynchronousCompositor::Frame frame; | 277 return nullptr; |
| 214 frame.output_surface_id = info.output_surface_id; | |
| 215 frame.frame = ConstructEmptyFrame(); | |
| 216 cc::TransferableResource resource; | |
| 217 resource.id = info.resource_id; | |
| 218 frame.frame->delegated_frame_data->resource_list.push_back(resource); | |
| 219 frames_.push(std::move(frame)); | |
| 220 | |
| 221 // Keep a id -> count map for the last ouptut_surface_id. | |
| 222 if (last_output_surface_id_ != info.output_surface_id) { | |
| 223 expected_return_count_.clear(); | |
| 224 last_output_surface_id_ = info.output_surface_id; | |
| 225 } | |
| 226 if (expected_return_count_.count(info.resource_id)) { | |
| 227 expected_return_count_[info.resource_id]++; | |
| 228 } else { | |
| 229 expected_return_count_[info.resource_id] = 1; | |
| 230 } | |
| 231 } | 278 } |
| 232 | 279 |
| 233 browser_view_renderer_->PostInvalidate(); | 280 std::unique_ptr<content::SynchronousCompositor::Frame> frame( |
| 281 new content::SynchronousCompositor::Frame); |
| 282 frame->output_surface_id = infos[frame_number].output_surface_id; |
| 283 frame->frame = ConstructFrame(infos[frame_number].resource_id); |
| 284 |
| 285 if (last_output_surface_id_ != infos[frame_number].output_surface_id) { |
| 286 expected_return_count_.clear(); |
| 287 last_output_surface_id_ = infos[frame_number].output_surface_id; |
| 288 } |
| 289 ++expected_return_count_[infos[frame_number].resource_id]; |
| 290 return frame; |
| 234 } | 291 } |
| 235 | 292 |
| 236 void WillOnDraw() override { | 293 void StartTest() override { |
| 237 if (!frames_.empty()) { | 294 last_output_surface_id_ = -1U; |
| 238 compositor_->SetHardwareFrame(frames_.front().output_surface_id, | 295 ResourceRenderingTest::StartTest(); |
| 239 std::move(frames_.front().frame)); | |
| 240 } | |
| 241 } | 296 } |
| 242 | 297 |
| 243 void DidOnDraw(bool success) override { | 298 void CheckResults() override { |
| 244 EXPECT_TRUE(success); | 299 GetCompositorFrameConsumer()->DeleteHardwareRendererOnUI(); |
| 245 if (frames_.empty()) { | |
| 246 ui_task_runner_->PostTask( | |
| 247 FROM_HERE, base::Bind(&SwitchOutputSurfaceIdTest::CheckResults, | |
| 248 base::Unretained(this))); | |
| 249 } else { | |
| 250 frames_.pop(); | |
| 251 browser_view_renderer_->PostInvalidate(); | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 void CheckResults() { | |
| 256 window_->Detach(); | 300 window_->Detach(); |
| 257 window_.reset(); | 301 window_.reset(); |
| 258 | 302 |
| 259 // Make sure resources for the last output surface are returned. | 303 // Make sure resources for the last output surface are returned. |
| 260 content::TestSynchronousCompositor::FrameAckArray returned_resources_array; | 304 EXPECT_EQ(expected_return_count_, |
| 261 compositor_->SwapReturnedResources(&returned_resources_array); | 305 GetReturnedResourceCounts()[last_output_surface_id_]); |
| 262 for (const auto& resources : returned_resources_array) { | |
| 263 if (resources.output_surface_id != last_output_surface_id_) | |
| 264 continue; | |
| 265 for (const auto& returned_resource : resources.resources) { | |
| 266 EXPECT_TRUE(!!expected_return_count_.count(returned_resource.id)); | |
| 267 EXPECT_GE(expected_return_count_[returned_resource.id], | |
| 268 returned_resource.count); | |
| 269 expected_return_count_[returned_resource.id] -= | |
| 270 returned_resource.count; | |
| 271 if (!expected_return_count_[returned_resource.id]) | |
| 272 expected_return_count_.erase(returned_resource.id); | |
| 273 } | |
| 274 } | |
| 275 EXPECT_TRUE(expected_return_count_.empty()); | |
| 276 | |
| 277 EndTest(); | 306 EndTest(); |
| 278 } | 307 } |
| 279 | 308 |
| 280 private: | 309 private: |
| 281 std::queue<content::SynchronousCompositor::Frame> frames_; | |
| 282 uint32_t last_output_surface_id_; | 310 uint32_t last_output_surface_id_; |
| 283 std::map<cc::ResourceId, int> expected_return_count_; | 311 ResourceCountMap expected_return_count_; |
| 284 }; | 312 }; |
| 285 | 313 |
| 286 RENDERING_TEST_F(SwitchOutputSurfaceIdTest); | 314 RENDERING_TEST_F(SwitchOutputSurfaceIdTest); |
| 287 | 315 |
| 316 class RenderThreadManagerDeletionTest : public ResourceRenderingTest { |
| 317 std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame( |
| 318 int frame_number) override { |
| 319 if (frame_number > 0) { |
| 320 return nullptr; |
| 321 } |
| 322 |
| 323 const uint32_t output_surface_id = 0u; |
| 324 const cc::ResourceId resource_id = |
| 325 static_cast<cc::ResourceId>(frame_number); |
| 326 |
| 327 std::unique_ptr<content::SynchronousCompositor::Frame> frame( |
| 328 new content::SynchronousCompositor::Frame); |
| 329 frame->output_surface_id = output_surface_id; |
| 330 frame->frame = ConstructFrame(resource_id); |
| 331 ++expected_return_count_[output_surface_id][resource_id]; |
| 332 return frame; |
| 333 } |
| 334 |
| 335 void CheckResults() override { |
| 336 OutputSurfaceResourceCountMap resource_counts; |
| 337 render_thread_manager_.reset(); |
| 338 // Make sure resources for the last frame are returned. |
| 339 EXPECT_EQ(expected_return_count_, GetReturnedResourceCounts()); |
| 340 EndTest(); |
| 341 } |
| 342 |
| 343 private: |
| 344 OutputSurfaceResourceCountMap expected_return_count_; |
| 345 }; |
| 346 |
| 347 RENDERING_TEST_F(RenderThreadManagerDeletionTest); |
| 348 |
| 288 } // namespace android_webview | 349 } // namespace android_webview |
| OLD | NEW |