OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/render_widget_host_view_aura.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/scoped_vector.h" |
9 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "cc/output/compositor_frame.h" | 14 #include "cc/output/compositor_frame.h" |
14 #include "cc/output/compositor_frame_metadata.h" | 15 #include "cc/output/compositor_frame_metadata.h" |
15 #include "cc/output/copy_output_request.h" | 16 #include "cc/output/copy_output_request.h" |
16 #include "cc/surfaces/surface.h" | 17 #include "cc/surfaces/surface.h" |
17 #include "cc/surfaces/surface_manager.h" | 18 #include "cc/surfaces/surface_manager.h" |
18 #include "content/browser/browser_thread_impl.h" | 19 #include "content/browser/browser_thread_impl.h" |
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 else | 2052 else |
2052 EXPECT_NE(surface_id, view_->surface_id()); | 2053 EXPECT_NE(surface_id, view_->surface_id()); |
2053 } | 2054 } |
2054 | 2055 |
2055 class RenderWidgetHostViewAuraCopyRequestTest | 2056 class RenderWidgetHostViewAuraCopyRequestTest |
2056 : public RenderWidgetHostViewAuraShutdownTest { | 2057 : public RenderWidgetHostViewAuraShutdownTest { |
2057 public: | 2058 public: |
2058 RenderWidgetHostViewAuraCopyRequestTest() | 2059 RenderWidgetHostViewAuraCopyRequestTest() |
2059 : callback_count_(0), result_(false) {} | 2060 : callback_count_(0), result_(false) {} |
2060 | 2061 |
2061 void CallbackMethod(const base::Closure& quit_closure, bool result) { | 2062 void CallbackMethod(bool result) { |
2062 result_ = result; | 2063 result_ = result; |
2063 callback_count_++; | 2064 callback_count_++; |
2064 quit_closure.Run(); | 2065 quit_closure_.Run(); |
| 2066 } |
| 2067 |
| 2068 void RunLoopUntilCallback() { |
| 2069 base::RunLoop run_loop; |
| 2070 quit_closure_ = run_loop.QuitClosure(); |
| 2071 run_loop.Run(); |
2065 } | 2072 } |
2066 | 2073 |
2067 int callback_count_; | 2074 int callback_count_; |
2068 bool result_; | 2075 bool result_; |
2069 | 2076 |
2070 private: | 2077 private: |
| 2078 base::Closure quit_closure_; |
| 2079 |
2071 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraCopyRequestTest); | 2080 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraCopyRequestTest); |
2072 }; | 2081 }; |
2073 | 2082 |
2074 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) { | 2083 // Tests that only one copy/readback request will be executed per one browser |
2075 base::RunLoop run_loop; | 2084 // composite operation, even when multiple render frame swaps occur in between |
2076 | 2085 // browser composites, and even if the frame subscriber desires more frames than |
| 2086 // the number of browser composites. |
| 2087 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DedupeFrameSubscriberRequests) { |
2077 gfx::Rect view_rect(100, 100); | 2088 gfx::Rect view_rect(100, 100); |
2078 scoped_ptr<cc::CopyOutputRequest> request; | 2089 scoped_ptr<cc::CopyOutputRequest> request; |
2079 | 2090 |
| 2091 view_->InitAsChild(NULL); |
| 2092 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( |
| 2093 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, |
| 2094 base::Unretained(view_))); |
| 2095 aura::client::ParentWindowWithContext( |
| 2096 view_->GetNativeView(), |
| 2097 parent_view_->GetNativeView()->GetRootWindow(), |
| 2098 gfx::Rect()); |
| 2099 view_->SetSize(view_rect.size()); |
| 2100 view_->Show(); |
| 2101 |
| 2102 view_->BeginFrameSubscription(make_scoped_ptr(new FakeFrameSubscriber( |
| 2103 view_rect.size(), |
| 2104 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, |
| 2105 base::Unretained(this)))).Pass()); |
| 2106 int expected_callback_count = 0; |
| 2107 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2108 ASSERT_FALSE(view_->last_copy_request_); |
| 2109 |
| 2110 // Normal case: A browser composite executes for each render frame swap. |
| 2111 for (int i = 0; i < 3; ++i) { |
| 2112 // Renderer provides another frame. |
| 2113 view_->OnSwapCompositorFrame( |
| 2114 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
| 2115 ASSERT_TRUE(view_->last_copy_request_); |
| 2116 request = view_->last_copy_request_.Pass(); |
| 2117 |
| 2118 // Browser composites with the frame, executing the copy request, and then |
| 2119 // the result is delivered. |
| 2120 view_->GetDelegatedFrameHost()->OnCompositingStarted( |
| 2121 nullptr, base::TimeTicks::Now()); |
| 2122 request->SendTextureResult(view_rect.size(), |
| 2123 request->texture_mailbox(), |
| 2124 scoped_ptr<cc::SingleReleaseCallback>()); |
| 2125 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr); |
| 2126 RunLoopUntilCallback(); |
| 2127 |
| 2128 // The callback should be run with success status. |
| 2129 ++expected_callback_count; |
| 2130 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2131 EXPECT_TRUE(result_); |
| 2132 } |
| 2133 |
| 2134 // De-duping cases: One browser composite executes per varied number of render |
| 2135 // frame swaps. |
| 2136 for (int i = 0; i < 3; ++i) { |
| 2137 const int num_swaps = 1 + i % 3; |
| 2138 |
| 2139 // The renderer provides |num_swaps| frames. |
| 2140 cc::CopyOutputRequest* the_only_request = nullptr; |
| 2141 for (int j = 0; j < num_swaps; ++j) { |
| 2142 view_->OnSwapCompositorFrame( |
| 2143 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
| 2144 ASSERT_TRUE(view_->last_copy_request_); |
| 2145 if (the_only_request) |
| 2146 ASSERT_EQ(the_only_request, view_->last_copy_request_.get()); |
| 2147 else |
| 2148 the_only_request = view_->last_copy_request_.get(); |
| 2149 if (j > 0) { |
| 2150 ++expected_callback_count; |
| 2151 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2152 EXPECT_FALSE(result_); // The prior copy request was aborted. |
| 2153 } |
| 2154 if (j == (num_swaps - 1)) |
| 2155 request = view_->last_copy_request_.Pass(); |
| 2156 } |
| 2157 |
| 2158 // Browser composites with the frame, executing the de-duped copy request, |
| 2159 // and then the result is delivered. |
| 2160 view_->GetDelegatedFrameHost()->OnCompositingStarted( |
| 2161 nullptr, base::TimeTicks::Now()); |
| 2162 request->SendTextureResult(view_rect.size(), |
| 2163 request->texture_mailbox(), |
| 2164 scoped_ptr<cc::SingleReleaseCallback>()); |
| 2165 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr); |
| 2166 RunLoopUntilCallback(); |
| 2167 |
| 2168 // The final callback should be run with success status. |
| 2169 ++expected_callback_count; |
| 2170 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2171 EXPECT_TRUE(result_); |
| 2172 } |
| 2173 |
| 2174 // Multiple de-duped copy requests in-flight. |
| 2175 for (int i = 0; i < 3; ++i) { |
| 2176 const int num_in_flight = 1 + i % 3; |
| 2177 ScopedVector<cc::CopyOutputRequest> requests; |
| 2178 |
| 2179 for (int j = 0; j < num_in_flight; ++j) { |
| 2180 // Renderer provides another frame. |
| 2181 view_->OnSwapCompositorFrame( |
| 2182 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
| 2183 ASSERT_TRUE(view_->last_copy_request_); |
| 2184 requests.push_back(view_->last_copy_request_.Pass()); |
| 2185 |
| 2186 // Browser composites with the frame, but the response to the copy request |
| 2187 // is delayed. |
| 2188 view_->GetDelegatedFrameHost()->OnCompositingStarted( |
| 2189 nullptr, base::TimeTicks::Now()); |
| 2190 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr); |
| 2191 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2192 } |
| 2193 |
| 2194 // Deliver each response, and expect success. |
| 2195 for (cc::CopyOutputRequest* r : requests) { |
| 2196 r->SendTextureResult(view_rect.size(), |
| 2197 request->texture_mailbox(), |
| 2198 scoped_ptr<cc::SingleReleaseCallback>()); |
| 2199 RunLoopUntilCallback(); |
| 2200 ++expected_callback_count; |
| 2201 ASSERT_EQ(expected_callback_count, callback_count_); |
| 2202 EXPECT_TRUE(result_); |
| 2203 } |
| 2204 } |
| 2205 |
| 2206 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. |
| 2207 TearDownEnvironment(); |
| 2208 } |
| 2209 |
| 2210 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) { |
| 2211 gfx::Rect view_rect(100, 100); |
| 2212 scoped_ptr<cc::CopyOutputRequest> request; |
| 2213 |
2080 view_->InitAsChild(NULL); | 2214 view_->InitAsChild(NULL); |
2081 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( | 2215 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( |
2082 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, | 2216 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, |
2083 base::Unretained(view_))); | 2217 base::Unretained(view_))); |
2084 aura::client::ParentWindowWithContext( | 2218 aura::client::ParentWindowWithContext( |
2085 view_->GetNativeView(), | 2219 view_->GetNativeView(), |
2086 parent_view_->GetNativeView()->GetRootWindow(), | 2220 parent_view_->GetNativeView()->GetRootWindow(), |
2087 gfx::Rect()); | 2221 gfx::Rect()); |
2088 view_->SetSize(view_rect.size()); | 2222 view_->SetSize(view_rect.size()); |
2089 view_->Show(); | 2223 view_->Show(); |
2090 | 2224 |
2091 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber( | 2225 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber( |
2092 view_rect.size(), | 2226 view_rect.size(), |
2093 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, | 2227 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, |
2094 base::Unretained(this), | 2228 base::Unretained(this)))); |
2095 run_loop.QuitClosure()))); | |
2096 | 2229 |
2097 EXPECT_EQ(0, callback_count_); | 2230 EXPECT_EQ(0, callback_count_); |
2098 EXPECT_FALSE(view_->last_copy_request_); | 2231 EXPECT_FALSE(view_->last_copy_request_); |
2099 | 2232 |
2100 view_->BeginFrameSubscription(frame_subscriber.Pass()); | 2233 view_->BeginFrameSubscription(frame_subscriber.Pass()); |
2101 view_->OnSwapCompositorFrame( | 2234 view_->OnSwapCompositorFrame( |
2102 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); | 2235 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
2103 | 2236 |
2104 EXPECT_EQ(0, callback_count_); | 2237 EXPECT_EQ(0, callback_count_); |
2105 EXPECT_TRUE(view_->last_copy_request_); | 2238 EXPECT_TRUE(view_->last_copy_request_); |
2106 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox()); | 2239 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox()); |
2107 request = view_->last_copy_request_.Pass(); | 2240 request = view_->last_copy_request_.Pass(); |
2108 | 2241 |
| 2242 // Notify DelegatedFrameHost that the graphics commands were issued by calling |
| 2243 // OnCompositingStarted(). This clears the "frame subscriber de-duping" flag. |
| 2244 view_->GetDelegatedFrameHost()->OnCompositingStarted(nullptr, |
| 2245 base::TimeTicks::Now()); |
2109 // Send back the mailbox included in the request. There's no release callback | 2246 // Send back the mailbox included in the request. There's no release callback |
2110 // since the mailbox came from the RWHVA originally. | 2247 // since the mailbox came from the RWHVA originally. |
2111 request->SendTextureResult(view_rect.size(), | 2248 request->SendTextureResult(view_rect.size(), |
2112 request->texture_mailbox(), | 2249 request->texture_mailbox(), |
2113 scoped_ptr<cc::SingleReleaseCallback>()); | 2250 scoped_ptr<cc::SingleReleaseCallback>()); |
2114 | 2251 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr); |
2115 // This runs until the callback happens. | 2252 RunLoopUntilCallback(); |
2116 run_loop.Run(); | |
2117 | 2253 |
2118 // The callback should succeed. | 2254 // The callback should succeed. |
2119 EXPECT_EQ(1, callback_count_); | 2255 EXPECT_EQ(1, callback_count_); |
2120 EXPECT_TRUE(result_); | 2256 EXPECT_TRUE(result_); |
2121 | 2257 |
2122 view_->OnSwapCompositorFrame( | 2258 view_->OnSwapCompositorFrame( |
2123 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); | 2259 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
2124 | 2260 |
2125 EXPECT_EQ(1, callback_count_); | 2261 EXPECT_EQ(1, callback_count_); |
2126 request = view_->last_copy_request_.Pass(); | 2262 request = view_->last_copy_request_.Pass(); |
2127 | 2263 |
2128 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. | 2264 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. |
2129 TearDownEnvironment(); | 2265 TearDownEnvironment(); |
2130 | 2266 |
2131 // Send back the mailbox included in the request. There's no release callback | 2267 // The DelegatedFrameHost should have run all remaining callbacks from its |
2132 // since the mailbox came from the RWHVA originally. | 2268 // destructor. |
| 2269 EXPECT_EQ(2, callback_count_); |
| 2270 EXPECT_FALSE(result_); |
| 2271 |
| 2272 // Send the result after-the-fact. It goes nowhere since DelegatedFrameHost |
| 2273 // has been destroyed. |
2133 request->SendTextureResult(view_rect.size(), | 2274 request->SendTextureResult(view_rect.size(), |
2134 request->texture_mailbox(), | 2275 request->texture_mailbox(), |
2135 scoped_ptr<cc::SingleReleaseCallback>()); | 2276 scoped_ptr<cc::SingleReleaseCallback>()); |
2136 | |
2137 // Because the copy request callback may be holding state within it, that | |
2138 // state must handle the RWHVA and ImageTransportFactory going away before the | |
2139 // callback is called. This test passes if it does not crash as a result of | |
2140 // these things being destroyed. | |
2141 EXPECT_EQ(2, callback_count_); | 2277 EXPECT_EQ(2, callback_count_); |
2142 EXPECT_FALSE(result_); | 2278 EXPECT_FALSE(result_); |
2143 } | 2279 } |
2144 | 2280 |
2145 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) { | 2281 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) { |
2146 gfx::Rect view_rect(100, 100); | 2282 gfx::Rect view_rect(100, 100); |
2147 | 2283 |
2148 view_->InitAsChild(NULL); | 2284 view_->InitAsChild(NULL); |
2149 aura::client::ParentWindowWithContext( | 2285 aura::client::ParentWindowWithContext( |
2150 view_->GetNativeView(), | 2286 view_->GetNativeView(), |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3216 ui::TouchEvent press2( | 3352 ui::TouchEvent press2( |
3217 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow()); | 3353 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow()); |
3218 view_->OnTouchEvent(&press2); | 3354 view_->OnTouchEvent(&press2); |
3219 SendInputEventACK(blink::WebInputEvent::TouchStart, | 3355 SendInputEventACK(blink::WebInputEvent::TouchStart, |
3220 INPUT_EVENT_ACK_STATE_CONSUMED); | 3356 INPUT_EVENT_ACK_STATE_CONSUMED); |
3221 | 3357 |
3222 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count()); | 3358 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count()); |
3223 } | 3359 } |
3224 | 3360 |
3225 } // namespace content | 3361 } // namespace content |
OLD | NEW |