Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_aura_unittest.cc

Issue 986823002: De-dupe copy requests for tab capture in DelegatedFrameHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify by doing a little queuing in DelegatedFrameHost. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/linked_ptr.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
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 < 10; ++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 < 50; ++i) {
danakj 2015/03/10 17:17:17 isnt i < 3 enough? the rest are redundant?
miu 2015/03/10 20:54:07 Done.
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 < 10; ++i) {
2176 const int num_in_flight = 1 + i % 3;
2177 std::vector<linked_ptr<cc::CopyOutputRequest>> requests;
danakj 2015/03/10 17:17:17 Can you use ScopedVector instead of linked_ptr ple
miu 2015/03/10 20:54:07 Done.
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(make_linked_ptr(view_->last_copy_request_.release()));
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 (linked_ptr<cc::CopyOutputRequest>& r : requests) {
2196 r->SendTextureResult(view_rect.size(),
2197 request->texture_mailbox(),
2198 scoped_ptr<cc::SingleReleaseCallback>());
2199 r.reset();
2200 RunLoopUntilCallback();
2201 ++expected_callback_count;
2202 ASSERT_EQ(expected_callback_count, callback_count_);
2203 EXPECT_TRUE(result_);
2204 }
2205 }
2206
2207 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
2208 TearDownEnvironment();
2209 }
2210
2211 TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) {
2212 gfx::Rect view_rect(100, 100);
2213 scoped_ptr<cc::CopyOutputRequest> request;
2214
2080 view_->InitAsChild(NULL); 2215 view_->InitAsChild(NULL);
2081 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting( 2216 view_->GetDelegatedFrameHost()->SetRequestCopyOfOutputCallbackForTesting(
2082 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput, 2217 base::Bind(&FakeRenderWidgetHostViewAura::InterceptCopyOfOutput,
2083 base::Unretained(view_))); 2218 base::Unretained(view_)));
2084 aura::client::ParentWindowWithContext( 2219 aura::client::ParentWindowWithContext(
2085 view_->GetNativeView(), 2220 view_->GetNativeView(),
2086 parent_view_->GetNativeView()->GetRootWindow(), 2221 parent_view_->GetNativeView()->GetRootWindow(),
2087 gfx::Rect()); 2222 gfx::Rect());
2088 view_->SetSize(view_rect.size()); 2223 view_->SetSize(view_rect.size());
2089 view_->Show(); 2224 view_->Show();
2090 2225
2091 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber( 2226 scoped_ptr<FakeFrameSubscriber> frame_subscriber(new FakeFrameSubscriber(
2092 view_rect.size(), 2227 view_rect.size(),
2093 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod, 2228 base::Bind(&RenderWidgetHostViewAuraCopyRequestTest::CallbackMethod,
2094 base::Unretained(this), 2229 base::Unretained(this))));
2095 run_loop.QuitClosure())));
2096 2230
2097 EXPECT_EQ(0, callback_count_); 2231 EXPECT_EQ(0, callback_count_);
2098 EXPECT_FALSE(view_->last_copy_request_); 2232 EXPECT_FALSE(view_->last_copy_request_);
2099 2233
2100 view_->BeginFrameSubscription(frame_subscriber.Pass()); 2234 view_->BeginFrameSubscription(frame_subscriber.Pass());
2101 view_->OnSwapCompositorFrame( 2235 view_->OnSwapCompositorFrame(
2102 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); 2236 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2103 2237
2104 EXPECT_EQ(0, callback_count_); 2238 EXPECT_EQ(0, callback_count_);
2105 EXPECT_TRUE(view_->last_copy_request_); 2239 EXPECT_TRUE(view_->last_copy_request_);
2106 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox()); 2240 EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox());
2107 request = view_->last_copy_request_.Pass(); 2241 request = view_->last_copy_request_.Pass();
2108 2242
2243 // Notify DelegatedFrameHost that the graphics commands were issued by calling
2244 // OnCompositingStarted(). This clears the "frame subscriber de-duping" flag.
2245 view_->GetDelegatedFrameHost()->OnCompositingStarted(nullptr,
2246 base::TimeTicks::Now());
2109 // Send back the mailbox included in the request. There's no release callback 2247 // Send back the mailbox included in the request. There's no release callback
2110 // since the mailbox came from the RWHVA originally. 2248 // since the mailbox came from the RWHVA originally.
2111 request->SendTextureResult(view_rect.size(), 2249 request->SendTextureResult(view_rect.size(),
2112 request->texture_mailbox(), 2250 request->texture_mailbox(),
2113 scoped_ptr<cc::SingleReleaseCallback>()); 2251 scoped_ptr<cc::SingleReleaseCallback>());
2114 2252 view_->GetDelegatedFrameHost()->OnCompositingEnded(nullptr);
2115 // This runs until the callback happens. 2253 RunLoopUntilCallback();
2116 run_loop.Run();
2117 2254
2118 // The callback should succeed. 2255 // The callback should succeed.
2119 EXPECT_EQ(1, callback_count_); 2256 EXPECT_EQ(1, callback_count_);
2120 EXPECT_TRUE(result_); 2257 EXPECT_TRUE(result_);
2121 2258
2122 view_->OnSwapCompositorFrame( 2259 view_->OnSwapCompositorFrame(
2123 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect))); 2260 1, MakeDelegatedFrame(1.f, view_rect.size(), gfx::Rect(view_rect)));
2124 2261
2125 EXPECT_EQ(1, callback_count_); 2262 EXPECT_EQ(1, callback_count_);
2126 request = view_->last_copy_request_.Pass(); 2263 request = view_->last_copy_request_.Pass();
2127 2264
2128 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory. 2265 // Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
2129 TearDownEnvironment(); 2266 TearDownEnvironment();
2130 2267
2131 // Send back the mailbox included in the request. There's no release callback 2268 // The DelegatedFrameHost should have run all remaining callbacks from its
2132 // since the mailbox came from the RWHVA originally. 2269 // destructor.
2270 EXPECT_EQ(2, callback_count_);
danakj 2015/03/10 17:17:17 I think I prefer to keep these EXPECTs after the S
miu 2015/03/10 20:54:07 The reason I moved them is that the TearDownEnviro
danakj 2015/03/10 20:59:21 Cool thanks! SG
2271 EXPECT_FALSE(result_);
2272
2273 // Send the result after-the-fact. It goes nowhere since DelegatedFrameHost
2274 // has been destroyed.
2133 request->SendTextureResult(view_rect.size(), 2275 request->SendTextureResult(view_rect.size(),
2134 request->texture_mailbox(), 2276 request->texture_mailbox(),
2135 scoped_ptr<cc::SingleReleaseCallback>()); 2277 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_);
2142 EXPECT_FALSE(result_);
2143 } 2278 }
2144 2279
2145 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) { 2280 TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) {
2146 gfx::Rect view_rect(100, 100); 2281 gfx::Rect view_rect(100, 100);
2147 2282
2148 view_->InitAsChild(NULL); 2283 view_->InitAsChild(NULL);
2149 aura::client::ParentWindowWithContext( 2284 aura::client::ParentWindowWithContext(
2150 view_->GetNativeView(), 2285 view_->GetNativeView(),
2151 parent_view_->GetNativeView()->GetRootWindow(), 2286 parent_view_->GetNativeView()->GetRootWindow(),
2152 gfx::Rect()); 2287 gfx::Rect());
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 ui::TouchEvent press2( 3351 ui::TouchEvent press2(
3217 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow()); 3352 ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow());
3218 view_->OnTouchEvent(&press2); 3353 view_->OnTouchEvent(&press2);
3219 SendInputEventACK(blink::WebInputEvent::TouchStart, 3354 SendInputEventACK(blink::WebInputEvent::TouchStart,
3220 INPUT_EVENT_ACK_STATE_CONSUMED); 3355 INPUT_EVENT_ACK_STATE_CONSUMED);
3221 3356
3222 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count()); 3357 EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count());
3223 } 3358 }
3224 3359
3225 } // namespace content 3360 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698