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

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: Addressed danakj's and hubbe's comments. 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
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_aura.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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 < 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 < 10; ++i) {
danakj 2015/03/10 20:59:21 (btw 3 would be enough here too right?)
miu 2015/03/10 21:05:21 Oh yeah. Duh. Done; and in the "normal case" loo
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_aura.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698