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" | |
10 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
11 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
13 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
14 #include "cc/output/compositor_frame.h" | 13 #include "cc/output/compositor_frame.h" |
15 #include "cc/output/compositor_frame_metadata.h" | 14 #include "cc/output/compositor_frame_metadata.h" |
16 #include "cc/output/copy_output_request.h" | 15 #include "cc/output/copy_output_request.h" |
17 #include "cc/surfaces/surface.h" | 16 #include "cc/surfaces/surface.h" |
18 #include "cc/surfaces/surface_manager.h" | 17 #include "cc/surfaces/surface_manager.h" |
19 #include "content/browser/browser_thread_impl.h" | 18 #include "content/browser/browser_thread_impl.h" |
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 else | 2051 else |
2053 EXPECT_NE(surface_id, view_->surface_id()); | 2052 EXPECT_NE(surface_id, view_->surface_id()); |
2054 } | 2053 } |
2055 | 2054 |
2056 class RenderWidgetHostViewAuraCopyRequestTest | 2055 class RenderWidgetHostViewAuraCopyRequestTest |
2057 : public RenderWidgetHostViewAuraShutdownTest { | 2056 : public RenderWidgetHostViewAuraShutdownTest { |
2058 public: | 2057 public: |
2059 RenderWidgetHostViewAuraCopyRequestTest() | 2058 RenderWidgetHostViewAuraCopyRequestTest() |
2060 : callback_count_(0), result_(false) {} | 2059 : callback_count_(0), result_(false) {} |
2061 | 2060 |
2062 void CallbackMethod(bool result) { | 2061 void CallbackMethod(const base::Closure& quit_closure, bool result) { |
2063 result_ = result; | 2062 result_ = result; |
2064 callback_count_++; | 2063 callback_count_++; |
2065 quit_closure_.Run(); | 2064 quit_closure.Run(); |
2066 } | |
2067 | |
2068 void RunLoopUntilCallback() { | |
2069 base::RunLoop run_loop; | |
2070 quit_closure_ = run_loop.QuitClosure(); | |
2071 run_loop.Run(); | |
2072 } | 2065 } |
2073 | 2066 |
2074 int callback_count_; | 2067 int callback_count_; |
2075 bool result_; | 2068 bool result_; |
2076 | 2069 |
2077 private: | 2070 private: |
2078 base::Closure quit_closure_; | |
2079 | |
2080 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraCopyRequestTest); | 2071 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraCopyRequestTest); |
2081 }; | 2072 }; |
2082 | 2073 |
2083 // Tests that only one copy/readback request will be executed per one browser | 2074 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) { |
2084 // composite operation, even when multiple render frame swaps occur in between | 2075 base::RunLoop run_loop; |
2085 // browser composites, and even if the frame subscriber desires more frames than | 2076 |
2086 // the number of browser composites. | |
2087 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DedupeFrameSubscriberRequests) { | |
2088 gfx::Rect view_rect(100, 100); | 2077 gfx::Rect view_rect(100, 100); |
2089 scoped_ptr<cc::CopyOutputRequest> request; | 2078 scoped_ptr<cc::CopyOutputRequest> request; |
2090 | 2079 |
2091 view_->InitAsChild(NULL); | 2080 view_->InitAsChild(NULL); |
2092 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( | 2081 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( |
2093 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, | 2082 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, |
2094 base::Unretained(view_))); | 2083 base::Unretained(view_))); |
2095 aura::client::ParentWindowWithContext( | 2084 aura::client::ParentWindowWithContext( |
2096 view_->GetNativeView(), | 2085 view_->GetNativeView(), |
2097 parent_view_->GetNativeView()->GetRootWindow(), | 2086 parent_view_->GetNativeView()->GetRootWindow(), |
2098 gfx::Rect()); | 2087 gfx::Rect()); |
2099 view_->SetSize(view_rect.size()); | 2088 view_->SetSize(view_rect.size()); |
2100 view_->Show(); | 2089 view_->Show(); |
2101 | 2090 |
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 | |
2214 view_->InitAsChild(NULL); | |
2215 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( | |
2216 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, | |
2217 base::Unretained(view_))); | |
2218 aura::client::ParentWindowWithContext( | |
2219 view_->GetNativeView(), | |
2220 parent_view_->GetNativeView()->GetRootWindow(), | |
2221 gfx::Rect()); | |
2222 view_->SetSize(view_rect.size()); | |
2223 view_->Show(); | |
2224 | |
2225 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber( | 2091 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber( |
2226 view_rect.size(), | 2092 view_rect.size(), |
2227 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, | 2093 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, |
2228 base::Unretained(this)))); | 2094 base::Unretained(this), |
| 2095 run_loop.QuitClosure()))); |
2229 | 2096 |
2230 EXPECT_EQ(0, callback_count_); | 2097 EXPECT_EQ(0, callback_count_); |
2231 EXPECT_FALSE(view_->last_copy_request_); | 2098 EXPECT_FALSE(view_->last_copy_request_); |
2232 | 2099 |
2233 view_->BeginFrameSubscription(frame_subscriber.Pass()); | 2100 view_->BeginFrameSubscription(frame_subscriber.Pass()); |
2234 view_->OnSwapCompositorFrame( | 2101 view_->OnSwapCompositorFrame( |
2235 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); | 2102 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
2236 | 2103 |
2237 EXPECT_EQ(0, callback_count_); | 2104 EXPECT_EQ(0, callback_count_); |
2238 EXPECT_TRUE(view_->last_copy_request_); | 2105 EXPECT_TRUE(view_->last_copy_request_); |
2239 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox()); | 2106 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox()); |
2240 request = view_->last_copy_request_.Pass(); | 2107 request = view_->last_copy_request_.Pass(); |
2241 | 2108 |
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()); | |
2246 // Send back the mailbox included in the request. There's no release callback | 2109 // Send back the mailbox included in the request. There's no release callback |
2247 // since the mailbox came from the RWHVA originally. | 2110 // since the mailbox came from the RWHVA originally. |
2248 request->SendTextureResult(view_rect.size(), | 2111 request->SendTextureResult(view_rect.size(), |
2249 request->texture_mailbox(), | 2112 request->texture_mailbox(), |
2250 scoped_ptr<cc::SingleReleaseCallback>()); | 2113 scoped_ptr<cc::SingleReleaseCallback>()); |
2251 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr); | 2114 |
2252 RunLoopUntilCallback(); | 2115 // This runs until the callback happens. |
| 2116 run_loop.Run(); |
2253 | 2117 |
2254 // The callback should succeed. | 2118 // The callback should succeed. |
2255 EXPECT_EQ(1, callback_count_); | 2119 EXPECT_EQ(1, callback_count_); |
2256 EXPECT_TRUE(result_); | 2120 EXPECT_TRUE(result_); |
2257 | 2121 |
2258 view_->OnSwapCompositorFrame( | 2122 view_->OnSwapCompositorFrame( |
2259 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); | 2123 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); |
2260 | 2124 |
2261 EXPECT_EQ(1, callback_count_); | 2125 EXPECT_EQ(1, callback_count_); |
2262 request = view_->last_copy_request_.Pass(); | 2126 request = view_->last_copy_request_.Pass(); |
2263 | 2127 |
2264 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. | 2128 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. |
2265 TearDownEnvironment(); | 2129 TearDownEnvironment(); |
2266 | 2130 |
2267 // The DelegatedFrameHost should have run all remaining callbacks from its | 2131 // Send back the mailbox included in the request. There's no release callback |
2268 // destructor. | 2132 // since the mailbox came from the RWHVA originally. |
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. | |
2274 request->SendTextureResult(view_rect.size(), | 2133 request->SendTextureResult(view_rect.size(), |
2275 request->texture_mailbox(), | 2134 request->texture_mailbox(), |
2276 scoped_ptr<cc::SingleReleaseCallback>()); | 2135 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. |
2277 EXPECT_EQ(2, callback_count_); | 2141 EXPECT_EQ(2, callback_count_); |
2278 EXPECT_FALSE(result_); | 2142 EXPECT_FALSE(result_); |
2279 } | 2143 } |
2280 | 2144 |
2281 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) { | 2145 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) { |
2282 gfx::Rect view_rect(100, 100); | 2146 gfx::Rect view_rect(100, 100); |
2283 | 2147 |
2284 view_->InitAsChild(NULL); | 2148 view_->InitAsChild(NULL); |
2285 aura::client::ParentWindowWithContext( | 2149 aura::client::ParentWindowWithContext( |
2286 view_->GetNativeView(), | 2150 view_->GetNativeView(), |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3352 ui::TouchEvent press2( | 3216 ui::TouchEvent press2( |
3353 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow()); | 3217 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow()); |
3354 view_->OnTouchEvent(&press2); | 3218 view_->OnTouchEvent(&press2); |
3355 SendInputEventACK(blink::WebInputEvent::TouchStart, | 3219 SendInputEventACK(blink::WebInputEvent::TouchStart, |
3356 INPUT_EVENT_ACK_STATE_CONSUMED); | 3220 INPUT_EVENT_ACK_STATE_CONSUMED); |
3357 | 3221 |
3358 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count()); | 3222 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count()); |
3359 } | 3223 } |
3360 | 3224 |
3361 } // namespace content | 3225 } // namespace content |
OLD | NEW |