12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/gpu/gpu_data_manager_impl.h"
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/renderer_host/dip_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/port/browser/render_widget_host_view_port.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/compositor_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_paths.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/content_switches.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/common/url_constants.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/test/browser_test_utils.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/shell/shell.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/content_browser_test.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/content_browser_test_utils.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/video_frame.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/filters/skcanvas_video_renderer.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h"
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/skia/include/core/SkBitmap.h"
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/skia/include/core/SkCanvas.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/skia/include/core/SkDevice.h"
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/base/ui_base_switches.h"
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/size_conversions.h"
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/gl/gl_switches.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gl/io_surface_support_mac.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/base/win/dpi.h"
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Convenience macro: Short-circuit a pass for the tests where platform support
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// for forced-compositing mode (or disabled-compositing mode) is lacking.
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define SET_UP_SURFACE_OR_PASS_TEST(wait_message)  \
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!SetUpSourceSurface(wait_message)) {  \
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING)  \
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        << ("Blindly passing this test: This platform does not support "  \
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            "forced compositing (or forced-disabled compositing) mode.");  \
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;  \
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Convenience macro: Short-circuit a pass for platforms where setting up
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// high-DPI fails.
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#define PASS_TEST_IF_SCALE_FACTOR_NOT_SUPPORTED(factor) \
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (ui::GetScaleFactorScale( \
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          GetScaleFactorForView(GetRenderWidgetHostViewPort())) != factor) {  \
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LOG(WARNING) << "Blindly passing this test: failed to set up "  \
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    "scale factor: " << factor;  \
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return false;  \
63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Common base class for browser tests.  This is subclassed twice: Once to test
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// the browser in forced-compositing mode, and once to test with compositing
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// mode disabled.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewBrowserTest()
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : frame_size_(400, 300),
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        callback_invoke_count_(0),
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        frames_captured_(0) {}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ContentBrowserTest::SetUpInProcessBrowserTestFixture();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Attempts to set up the source surface.  Returns false if unsupported on the
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // current platform.
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool SetUpSourceSurface(const char* wait_message) = 0;
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int callback_invoke_count() const {
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return callback_invoke_count_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int frames_captured() const {
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return frames_captured_;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gfx::Size& frame_size() const {
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return frame_size_;
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const base::FilePath& test_dir() const {
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return test_dir_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderViewHost* GetRenderViewHost() const {
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(rvh);
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return rvh;
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostImpl* GetRenderWidgetHost() const {
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From(
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        shell()->web_contents()->GetRenderWidgetHostView()->
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            GetRenderWidgetHost());
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(rwh);
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return rwh;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const {
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetHostViewPort* const view =
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        RenderWidgetHostViewPort::FromRWHV(GetRenderViewHost()->GetView());
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(view);
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return view;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using CopyFromBackingStore() API.
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FinishCopyFromBackingStore(const base::Closure& quit_closure,
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  bool frame_captured,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const SkBitmap& bitmap) {
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured) {
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(bitmap.empty());
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!quit_closure.is_null())
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      quit_closure.Run();
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                        bool frame_captured) {
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!quit_closure.is_null())
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      quit_closure.Run();
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using frame subscriber API.
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop,
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      base::Closure quit_closure,
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      base::Time timestamp,
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      bool frame_captured) {
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured)
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!quit_closure.is_null())
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      loop->PostTask(FROM_HERE, quit_closure);
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Copy one frame using the CopyFromBackingStore API.
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void RunBasicCopyFromBackingStoreTest() {
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SET_UP_SURFACE_OR_PASS_TEST(NULL);
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Windows), the operation will fail until the first "present" has been
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // made.
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int count_attempts = 0;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    while (true) {
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++count_attempts;
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::RunLoop run_loop;
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetRenderViewHost()->CopyFromBackingStore(
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          gfx::Rect(),
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          frame_size(),
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              base::Unretained(this),
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              run_loop.QuitClosure()));
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      run_loop.Run();
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (frames_captured())
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        break;
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      else
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        GiveItSomeTime();
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(count_attempts, callback_invoke_count());
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(1, frames_captured());
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Waits until the source is available for copying.
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void WaitForCopySourceReady() {
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    while (!GetRenderWidgetHostViewPort()->IsSurfaceAvailableForCopy())
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GiveItSomeTime();
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Run the current message loop for a short time without unwinding the current
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // call stack.
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static void GiveItSomeTime() {
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::RunLoop run_loop;
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        FROM_HERE,
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        run_loop.QuitClosure(),
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(10));
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    run_loop.Run();
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gfx::Size frame_size_;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_dir_;
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int callback_invoke_count_;
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int frames_captured_;
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class CompositingRenderWidgetHostViewBrowserTest
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : public RenderWidgetHostViewBrowserTest {
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
214a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  virtual void SetUp() OVERRIDE {
215a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch    // We expect real pixel output for these tests.
216a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch    UseRealGLContexts();
217a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
218a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch    // On legacy windows, these tests need real GL bindings to pass.
219a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(OS_WIN) && !defined(USE_AURA)
220a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch    UseRealGLBindings();
221a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif
222a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
223a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch    RenderWidgetHostViewBrowserTest::SetUp();
224a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch  }
225a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Note: Not appending kForceCompositingMode switch here, since not all bots
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // support compositing.  Some bots will run with compositing on, and others
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // won't.  Therefore, the call to SetUpSourceSurface() later on will detect
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // whether compositing mode is actually on or not.  If not, the tests will
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // pass blindly, logging a warning message, since we cannot test what the
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // platform/implementation does not support.
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual GURL TestUrl() {
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return net::FilePathToFileURL(
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        test_dir().AppendASCII("rwhv_compositing_animation.html"));
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!IsForceCompositingModeEnabled())
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;  // See comment in SetUpCommandLine().
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_MACOSX)
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(IOSurfaceSupport::Initialize());
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    content::DOMMessageQueue message_queue;
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NavigateToURL(shell(), TestUrl());
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (wait_message != NULL) {
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      std::string result(wait_message);
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (!message_queue.WaitForMessage(&result)) {
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        return false;
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(USE_AURA)
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!GetRenderWidgetHost()->is_accelerated_compositing_active())
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;  // Renderer did not turn on accelerated compositing.
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Using accelerated compositing, but a compositing surface might not be
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // available yet.  So, wait for it.
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WaitForCopySourceReady();
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NonCompositingRenderWidgetHostViewBrowserTest
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : public RenderWidgetHostViewBrowserTest {
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Note: Appending the kDisableAcceleratedCompositing switch here, but there
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // are some builds that only use compositing and will ignore this switch.
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Therefore, the call to SetUpSourceSurface() later on will detect whether
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // compositing mode is actually off.  If it's on, the tests will pass
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // blindly, logging a warning message, since we cannot test what the
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // platform/implementation does not support.
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual GURL TestUrl() {
2852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return GURL(kAboutBlankURL);
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (IsForceCompositingModeEnabled())
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;  // See comment in SetUpCommandLine().
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    content::DOMMessageQueue message_queue;
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NavigateToURL(shell(), TestUrl());
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (wait_message != NULL) {
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      std::string result(wait_message);
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (!message_queue.WaitForMessage(&result)) {
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        return false;
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WaitForCopySourceReady();
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Return whether the renderer left accelerated compositing turned off.
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return !GetRenderWidgetHost()->is_accelerated_compositing_active();
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeFrameSubscriber(
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : callback_(callback) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldCaptureFrame(
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Time present_time,
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<media::VideoFrame>* storage,
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DeliverFrameCallback* callback) OVERRIDE {
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Only allow one frame capture to be made.  Otherwise, the compositor could
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // start multiple captures, unbounded, and eventually its own limiter logic
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // will begin invoking |callback| with a |false| result.  This flakes out
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the unit tests, since they receive a "failed" callback before the later
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // "success" callbacks.
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (callback_.is_null())
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *callback = callback_;
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Reset();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeliverFrameCallback callback_;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Disable tests for Android and IOS as these platforms have incomplete
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// implementation.
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The CopyFromBackingStore() API should work on all platforms when compositing
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// is enabled.
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromBackingStore) {
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunBasicCopyFromBackingStoreTest();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The CopyFromBackingStore() API should work on all platforms when compositing
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// is disabled.
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromBackingStore) {
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunBasicCopyFromBackingStoreTest();
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Tests that the callback passed to CopyFromBackingStore is always called,
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// even when the RenderWidgetHost is deleting in the middle of an async copy.
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromBackingStore_CallbackDespiteDelete) {
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GetRenderViewHost()->CopyFromBackingStore(
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(),
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      frame_size(),
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this), run_loop.QuitClosure()));
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Delete the surface before the callback is run.
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease();
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, callback_invoke_count());
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// always called, even when the RenderWidgetHost is deleting in the middle of
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// an async copy.
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromCompositingSurface_CallbackDespiteDelete) {
3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanCopyToVideoFrame()) {
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) <<
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         "not supported on this platform.");
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
386a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<media::VideoFrame> dest =
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Unretained(this), run_loop.QuitClosure()));
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Delete the surface before the callback is run.
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->AcceleratedSurfaceRelease();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, callback_invoke_count());
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// With compositing turned off, no platforms should support the
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// CopyFromCompositingSurfaceToVideoFrame() API.
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromCompositingSurfaceToVideoFrameCallbackTest) {
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame());
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Test basic frame subscription functionality.  We subscribe, and then run
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// until at least one DeliverFrameCallback has been invoked.
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FrameSubscriberTest) {
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanSubscribeFrame()) {
41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "supported on this platform.");
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::RunLoop run_loop;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new FakeFrameSubscriber(
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     base::Unretained(this),
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     base::MessageLoopProxy::current(),
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     run_loop.QuitClosure())));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->BeginFrameSubscription(subscriber.Pass());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->EndFrameSubscription();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_LE(1, callback_invoke_count());
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_LE(1, frames_captured());
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that we can copy twice from an accelerated composited page.
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanCopyToVideoFrame()) {
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) << ("Blindly passing this test: "
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "CopyFromCompositingSurfaceToVideoFrame() not supported "
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "on this platform.");
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<media::VideoFrame> first_output =
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(first_output.get());
45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<media::VideoFrame> second_output =
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(second_output.get());
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()),
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      first_output,
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this),
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::MessageLoopProxy::current(),
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Closure(),
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Time::Now()));
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()), second_output,
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this),
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::MessageLoopProxy::current(),
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 run_loop.QuitClosure(),
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Time::Now()));
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2, callback_invoke_count());
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2, frames_captured());
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass CompositingRenderWidgetHostViewBrowserTestTabCapture
4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : public CompositingRenderWidgetHostViewBrowserTest {
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CompositingRenderWidgetHostViewBrowserTestTabCapture()
4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : expected_copy_from_compositing_surface_result_(false),
4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        allowable_error_(0),
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        test_url_("data:text/html,<!doctype html>") {}
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void CopyFromCompositingSurfaceCallback(base::Closure quit_callback,
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          bool result,
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          const SkBitmap& bitmap) {
4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!result) {
4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quit_callback.Run();
4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
4907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SkBitmap& expected_bitmap =
4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        expected_copy_from_compositing_surface_bitmap_;
4947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_bitmap.width(), bitmap.width());
4957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_bitmap.height(), bitmap.height());
4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_bitmap.config(), bitmap.config());
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkAutoLockPixels bitmap_lock(bitmap);
4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int fails = 0;
5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!exclude_rect_.IsEmpty() && exclude_rect_.Contains(i, j))
5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        SkColor expected_color = expected_bitmap.getColor(i, j);
5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        SkColor color = bitmap.getColor(i, j);
5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_alpha = SkColorGetA(expected_color);
5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int alpha = SkColorGetA(color);
5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_red = SkColorGetR(expected_color);
5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int red = SkColorGetR(color);
5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_green = SkColorGetG(expected_color);
5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int green = SkColorGetG(color);
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_blue = SkColorGetB(expected_color);
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int blue = SkColorGetB(color);
5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_alpha, alpha, allowable_error_)
5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_red, red, allowable_error_)
5217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
5237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
5257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_green, green, allowable_error_)
5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
5297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
5307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_blue, blue, allowable_error_)
5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
5347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
5357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
5377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_LT(fails, 10);
5387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_callback.Run();
5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void CopyFromCompositingSurfaceCallbackForVideo(
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_refptr<media::VideoFrame> video_frame,
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Closure quit_callback,
5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      bool result) {
5467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
5477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!result) {
5487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quit_callback.Run();
5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
5517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    media::SkCanvasVideoRenderer video_renderer;
5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkBitmap bitmap;
5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bitmap.setConfig(SkBitmap::kARGB_8888_Config,
5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     video_frame->visible_rect().width(),
5577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     video_frame->visible_rect().height());
5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bitmap.allocPixels();
5597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bitmap.setIsOpaque(true);
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkDevice device(bitmap);
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkCanvas canvas(&device);
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    video_renderer.Paint(video_frame.get(),
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         &canvas,
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         video_frame->visible_rect(),
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         0xff);
5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CopyFromCompositingSurfaceCallback(quit_callback,
5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       result,
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       bitmap);
5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetExpectedCopyFromCompositingSurfaceResult(bool result,
5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                   const SkBitmap& bitmap) {
5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    expected_copy_from_compositing_surface_result_ = result;
5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    expected_copy_from_compositing_surface_bitmap_ = bitmap;
5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetAllowableError(int amount) { allowable_error_ = amount; }
5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetExcludeRect(gfx::Rect exclude) { exclude_rect_ = exclude; }
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual GURL TestUrl() OVERRIDE {
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return GURL(test_url_);
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetTestUrl(std::string url) { test_url_ = url; }
5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
589558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Loads a page two boxes side-by-side, each half the width of
590558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // |html_rect_size|, and with different background colors. The test then
591558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // copies from |copy_rect| region of the page into a bitmap of size
592558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // |output_size|, and compares that with a bitmap of size
593558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // |expected_bitmap_size|.
594558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Note that |output_size| may not have the same size as |copy_rect| (e.g.
595558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // when the output is scaled). Also note that |expected_bitmap_size| may not
596558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // be the same as |output_size| (e.g. when the device scale factor is not 1).
597558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void PerformTestWithLeftRightRects(const gfx::Size& html_rect_size,
598558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     const gfx::Rect& copy_rect,
599558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     const gfx::Size& output_size,
600558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     const gfx::Size& expected_bitmap_size,
601558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     bool video_frame) {
602558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const gfx::Size box_size(html_rect_size.width() / 2,
603558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                             html_rect_size.height());
604558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetTestUrl(base::StringPrintf(
605558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "data:text/html,<!doctype html>"
606558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<div class='left'>"
607558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  <div class='right'></div>"
608558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</div>"
609558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<style>"
610558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "body { padding: 0; margin: 0; }"
611558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ".left { position: absolute;"
612558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        background: #0ff;"
613558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        width: %dpx;"
614558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        height: %dpx;"
615558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "}"
616558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ".right { position: absolute;"
617558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         left: %dpx;"
618558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         background: #ff0;"
619558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         width: %dpx;"
620558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         height: %dpx;"
621558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "}"
622558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</style>"
623558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<script>"
624558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  domAutomationController.setAutomationId(0);"
625558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  domAutomationController.send(\"DONE\");"
626558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</script>",
627558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
628558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.height(),
629558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
630558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
631558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.height()));
632558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
633558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
634558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!ShouldContinueAfterTestURLLoad())
635558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return;
636558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
637558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    RenderWidgetHostViewPort* rwhvp = GetRenderWidgetHostViewPort();
638558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
639558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // The page is loaded in the renderer, wait for a new frame to arrive.
640558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    uint32 frame = rwhvp->RendererFrameNumber();
641558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    GetRenderWidgetHost()->ScheduleComposite();
642558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    while (rwhvp->RendererFrameNumber() == frame)
643558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      GiveItSomeTime();
644558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
645558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SkBitmap expected_bitmap;
646558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetupLeftRightBitmap(expected_bitmap_size, &expected_bitmap);
647558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
648558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
649558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::RunLoop run_loop;
650558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (video_frame) {
651558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // Allow pixel differences as long as we have the right idea.
652558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetAllowableError(0x10);
653558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // Exclude the middle two columns which are blended between the two sides.
654558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetExcludeRect(
655558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height()));
656558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
657558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      scoped_refptr<media::VideoFrame> video_frame =
658558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
659d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                         expected_bitmap_size,
660d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                         gfx::Rect(expected_bitmap_size),
661d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                         expected_bitmap_size,
662558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                         base::TimeDelta());
663558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
664558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Callback<void(bool success)> callback =
665558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
666558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                         CopyFromCompositingSurfaceCallbackForVideo,
667558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     base::Unretained(this),
668558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     video_frame,
669558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     run_loop.QuitClosure());
670558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      rwhvp->CopyFromCompositingSurfaceToVideoFrame(copy_rect,
671558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                    video_frame,
672558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                    callback);
673558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    } else {
674558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Callback<void(bool, const SkBitmap&)> callback =
675558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
676558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                       CopyFromCompositingSurfaceCallback,
677558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   base::Unretained(this),
678558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   run_loop.QuitClosure());
679558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      rwhvp->CopyFromCompositingSurface(copy_rect, output_size, callback);
680558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
681558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    run_loop.Run();
682558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
683558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
684558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Sets up |bitmap| to have size |copy_size|. It floods the left half with
685558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // #0ff and the right half with #ff0.
686558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetupLeftRightBitmap(const gfx::Size& copy_size, SkBitmap* bitmap) {
687558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bitmap->setConfig(
688558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        SkBitmap::kARGB_8888_Config, copy_size.width(), copy_size.height());
689558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bitmap->allocPixels();
690558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Left half is #0ff.
691558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bitmap->eraseARGB(255, 0, 255, 255);
692558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Right half is #ff0.
693558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    {
694558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SkAutoLockPixels lock(*bitmap);
695558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      for (int i = 0; i < copy_size.width() / 2; ++i) {
696558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        for (int j = 0; j < copy_size.height(); ++j) {
697558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          *(bitmap->getAddr32(copy_size.width() / 2 + i, j)) =
698558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch              SkColorSetARGB(255, 255, 255, 0);
699558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        }
700558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
701558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
702558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
703558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
704558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected:
705558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual bool ShouldContinueAfterTestURLLoad() {
706558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return true;
707558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
708558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
7107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool expected_copy_from_compositing_surface_result_;
7117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SkBitmap expected_copy_from_compositing_surface_bitmap_;
7127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int allowable_error_;
7137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  gfx::Rect exclude_rect_;
7147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string test_url_;
7157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
7167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7177dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Origin_Unscaled) {
719558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
720558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
721558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
722558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
723558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
724558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
725558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
726558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
727558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
728558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7317dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Origin_Scaled) {
733558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
734558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(200, 100);
735558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
736558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
737558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
738558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
739558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
740558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
741558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
742558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7457dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Cropped_Unscaled) {
7477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 60x60 pixels from the center of the tab contents.
748558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
749558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
750558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(60, 60));
751558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
752558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
753558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
754558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
755558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
756558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
757558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
758558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
759558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7627dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Cropped_Scaled) {
7647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 60x60 pixels from the center of the tab contents.
765558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
766558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
767558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(60, 60));
768558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(20, 10);
769558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
770558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
771558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
772558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
773558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
774558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
775558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
776558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_ForVideoFrame) {
7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
782558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
783558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
784558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(90, 60));
785558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
786558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
787558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
788558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = true;
789558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
790558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
791558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
792558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
793558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7967dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_ForVideoFrame_Scaled) {
7987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
799558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
800558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
801558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(90, 60));
8027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Scale to 30 x 20 (preserve aspect ratio).
803558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(30, 20);
804558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size expected_bitmap_size = output_size;
805558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
806558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = true;
807558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
808558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
809558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
810558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
811558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
812558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
8137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
814558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass CompositingRenderWidgetHostViewTabCaptureHighDPI
815558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : public CompositingRenderWidgetHostViewBrowserTestTabCapture {
816558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
817558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  CompositingRenderWidgetHostViewTabCaptureHighDPI()
818558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      : kScale(2.f) {
819558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
8207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
821558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
822558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    CompositingRenderWidgetHostViewBrowserTestTabCapture::SetUpCommandLine(cmd);
823558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    cmd->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
824558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                           base::StringPrintf("%f", scale()));
825558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
826558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    cmd->AppendSwitchASCII(switches::kHighDPISupport, "1");
827558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::EnableHighDPISupport();
828558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
8297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
8307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
831558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  float scale() const { return kScale; }
832558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
833558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch private:
834558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual bool ShouldContinueAfterTestURLLoad() OVERRIDE {
835558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    PASS_TEST_IF_SCALE_FACTOR_NOT_SUPPORTED(scale());
836558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return true;
837558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
838558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
839558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const float kScale;
840558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
841558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewTabCaptureHighDPI);
842558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
843558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
844558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewTabCaptureHighDPI,
845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       CopyFromCompositingSurface) {
846558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(200, 150);
847d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size output_size = copy_rect.size();
848d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size expected_bitmap_size =
849d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      gfx::ToFlooredSize(gfx::ScaleSize(output_size, scale(), scale()));
850558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(200, 150);
851558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
852558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
853558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
854d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                output_size,
855d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                expected_bitmap_size,
856d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                video_frame);
857d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
858d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
859d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewTabCaptureHighDPI,
860a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       CopyFromCompositingSurfaceVideoFrame) {
861d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size html_rect_size(200, 150);
862d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
863d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Rect copy_rect =
864d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      gfx::Rect(gfx::Rect(html_rect_size).CenterPoint() - gfx::Vector2d(45, 30),
865d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                gfx::Size(90, 60));
866d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size output_size = copy_rect.size();
867d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size expected_bitmap_size =
868d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      gfx::ToFlooredSize(gfx::ScaleSize(output_size, scale(), scale()));
869d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool video_frame = true;
870d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
871d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                copy_rect,
872d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                output_size,
873558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                expected_bitmap_size,
874558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
8757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
87790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
87890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
881