15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/compositor/image_transport_factory.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/run_loop.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "cc/output/context_provider.h"
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/compositor/owned_mailbox.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/compositor/compositor.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace content {
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)typedef ContentBrowserTest ImageTransportFactoryBrowserTest;
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class MockImageTransportFactoryObserver : public ImageTransportFactoryObserver {
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MOCK_METHOD0(OnLostResources, void());
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This crashes on Mac ASAN: http://crbug.com/335083
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Flaky on ChromeOS: crbug.com/394083
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_TestLostContext DISABLED_TestLostContext
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_TestLostContext TestLostContext
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Checks that upon context loss, the observer is called and the created
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// resources are reset.
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       MAYBE_TestLostContext) {
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This test doesn't make sense in software compositing mode.
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor())
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<OwnedMailbox> mailbox =
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new OwnedMailbox(factory->GetGLHelper());
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(mailbox->mailbox().IsZero());
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockImageTransportFactoryObserver observer;
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  factory->AddObserver(&observer);
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::RunLoop run_loop;
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_CALL(observer, OnLostResources())
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::ContextFactory* context_factory = factory->GetContextFactory();
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gpu::gles2::GLES2Interface* gl =
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      context_factory->SharedMainThreadContextProvider()->ContextGL();
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          GL_INNOCENT_CONTEXT_RESET_ARB);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We have to flush to make sure that the client side gets a chance to notice
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the context is gone.
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gl->Flush();
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  run_loop.Run();
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(mailbox->mailbox().IsZero());
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  factory->RemoveObserver(&observer);
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ImageTransportFactoryTearDownBrowserTest : public ContentBrowserTest {
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ImageTransportFactoryTearDownBrowserTest() {}
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void TearDown() {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (mailbox_.get())
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_TRUE(mailbox_->mailbox().IsZero());
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ContentBrowserTest::TearDown();
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) protected:
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<OwnedMailbox> mailbox_;
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// This crashes on Mac. ImageTransportFactory is NULL unless
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// --enable-delegated-renderer is passed, and after that, we'd need to spawn a
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// renderer and get a frame before we create a browser compositor, necessary for
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the GLHelper to not be NULL.
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// http://crbug.com/335083
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_MACOSX)
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define MAYBE_LoseOnTearDown DISABLED_LoseOnTearDown
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define MAYBE_LoseOnTearDown LoseOnTearDown
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Checks that upon destruction of the ImageTransportFactory, the observer is
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// called and the created resources are reset.
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ImageTransportFactoryTearDownBrowserTest,
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       MAYBE_LoseOnTearDown) {
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // This test doesn't make sense in software compositing mode.
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor())
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GLHelper* helper = factory->GetGLHelper();
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(helper);
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mailbox_ = new OwnedMailbox(helper);
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(mailbox_->mailbox().IsZero());
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // anonymous namespace
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace content
111