test_compositor_host_mac.mm revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/test/test_compositor_host.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSApplication.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSOpenGL.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSView.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSWindow.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <Foundation/NSAutoreleasePool.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/mac/scoped_nsobject.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AcceleratedTestView provides an NSView class that delegates drawing to a
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ui::Compositor delegate, setting up the NSOpenGLContext as required.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface AcceleratedTestView : NSView {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Compositor* compositor_;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Designated initializer.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation AcceleratedTestView
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The frame will be resized when reparented into the window's view hierarchy.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self = [super initWithFrame:NSZeroRect];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = compositor;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)drawRect:(NSRect)rect {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_) << "Drawing with no compositor set.";
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor_->Draw();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use Objective-C memory semantics need to have a top-level
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NSAutoreleasePool set up and initialized prior to execution and drained upon
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exit.  The tests will leak otherwise.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FoundationHost {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FoundationHost() {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_ = [[NSAutoreleasePool alloc] init];
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FoundationHost() {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [pool_ drain];
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSAutoreleasePool* pool_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FoundationHost);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use the AppKit framework need to have the NSApplication
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialized prior to doing anything with display objects such as windows,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views, or controls.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppKitHost : public FoundationHost {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppKitHost() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [NSApplication sharedApplication];
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppKitHost() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppKitHost);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TestCompositorHostMac provides a window surface and a coordinated compositor
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use in the compositor unit tests.
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestCompositorHostMac : public TestCompositorHost,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public AppKitHost {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestCompositorHostMac(const gfx::Rect& bounds,
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        ui::ContextFactory* context_factory);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestCompositorHostMac();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TestCompositorHost:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Show() OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ui::Compositor* GetCompositor() OVERRIDE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds_;
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui::ContextFactory* context_factory_;
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::Compositor> compositor_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Owned.  Released when window is closed.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSWindow* window_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestCompositorHostMac);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TestCompositorHostMac::TestCompositorHostMac(
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const gfx::Rect& bounds,
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui::ContextFactory* context_factory)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : bounds_(bounds), context_factory_(context_factory), window_(nil) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompositorHostMac::~TestCompositorHostMac() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release reference to |compositor_|.  Important because the |compositor_|
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // holds |this| as its delegate, so that reference must be removed here.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [[window_ contentView] setCompositor:NULL];
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ setContentView:nil];
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ orderOut:nil];
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ close];
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompositorHostMac::Show() {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!window_);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = [[NSWindow alloc]
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                initWithContentRect:NSMakeRect(bounds_.x(),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.y(),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.width(),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.height())
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          styleMask:NSBorderlessWindowMask
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            backing:NSBackingStoreBuffered
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              defer:NO];
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::scoped_nsobject<AcceleratedTestView> view(
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      [[AcceleratedTestView alloc] init]);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  compositor_.reset(new ui::Compositor(view,
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       context_factory_,
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       base::ThreadTaskRunnerHandle::Get()));
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  compositor_->SetScaleAndSize(1.0f, bounds_.size());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [view setCompositor:compositor_.get()];
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ setContentView:view];
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ orderFront:nil];
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Compositor* TestCompositorHostMac::GetCompositor() {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_.get();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TestCompositorHost* TestCompositorHost::Create(
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const gfx::Rect& bounds,
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui::ContextFactory* context_factory) {
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new TestCompositorHostMac(bounds, context_factory);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
155