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"
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/browser/gpu/compositor_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/gpu/gpu_data_manager_impl.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/renderer_host/dip_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_view_base.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_paths.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/content_switches.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/common/url_constants.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/test/browser_test_utils.h"
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h"
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h"
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/video_frame.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/filters/skcanvas_video_renderer.h"
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h"
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/skia/include/core/SkBitmap.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/skia/include/core/SkCanvas.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/layout.h"
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/base/ui_base_switches.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/gfx/geometry/size_conversions.h"
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/switches.h"
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/gl/gl_switches.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/win/windows_version.h"
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/dpi.h"
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Convenience macro: Short-circuit a pass for the tests where platform support
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// for forced-compositing mode (or disabled-compositing mode) is lacking.
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define SET_UP_SURFACE_OR_PASS_TEST(wait_message)  \
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!SetUpSourceSurface(wait_message)) {  \
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING)  \
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        << ("Blindly passing this test: This platform does not support "  \
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            "forced compositing (or forced-disabled compositing) mode.");  \
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;  \
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Common base class for browser tests.  This is subclassed twice: Once to test
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// the browser in forced-compositing mode, and once to test with compositing
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// mode disabled.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostViewBrowserTest()
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : frame_size_(400, 300),
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        callback_invoke_count_(0),
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        frames_captured_(0) {}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Attempts to set up the source surface.  Returns false if unsupported on the
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // current platform.
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool SetUpSourceSurface(const char* wait_message) = 0;
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int callback_invoke_count() const {
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return callback_invoke_count_;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int frames_captured() const {
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return frames_captured_;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gfx::Size& frame_size() const {
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return frame_size_;
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const base::FilePath& test_dir() const {
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return test_dir_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderViewHost* GetRenderViewHost() const {
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(rvh);
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return rvh;
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RenderWidgetHostImpl* GetRenderWidgetHost() const {
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From(
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        shell()->web_contents()->GetRenderWidgetHostView()->
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            GetRenderWidgetHost());
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(rwh);
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return rwh;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return static_cast<RenderWidgetHostViewBase*>(
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        GetRenderViewHost()->GetView());
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using CopyFromBackingStore() API.
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FinishCopyFromBackingStore(const base::Closure& quit_closure,
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  bool frame_captured,
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const SkBitmap& bitmap) {
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured) {
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(bitmap.empty());
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!quit_closure.is_null())
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      quit_closure.Run();
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                        bool frame_captured) {
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured)
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!quit_closure.is_null())
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      quit_closure.Run();
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Callback when using frame subscriber API.
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop,
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      base::Closure quit_closure,
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      base::TimeTicks timestamp,
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      bool frame_captured) {
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++callback_invoke_count_;
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (frame_captured)
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++frames_captured_;
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!quit_closure.is_null())
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      loop->PostTask(FROM_HERE, quit_closure);
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Copy one frame using the CopyFromBackingStore API.
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void RunBasicCopyFromBackingStoreTest() {
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SET_UP_SURFACE_OR_PASS_TEST(NULL);
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Windows), the operation will fail until the first "present" has been
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // made.
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int count_attempts = 0;
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    while (true) {
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ++count_attempts;
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::RunLoop run_loop;
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetRenderViewHost()->CopyFromBackingStore(
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          gfx::Rect(),
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          frame_size(),
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              base::Unretained(this),
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              run_loop.QuitClosure()),
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          kN32_SkColorType);
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      run_loop.Run();
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (frames_captured())
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        break;
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      else
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        GiveItSomeTime();
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(count_attempts, callback_invoke_count());
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(1, frames_captured());
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Waits until the source is available for copying.
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void WaitForCopySourceReady() {
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    while (!GetRenderWidgetHostView()->IsSurfaceAvailableForCopy())
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GiveItSomeTime();
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Run the current message loop for a short time without unwinding the current
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // call stack.
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static void GiveItSomeTime() {
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::RunLoop run_loop;
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        FROM_HERE,
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        run_loop.QuitClosure(),
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(10));
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    run_loop.Run();
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gfx::Size frame_size_;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_dir_;
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int callback_invoke_count_;
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int frames_captured_;
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum CompositingMode {
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GL_COMPOSITING,
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SOFTWARE_COMPOSITING,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class CompositingRenderWidgetHostViewBrowserTest
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public RenderWidgetHostViewBrowserTest,
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      public testing::WithParamInterface<CompositingMode> {
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit CompositingRenderWidgetHostViewBrowserTest()
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : compositing_mode_(GetParam()) {}
209c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (compositing_mode_ == SOFTWARE_COMPOSITING)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      UseSoftwareCompositing();
213c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    RenderWidgetHostViewBrowserTest::SetUp();
214c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
215c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual GURL TestUrl() {
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return net::FilePathToFileURL(
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        test_dir().AppendASCII("rwhv_compositing_animation.html"));
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    content::DOMMessageQueue message_queue;
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NavigateToURL(shell(), TestUrl());
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (wait_message != NULL) {
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      std::string result(wait_message);
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (!message_queue.WaitForMessage(&result)) {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        return false;
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // A frame might not be available yet. So, wait for it.
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WaitForCopySourceReady();
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CompositingMode compositing_mode_;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewBrowserTest);
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeFrameSubscriber(
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : callback_(callback) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  base::TimeTicks present_time,
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  scoped_refptr<media::VideoFrame>* storage,
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  DeliverFrameCallback* callback) OVERRIDE {
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Only allow one frame capture to be made.  Otherwise, the compositor could
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // start multiple captures, unbounded, and eventually its own limiter logic
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // will begin invoking |callback| with a |false| result.  This flakes out
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the unit tests, since they receive a "failed" callback before the later
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // "success" callbacks.
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (callback_.is_null())
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *callback = callback_;
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Reset();
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeliverFrameCallback callback_;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Disable tests for Android and IOS as these platforms have incomplete
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// implementation.
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The CopyFromBackingStore() API should work on all platforms when compositing
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// is enabled.
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromBackingStore) {
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunBasicCopyFromBackingStoreTest();
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Tests that the callback passed to CopyFromBackingStore is always called,
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// even when the RenderWidgetHost is deleting in the middle of an async copy.
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       CopyFromBackingStore_CallbackDespiteDelete) {
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GetRenderViewHost()->CopyFromBackingStore(
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(),
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      frame_size(),
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this),
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 run_loop.QuitClosure()),
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      kN32_SkColorType);
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Delete the surface before the callback is run.
297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GetRenderWidgetHostView()->AcceleratedSurfaceRelease();
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, callback_invoke_count());
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// always called, even when the RenderWidgetHost is deleting in the middle of
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// an async copy.
3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test is flaky on Win. http://crbug.com/276783
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) || (defined(OS_CHROMEOS) && !defined(NDEBUG))
3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISABLED_CopyFromCompositingSurface_CallbackDespiteDelete
3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else
3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CopyFromCompositingSurface_CallbackDespiteDelete
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete) {
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanCopyToVideoFrame()) {
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) <<
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         "not supported on this platform.");
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
325c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<media::VideoFrame> dest =
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Unretained(this), run_loop.QuitClosure()));
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Delete the surface before the callback is run.
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->AcceleratedSurfaceRelease();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, callback_invoke_count());
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Test basic frame subscription functionality.  We subscribe, and then run
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// until at least one DeliverFrameCallback has been invoked.
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FrameSubscriberTest) {
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanSubscribeFrame()) {
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "supported on this platform.");
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::RunLoop run_loop;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new FakeFrameSubscriber(
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     base::Unretained(this),
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     base::MessageLoopProxy::current(),
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     run_loop.QuitClosure())));
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->BeginFrameSubscription(subscriber.Pass());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->EndFrameSubscription();
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_LE(1, callback_invoke_count());
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_LE(1, frames_captured());
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that we can copy twice from an accelerated composited page.
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SET_UP_SURFACE_OR_PASS_TEST(NULL);
370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!view->CanCopyToVideoFrame()) {
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(WARNING) << ("Blindly passing this test: "
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "CopyFromCompositingSurfaceToVideoFrame() not supported "
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "on this platform.");
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<media::VideoFrame> first_output =
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(first_output.get());
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<media::VideoFrame> second_output =
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      media::VideoFrame::CreateBlackFrame(frame_size());
384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(second_output.get());
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()),
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      first_output,
38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this),
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::MessageLoopProxy::current(),
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Closure(),
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::TimeTicks::Now()));
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view->CopyFromCompositingSurfaceToVideoFrame(
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::Rect(view->GetViewBounds().size()),
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      second_output,
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this),
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::MessageLoopProxy::current(),
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 run_loop.QuitClosure(),
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::TimeTicks::Now()));
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2, callback_invoke_count());
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2, frames_captured());
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass CompositingRenderWidgetHostViewBrowserTestTabCapture
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : public CompositingRenderWidgetHostViewBrowserTest {
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CompositingRenderWidgetHostViewBrowserTestTabCapture()
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : expected_copy_from_compositing_surface_result_(false),
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        allowable_error_(0),
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        test_url_("data:text/html,<!doctype html>") {}
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EnablePixelOutput();
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTest::SetUp();
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void CopyFromCompositingSurfaceCallback(base::Closure quit_callback,
4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          bool result,
4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          const SkBitmap& bitmap) {
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!result) {
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quit_callback.Run();
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SkBitmap& expected_bitmap =
4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        expected_copy_from_compositing_surface_bitmap_;
4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_bitmap.width(), bitmap.width());
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_bitmap.height(), bitmap.height());
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_EQ(expected_bitmap.colorType(), bitmap.colorType());
4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkAutoLockPixels bitmap_lock(bitmap);
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int fails = 0;
4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!exclude_rect_.IsEmpty() && exclude_rect_.Contains(i, j))
4407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        SkColor expected_color = expected_bitmap.getColor(i, j);
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        SkColor color = bitmap.getColor(i, j);
4447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_alpha = SkColorGetA(expected_color);
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int alpha = SkColorGetA(color);
4467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_red = SkColorGetR(expected_color);
4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int red = SkColorGetR(color);
4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_green = SkColorGetG(expected_color);
4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int green = SkColorGetG(color);
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int expected_blue = SkColorGetB(expected_color);
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int blue = SkColorGetB(color);
4527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_alpha, alpha, allowable_error_)
4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
4547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_red, red, allowable_error_)
4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
4627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_green, green, allowable_error_)
4637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
4657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
4667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
4677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        EXPECT_NEAR(expected_blue, blue, allowable_error_)
4687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << "expected_color: " << std::hex << expected_color
4697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " color: " <<  color
4707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failed at " << std::dec << i << ", " << j
4717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            << " Failure " << ++fails;
4727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_LT(fails, 10);
4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_callback.Run();
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void CopyFromCompositingSurfaceCallbackForVideo(
4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_refptr<media::VideoFrame> video_frame,
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Closure quit_callback,
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      bool result) {
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!result) {
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quit_callback.Run();
4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    media::SkCanvasVideoRenderer video_renderer;
4907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkBitmap bitmap;
492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bitmap.allocN32Pixels(video_frame->visible_rect().width(),
493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          video_frame->visible_rect().height());
49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Don't clear the canvas because drawing a video frame by Src mode.
495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SkCanvas canvas(bitmap);
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    video_renderer.Copy(video_frame, &canvas);
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CopyFromCompositingSurfaceCallback(quit_callback,
4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       result,
5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       bitmap);
5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetExpectedCopyFromCompositingSurfaceResult(bool result,
5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                   const SkBitmap& bitmap) {
5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    expected_copy_from_compositing_surface_result_ = result;
5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    expected_copy_from_compositing_surface_bitmap_ = bitmap;
5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetAllowableError(int amount) { allowable_error_ = amount; }
5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetExcludeRect(gfx::Rect exclude) { exclude_rect_ = exclude; }
5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual GURL TestUrl() OVERRIDE {
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return GURL(test_url_);
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetTestUrl(std::string url) { test_url_ = url; }
5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
518558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Loads a page two boxes side-by-side, each half the width of
519558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // |html_rect_size|, and with different background colors. The test then
520558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // copies from |copy_rect| region of the page into a bitmap of size
5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // |output_size|, and examines the resulting bitmap/VideoFrame.
522558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Note that |output_size| may not have the same size as |copy_rect| (e.g.
5236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // when the output is scaled).
524558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void PerformTestWithLeftRightRects(const gfx::Size& html_rect_size,
525558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     const gfx::Rect& copy_rect,
526558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     const gfx::Size& output_size,
527558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     bool video_frame) {
528558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const gfx::Size box_size(html_rect_size.width() / 2,
529558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                             html_rect_size.height());
530558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetTestUrl(base::StringPrintf(
531558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "data:text/html,<!doctype html>"
532558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<div class='left'>"
533558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  <div class='right'></div>"
534558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</div>"
535558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<style>"
536558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "body { padding: 0; margin: 0; }"
537558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ".left { position: absolute;"
538558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        background: #0ff;"
539558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        width: %dpx;"
540558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "        height: %dpx;"
541558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "}"
542558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ".right { position: absolute;"
543558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         left: %dpx;"
544558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         background: #ff0;"
545558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         width: %dpx;"
546558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "         height: %dpx;"
547558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "}"
548558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</style>"
549558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "<script>"
550558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  domAutomationController.setAutomationId(0);"
551558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "  domAutomationController.send(\"DONE\");"
552558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "</script>",
553558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
554558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.height(),
555558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
556558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.width(),
557558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        box_size.height()));
558558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
559558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
560558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!ShouldContinueAfterTestURLLoad())
561558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return;
562558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    RenderWidgetHostViewBase* rwhvp = GetRenderWidgetHostView();
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (video_frame && !rwhvp->CanCopyToVideoFrame()) {
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // This should only happen on Mac when using the software compositor.
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Otherwise, raise an error. This can be removed when Mac is moved to a
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // browser compositor.
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // http://crbug.com/314190
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_MACOSX)
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) {
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        LOG(WARNING) << ("Blindly passing this test because copying to "
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         "video frames is not supported on this platform.");
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return;
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
578558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
579558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // The page is loaded in the renderer, wait for a new frame to arrive.
580558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    uint32 frame = rwhvp->RendererFrameNumber();
5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    while (!GetRenderWidgetHost()->ScheduleComposite())
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GiveItSomeTime();
583558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    while (rwhvp->RendererFrameNumber() == frame)
584558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      GiveItSomeTime();
585558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
586558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SkBitmap expected_bitmap;
5876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetupLeftRightBitmap(output_size, &expected_bitmap);
588558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
589558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
590558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::RunLoop run_loop;
591558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (video_frame) {
592558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // Allow pixel differences as long as we have the right idea.
593558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetAllowableError(0x10);
594558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // Exclude the middle two columns which are blended between the two sides.
595558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SetExcludeRect(
596558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height()));
597558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
598558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      scoped_refptr<media::VideoFrame> video_frame =
599558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
6006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         output_size,
6016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         gfx::Rect(output_size),
6026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         output_size,
603558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                         base::TimeDelta());
604558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
605558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Callback<void(bool success)> callback =
606558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
607558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                         CopyFromCompositingSurfaceCallbackForVideo,
608558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     base::Unretained(this),
609558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     video_frame,
610558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                     run_loop.QuitClosure());
611558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      rwhvp->CopyFromCompositingSurfaceToVideoFrame(copy_rect,
612558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                    video_frame,
613558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                    callback);
614558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    } else {
615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (IsDelegatedRendererEnabled()) {
616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (!content::GpuDataManager::GetInstance()
617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 ->CanUseGpuBrowserCompositor()) {
618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          // Skia rendering can cause color differences, particularly in the
619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          // middle two columns.
620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          SetAllowableError(2);
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          SetExcludeRect(gfx::Rect(
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              output_size.width() / 2 - 1, 0, 2, output_size.height()));
623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }
6248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
626558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Callback<void(bool, const SkBitmap&)> callback =
627558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
628558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                       CopyFromCompositingSurfaceCallback,
629558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   base::Unretained(this),
630558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   run_loop.QuitClosure());
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rwhvp->CopyFromCompositingSurface(copy_rect,
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        output_size,
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        callback,
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                        kN32_SkColorType);
635558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
636558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    run_loop.Run();
637558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
638558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
639558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Sets up |bitmap| to have size |copy_size|. It floods the left half with
640558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // #0ff and the right half with #ff0.
641558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetupLeftRightBitmap(const gfx::Size& copy_size, SkBitmap* bitmap) {
642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bitmap->allocN32Pixels(copy_size.width(), copy_size.height());
643558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Left half is #0ff.
644558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bitmap->eraseARGB(255, 0, 255, 255);
645558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Right half is #ff0.
646558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    {
647558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      SkAutoLockPixels lock(*bitmap);
648558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      for (int i = 0; i < copy_size.width() / 2; ++i) {
649558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        for (int j = 0; j < copy_size.height(); ++j) {
650558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          *(bitmap->getAddr32(copy_size.width() / 2 + i, j)) =
651558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch              SkColorSetARGB(255, 255, 255, 0);
652558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        }
653558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
654558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
655558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
656558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
657558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected:
658558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual bool ShouldContinueAfterTestURLLoad() {
659558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return true;
660558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
661558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
6627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool expected_copy_from_compositing_surface_result_;
6647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SkBitmap expected_copy_from_compositing_surface_bitmap_;
6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int allowable_error_;
6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  gfx::Rect exclude_rect_;
6677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string test_url_;
6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
6717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Origin_Unscaled) {
672558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
673558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
674558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
675558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
676558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
677558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
678558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
679558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
6837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Origin_Scaled) {
684558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
685558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(200, 100);
686558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
687558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
688558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
689558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
690558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
691558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Cropped_Unscaled) {
6967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 60x60 pixels from the center of the tab contents.
697558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
698558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
699558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(60, 60));
700558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
701558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
702558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
703558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
704558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
705558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
706558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_Cropped_Scaled) {
7117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 60x60 pixels from the center of the tab contents.
712558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
713558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
714558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(60, 60));
715558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(20, 10);
716558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
717558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
718558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
719558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
720558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
721558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_ForVideoFrame) {
7267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
727558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
728558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
729558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(90, 60));
730558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size = copy_rect.size();
731558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
732558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = true;
733558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
734558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
735558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
736558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
7377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
7407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       CopyFromCompositingSurface_ForVideoFrame_Scaled) {
7417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
742558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(400, 300);
743558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
744558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        gfx::Size(90, 60));
7457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Scale to 30 x 20 (preserve aspect ratio).
746558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size output_size(30, 20);
747558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(400, 300);
748558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = true;
749558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
750558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
751558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                output_size,
752558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
753558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
7547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
756558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : public CompositingRenderWidgetHostViewBrowserTestTabCapture {
757558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
7586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI() {}
7597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) protected:
7616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void SetUpCommandLine(base::CommandLine* cmd) OVERRIDE {
7626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCapture::SetUpCommandLine(cmd);
763558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    cmd->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
764558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                           base::StringPrintf("%f", scale()));
7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
7667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
767558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual bool ShouldContinueAfterTestURLLoad() OVERRIDE {
768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Short-circuit a pass for platforms where setting up high-DPI fails.
7696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const float actual_scale_factor =
7706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        GetScaleFactorForView(GetRenderWidgetHostView());
7716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (actual_scale_factor != scale()) {
7726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      LOG(WARNING) << "Blindly passing this test; unable to force device scale "
7736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   << "factor: seems to be " << actual_scale_factor
7746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   << " but expected " << scale();
775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
7776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    VLOG(1) << ("Successfully forced device scale factor.  Moving forward with "
7786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                "this test!  :-)");
779558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return true;
780558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
781558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static float scale() { return 2.0f; }
783558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private:
7856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(
7866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI);
787558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
788558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// ImageSkia (related to ResourceBundle) implementation crashes the process on
7906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Windows when this content_browsertest forces a device scale factor.
7916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// http://crbug.com/399349
79203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//
79303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// These tests are flaky on ChromeOS builders.  See http://crbug.com/406018.
79403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_CHROMEOS)
7956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_EntireRegion DISABLED_CopyToBitmap_EntireRegion
7966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_CenterRegion DISABLED_CopyToBitmap_CenterRegion
7976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_ScaledResult DISABLED_CopyToBitmap_ScaledResult
7986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_EntireRegion \
7996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            DISABLED_CopyToVideoFrame_EntireRegion
8006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_CenterRegion \
8016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            DISABLED_CopyToVideoFrame_CenterRegion
8026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_ScaledResult \
8036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            DISABLED_CopyToVideoFrame_ScaledResult
8046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#else
8056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_EntireRegion CopyToBitmap_EntireRegion
8066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_CenterRegion CopyToBitmap_CenterRegion
8076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToBitmap_ScaledResult CopyToBitmap_ScaledResult
8086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_EntireRegion CopyToVideoFrame_EntireRegion
8096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_CenterRegion CopyToVideoFrame_CenterRegion
8106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define MAYBE_CopyToVideoFrame_ScaledResult CopyToVideoFrame_ScaledResult
8116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
8126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToBitmap_EntireRegion) {
8166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size html_rect_size(200, 150);
817558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect copy_rect(200, 150);
8186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Scale the output size so that, internally, scaling is not occurring.
8196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size =
8206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::ToRoundedSize(gfx::ScaleSize(copy_rect.size(), scale()));
8216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool video_frame = false;
8226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  PerformTestWithLeftRightRects(html_rect_size,
8236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                copy_rect,
8246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                output_size,
8256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                video_frame);
8266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
8276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToBitmap_CenterRegion) {
831558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Size html_rect_size(200, 150);
8326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Grab 90x60 pixels from the center of the tab contents.
8336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Rect copy_rect =
8346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::Rect(gfx::Rect(html_rect_size).CenterPoint() - gfx::Vector2d(45, 30),
8356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                gfx::Size(90, 60));
8366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Scale the output size so that, internally, scaling is not occurring.
8376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size =
8386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::ToRoundedSize(gfx::ScaleSize(copy_rect.size(), scale()));
8396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool video_frame = false;
8406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  PerformTestWithLeftRightRects(html_rect_size,
8416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                copy_rect,
8426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                output_size,
8436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                video_frame);
8446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
8456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToBitmap_ScaledResult) {
8496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size html_rect_size(200, 100);
8506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Rect copy_rect(200, 100);
8516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Output is being down-scaled since output_size is in phyiscal pixels.
8526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size(200, 100);
853558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool video_frame = false;
854558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
855558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                copy_rect,
856d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                output_size,
857d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                video_frame);
858d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
859d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
8606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToVideoFrame_EntireRegion) {
8636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size html_rect_size(200, 150);
8646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Rect copy_rect(200, 150);
8656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Scale the output size so that, internally, scaling is not occurring.
8666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size =
8676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::ToRoundedSize(gfx::ScaleSize(copy_rect.size(), scale()));
8686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool video_frame = true;
8696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  PerformTestWithLeftRightRects(html_rect_size,
8706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                copy_rect,
8716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                output_size,
8726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                video_frame);
8736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
8746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToVideoFrame_CenterRegion) {
878d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Size html_rect_size(200, 150);
879d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Grab 90x60 pixels from the center of the tab contents.
880d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gfx::Rect copy_rect =
881d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      gfx::Rect(gfx::Rect(html_rect_size).CenterPoint() - gfx::Vector2d(45, 30),
882d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                gfx::Size(90, 60));
8836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Scale the output size so that, internally, scaling is not occurring.
8846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size =
8856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      gfx::ToRoundedSize(gfx::ScaleSize(copy_rect.size(), scale()));
886d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool video_frame = true;
887d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  PerformTestWithLeftRightRects(html_rect_size,
888d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                copy_rect,
889d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                output_size,
890558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                video_frame);
8917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)IN_PROC_BROWSER_TEST_P(
8946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
8956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MAYBE_CopyToVideoFrame_ScaledResult) {
8966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size html_rect_size(200, 100);
8976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Rect copy_rect(200, 100);
8986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Output is being down-scaled since output_size is in phyiscal pixels.
8996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gfx::Size output_size(200, 100);
9006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool video_frame = true;
9016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  PerformTestWithLeftRightRects(html_rect_size,
9026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                copy_rect,
9036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                output_size,
9046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                video_frame);
9056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        CompositingRenderWidgetHostViewBrowserTest,
9096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        testing::Values(GL_COMPOSITING, SOFTWARE_COMPOSITING));
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        CompositingRenderWidgetHostViewBrowserTestTabCapture,
9126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        testing::Values(GL_COMPOSITING, SOFTWARE_COMPOSITING));
9136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
9146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    GLAndSoftwareCompositing,
9156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
9166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    testing::Values(GL_COMPOSITING, SOFTWARE_COMPOSITING));
9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
91990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
92090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
922